Fix: lttng: enable-channel: leak of popt arguments
[lttng-tools.git] / src / common / dynamic-array.cpp
1 /*
2 * Copyright (C) 2019 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include <common/dynamic-array.hpp>
9
10 void lttng_dynamic_array_init(struct lttng_dynamic_array *array,
11 size_t element_size,
12 lttng_dynamic_array_element_destructor destructor)
13 {
14 lttng_dynamic_buffer_init(&array->buffer);
15 array->element_size = element_size;
16 array->size = 0;
17 array->destructor = destructor;
18 }
19
20 int lttng_dynamic_array_set_count(struct lttng_dynamic_array *array,
21 size_t new_element_count)
22 {
23 int ret;
24
25 if (!array) {
26 ret = -1;
27 goto end;
28 }
29
30 if (array->destructor) {
31 size_t i;
32
33 for (i = new_element_count; i < array->size; i++) {
34 void *element = lttng_dynamic_array_get_element(
35 array, i);
36
37 array->destructor(element);
38 }
39 }
40
41 array->size = new_element_count;
42 ret = lttng_dynamic_buffer_set_size(&array->buffer,
43 new_element_count * array->element_size);
44 end:
45 return ret;
46 }
47
48 int lttng_dynamic_array_add_element(struct lttng_dynamic_array *array,
49 const void *element)
50 {
51 int ret;
52
53 if (!array || !element) {
54 ret = -1;
55 goto end;
56 }
57
58 ret = lttng_dynamic_buffer_append(&array->buffer, element,
59 array->element_size);
60 if (ret) {
61 goto end;
62 }
63 array->size++;
64 end:
65 return ret;
66 }
67
68 int lttng_dynamic_array_remove_element(struct lttng_dynamic_array *array,
69 size_t element_index)
70 {
71 void *element = lttng_dynamic_array_get_element(array,
72 element_index);
73
74 if (array->destructor) {
75 array->destructor(element);
76 }
77 if (element_index != lttng_dynamic_array_get_count(array) - 1) {
78 void *next_element = lttng_dynamic_array_get_element(array,
79 element_index + 1);
80
81 memmove(element, next_element,
82 (array->size - element_index - 1) * array->element_size);
83 }
84 array->size--;
85 return lttng_dynamic_buffer_set_size(&array->buffer,
86 array->buffer.size - array->element_size);
87 }
88
89 void lttng_dynamic_array_reset(struct lttng_dynamic_array *array)
90 {
91 if (array->destructor) {
92 size_t i;
93
94 for (i = 0; i < lttng_dynamic_array_get_count(array); i++) {
95 array->destructor(lttng_dynamic_array_get_element(array,
96 i));
97 }
98 }
99
100 lttng_dynamic_buffer_reset(&array->buffer);
101 array->size = 0;
102 }
103
104 void lttng_dynamic_array_clear(struct lttng_dynamic_array *array)
105 {
106 if (array->destructor) {
107 size_t i;
108
109 for (i = 0; i < lttng_dynamic_array_get_count(array); i++) {
110 array->destructor(lttng_dynamic_array_get_element(array,
111 i));
112 }
113 }
114
115 (void) lttng_dynamic_buffer_set_size(&array->buffer, 0);
116 array->size = 0;
117 }
118
119 void lttng_dynamic_pointer_array_init(
120 struct lttng_dynamic_pointer_array *array,
121 lttng_dynamic_pointer_array_destructor destructor)
122 {
123 lttng_dynamic_array_init(&array->array, sizeof(void *), destructor);
124 }
125
126 int lttng_dynamic_pointer_array_remove_pointer(
127 struct lttng_dynamic_pointer_array *array, size_t index)
128 {
129 int ret;
130 const lttng_dynamic_array_element_destructor destructor =
131 array->array.destructor;
132
133 /*
134 * Prevent the destructor from being used by the underlying
135 * dynamic array.
136 */
137 array->array.destructor = NULL;
138 if (destructor) {
139 destructor(lttng_dynamic_pointer_array_get_pointer(array,
140 index));
141 }
142 ret = lttng_dynamic_array_remove_element(&array->array, index);
143 array->array.destructor = destructor;
144 return ret;
145 }
146
147 /* Release any memory used by the dynamic array. */
148 void lttng_dynamic_pointer_array_reset(
149 struct lttng_dynamic_pointer_array *array)
150 {
151 if (array->array.destructor) {
152 size_t i, count = lttng_dynamic_pointer_array_get_count(array);
153
154 for (i = 0; i < count; i++) {
155 void *ptr = lttng_dynamic_pointer_array_get_pointer(
156 array, i);
157 array->array.destructor(ptr);
158 }
159 /*
160 * Prevent the destructor from being used by the underlying
161 * dynamic array.
162 */
163 array->array.destructor = NULL;
164 }
165 lttng_dynamic_array_reset(&array->array);
166 }
167
168 void lttng_dynamic_pointer_array_clear(
169 struct lttng_dynamic_pointer_array *array)
170 {
171 const lttng_dynamic_array_element_destructor destructor =
172 array->array.destructor;
173
174 /*
175 * Prevent the destructor from being used by the underlying
176 * dynamic array.
177 */
178 array->array.destructor = NULL;
179 if (destructor) {
180 size_t i, count = lttng_dynamic_pointer_array_get_count(array);
181
182 for (i = 0; i < count; i++) {
183 void *ptr = lttng_dynamic_pointer_array_get_pointer(
184 array, i);
185 destructor(ptr);
186 }
187 }
188 lttng_dynamic_array_clear(&array->array);
189 array->array.destructor = destructor;
190 }
This page took 0.032906 seconds and 4 git commands to generate.