Commit | Line | Data |
---|---|---|
273b65be | 1 | /* |
2e33ac5a | 2 | * fields.c |
273b65be | 3 | * |
56e18c4c | 4 | * Babeltrace trace IR - Event Fields |
273b65be | 5 | * |
de9dd397 | 6 | * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com> |
273b65be JG |
7 | * |
8 | * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
9 | * | |
10 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
11 | * of this software and associated documentation files (the "Software"), to deal | |
12 | * in the Software without restriction, including without limitation the rights | |
13 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
14 | * copies of the Software, and to permit persons to whom the Software is | |
15 | * furnished to do so, subject to the following conditions: | |
16 | * | |
17 | * The above copyright notice and this permission notice shall be included in | |
18 | * all copies or substantial portions of the Software. | |
19 | * | |
20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
25 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
26 | * SOFTWARE. | |
27 | */ | |
28 | ||
fc25abce PP |
29 | #define BT_LOG_TAG "FIELDS" |
30 | #include <babeltrace/lib-logging-internal.h> | |
31 | ||
3dca2276 | 32 | #include <babeltrace/assert-pre-internal.h> |
56e18c4c PP |
33 | #include <babeltrace/trace-ir/fields.h> |
34 | #include <babeltrace/trace-ir/fields-internal.h> | |
5cd6d0e5 | 35 | #include <babeltrace/trace-ir/field-classes-internal.h> |
83509119 | 36 | #include <babeltrace/object-internal.h> |
65300d60 | 37 | #include <babeltrace/object.h> |
3d9990ac PP |
38 | #include <babeltrace/compiler-internal.h> |
39 | #include <babeltrace/compat/fcntl-internal.h> | |
40 | #include <babeltrace/align-internal.h> | |
f6ccaed9 | 41 | #include <babeltrace/assert-internal.h> |
fc25abce | 42 | #include <inttypes.h> |
273b65be | 43 | |
cb6f1f7d | 44 | static |
44c440bc | 45 | void reset_single_field(struct bt_field *field); |
cb6f1f7d PP |
46 | |
47 | static | |
44c440bc | 48 | void reset_array_field(struct bt_field *field); |
cb6f1f7d PP |
49 | |
50 | static | |
44c440bc | 51 | void reset_structure_field(struct bt_field *field); |
cb6f1f7d PP |
52 | |
53 | static | |
44c440bc | 54 | void reset_variant_field(struct bt_field *field); |
cb6f1f7d PP |
55 | |
56 | static | |
44c440bc | 57 | void set_single_field_is_frozen(struct bt_field *field, bool is_frozen); |
cb6f1f7d PP |
58 | |
59 | static | |
44c440bc | 60 | void set_array_field_is_frozen(struct bt_field *field, bool is_frozen); |
cb6f1f7d PP |
61 | |
62 | static | |
44c440bc | 63 | void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen); |
cb6f1f7d PP |
64 | |
65 | static | |
44c440bc | 66 | void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen); |
cb6f1f7d PP |
67 | |
68 | static | |
44c440bc | 69 | bool single_field_is_set(struct bt_field *field); |
cb6f1f7d PP |
70 | |
71 | static | |
44c440bc | 72 | bool array_field_is_set(struct bt_field *field); |
cb6f1f7d PP |
73 | |
74 | static | |
44c440bc | 75 | bool structure_field_is_set(struct bt_field *field); |
cb6f1f7d PP |
76 | |
77 | static | |
44c440bc | 78 | bool variant_field_is_set(struct bt_field *field); |
cb6f1f7d PP |
79 | |
80 | static | |
44c440bc PP |
81 | struct bt_field_methods integer_field_methods = { |
82 | .set_is_frozen = set_single_field_is_frozen, | |
83 | .is_set = single_field_is_set, | |
84 | .reset = reset_single_field, | |
3dca2276 | 85 | }; |
273b65be | 86 | |
44c440bc PP |
87 | static |
88 | struct bt_field_methods real_field_methods = { | |
89 | .set_is_frozen = set_single_field_is_frozen, | |
90 | .is_set = single_field_is_set, | |
91 | .reset = reset_single_field, | |
12c8a1a3 JG |
92 | }; |
93 | ||
44c440bc PP |
94 | static |
95 | struct bt_field_methods string_field_methods = { | |
96 | .set_is_frozen = set_single_field_is_frozen, | |
97 | .is_set = single_field_is_set, | |
98 | .reset = reset_single_field, | |
273b65be JG |
99 | }; |
100 | ||
44c440bc PP |
101 | static |
102 | struct bt_field_methods structure_field_methods = { | |
103 | .set_is_frozen = set_structure_field_is_frozen, | |
104 | .is_set = structure_field_is_set, | |
105 | .reset = reset_structure_field, | |
87d43dc1 JG |
106 | }; |
107 | ||
44c440bc PP |
108 | static |
109 | struct bt_field_methods array_field_methods = { | |
110 | .set_is_frozen = set_array_field_is_frozen, | |
111 | .is_set = array_field_is_set, | |
112 | .reset = reset_array_field, | |
918be005 PP |
113 | }; |
114 | ||
76f869ab | 115 | static |
44c440bc PP |
116 | struct bt_field_methods variant_field_methods = { |
117 | .set_is_frozen = set_variant_field_is_frozen, | |
118 | .is_set = variant_field_is_set, | |
119 | .reset = reset_variant_field, | |
120 | }; | |
76f869ab | 121 | |
3dca2276 | 122 | static |
5cd6d0e5 | 123 | struct bt_field *create_integer_field(struct bt_field_class *); |
3dca2276 PP |
124 | |
125 | static | |
5cd6d0e5 | 126 | struct bt_field *create_real_field(struct bt_field_class *); |
3dca2276 PP |
127 | |
128 | static | |
5cd6d0e5 | 129 | struct bt_field *create_string_field(struct bt_field_class *); |
3dca2276 PP |
130 | |
131 | static | |
5cd6d0e5 | 132 | struct bt_field *create_structure_field(struct bt_field_class *); |
3dca2276 PP |
133 | |
134 | static | |
5cd6d0e5 | 135 | struct bt_field *create_static_array_field(struct bt_field_class *); |
f6ccaed9 | 136 | |
3dca2276 | 137 | static |
5cd6d0e5 | 138 | struct bt_field *create_dynamic_array_field(struct bt_field_class *); |
f6ccaed9 | 139 | |
3dca2276 | 140 | static |
5cd6d0e5 | 141 | struct bt_field *create_variant_field(struct bt_field_class *); |
f6ccaed9 | 142 | |
3dca2276 | 143 | static |
5cd6d0e5 | 144 | struct bt_field *(* const field_create_funcs[])(struct bt_field_class *) = { |
864cad70 PP |
145 | [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER] = create_integer_field, |
146 | [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER] = create_integer_field, | |
147 | [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION] = create_integer_field, | |
148 | [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION] = create_integer_field, | |
149 | [BT_FIELD_CLASS_TYPE_REAL] = create_real_field, | |
150 | [BT_FIELD_CLASS_TYPE_STRING] = create_string_field, | |
151 | [BT_FIELD_CLASS_TYPE_STRUCTURE] = create_structure_field, | |
152 | [BT_FIELD_CLASS_TYPE_STATIC_ARRAY] = create_static_array_field, | |
153 | [BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY] = create_dynamic_array_field, | |
154 | [BT_FIELD_CLASS_TYPE_VARIANT] = create_variant_field, | |
3dca2276 | 155 | }; |
f6ccaed9 | 156 | |
312c056a | 157 | static |
44c440bc | 158 | void destroy_integer_field(struct bt_field *field); |
312c056a PP |
159 | |
160 | static | |
44c440bc | 161 | void destroy_real_field(struct bt_field *field); |
312c056a PP |
162 | |
163 | static | |
44c440bc | 164 | void destroy_string_field(struct bt_field *field); |
312c056a PP |
165 | |
166 | static | |
44c440bc | 167 | void destroy_structure_field(struct bt_field *field); |
312c056a PP |
168 | |
169 | static | |
44c440bc | 170 | void destroy_array_field(struct bt_field *field); |
312c056a PP |
171 | |
172 | static | |
44c440bc | 173 | void destroy_variant_field(struct bt_field *field); |
312c056a PP |
174 | |
175 | static | |
176 | void (* const field_destroy_funcs[])(struct bt_field *) = { | |
864cad70 PP |
177 | [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER] = destroy_integer_field, |
178 | [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER] = destroy_integer_field, | |
179 | [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION] = destroy_integer_field, | |
180 | [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION] = destroy_integer_field, | |
181 | [BT_FIELD_CLASS_TYPE_REAL] = destroy_real_field, | |
182 | [BT_FIELD_CLASS_TYPE_STRING] = destroy_string_field, | |
183 | [BT_FIELD_CLASS_TYPE_STRUCTURE] = destroy_structure_field, | |
184 | [BT_FIELD_CLASS_TYPE_STATIC_ARRAY] = destroy_array_field, | |
185 | [BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY] = destroy_array_field, | |
186 | [BT_FIELD_CLASS_TYPE_VARIANT] = destroy_variant_field, | |
312c056a PP |
187 | }; |
188 | ||
5cd6d0e5 | 189 | struct bt_field_class *bt_field_borrow_class(struct bt_field *field) |
cb6f1f7d | 190 | { |
44c440bc | 191 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
5cd6d0e5 | 192 | return field->class; |
cb6f1f7d PP |
193 | } |
194 | ||
864cad70 | 195 | enum bt_field_class_type bt_field_get_class_type(struct bt_field *field) |
cb6f1f7d | 196 | { |
44c440bc | 197 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
864cad70 | 198 | return field->class->type; |
cb6f1f7d PP |
199 | } |
200 | ||
312c056a | 201 | BT_HIDDEN |
5cd6d0e5 | 202 | struct bt_field *bt_field_create(struct bt_field_class *fc) |
273b65be | 203 | { |
50842bdc | 204 | struct bt_field *field = NULL; |
44c440bc | 205 | |
5cd6d0e5 | 206 | BT_ASSERT_PRE_NON_NULL(fc, "Field class"); |
864cad70 PP |
207 | BT_ASSERT(bt_field_class_has_known_type(fc)); |
208 | field = field_create_funcs[fc->type](fc); | |
273b65be | 209 | if (!field) { |
5cd6d0e5 PP |
210 | BT_LIB_LOGE("Cannot create field object from field classe: " |
211 | "%![fc-]+F", fc); | |
3dca2276 | 212 | goto end; |
273b65be JG |
213 | } |
214 | ||
3dca2276 PP |
215 | end: |
216 | return field; | |
273b65be JG |
217 | } |
218 | ||
44c440bc | 219 | static inline |
5cd6d0e5 | 220 | void init_field(struct bt_field *field, struct bt_field_class *fc, |
44c440bc | 221 | struct bt_field_methods *methods) |
cd95e351 | 222 | { |
44c440bc | 223 | BT_ASSERT(field); |
5cd6d0e5 | 224 | BT_ASSERT(fc); |
44c440bc PP |
225 | bt_object_init_unique(&field->base); |
226 | field->methods = methods; | |
65300d60 | 227 | field->class = bt_object_get_ref(fc); |
cd95e351 JG |
228 | } |
229 | ||
44c440bc | 230 | static |
5cd6d0e5 | 231 | struct bt_field *create_integer_field(struct bt_field_class *fc) |
4ebcc695 | 232 | { |
44c440bc PP |
233 | struct bt_field_integer *int_field; |
234 | ||
5cd6d0e5 | 235 | BT_LIB_LOGD("Creating integer field object: %![fc-]+F", fc); |
44c440bc PP |
236 | int_field = g_new0(struct bt_field_integer, 1); |
237 | if (!int_field) { | |
238 | BT_LOGE_STR("Failed to allocate one integer field."); | |
239 | goto end; | |
240 | } | |
241 | ||
5cd6d0e5 | 242 | init_field((void *) int_field, fc, &integer_field_methods); |
44c440bc PP |
243 | BT_LIB_LOGD("Created integer field object: %!+f", int_field); |
244 | ||
245 | end: | |
246 | return (void *) int_field; | |
4ebcc695 PP |
247 | } |
248 | ||
44c440bc | 249 | static |
5cd6d0e5 | 250 | struct bt_field *create_real_field(struct bt_field_class *fc) |
2e8876d3 | 251 | { |
44c440bc | 252 | struct bt_field_real *real_field; |
cb6f1f7d | 253 | |
5cd6d0e5 | 254 | BT_LIB_LOGD("Creating real field object: %![fc-]+F", fc); |
44c440bc PP |
255 | real_field = g_new0(struct bt_field_real, 1); |
256 | if (!real_field) { | |
257 | BT_LOGE_STR("Failed to allocate one real field."); | |
258 | goto end; | |
259 | } | |
260 | ||
5cd6d0e5 | 261 | init_field((void *) real_field, fc, &real_field_methods); |
44c440bc PP |
262 | BT_LIB_LOGD("Created real field object: %!+f", real_field); |
263 | ||
264 | end: | |
265 | return (void *) real_field; | |
2e8876d3 PP |
266 | } |
267 | ||
44c440bc | 268 | static |
5cd6d0e5 | 269 | struct bt_field *create_string_field(struct bt_field_class *fc) |
273b65be | 270 | { |
44c440bc | 271 | struct bt_field_string *string_field; |
cb6f1f7d | 272 | |
5cd6d0e5 | 273 | BT_LIB_LOGD("Creating string field object: %![fc-]+F", fc); |
44c440bc PP |
274 | string_field = g_new0(struct bt_field_string, 1); |
275 | if (!string_field) { | |
276 | BT_LOGE_STR("Failed to allocate one string field."); | |
277 | goto end; | |
278 | } | |
cb6f1f7d | 279 | |
5cd6d0e5 | 280 | init_field((void *) string_field, fc, &string_field_methods); |
44c440bc PP |
281 | string_field->buf = g_array_sized_new(FALSE, FALSE, |
282 | sizeof(char), 1); | |
283 | if (!string_field->buf) { | |
284 | BT_LOGE_STR("Failed to allocate a GArray."); | |
65300d60 | 285 | BT_OBJECT_PUT_REF_AND_RESET(string_field); |
44c440bc PP |
286 | goto end; |
287 | } | |
cb6f1f7d | 288 | |
44c440bc PP |
289 | g_array_index(string_field->buf, char, 0) = '\0'; |
290 | BT_LIB_LOGD("Created string field object: %!+f", string_field); | |
cb6f1f7d | 291 | |
44c440bc PP |
292 | end: |
293 | return (void *) string_field; | |
294 | } | |
cb6f1f7d | 295 | |
44c440bc | 296 | static inline |
5cd6d0e5 PP |
297 | int create_fields_from_named_field_classes( |
298 | struct bt_field_class_named_field_class_container *fc, | |
44c440bc PP |
299 | GPtrArray **fields) |
300 | { | |
301 | int ret = 0; | |
302 | uint64_t i; | |
cb6f1f7d | 303 | |
44c440bc PP |
304 | *fields = g_ptr_array_new_with_free_func( |
305 | (GDestroyNotify) bt_field_destroy); | |
306 | if (!*fields) { | |
307 | BT_LOGE_STR("Failed to allocate a GPtrArray."); | |
308 | ret = -1; | |
309 | goto end; | |
cb6f1f7d PP |
310 | } |
311 | ||
5cd6d0e5 | 312 | g_ptr_array_set_size(*fields, fc->named_fcs->len); |
44c440bc | 313 | |
5cd6d0e5 | 314 | for (i = 0; i < fc->named_fcs->len; i++) { |
44c440bc | 315 | struct bt_field *field; |
5cd6d0e5 PP |
316 | struct bt_named_field_class *named_fc = |
317 | BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc, i); | |
44c440bc | 318 | |
5cd6d0e5 | 319 | field = bt_field_create(named_fc->fc); |
44c440bc PP |
320 | if (!field) { |
321 | BT_LIB_LOGE("Failed to create structure member or variant option field: " | |
5cd6d0e5 PP |
322 | "name=\"%s\", %![fc-]+F", |
323 | named_fc->name->str, named_fc->fc); | |
44c440bc PP |
324 | ret = -1; |
325 | goto end; | |
326 | } | |
327 | ||
328 | g_ptr_array_index(*fields, i) = field; | |
329 | } | |
cb6f1f7d PP |
330 | |
331 | end: | |
332 | return ret; | |
273b65be JG |
333 | } |
334 | ||
44c440bc | 335 | static |
5cd6d0e5 | 336 | struct bt_field *create_structure_field(struct bt_field_class *fc) |
cd95e351 | 337 | { |
44c440bc | 338 | struct bt_field_structure *struct_field; |
cb6f1f7d | 339 | |
5cd6d0e5 | 340 | BT_LIB_LOGD("Creating structure field object: %![fc-]+F", fc); |
44c440bc PP |
341 | struct_field = g_new0(struct bt_field_structure, 1); |
342 | if (!struct_field) { | |
343 | BT_LOGE_STR("Failed to allocate one structure field."); | |
344 | goto end; | |
345 | } | |
fc25abce | 346 | |
5cd6d0e5 | 347 | init_field((void *) struct_field, fc, &structure_field_methods); |
44c440bc | 348 | |
5cd6d0e5 | 349 | if (create_fields_from_named_field_classes((void *) fc, |
44c440bc PP |
350 | &struct_field->fields)) { |
351 | BT_LIB_LOGE("Cannot create structure member fields: " | |
5cd6d0e5 | 352 | "%![fc-]+F", fc); |
65300d60 | 353 | BT_OBJECT_PUT_REF_AND_RESET(struct_field); |
44c440bc | 354 | goto end; |
cb6f1f7d PP |
355 | } |
356 | ||
44c440bc | 357 | BT_LIB_LOGD("Created structure field object: %!+f", struct_field); |
cb6f1f7d | 358 | |
44c440bc PP |
359 | end: |
360 | return (void *) struct_field; | |
cd95e351 JG |
361 | } |
362 | ||
44c440bc | 363 | static |
5cd6d0e5 | 364 | struct bt_field *create_variant_field(struct bt_field_class *fc) |
273b65be | 365 | { |
44c440bc | 366 | struct bt_field_variant *var_field; |
cb6f1f7d | 367 | |
5cd6d0e5 | 368 | BT_LIB_LOGD("Creating variant field object: %![fc-]+F", fc); |
44c440bc PP |
369 | var_field = g_new0(struct bt_field_variant, 1); |
370 | if (!var_field) { | |
371 | BT_LOGE_STR("Failed to allocate one variant field."); | |
372 | goto end; | |
373 | } | |
f6ccaed9 | 374 | |
5cd6d0e5 | 375 | init_field((void *) var_field, fc, &variant_field_methods); |
cb6f1f7d | 376 | |
5cd6d0e5 | 377 | if (create_fields_from_named_field_classes((void *) fc, |
44c440bc PP |
378 | &var_field->fields)) { |
379 | BT_LIB_LOGE("Cannot create variant member fields: " | |
5cd6d0e5 | 380 | "%![fc-]+F", fc); |
65300d60 | 381 | BT_OBJECT_PUT_REF_AND_RESET(var_field); |
44c440bc PP |
382 | goto end; |
383 | } | |
273b65be | 384 | |
44c440bc | 385 | BT_LIB_LOGD("Created variant field object: %!+f", var_field); |
cb6f1f7d | 386 | |
44c440bc PP |
387 | end: |
388 | return (void *) var_field; | |
cb6f1f7d PP |
389 | } |
390 | ||
391 | static inline | |
44c440bc | 392 | int init_array_field_fields(struct bt_field_array *array_field) |
cb6f1f7d PP |
393 | { |
394 | int ret = 0; | |
44c440bc | 395 | uint64_t i; |
5cd6d0e5 | 396 | struct bt_field_class_array *array_fc; |
cb6f1f7d | 397 | |
44c440bc | 398 | BT_ASSERT(array_field); |
5cd6d0e5 | 399 | array_fc = (void *) array_field->common.class; |
44c440bc PP |
400 | array_field->fields = g_ptr_array_sized_new(array_field->length); |
401 | if (!array_field->fields) { | |
402 | BT_LOGE_STR("Failed to allocate a GPtrArray."); | |
cb6f1f7d PP |
403 | ret = -1; |
404 | goto end; | |
405 | } | |
406 | ||
44c440bc PP |
407 | g_ptr_array_set_free_func(array_field->fields, |
408 | (GDestroyNotify) bt_field_destroy); | |
409 | g_ptr_array_set_size(array_field->fields, array_field->length); | |
410 | ||
411 | for (i = 0; i < array_field->length; i++) { | |
412 | array_field->fields->pdata[i] = bt_field_create( | |
5cd6d0e5 | 413 | array_fc->element_fc); |
44c440bc PP |
414 | if (!array_field->fields->pdata[i]) { |
415 | BT_LIB_LOGE("Cannot create array field's element field: " | |
5cd6d0e5 | 416 | "index=%" PRIu64 ", %![fc-]+F", i, array_fc); |
44c440bc PP |
417 | ret = -1; |
418 | goto end; | |
419 | } | |
420 | } | |
cb6f1f7d PP |
421 | |
422 | end: | |
423 | return ret; | |
3f4a108d PP |
424 | } |
425 | ||
44c440bc | 426 | static |
5cd6d0e5 | 427 | struct bt_field *create_static_array_field(struct bt_field_class *fc) |
f78d67fb | 428 | { |
5cd6d0e5 | 429 | struct bt_field_class_static_array *array_fc = (void *) fc; |
44c440bc | 430 | struct bt_field_array *array_field; |
312c056a | 431 | |
5cd6d0e5 | 432 | BT_LIB_LOGD("Creating static array field object: %![fc-]+F", fc); |
44c440bc PP |
433 | array_field = g_new0(struct bt_field_array, 1); |
434 | if (!array_field) { | |
435 | BT_LOGE_STR("Failed to allocate one static array field."); | |
436 | goto end; | |
437 | } | |
f78d67fb | 438 | |
5cd6d0e5 PP |
439 | init_field((void *) array_field, fc, &array_field_methods); |
440 | array_field->length = array_fc->length; | |
cb6f1f7d | 441 | |
44c440bc PP |
442 | if (init_array_field_fields(array_field)) { |
443 | BT_LIB_LOGE("Cannot create static array fields: " | |
5cd6d0e5 | 444 | "%![fc-]+F", fc); |
65300d60 | 445 | BT_OBJECT_PUT_REF_AND_RESET(array_field); |
44c440bc PP |
446 | goto end; |
447 | } | |
312c056a | 448 | |
44c440bc | 449 | BT_LIB_LOGD("Created static array field object: %!+f", array_field); |
cb6f1f7d | 450 | |
44c440bc PP |
451 | end: |
452 | return (void *) array_field; | |
273b65be JG |
453 | } |
454 | ||
44c440bc | 455 | static |
5cd6d0e5 | 456 | struct bt_field *create_dynamic_array_field(struct bt_field_class *fc) |
cd95e351 | 457 | { |
44c440bc | 458 | struct bt_field_array *array_field; |
312c056a | 459 | |
5cd6d0e5 | 460 | BT_LIB_LOGD("Creating dynamic array field object: %![fc-]+F", fc); |
44c440bc PP |
461 | array_field = g_new0(struct bt_field_array, 1); |
462 | if (!array_field) { | |
463 | BT_LOGE_STR("Failed to allocate one dynamic array field."); | |
464 | goto end; | |
465 | } | |
466 | ||
5cd6d0e5 | 467 | init_field((void *) array_field, fc, &array_field_methods); |
44c440bc PP |
468 | |
469 | if (init_array_field_fields(array_field)) { | |
470 | BT_LIB_LOGE("Cannot create dynamic array fields: " | |
5cd6d0e5 | 471 | "%![fc-]+F", fc); |
65300d60 | 472 | BT_OBJECT_PUT_REF_AND_RESET(array_field); |
44c440bc | 473 | goto end; |
cb6f1f7d PP |
474 | } |
475 | ||
44c440bc PP |
476 | BT_LIB_LOGD("Created dynamic array field object: %!+f", array_field); |
477 | ||
478 | end: | |
479 | return (void *) array_field; | |
312c056a PP |
480 | } |
481 | ||
44c440bc | 482 | int64_t bt_field_signed_integer_get_value(struct bt_field *field) |
312c056a | 483 | { |
cb6f1f7d | 484 | struct bt_field_integer *int_field = (void *) field; |
312c056a | 485 | |
44c440bc PP |
486 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
487 | BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); | |
488 | BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field"); | |
489 | return int_field->value.i; | |
cd95e351 JG |
490 | } |
491 | ||
44c440bc | 492 | void bt_field_signed_integer_set_value(struct bt_field *field, int64_t value) |
cd95e351 | 493 | { |
44c440bc | 494 | struct bt_field_integer *int_field = (void *) field; |
312c056a | 495 | |
44c440bc PP |
496 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
497 | BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field"); | |
498 | BT_ASSERT_PRE_FIELD_HOT(field, "Field"); | |
499 | BT_ASSERT_PRE(bt_util_value_is_in_range_signed( | |
5cd6d0e5 | 500 | ((struct bt_field_class_integer *) field->class)->range, value), |
44c440bc | 501 | "Value is out of bounds: value=%" PRId64 ", %![field-]+f, " |
5cd6d0e5 | 502 | "%![fc-]+F", value, field, field->class); |
44c440bc PP |
503 | int_field->value.i = value; |
504 | bt_field_set_single(field, true); | |
cd95e351 JG |
505 | } |
506 | ||
44c440bc | 507 | uint64_t bt_field_unsigned_integer_get_value(struct bt_field *field) |
273b65be | 508 | { |
44c440bc PP |
509 | struct bt_field_integer *int_field = (void *) field; |
510 | ||
511 | BT_ASSERT_PRE_NON_NULL(field, "Field"); | |
512 | BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); | |
513 | BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field"); | |
514 | return int_field->value.u; | |
273b65be JG |
515 | } |
516 | ||
44c440bc PP |
517 | void bt_field_unsigned_integer_set_value(struct bt_field *field, |
518 | uint64_t value) | |
cd95e351 | 519 | { |
44c440bc | 520 | struct bt_field_integer *int_field = (void *) field; |
312c056a | 521 | |
44c440bc PP |
522 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
523 | BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field"); | |
524 | BT_ASSERT_PRE_FIELD_HOT(field, "Field"); | |
525 | BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned( | |
5cd6d0e5 | 526 | ((struct bt_field_class_integer *) field->class)->range, value), |
44c440bc | 527 | "Value is out of bounds: value=%" PRIu64 ", %![field-]+f, " |
5cd6d0e5 | 528 | "%![fc-]+F", value, field, field->class); |
44c440bc PP |
529 | int_field->value.u = value; |
530 | bt_field_set_single(field, true); | |
cd95e351 JG |
531 | } |
532 | ||
44c440bc | 533 | double bt_field_real_get_value(struct bt_field *field) |
273b65be | 534 | { |
44c440bc PP |
535 | struct bt_field_real *real_field = (void *) field; |
536 | ||
537 | BT_ASSERT_PRE_NON_NULL(field, "Field"); | |
538 | BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); | |
864cad70 | 539 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_REAL, "Field"); |
44c440bc | 540 | return real_field->value; |
f6ccaed9 PP |
541 | } |
542 | ||
44c440bc | 543 | void bt_field_real_set_value(struct bt_field *field, double value) |
f6ccaed9 | 544 | { |
44c440bc | 545 | struct bt_field_real *real_field = (void *) field; |
cb6f1f7d | 546 | |
44c440bc | 547 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
864cad70 | 548 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_REAL, "Field"); |
44c440bc PP |
549 | BT_ASSERT_PRE_FIELD_HOT(field, "Field"); |
550 | BT_ASSERT_PRE( | |
5cd6d0e5 | 551 | !((struct bt_field_class_real *) field->class)->is_single_precision || |
44c440bc PP |
552 | (double) (float) value == value, |
553 | "Invalid value for a single-precision real number: value=%f, " | |
5cd6d0e5 | 554 | "%![fc-]+F", value, field->class); |
44c440bc PP |
555 | real_field->value = value; |
556 | bt_field_set_single(field, true); | |
557 | } | |
558 | ||
559 | int bt_field_unsigned_enumeration_get_mapping_labels(struct bt_field *field, | |
5cd6d0e5 | 560 | bt_field_class_enumeration_mapping_label_array *label_array, |
44c440bc PP |
561 | uint64_t *count) |
562 | { | |
563 | struct bt_field_integer *int_field = (void *) field; | |
564 | ||
565 | BT_ASSERT_PRE_NON_NULL(field, "Field"); | |
566 | BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)"); | |
567 | BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)"); | |
568 | BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); | |
864cad70 PP |
569 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, |
570 | BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field"); | |
5cd6d0e5 PP |
571 | return bt_field_class_unsigned_enumeration_get_mapping_labels_by_value( |
572 | field->class, int_field->value.u, label_array, count); | |
273b65be JG |
573 | } |
574 | ||
44c440bc | 575 | int bt_field_signed_enumeration_get_mapping_labels(struct bt_field *field, |
5cd6d0e5 | 576 | bt_field_class_enumeration_mapping_label_array *label_array, |
44c440bc | 577 | uint64_t *count) |
cd95e351 | 578 | { |
44c440bc | 579 | struct bt_field_integer *int_field = (void *) field; |
cb6f1f7d | 580 | |
44c440bc PP |
581 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
582 | BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)"); | |
583 | BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)"); | |
584 | BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); | |
864cad70 PP |
585 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, |
586 | BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field"); | |
5cd6d0e5 PP |
587 | return bt_field_class_signed_enumeration_get_mapping_labels_by_value( |
588 | field->class, int_field->value.i, label_array, count); | |
f6ccaed9 | 589 | } |
fc25abce | 590 | |
3dca2276 | 591 | const char *bt_field_string_get_value(struct bt_field *field) |
f6ccaed9 | 592 | { |
44c440bc PP |
593 | struct bt_field_string *string_field = (void *) field; |
594 | ||
595 | BT_ASSERT_PRE_NON_NULL(field, "Field"); | |
596 | BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); | |
864cad70 | 597 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING, |
44c440bc PP |
598 | "Field"); |
599 | return (const char *) string_field->buf->data; | |
600 | } | |
601 | ||
602 | uint64_t bt_field_string_get_length(struct bt_field *field) | |
603 | { | |
604 | struct bt_field_string *string_field = (void *) field; | |
cb6f1f7d | 605 | |
44c440bc PP |
606 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
607 | BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); | |
864cad70 | 608 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING, |
44c440bc PP |
609 | "Field"); |
610 | return string_field->length; | |
cd95e351 JG |
611 | } |
612 | ||
3dca2276 | 613 | int bt_field_string_set_value(struct bt_field *field, const char *value) |
273b65be | 614 | { |
44c440bc | 615 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
cb6f1f7d | 616 | BT_ASSERT_PRE_NON_NULL(value, "Value"); |
44c440bc | 617 | BT_ASSERT_PRE_FIELD_HOT(field, "Field"); |
864cad70 | 618 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING, |
44c440bc | 619 | "Field"); |
cb6f1f7d | 620 | bt_field_string_clear(field); |
44c440bc PP |
621 | return bt_field_string_append_with_length(field, value, |
622 | (uint64_t) strlen(value)); | |
273b65be JG |
623 | } |
624 | ||
3dca2276 | 625 | int bt_field_string_append(struct bt_field *field, const char *value) |
cd95e351 | 626 | { |
44c440bc PP |
627 | return bt_field_string_append_with_length(field, value, |
628 | (uint64_t) strlen(value)); | |
cd95e351 JG |
629 | } |
630 | ||
44c440bc PP |
631 | int bt_field_string_append_with_length(struct bt_field *field, |
632 | const char *value, uint64_t length) | |
273b65be | 633 | { |
cb6f1f7d PP |
634 | struct bt_field_string *string_field = (void *) field; |
635 | char *data; | |
44c440bc | 636 | uint64_t new_length; |
273b65be | 637 | |
44c440bc | 638 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
cb6f1f7d | 639 | BT_ASSERT_PRE_NON_NULL(value, "Value"); |
44c440bc | 640 | BT_ASSERT_PRE_FIELD_HOT(field, "Field"); |
864cad70 PP |
641 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, |
642 | BT_FIELD_CLASS_TYPE_STRING, "Field"); | |
312c056a | 643 | |
cb6f1f7d PP |
644 | /* Make sure no null bytes are appended */ |
645 | BT_ASSERT_PRE(memchr(value, '\0', length) == NULL, | |
646 | "String value to append contains a null character: " | |
44c440bc | 647 | "partial-value=\"%.32s\", length=%" PRIu64, value, length); |
c6f9c5a3 | 648 | |
44c440bc | 649 | new_length = length + string_field->length; |
cb6f1f7d | 650 | |
44c440bc PP |
651 | if (unlikely(new_length + 1 > string_field->buf->len)) { |
652 | g_array_set_size(string_field->buf, new_length + 1); | |
c6f9c5a3 PP |
653 | } |
654 | ||
cb6f1f7d | 655 | data = string_field->buf->data; |
44c440bc PP |
656 | memcpy(data + string_field->length, value, length); |
657 | ((char *) string_field->buf->data)[new_length] = '\0'; | |
658 | string_field->length = new_length; | |
659 | bt_field_set_single(field, true); | |
cb6f1f7d PP |
660 | return 0; |
661 | } | |
3dca2276 | 662 | |
cb6f1f7d PP |
663 | int bt_field_string_clear(struct bt_field *field) |
664 | { | |
665 | struct bt_field_string *string_field = (void *) field; | |
666 | ||
44c440bc PP |
667 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
668 | BT_ASSERT_PRE_FIELD_HOT(field, "Field"); | |
864cad70 PP |
669 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, |
670 | BT_FIELD_CLASS_TYPE_STRING, "Field"); | |
44c440bc PP |
671 | string_field->length = 0; |
672 | bt_field_set_single(field, true); | |
cb6f1f7d PP |
673 | return 0; |
674 | } | |
675 | ||
44c440bc | 676 | uint64_t bt_field_array_get_length(struct bt_field *field) |
cb6f1f7d | 677 | { |
44c440bc | 678 | struct bt_field_array *array_field = (void *) field; |
c6f9c5a3 | 679 | |
44c440bc PP |
680 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
681 | BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field"); | |
682 | return array_field->length; | |
3dca2276 | 683 | } |
f98c6554 | 684 | |
44c440bc PP |
685 | int bt_field_dynamic_array_set_length(struct bt_field *field, |
686 | uint64_t length) | |
3dca2276 | 687 | { |
44c440bc PP |
688 | int ret = 0; |
689 | struct bt_field_array *array_field = (void *) field; | |
f98c6554 | 690 | |
44c440bc | 691 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
864cad70 PP |
692 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, |
693 | BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, "Field"); | |
44c440bc | 694 | BT_ASSERT_PRE_FIELD_HOT(field, "Field"); |
273b65be | 695 | |
44c440bc PP |
696 | if (unlikely(length > array_field->fields->len)) { |
697 | /* Make more room */ | |
5cd6d0e5 | 698 | struct bt_field_class_array *array_fc; |
44c440bc PP |
699 | uint64_t cur_len = array_field->fields->len; |
700 | uint64_t i; | |
cb6f1f7d | 701 | |
44c440bc | 702 | g_ptr_array_set_size(array_field->fields, length); |
5cd6d0e5 | 703 | array_fc = (void *) field->class; |
cb6f1f7d | 704 | |
44c440bc PP |
705 | for (i = cur_len; i < array_field->fields->len; i++) { |
706 | struct bt_field *elem_field = bt_field_create( | |
5cd6d0e5 | 707 | array_fc->element_fc); |
273b65be | 708 | |
44c440bc PP |
709 | if (!elem_field) { |
710 | BT_LIB_LOGE("Cannot create element field for " | |
711 | "dynamic array field: " | |
712 | "index=%" PRIu64 ", " | |
713 | "%![array-field-]+f", i, field); | |
714 | ret = -1; | |
715 | goto end; | |
716 | } | |
c58b9c62 | 717 | |
44c440bc PP |
718 | BT_ASSERT(!array_field->fields->pdata[i]); |
719 | array_field->fields->pdata[i] = elem_field; | |
c58b9c62 | 720 | } |
c58b9c62 JG |
721 | } |
722 | ||
44c440bc | 723 | array_field->length = length; |
3dca2276 | 724 | |
273b65be | 725 | end: |
c58b9c62 | 726 | return ret; |
273b65be JG |
727 | } |
728 | ||
44c440bc PP |
729 | struct bt_field *bt_field_array_borrow_element_field_by_index( |
730 | struct bt_field *field, uint64_t index) | |
312c056a | 731 | { |
44c440bc | 732 | struct bt_field_array *array_field = (void *) field; |
312c056a | 733 | |
44c440bc PP |
734 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
735 | BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field"); | |
736 | BT_ASSERT_PRE_VALID_INDEX(index, array_field->length); | |
737 | return array_field->fields->pdata[index]; | |
312c056a PP |
738 | } |
739 | ||
44c440bc PP |
740 | struct bt_field *bt_field_structure_borrow_member_field_by_index( |
741 | struct bt_field *field, uint64_t index) | |
4d4b475d | 742 | { |
44c440bc | 743 | struct bt_field_structure *struct_field = (void *) field; |
4d4b475d | 744 | |
44c440bc | 745 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
864cad70 PP |
746 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, |
747 | BT_FIELD_CLASS_TYPE_STRUCTURE, "Field"); | |
44c440bc PP |
748 | BT_ASSERT_PRE_VALID_INDEX(index, struct_field->fields->len); |
749 | return struct_field->fields->pdata[index]; | |
4d4b475d PP |
750 | } |
751 | ||
44c440bc PP |
752 | struct bt_field *bt_field_structure_borrow_member_field_by_name( |
753 | struct bt_field *field, const char *name) | |
273b65be | 754 | { |
44c440bc | 755 | struct bt_field *ret_field = NULL; |
5cd6d0e5 | 756 | struct bt_field_class_structure *struct_fc; |
44c440bc PP |
757 | struct bt_field_structure *struct_field = (void *) field; |
758 | gpointer orig_key; | |
759 | gpointer index; | |
fc25abce | 760 | |
44c440bc PP |
761 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
762 | BT_ASSERT_PRE_NON_NULL(name, "Field name"); | |
864cad70 PP |
763 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, |
764 | BT_FIELD_CLASS_TYPE_STRUCTURE, "Field"); | |
5cd6d0e5 | 765 | struct_fc = (void *) field->class; |
312c056a | 766 | |
5cd6d0e5 | 767 | if (!g_hash_table_lookup_extended(struct_fc->common.name_to_index, name, |
44c440bc | 768 | &orig_key, &index)) { |
312c056a | 769 | goto end; |
fc25abce PP |
770 | } |
771 | ||
44c440bc PP |
772 | ret_field = struct_field->fields->pdata[GPOINTER_TO_UINT(index)]; |
773 | BT_ASSERT(ret_field); | |
312c056a PP |
774 | |
775 | end: | |
44c440bc | 776 | return ret_field; |
273b65be JG |
777 | } |
778 | ||
44c440bc PP |
779 | struct bt_field *bt_field_variant_borrow_selected_option_field( |
780 | struct bt_field *field) | |
273b65be | 781 | { |
44c440bc | 782 | struct bt_field_variant *var_field = (void *) field; |
273b65be | 783 | |
44c440bc | 784 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
864cad70 PP |
785 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, |
786 | BT_FIELD_CLASS_TYPE_VARIANT, "Field"); | |
44c440bc PP |
787 | BT_ASSERT_PRE(var_field->selected_field, |
788 | "Variant field has no selected field: %!+f", field); | |
789 | return var_field->selected_field; | |
273b65be JG |
790 | } |
791 | ||
44c440bc PP |
792 | int bt_field_variant_select_option_field(struct bt_field *field, |
793 | uint64_t index) | |
273b65be | 794 | { |
44c440bc | 795 | struct bt_field_variant *var_field = (void *) field; |
fc25abce | 796 | |
44c440bc | 797 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
864cad70 PP |
798 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, |
799 | BT_FIELD_CLASS_TYPE_VARIANT, "Field"); | |
44c440bc PP |
800 | BT_ASSERT_PRE_FIELD_HOT(field, "Field"); |
801 | BT_ASSERT_PRE_VALID_INDEX(index, var_field->fields->len); | |
802 | var_field->selected_field = var_field->fields->pdata[index]; | |
803 | var_field->selected_index = index; | |
804 | return 0; | |
273b65be JG |
805 | } |
806 | ||
44c440bc PP |
807 | uint64_t bt_field_variant_get_selected_option_field_index( |
808 | struct bt_field *field) | |
312c056a | 809 | { |
44c440bc | 810 | struct bt_field_variant *var_field = (void *) field; |
312c056a | 811 | |
44c440bc | 812 | BT_ASSERT_PRE_NON_NULL(field, "Field"); |
864cad70 PP |
813 | BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, |
814 | BT_FIELD_CLASS_TYPE_VARIANT, "Field"); | |
44c440bc PP |
815 | BT_ASSERT_PRE(var_field->selected_field, |
816 | "Variant field has no selected field: %!+f", field); | |
817 | return var_field->selected_index; | |
312c056a PP |
818 | } |
819 | ||
44c440bc PP |
820 | static inline |
821 | void bt_field_finalize(struct bt_field *field) | |
273b65be | 822 | { |
44c440bc | 823 | BT_ASSERT(field); |
5cd6d0e5 | 824 | BT_LOGD_STR("Putting field's class."); |
65300d60 | 825 | bt_object_put_ref(field->class); |
273b65be JG |
826 | } |
827 | ||
828 | static | |
44c440bc | 829 | void destroy_integer_field(struct bt_field *field) |
273b65be | 830 | { |
44c440bc PP |
831 | BT_ASSERT(field); |
832 | BT_LIB_LOGD("Destroying integer field object: %!+f", field); | |
833 | bt_field_finalize(field); | |
834 | g_free(field); | |
273b65be JG |
835 | } |
836 | ||
cb6f1f7d | 837 | static |
44c440bc | 838 | void destroy_real_field(struct bt_field *field) |
273b65be | 839 | { |
44c440bc PP |
840 | BT_ASSERT(field); |
841 | BT_LIB_LOGD("Destroying real field object: %!+f", field); | |
842 | bt_field_finalize(field); | |
843 | g_free(field); | |
273b65be JG |
844 | } |
845 | ||
cb6f1f7d | 846 | static |
44c440bc | 847 | void destroy_structure_field(struct bt_field *field) |
273b65be | 848 | { |
44c440bc | 849 | struct bt_field_structure *struct_field = (void *) field; |
273b65be | 850 | |
f6ccaed9 | 851 | BT_ASSERT(field); |
44c440bc PP |
852 | BT_LIB_LOGD("Destroying structure field object: %!+f", field); |
853 | bt_field_finalize(field); | |
f6ccaed9 | 854 | |
44c440bc PP |
855 | if (struct_field->fields) { |
856 | g_ptr_array_free(struct_field->fields, TRUE); | |
273b65be | 857 | } |
f6ccaed9 | 858 | |
44c440bc | 859 | g_free(field); |
273b65be JG |
860 | } |
861 | ||
cb6f1f7d | 862 | static |
44c440bc | 863 | void destroy_variant_field(struct bt_field *field) |
273b65be | 864 | { |
44c440bc | 865 | struct bt_field_variant *var_field = (void *) field; |
273b65be | 866 | |
f6ccaed9 | 867 | BT_ASSERT(field); |
44c440bc PP |
868 | BT_LIB_LOGD("Destroying variant field object: %!+f", field); |
869 | bt_field_finalize(field); | |
312c056a | 870 | |
44c440bc PP |
871 | if (var_field->fields) { |
872 | g_ptr_array_free(var_field->fields, TRUE); | |
fc25abce | 873 | } |
f6ccaed9 | 874 | |
44c440bc | 875 | g_free(field); |
273b65be JG |
876 | } |
877 | ||
cb6f1f7d | 878 | static |
44c440bc | 879 | void destroy_array_field(struct bt_field *field) |
273b65be | 880 | { |
44c440bc | 881 | struct bt_field_array *array_field = (void *) field; |
273b65be | 882 | |
f6ccaed9 | 883 | BT_ASSERT(field); |
44c440bc PP |
884 | BT_LIB_LOGD("Destroying array field object: %!+f", field); |
885 | bt_field_finalize(field); | |
3dca2276 | 886 | |
44c440bc PP |
887 | if (array_field->fields) { |
888 | g_ptr_array_free(array_field->fields, TRUE); | |
273b65be | 889 | } |
f6ccaed9 | 890 | |
44c440bc | 891 | g_free(field); |
273b65be JG |
892 | } |
893 | ||
cb6f1f7d | 894 | static |
44c440bc | 895 | void destroy_string_field(struct bt_field *field) |
273b65be | 896 | { |
44c440bc | 897 | struct bt_field_string *string_field = (void *) field; |
273b65be | 898 | |
f6ccaed9 | 899 | BT_ASSERT(field); |
44c440bc PP |
900 | BT_LIB_LOGD("Destroying string field object: %!+f", field); |
901 | bt_field_finalize(field); | |
3dca2276 | 902 | |
44c440bc PP |
903 | if (string_field->buf) { |
904 | g_array_free(string_field->buf, TRUE); | |
273b65be | 905 | } |
44c440bc PP |
906 | |
907 | g_free(field); | |
273b65be JG |
908 | } |
909 | ||
44c440bc PP |
910 | BT_HIDDEN |
911 | void bt_field_destroy(struct bt_field *field) | |
12c8a1a3 | 912 | { |
f6ccaed9 | 913 | BT_ASSERT(field); |
864cad70 PP |
914 | BT_ASSERT(bt_field_class_has_known_type(field->class)); |
915 | field_destroy_funcs[field->class->type](field); | |
12c8a1a3 JG |
916 | } |
917 | ||
cb6f1f7d | 918 | static |
44c440bc | 919 | void reset_single_field(struct bt_field *field) |
12c8a1a3 | 920 | { |
f6ccaed9 | 921 | BT_ASSERT(field); |
44c440bc | 922 | field->is_set = false; |
12c8a1a3 JG |
923 | } |
924 | ||
cb6f1f7d | 925 | static |
44c440bc | 926 | void reset_structure_field(struct bt_field *field) |
12c8a1a3 | 927 | { |
44c440bc PP |
928 | uint64_t i; |
929 | struct bt_field_structure *struct_field = (void *) field; | |
12c8a1a3 | 930 | |
f6ccaed9 | 931 | BT_ASSERT(field); |
44c440bc PP |
932 | |
933 | for (i = 0; i < struct_field->fields->len; i++) { | |
934 | bt_field_reset(struct_field->fields->pdata[i]); | |
935 | } | |
12c8a1a3 JG |
936 | } |
937 | ||
cb6f1f7d | 938 | static |
44c440bc | 939 | void reset_variant_field(struct bt_field *field) |
12c8a1a3 | 940 | { |
44c440bc PP |
941 | uint64_t i; |
942 | struct bt_field_variant *var_field = (void *) field; | |
12c8a1a3 | 943 | |
f6ccaed9 | 944 | BT_ASSERT(field); |
f6ccaed9 | 945 | |
44c440bc PP |
946 | for (i = 0; i < var_field->fields->len; i++) { |
947 | bt_field_reset(var_field->fields->pdata[i]); | |
12c8a1a3 | 948 | } |
12c8a1a3 JG |
949 | } |
950 | ||
cb6f1f7d | 951 | static |
44c440bc | 952 | void reset_array_field(struct bt_field *field) |
12c8a1a3 | 953 | { |
312c056a | 954 | uint64_t i; |
44c440bc | 955 | struct bt_field_array *array_field = (void *) field; |
12c8a1a3 | 956 | |
f6ccaed9 | 957 | BT_ASSERT(field); |
f6ccaed9 | 958 | |
44c440bc PP |
959 | for (i = 0; i < array_field->fields->len; i++) { |
960 | bt_field_reset(array_field->fields->pdata[i]); | |
12c8a1a3 | 961 | } |
12c8a1a3 JG |
962 | } |
963 | ||
cb6f1f7d | 964 | static |
44c440bc | 965 | void set_single_field_is_frozen(struct bt_field *field, bool is_frozen) |
918be005 | 966 | { |
312c056a | 967 | field->frozen = is_frozen; |
918be005 PP |
968 | } |
969 | ||
cb6f1f7d | 970 | static |
44c440bc | 971 | void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen) |
918be005 | 972 | { |
312c056a | 973 | uint64_t i; |
44c440bc | 974 | struct bt_field_structure *struct_field = (void *) field; |
918be005 | 975 | |
44c440bc PP |
976 | BT_LIB_LOGD("Setting structure field's frozen state: " |
977 | "%![field-]+f, is-frozen=%d", field, is_frozen); | |
fc25abce | 978 | |
44c440bc PP |
979 | for (i = 0; i < struct_field->fields->len; i++) { |
980 | struct bt_field *member_field = struct_field->fields->pdata[i]; | |
918be005 | 981 | |
44c440bc PP |
982 | BT_LIB_LOGD("Setting structure field's member field's " |
983 | "frozen state: %![field-]+f, index=%" PRIu64, | |
984 | member_field, i); | |
985 | bt_field_set_is_frozen(member_field, is_frozen); | |
918be005 PP |
986 | } |
987 | ||
44c440bc | 988 | set_single_field_is_frozen(field, is_frozen); |
918be005 PP |
989 | } |
990 | ||
cb6f1f7d | 991 | static |
44c440bc | 992 | void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen) |
918be005 | 993 | { |
312c056a | 994 | uint64_t i; |
44c440bc | 995 | struct bt_field_variant *var_field = (void *) field; |
918be005 | 996 | |
44c440bc PP |
997 | BT_LIB_LOGD("Setting variant field's frozen state: " |
998 | "%![field-]+f, is-frozen=%d", field, is_frozen); | |
312c056a | 999 | |
44c440bc PP |
1000 | for (i = 0; i < var_field->fields->len; i++) { |
1001 | struct bt_field *option_field = var_field->fields->pdata[i]; | |
312c056a | 1002 | |
44c440bc PP |
1003 | BT_LIB_LOGD("Setting variant field's option field's " |
1004 | "frozen state: %![field-]+f, index=%" PRIu64, | |
1005 | option_field, i); | |
1006 | bt_field_set_is_frozen(option_field, is_frozen); | |
312c056a PP |
1007 | } |
1008 | ||
44c440bc | 1009 | set_single_field_is_frozen(field, is_frozen); |
918be005 PP |
1010 | } |
1011 | ||
cb6f1f7d | 1012 | static |
44c440bc | 1013 | void set_array_field_is_frozen(struct bt_field *field, bool is_frozen) |
918be005 | 1014 | { |
44c440bc | 1015 | uint64_t i; |
cb6f1f7d | 1016 | struct bt_field_array *array_field = (void *) field; |
918be005 | 1017 | |
44c440bc PP |
1018 | BT_LIB_LOGD("Setting array field's frozen state: " |
1019 | "%![field-]+f, is-frozen=%d", field, is_frozen); | |
fc25abce | 1020 | |
44c440bc PP |
1021 | for (i = 0; i < array_field->fields->len; i++) { |
1022 | struct bt_field *elem_field = array_field->fields->pdata[i]; | |
918be005 | 1023 | |
44c440bc PP |
1024 | BT_LIB_LOGD("Setting array field's element field's " |
1025 | "frozen state: %![field-]+f, index=%" PRIu64, | |
fc25abce | 1026 | elem_field, i); |
44c440bc | 1027 | bt_field_set_is_frozen(elem_field, is_frozen); |
918be005 PP |
1028 | } |
1029 | ||
44c440bc | 1030 | set_single_field_is_frozen(field, is_frozen); |
918be005 PP |
1031 | } |
1032 | ||
1033 | BT_HIDDEN | |
44c440bc | 1034 | void _bt_field_set_is_frozen(struct bt_field *field, |
312c056a | 1035 | bool is_frozen) |
918be005 | 1036 | { |
44c440bc PP |
1037 | BT_ASSERT(field); |
1038 | BT_LIB_LOGD("Setting field object's frozen state: %!+f, is-frozen=%d", | |
312c056a | 1039 | field, is_frozen); |
312c056a PP |
1040 | BT_ASSERT(field->methods->set_is_frozen); |
1041 | field->methods->set_is_frozen(field, is_frozen); | |
918be005 | 1042 | } |
76f869ab | 1043 | |
cb6f1f7d | 1044 | static |
44c440bc | 1045 | bool single_field_is_set(struct bt_field *field) |
76f869ab | 1046 | { |
44c440bc PP |
1047 | BT_ASSERT(field); |
1048 | return field->is_set; | |
76f869ab JG |
1049 | } |
1050 | ||
cb6f1f7d | 1051 | static |
44c440bc | 1052 | bool structure_field_is_set(struct bt_field *field) |
76f869ab | 1053 | { |
44c440bc PP |
1054 | bool is_set = true; |
1055 | uint64_t i; | |
1056 | struct bt_field_structure *struct_field = (void *) field; | |
76f869ab | 1057 | |
f6ccaed9 | 1058 | BT_ASSERT(field); |
3dca2276 | 1059 | |
44c440bc PP |
1060 | for (i = 0; i < struct_field->fields->len; i++) { |
1061 | is_set = bt_field_is_set(struct_field->fields->pdata[i]); | |
d4bf905a | 1062 | if (!is_set) { |
76f869ab JG |
1063 | goto end; |
1064 | } | |
1065 | } | |
3dca2276 | 1066 | |
76f869ab | 1067 | end: |
d4bf905a | 1068 | return is_set; |
76f869ab JG |
1069 | } |
1070 | ||
cb6f1f7d | 1071 | static |
44c440bc | 1072 | bool variant_field_is_set(struct bt_field *field) |
76f869ab | 1073 | { |
44c440bc PP |
1074 | struct bt_field_variant *var_field = (void *) field; |
1075 | bool is_set = false; | |
76f869ab | 1076 | |
f6ccaed9 | 1077 | BT_ASSERT(field); |
3dca2276 | 1078 | |
44c440bc PP |
1079 | if (var_field->selected_field) { |
1080 | is_set = bt_field_is_set(var_field->selected_field); | |
76f869ab | 1081 | } |
3dca2276 | 1082 | |
d4bf905a | 1083 | return is_set; |
76f869ab JG |
1084 | } |
1085 | ||
cb6f1f7d | 1086 | static |
44c440bc | 1087 | bool array_field_is_set(struct bt_field *field) |
76f869ab | 1088 | { |
44c440bc PP |
1089 | bool is_set = true; |
1090 | uint64_t i; | |
1091 | struct bt_field_array *array_field = (void *) field; | |
76f869ab | 1092 | |
f6ccaed9 | 1093 | BT_ASSERT(field); |
3dca2276 | 1094 | |
44c440bc PP |
1095 | for (i = 0; i < array_field->length; i++) { |
1096 | is_set = bt_field_is_set(array_field->fields->pdata[i]); | |
d4bf905a | 1097 | if (!is_set) { |
76f869ab JG |
1098 | goto end; |
1099 | } | |
1100 | } | |
3dca2276 | 1101 | |
76f869ab | 1102 | end: |
d4bf905a | 1103 | return is_set; |
76f869ab | 1104 | } |