nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* GObject - GLib Type, Object, Parameter and Signal Library |
2 | * Copyright (C) 2001 Red Hat, Inc. |
||
3 | * |
||
4 | * This library is free software; you can redistribute it and/or |
||
5 | * modify it under the terms of the GNU Lesser General Public |
||
6 | * License as published by the Free Software Foundation; either |
||
7 | * version 2 of the License, or (at your option) any later version. |
||
8 | * |
||
9 | * This library is distributed in the hope that it will be useful, |
||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
12 | * Lesser General Public License for more details. |
||
13 | * |
||
14 | * You should have received a copy of the GNU Lesser General |
||
15 | * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. |
||
16 | */ |
||
17 | |||
18 | /* |
||
19 | * MT safe |
||
20 | */ |
||
21 | |||
22 | #include "config.h" |
||
23 | |||
24 | #include <string.h> |
||
25 | #include <stdlib.h> /* qsort() */ |
||
26 | |||
27 | #include "gvaluearray.h" |
||
28 | |||
29 | |||
30 | /** |
||
31 | * SECTION:value_arrays |
||
32 | * @short_description: A container structure to maintain an array of |
||
33 | * generic values |
||
34 | * @see_also: #GValue, #GParamSpecValueArray, g_param_spec_value_array() |
||
35 | * @title: Value arrays |
||
36 | * |
||
37 | * The prime purpose of a #GValueArray is for it to be used as an |
||
38 | * object property that holds an array of values. A #GValueArray wraps |
||
39 | * an array of #GValue elements in order for it to be used as a boxed |
||
40 | * type through %G_TYPE_VALUE_ARRAY. |
||
41 | * |
||
42 | * #GValueArray is deprecated in favour of #GArray since GLib 2.32. It |
||
43 | * is possible to create a #GArray that behaves like a #GValueArray by |
||
44 | * using the size of #GValue as the element size, and by setting |
||
45 | * g_value_unset() as the clear function using g_array_set_clear_func(), |
||
46 | * for instance, the following code: |
||
47 | * |
||
48 | * |[<!-- language="C" --> |
||
49 | * GValueArray *array = g_value_array_new (10); |
||
50 | * ]| |
||
51 | * |
||
52 | * can be replaced by: |
||
53 | * |
||
54 | * |[<!-- language="C" --> |
||
55 | * GArray *array = g_array_sized_new (FALSE, TRUE, sizeof (GValue), 10); |
||
56 | * g_array_set_clear_func (array, (GDestroyNotify) g_value_unset); |
||
57 | * ]| |
||
58 | */ |
||
59 | |||
60 | |||
61 | #ifdef DISABLE_MEM_POOLS |
||
62 | # define GROUP_N_VALUES (1) /* power of 2 !! */ |
||
63 | #else |
||
64 | # define GROUP_N_VALUES (8) /* power of 2 !! */ |
||
65 | #endif |
||
66 | |||
67 | |||
68 | /* --- functions --- */ |
||
69 | /** |
||
70 | * g_value_array_get_nth: |
||
71 | * @value_array: #GValueArray to get a value from |
||
72 | * @index_: index of the value of interest |
||
73 | * |
||
74 | * Return a pointer to the value at @index_ containd in @value_array. |
||
75 | * |
||
76 | * Returns: (transfer none): pointer to a value at @index_ in @value_array |
||
77 | * |
||
78 | * Deprecated: 2.32: Use g_array_index() instead. |
||
79 | */ |
||
80 | GValue* |
||
81 | g_value_array_get_nth (GValueArray *value_array, |
||
82 | guint index) |
||
83 | { |
||
84 | g_return_val_if_fail (value_array != NULL, NULL); |
||
85 | g_return_val_if_fail (index < value_array->n_values, NULL); |
||
86 | |||
87 | return value_array->values + index; |
||
88 | } |
||
89 | |||
90 | static inline void |
||
91 | value_array_grow (GValueArray *value_array, |
||
92 | guint n_values, |
||
93 | gboolean zero_init) |
||
94 | { |
||
95 | g_return_if_fail (n_values >= value_array->n_values); |
||
96 | |||
97 | value_array->n_values = n_values; |
||
98 | if (value_array->n_values > value_array->n_prealloced) |
||
99 | { |
||
100 | guint i = value_array->n_prealloced; |
||
101 | |||
102 | value_array->n_prealloced = (value_array->n_values + GROUP_N_VALUES - 1) & ~(GROUP_N_VALUES - 1); |
||
103 | value_array->values = g_renew (GValue, value_array->values, value_array->n_prealloced); |
||
104 | if (!zero_init) |
||
105 | i = value_array->n_values; |
||
106 | memset (value_array->values + i, 0, |
||
107 | (value_array->n_prealloced - i) * sizeof (value_array->values[0])); |
||
108 | } |
||
109 | } |
||
110 | |||
111 | static inline void |
||
112 | value_array_shrink (GValueArray *value_array) |
||
113 | { |
||
114 | #ifdef DISABLE_MEM_POOLS |
||
115 | if (value_array->n_prealloced >= value_array->n_values + GROUP_N_VALUES) |
||
116 | { |
||
117 | value_array->n_prealloced = (value_array->n_values + GROUP_N_VALUES - 1) & ~(GROUP_N_VALUES - 1); |
||
118 | value_array->values = g_renew (GValue, value_array->values, value_array->n_prealloced); |
||
119 | } |
||
120 | #endif |
||
121 | } |
||
122 | |||
123 | /** |
||
124 | * g_value_array_new: |
||
125 | * @n_prealloced: number of values to preallocate space for |
||
126 | * |
||
127 | * Allocate and initialize a new #GValueArray, optionally preserve space |
||
128 | * for @n_prealloced elements. New arrays always contain 0 elements, |
||
129 | * regardless of the value of @n_prealloced. |
||
130 | * |
||
131 | * Returns: a newly allocated #GValueArray with 0 values |
||
132 | * |
||
133 | * Deprecated: 2.32: Use #GArray and g_array_sized_new() instead. |
||
134 | */ |
||
135 | GValueArray* |
||
136 | g_value_array_new (guint n_prealloced) |
||
137 | { |
||
138 | GValueArray *value_array = g_slice_new (GValueArray); |
||
139 | |||
140 | value_array->n_values = 0; |
||
141 | value_array->n_prealloced = 0; |
||
142 | value_array->values = NULL; |
||
143 | value_array_grow (value_array, n_prealloced, TRUE); |
||
144 | value_array->n_values = 0; |
||
145 | |||
146 | return value_array; |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * g_value_array_free: |
||
151 | * @value_array: #GValueArray to free |
||
152 | * |
||
153 | * Free a #GValueArray including its contents. |
||
154 | * |
||
155 | * Deprecated: 2.32: Use #GArray and g_array_unref() instead. |
||
156 | */ |
||
157 | void |
||
158 | g_value_array_free (GValueArray *value_array) |
||
159 | { |
||
160 | guint i; |
||
161 | |||
162 | g_return_if_fail (value_array != NULL); |
||
163 | |||
164 | for (i = 0; i < value_array->n_values; i++) |
||
165 | { |
||
166 | GValue *value = value_array->values + i; |
||
167 | |||
168 | if (G_VALUE_TYPE (value) != 0) /* we allow unset values in the array */ |
||
169 | g_value_unset (value); |
||
170 | } |
||
171 | g_free (value_array->values); |
||
172 | g_slice_free (GValueArray, value_array); |
||
173 | } |
||
174 | |||
175 | /** |
||
176 | * g_value_array_copy: |
||
177 | * @value_array: #GValueArray to copy |
||
178 | * |
||
179 | * Construct an exact copy of a #GValueArray by duplicating all its |
||
180 | * contents. |
||
181 | * |
||
182 | * Returns: (transfer full): Newly allocated copy of #GValueArray |
||
183 | * |
||
184 | * Deprecated: 2.32: Use #GArray and g_array_ref() instead. |
||
185 | */ |
||
186 | GValueArray* |
||
187 | g_value_array_copy (const GValueArray *value_array) |
||
188 | { |
||
189 | GValueArray *new_array; |
||
190 | guint i; |
||
191 | |||
192 | g_return_val_if_fail (value_array != NULL, NULL); |
||
193 | |||
194 | new_array = g_slice_new (GValueArray); |
||
195 | new_array->n_values = 0; |
||
196 | new_array->values = NULL; |
||
197 | new_array->n_prealloced = 0; |
||
198 | value_array_grow (new_array, value_array->n_values, TRUE); |
||
199 | for (i = 0; i < new_array->n_values; i++) |
||
200 | if (G_VALUE_TYPE (value_array->values + i) != 0) |
||
201 | { |
||
202 | GValue *value = new_array->values + i; |
||
203 | |||
204 | g_value_init (value, G_VALUE_TYPE (value_array->values + i)); |
||
205 | g_value_copy (value_array->values + i, value); |
||
206 | } |
||
207 | return new_array; |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * g_value_array_prepend: |
||
212 | * @value_array: #GValueArray to add an element to |
||
213 | * @value: (allow-none): #GValue to copy into #GValueArray, or %NULL |
||
214 | * |
||
215 | * Insert a copy of @value as first element of @value_array. If @value is |
||
216 | * %NULL, an uninitialized value is prepended. |
||
217 | * |
||
218 | * |
||
219 | * Returns: (transfer none): the #GValueArray passed in as @value_array |
||
220 | * |
||
221 | * Deprecated: 2.32: Use #GArray and g_array_prepend_val() instead. |
||
222 | */ |
||
223 | GValueArray* |
||
224 | g_value_array_prepend (GValueArray *value_array, |
||
225 | const GValue *value) |
||
226 | { |
||
227 | g_return_val_if_fail (value_array != NULL, NULL); |
||
228 | |||
229 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
||
230 | return g_value_array_insert (value_array, 0, value); |
||
231 | G_GNUC_END_IGNORE_DEPRECATIONS |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * g_value_array_append: |
||
236 | * @value_array: #GValueArray to add an element to |
||
237 | * @value: (allow-none): #GValue to copy into #GValueArray, or %NULL |
||
238 | * |
||
239 | * Insert a copy of @value as last element of @value_array. If @value is |
||
240 | * %NULL, an uninitialized value is appended. |
||
241 | * |
||
242 | * Returns: (transfer none): the #GValueArray passed in as @value_array |
||
243 | * |
||
244 | * Deprecated: 2.32: Use #GArray and g_array_append_val() instead. |
||
245 | */ |
||
246 | GValueArray* |
||
247 | g_value_array_append (GValueArray *value_array, |
||
248 | const GValue *value) |
||
249 | { |
||
250 | g_return_val_if_fail (value_array != NULL, NULL); |
||
251 | |||
252 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
||
253 | return g_value_array_insert (value_array, value_array->n_values, value); |
||
254 | G_GNUC_END_IGNORE_DEPRECATIONS |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * g_value_array_insert: |
||
259 | * @value_array: #GValueArray to add an element to |
||
260 | * @index_: insertion position, must be <= value_array->;n_values |
||
261 | * @value: (allow-none): #GValue to copy into #GValueArray, or %NULL |
||
262 | * |
||
263 | * Insert a copy of @value at specified position into @value_array. If @value |
||
264 | * is %NULL, an uninitialized value is inserted. |
||
265 | * |
||
266 | * Returns: (transfer none): the #GValueArray passed in as @value_array |
||
267 | * |
||
268 | * Deprecated: 2.32: Use #GArray and g_array_insert_val() instead. |
||
269 | */ |
||
270 | GValueArray* |
||
271 | g_value_array_insert (GValueArray *value_array, |
||
272 | guint index, |
||
273 | const GValue *value) |
||
274 | { |
||
275 | guint i; |
||
276 | |||
277 | g_return_val_if_fail (value_array != NULL, NULL); |
||
278 | g_return_val_if_fail (index <= value_array->n_values, value_array); |
||
279 | |||
280 | i = value_array->n_values; |
||
281 | value_array_grow (value_array, value_array->n_values + 1, FALSE); |
||
282 | if (index + 1 < value_array->n_values) |
||
283 | memmove (value_array->values + index + 1, value_array->values + index, |
||
284 | (i - index) * sizeof (value_array->values[0])); |
||
285 | memset (value_array->values + index, 0, sizeof (value_array->values[0])); |
||
286 | if (value) |
||
287 | { |
||
288 | g_value_init (value_array->values + index, G_VALUE_TYPE (value)); |
||
289 | g_value_copy (value, value_array->values + index); |
||
290 | } |
||
291 | return value_array; |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * g_value_array_remove: |
||
296 | * @value_array: #GValueArray to remove an element from |
||
297 | * @index_: position of value to remove, which must be less than |
||
298 | * @value_array->n_values |
||
299 | * |
||
300 | * Remove the value at position @index_ from @value_array. |
||
301 | * |
||
302 | * Returns: (transfer none): the #GValueArray passed in as @value_array |
||
303 | * |
||
304 | * Deprecated: 2.32: Use #GArray and g_array_remove_index() instead. |
||
305 | */ |
||
306 | GValueArray* |
||
307 | g_value_array_remove (GValueArray *value_array, |
||
308 | guint index) |
||
309 | { |
||
310 | g_return_val_if_fail (value_array != NULL, NULL); |
||
311 | g_return_val_if_fail (index < value_array->n_values, value_array); |
||
312 | |||
313 | if (G_VALUE_TYPE (value_array->values + index) != 0) |
||
314 | g_value_unset (value_array->values + index); |
||
315 | value_array->n_values--; |
||
316 | if (index < value_array->n_values) |
||
317 | memmove (value_array->values + index, value_array->values + index + 1, |
||
318 | (value_array->n_values - index) * sizeof (value_array->values[0])); |
||
319 | value_array_shrink (value_array); |
||
320 | if (value_array->n_prealloced > value_array->n_values) |
||
321 | memset (value_array->values + value_array->n_values, 0, sizeof (value_array->values[0])); |
||
322 | |||
323 | return value_array; |
||
324 | } |
||
325 | |||
326 | /** |
||
327 | * g_value_array_sort: |
||
328 | * @value_array: #GValueArray to sort |
||
329 | * @compare_func: (scope call): function to compare elements |
||
330 | * |
||
331 | * Sort @value_array using @compare_func to compare the elements according to |
||
332 | * the semantics of #GCompareFunc. |
||
333 | * |
||
334 | * The current implementation uses the same sorting algorithm as standard |
||
335 | * C qsort() function. |
||
336 | * |
||
337 | * Returns: (transfer none): the #GValueArray passed in as @value_array |
||
338 | * |
||
339 | * Deprecated: 2.32: Use #GArray and g_array_sort(). |
||
340 | */ |
||
341 | GValueArray* |
||
342 | g_value_array_sort (GValueArray *value_array, |
||
343 | GCompareFunc compare_func) |
||
344 | { |
||
345 | g_return_val_if_fail (compare_func != NULL, NULL); |
||
346 | |||
347 | if (value_array->n_values) |
||
348 | qsort (value_array->values, |
||
349 | value_array->n_values, |
||
350 | sizeof (value_array->values[0]), |
||
351 | compare_func); |
||
352 | return value_array; |
||
353 | } |
||
354 | |||
355 | /** |
||
356 | * g_value_array_sort_with_data: (rename-to g_value_array_sort) |
||
357 | * @value_array: #GValueArray to sort |
||
358 | * @compare_func: (scope call): function to compare elements |
||
359 | * @user_data: (closure): extra data argument provided for @compare_func |
||
360 | * |
||
361 | * Sort @value_array using @compare_func to compare the elements according |
||
362 | * to the semantics of #GCompareDataFunc. |
||
363 | * |
||
364 | * The current implementation uses the same sorting algorithm as standard |
||
365 | * C qsort() function. |
||
366 | * |
||
367 | * Returns: (transfer none): the #GValueArray passed in as @value_array |
||
368 | * |
||
369 | * Deprecated: 2.32: Use #GArray and g_array_sort_with_data(). |
||
370 | */ |
||
371 | GValueArray* |
||
372 | g_value_array_sort_with_data (GValueArray *value_array, |
||
373 | GCompareDataFunc compare_func, |
||
374 | gpointer user_data) |
||
375 | { |
||
376 | g_return_val_if_fail (value_array != NULL, NULL); |
||
377 | g_return_val_if_fail (compare_func != NULL, NULL); |
||
378 | |||
379 | if (value_array->n_values) |
||
380 | g_qsort_with_data (value_array->values, |
||
381 | value_array->n_values, |
||
382 | sizeof (value_array->values[0]), |
||
383 | compare_func, user_data); |
||
384 | return value_array; |
||
385 | } |