Commit | Line | Data |
---|---|---|
2e33ac5a PP |
1 | #ifndef BABELTRACE_CTF_IR_FIELDS_INTERNAL_H |
2 | #define BABELTRACE_CTF_IR_FIELDS_INTERNAL_H | |
273b65be JG |
3 | |
4 | /* | |
2e33ac5a | 5 | * Babeltrace - CTF IR: Event Fields internal |
273b65be | 6 | * |
de9dd397 | 7 | * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com> |
273b65be JG |
8 | * |
9 | * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
10 | * | |
11 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
12 | * of this software and associated documentation files (the "Software"), to deal | |
13 | * in the Software without restriction, including without limitation the rights | |
14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
15 | * copies of the Software, and to permit persons to whom the Software is | |
16 | * furnished to do so, subject to the following conditions: | |
17 | * | |
18 | * The above copyright notice and this permission notice shall be included in | |
19 | * all copies or substantial portions of the Software. | |
20 | * | |
21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
27 | * SOFTWARE. | |
28 | */ | |
29 | ||
3dca2276 PP |
30 | #include <babeltrace/assert-pre-internal.h> |
31 | #include <babeltrace/common-internal.h> | |
32 | #include <babeltrace/ctf-ir/field-types-internal.h> | |
33 | #include <babeltrace/ctf-ir/utils-internal.h> | |
83509119 | 34 | #include <babeltrace/object-internal.h> |
273b65be | 35 | #include <babeltrace/babeltrace-internal.h> |
c55a9f58 | 36 | #include <babeltrace/types.h> |
dc3fffef | 37 | #include <stdint.h> |
4d4b475d | 38 | #include <string.h> |
3dca2276 | 39 | #include <inttypes.h> |
d990a4fb | 40 | #include <stdbool.h> |
273b65be JG |
41 | #include <glib.h> |
42 | ||
3dca2276 | 43 | #define BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(_field, _type_id, _name) \ |
312c056a | 44 | BT_ASSERT_PRE((_field)->type->id == ((int) (_type_id)), \ |
3dca2276 | 45 | _name " has the wrong type ID: expected-type-id=%s, " \ |
312c056a PP |
46 | "%![field-]+_f", \ |
47 | bt_common_field_type_id_string((int) (_type_id)), (_field)) | |
dc3fffef | 48 | |
3dca2276 PP |
49 | #define BT_ASSERT_PRE_FIELD_COMMON_IS_SET(_field, _name) \ |
50 | BT_ASSERT_PRE(bt_field_common_is_set_recursive(_field), \ | |
51 | _name " is not set: %!+_f", (_field)) | |
52 | ||
53 | #define BT_ASSERT_PRE_FIELD_COMMON_HOT(_field, _name) \ | |
54 | BT_ASSERT_PRE_HOT((_field), (_name), ": +%!+_f", (_field)) | |
55 | ||
56 | struct bt_field; | |
57 | struct bt_field_common; | |
58 | ||
312c056a PP |
59 | typedef void (*bt_field_common_method_set_is_frozen)(struct bt_field_common *, |
60 | bool); | |
3dca2276 PP |
61 | typedef int (*bt_field_common_method_validate)(struct bt_field_common *); |
62 | typedef struct bt_field_common *(*bt_field_common_method_copy)( | |
63 | struct bt_field_common *); | |
64 | typedef bt_bool (*bt_field_common_method_is_set)(struct bt_field_common *); | |
65 | typedef void (*bt_field_common_method_reset)(struct bt_field_common *); | |
66 | ||
67 | struct bt_field_common_methods { | |
312c056a | 68 | bt_field_common_method_set_is_frozen set_is_frozen; |
3dca2276 PP |
69 | bt_field_common_method_validate validate; |
70 | bt_field_common_method_copy copy; | |
71 | bt_field_common_method_is_set is_set; | |
72 | bt_field_common_method_reset reset; | |
73 | }; | |
74 | ||
75 | struct bt_field_common { | |
83509119 | 76 | struct bt_object base; |
3dca2276 PP |
77 | struct bt_field_type_common *type; |
78 | struct bt_field_common_methods *methods; | |
d990a4fb JG |
79 | bool payload_set; |
80 | bool frozen; | |
3dca2276 PP |
81 | |
82 | /* | |
83 | * Specialized data for either CTF IR or CTF writer APIs. | |
84 | * See comment in `field-types-internal.h` for more details. | |
85 | */ | |
86 | union { | |
87 | struct { | |
88 | } ir; | |
89 | struct { | |
90 | void *serialize_func; | |
91 | } writer; | |
92 | } spec; | |
273b65be JG |
93 | }; |
94 | ||
3dca2276 PP |
95 | struct bt_field_common_integer { |
96 | struct bt_field_common common; | |
dc3fffef PP |
97 | union { |
98 | int64_t signd; | |
99 | uint64_t unsignd; | |
100 | } payload; | |
273b65be JG |
101 | }; |
102 | ||
3dca2276 PP |
103 | struct bt_field_common_floating_point { |
104 | struct bt_field_common common; | |
dc3fffef | 105 | double payload; |
273b65be JG |
106 | }; |
107 | ||
3dca2276 PP |
108 | struct bt_field_common_structure { |
109 | struct bt_field_common common; | |
312c056a PP |
110 | |
111 | /* Array of `struct bt_field_common *`, owned by this */ | |
112 | GPtrArray *fields; | |
273b65be JG |
113 | }; |
114 | ||
3dca2276 PP |
115 | struct bt_field_common_variant { |
116 | struct bt_field_common common; | |
312c056a PP |
117 | |
118 | union { | |
119 | uint64_t u; | |
120 | int64_t i; | |
121 | } tag_value; | |
122 | ||
123 | /* Weak: belongs to `choices` below */ | |
124 | struct bt_field_common *current_field; | |
125 | ||
126 | /* Array of `struct bt_field_common *`, owned by this */ | |
127 | GPtrArray *fields; | |
273b65be JG |
128 | }; |
129 | ||
3dca2276 PP |
130 | struct bt_field_common_array { |
131 | struct bt_field_common common; | |
312c056a PP |
132 | |
133 | /* Array of `struct bt_field_common *`, owned by this */ | |
134 | GPtrArray *elements; | |
273b65be JG |
135 | }; |
136 | ||
3dca2276 PP |
137 | struct bt_field_common_sequence { |
138 | struct bt_field_common common; | |
312c056a PP |
139 | |
140 | /* | |
141 | * This is the true sequence field's length: its value can be | |
142 | * less than `elements->len` below because we never shrink the | |
143 | * array of elements to avoid reallocation. | |
144 | */ | |
145 | uint64_t length; | |
146 | ||
147 | /* Array of `struct bt_field_common *`, owned by this */ | |
148 | GPtrArray *elements; | |
273b65be JG |
149 | }; |
150 | ||
3dca2276 PP |
151 | struct bt_field_common_string { |
152 | struct bt_field_common common; | |
4d4b475d PP |
153 | GArray *buf; |
154 | size_t size; | |
273b65be JG |
155 | }; |
156 | ||
312c056a PP |
157 | struct bt_field_enumeration { |
158 | struct bt_field_common_integer common; | |
159 | }; | |
3dca2276 PP |
160 | |
161 | BT_HIDDEN | |
162 | struct bt_field_common *bt_field_common_copy(struct bt_field_common *field); | |
163 | ||
164 | BT_HIDDEN | |
165 | int bt_field_common_structure_initialize(struct bt_field_common *field, | |
166 | struct bt_field_type_common *type, | |
167 | bt_object_release_func release_func, | |
168 | struct bt_field_common_methods *methods, | |
312c056a PP |
169 | bt_field_common_create_func field_create_func, |
170 | GDestroyNotify field_release_func); | |
3dca2276 PP |
171 | |
172 | BT_HIDDEN | |
173 | int bt_field_common_array_initialize(struct bt_field_common *field, | |
174 | struct bt_field_type_common *type, | |
175 | bt_object_release_func release_func, | |
312c056a PP |
176 | struct bt_field_common_methods *methods, |
177 | bt_field_common_create_func field_create_func, | |
178 | GDestroyNotify field_destroy_func); | |
3dca2276 PP |
179 | |
180 | BT_HIDDEN | |
312c056a PP |
181 | int bt_field_common_sequence_initialize(struct bt_field_common *field, |
182 | struct bt_field_type_common *type, | |
183 | bt_object_release_func release_func, | |
184 | struct bt_field_common_methods *methods, | |
185 | GDestroyNotify field_destroy_func); | |
3dca2276 PP |
186 | |
187 | BT_HIDDEN | |
312c056a PP |
188 | int bt_field_common_variant_initialize(struct bt_field_common *field, |
189 | struct bt_field_type_common *type, | |
190 | bt_object_release_func release_func, | |
191 | struct bt_field_common_methods *methods, | |
192 | bt_field_common_create_func field_create_func, | |
193 | GDestroyNotify field_release_func); | |
194 | ||
4d4b475d PP |
195 | BT_HIDDEN |
196 | int bt_field_common_string_initialize(struct bt_field_common *field, | |
197 | struct bt_field_type_common *type, | |
198 | bt_object_release_func release_func, | |
199 | struct bt_field_common_methods *methods); | |
200 | ||
312c056a PP |
201 | BT_HIDDEN |
202 | int bt_field_common_generic_validate(struct bt_field_common *field); | |
3dca2276 PP |
203 | |
204 | BT_HIDDEN | |
205 | int bt_field_common_structure_validate_recursive(struct bt_field_common *field); | |
206 | ||
207 | BT_HIDDEN | |
208 | int bt_field_common_variant_validate_recursive(struct bt_field_common *field); | |
209 | ||
210 | BT_HIDDEN | |
211 | int bt_field_common_array_validate_recursive(struct bt_field_common *field); | |
212 | ||
213 | BT_HIDDEN | |
214 | int bt_field_common_sequence_validate_recursive(struct bt_field_common *field); | |
215 | ||
216 | BT_HIDDEN | |
217 | void bt_field_common_generic_reset(struct bt_field_common *field); | |
218 | ||
3dca2276 PP |
219 | BT_HIDDEN |
220 | void bt_field_common_structure_reset_recursive(struct bt_field_common *field); | |
221 | ||
222 | BT_HIDDEN | |
223 | void bt_field_common_variant_reset_recursive(struct bt_field_common *field); | |
224 | ||
225 | BT_HIDDEN | |
226 | void bt_field_common_array_reset_recursive(struct bt_field_common *field); | |
227 | ||
228 | BT_HIDDEN | |
229 | void bt_field_common_sequence_reset_recursive(struct bt_field_common *field); | |
230 | ||
3dca2276 | 231 | BT_HIDDEN |
312c056a PP |
232 | void bt_field_common_generic_set_is_frozen(struct bt_field_common *field, |
233 | bool is_frozen); | |
f6ccaed9 | 234 | |
273b65be | 235 | BT_HIDDEN |
312c056a PP |
236 | void bt_field_common_structure_set_is_frozen_recursive( |
237 | struct bt_field_common *field, bool is_frozen); | |
273b65be JG |
238 | |
239 | BT_HIDDEN | |
312c056a PP |
240 | void bt_field_common_variant_set_is_frozen_recursive( |
241 | struct bt_field_common *field, bool is_frozen); | |
f6ccaed9 PP |
242 | |
243 | BT_HIDDEN | |
312c056a PP |
244 | void bt_field_common_array_set_is_frozen_recursive( |
245 | struct bt_field_common *field, bool is_frozen); | |
f6ccaed9 PP |
246 | |
247 | BT_HIDDEN | |
312c056a PP |
248 | void bt_field_common_sequence_set_is_frozen_recursive( |
249 | struct bt_field_common *field, bool is_frozen); | |
273b65be | 250 | |
918be005 | 251 | BT_HIDDEN |
312c056a PP |
252 | void _bt_field_common_set_is_frozen_recursive(struct bt_field_common *field, |
253 | bool is_frozen); | |
3dca2276 PP |
254 | |
255 | BT_HIDDEN | |
256 | bt_bool bt_field_common_generic_is_set(struct bt_field_common *field); | |
257 | ||
3dca2276 PP |
258 | BT_HIDDEN |
259 | bt_bool bt_field_common_structure_is_set_recursive( | |
260 | struct bt_field_common *field); | |
261 | ||
262 | BT_HIDDEN | |
263 | bt_bool bt_field_common_variant_is_set_recursive(struct bt_field_common *field); | |
264 | ||
265 | BT_HIDDEN | |
266 | bt_bool bt_field_common_array_is_set_recursive(struct bt_field_common *field); | |
267 | ||
268 | BT_HIDDEN | |
269 | bt_bool bt_field_common_sequence_is_set_recursive(struct bt_field_common *field); | |
270 | ||
f6ccaed9 | 271 | #ifdef BT_DEV_MODE |
312c056a PP |
272 | # define bt_field_common_validate_recursive _bt_field_common_validate_recursive |
273 | # define bt_field_common_set_is_frozen_recursive _bt_field_common_set_is_frozen_recursive | |
274 | # define bt_field_common_is_set_recursive _bt_field_common_is_set_recursive | |
275 | # define bt_field_common_reset_recursive _bt_field_common_reset_recursive | |
276 | # define bt_field_common_set _bt_field_common_set | |
277 | # define bt_field_validate_recursive _bt_field_validate_recursive | |
278 | # define bt_field_set_is_frozen_recursive _bt_field_set_is_frozen_recursive | |
279 | # define bt_field_is_set_recursive _bt_field_is_set_recursive | |
280 | # define bt_field_reset_recursive _bt_field_reset_recursive | |
281 | # define bt_field_set _bt_field_set | |
f6ccaed9 | 282 | #else |
3dca2276 | 283 | # define bt_field_common_validate_recursive(_field) (-1) |
312c056a | 284 | # define bt_field_common_set_is_frozen_recursive(_field, _is_frozen) |
3dca2276 | 285 | # define bt_field_common_is_set_recursive(_field) (BT_FALSE) |
565b6706 | 286 | # define bt_field_common_reset_recursive(_field) |
3dca2276 PP |
287 | # define bt_field_common_set(_field, _val) |
288 | # define bt_field_validate_recursive(_field) (-1) | |
312c056a | 289 | # define bt_field_set_is_frozen_recursive(_field, _is_frozen) |
3dca2276 | 290 | # define bt_field_is_set_recursive(_field) (BT_FALSE) |
565b6706 | 291 | # define bt_field_reset_recursive(_field) |
f6ccaed9 PP |
292 | # define bt_field_set(_field, _val) |
293 | #endif | |
918be005 | 294 | |
3dca2276 PP |
295 | BT_ASSERT_FUNC |
296 | static inline bool field_type_common_has_known_id( | |
297 | struct bt_field_type_common *ft) | |
298 | { | |
312c056a PP |
299 | return (int) ft->id > BT_FIELD_TYPE_ID_UNKNOWN || |
300 | (int) ft->id < BT_FIELD_TYPE_ID_NR; | |
3dca2276 PP |
301 | } |
302 | ||
303 | static inline | |
304 | int _bt_field_common_validate_recursive(struct bt_field_common *field) | |
305 | { | |
306 | int ret = 0; | |
307 | ||
308 | if (!field) { | |
309 | BT_ASSERT_PRE_MSG("%s", "Invalid field: field is NULL."); | |
310 | ret = -1; | |
311 | goto end; | |
312 | } | |
313 | ||
314 | BT_ASSERT(field_type_common_has_known_id(field->type)); | |
315 | ||
316 | if (field->methods->validate) { | |
317 | ret = field->methods->validate(field); | |
318 | } | |
319 | ||
320 | end: | |
321 | return ret; | |
322 | } | |
323 | ||
324 | static inline | |
325 | void _bt_field_common_reset_recursive(struct bt_field_common *field) | |
326 | { | |
327 | BT_ASSERT(field); | |
328 | BT_ASSERT(field->methods->reset); | |
329 | field->methods->reset(field); | |
330 | } | |
331 | ||
332 | static inline | |
333 | void _bt_field_common_set(struct bt_field_common *field, bool value) | |
334 | { | |
335 | BT_ASSERT(field); | |
336 | field->payload_set = value; | |
337 | } | |
338 | ||
339 | static inline | |
340 | bt_bool _bt_field_common_is_set_recursive(struct bt_field_common *field) | |
341 | { | |
342 | bt_bool is_set = BT_FALSE; | |
343 | ||
344 | if (!field) { | |
345 | goto end; | |
346 | } | |
347 | ||
348 | BT_ASSERT(field_type_common_has_known_id(field->type)); | |
349 | BT_ASSERT(field->methods->is_set); | |
350 | is_set = field->methods->is_set(field); | |
351 | ||
352 | end: | |
353 | return is_set; | |
354 | } | |
355 | ||
356 | static inline | |
357 | void bt_field_common_initialize(struct bt_field_common *field, | |
358 | struct bt_field_type_common *ft, | |
359 | bt_object_release_func release_func, | |
360 | struct bt_field_common_methods *methods) | |
361 | { | |
362 | BT_ASSERT(field); | |
363 | BT_ASSERT(ft); | |
364 | bt_object_init(field, release_func); | |
365 | field->methods = methods; | |
366 | field->type = bt_get(ft); | |
367 | } | |
368 | ||
369 | static inline | |
094ff7c0 | 370 | struct bt_field_type_common *bt_field_common_borrow_type( |
3dca2276 PP |
371 | struct bt_field_common *field) |
372 | { | |
373 | struct bt_field_type_common *ret = NULL; | |
374 | ||
375 | BT_ASSERT_PRE_NON_NULL(field, "Field"); | |
094ff7c0 | 376 | ret = field->type; |
3dca2276 PP |
377 | return ret; |
378 | } | |
379 | ||
380 | static inline | |
312c056a | 381 | int64_t bt_field_common_sequence_get_length(struct bt_field_common *field) |
3dca2276 PP |
382 | { |
383 | struct bt_field_common_sequence *sequence = BT_FROM_COMMON(field); | |
384 | ||
385 | BT_ASSERT_PRE_NON_NULL(field, "Sequence field"); | |
386 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_SEQUENCE, | |
387 | "Field"); | |
312c056a | 388 | return (int64_t) sequence->length; |
3dca2276 PP |
389 | } |
390 | ||
391 | static inline | |
392 | int bt_field_common_sequence_set_length(struct bt_field_common *field, | |
312c056a | 393 | uint64_t length, bt_field_common_create_func field_create_func) |
3dca2276 PP |
394 | { |
395 | int ret = 0; | |
3dca2276 | 396 | struct bt_field_common_sequence *sequence = BT_FROM_COMMON(field); |
3dca2276 PP |
397 | |
398 | BT_ASSERT_PRE_NON_NULL(field, "Sequence field"); | |
3dca2276 | 399 | BT_ASSERT_PRE_FIELD_COMMON_HOT(field, "Sequence field"); |
3dca2276 | 400 | |
312c056a PP |
401 | if (length > sequence->elements->len) { |
402 | /* Make more room */ | |
403 | struct bt_field_type_common_sequence *sequence_ft; | |
404 | uint64_t cur_len = sequence->elements->len; | |
405 | uint64_t i; | |
406 | ||
407 | g_ptr_array_set_size(sequence->elements, length); | |
408 | sequence_ft = BT_FROM_COMMON(sequence->common.type); | |
409 | ||
410 | for (i = cur_len; i < sequence->elements->len; i++) { | |
411 | struct bt_field_common *elem_field = | |
412 | field_create_func(sequence_ft->element_ft); | |
413 | ||
414 | if (!elem_field) { | |
415 | ret = -1; | |
416 | goto end; | |
417 | } | |
418 | ||
419 | BT_ASSERT(!sequence->elements->pdata[i]); | |
420 | sequence->elements->pdata[i] = elem_field; | |
421 | } | |
3dca2276 PP |
422 | } |
423 | ||
312c056a | 424 | sequence->length = length; |
3dca2276 PP |
425 | |
426 | end: | |
427 | return ret; | |
428 | } | |
429 | ||
430 | static inline | |
094ff7c0 | 431 | struct bt_field_common *bt_field_common_structure_borrow_field_by_name( |
3dca2276 PP |
432 | struct bt_field_common *field, const char *name) |
433 | { | |
434 | struct bt_field_common *ret = NULL; | |
435 | GQuark field_quark; | |
436 | struct bt_field_type_common_structure *structure_ft; | |
437 | struct bt_field_common_structure *structure = BT_FROM_COMMON(field); | |
438 | size_t index; | |
439 | GHashTable *field_name_to_index; | |
440 | ||
441 | BT_ASSERT_PRE_NON_NULL(field, "Structure field"); | |
442 | BT_ASSERT_PRE_NON_NULL(name, "Field name"); | |
443 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field, | |
444 | BT_FIELD_TYPE_ID_STRUCT, "Field"); | |
445 | structure_ft = BT_FROM_COMMON(field->type); | |
446 | field_name_to_index = structure_ft->field_name_to_index; | |
447 | field_quark = g_quark_from_string(name); | |
448 | if (!g_hash_table_lookup_extended(field_name_to_index, | |
449 | GUINT_TO_POINTER(field_quark), | |
450 | NULL, (gpointer *) &index)) { | |
451 | BT_LOGV("Invalid parameter: no such field in structure field's type: " | |
452 | "struct-field-addr=%p, struct-ft-addr=%p, name=\"%s\"", | |
453 | field, field->type, name); | |
454 | goto error; | |
455 | } | |
456 | ||
094ff7c0 | 457 | ret = structure->fields->pdata[index]; |
3dca2276 PP |
458 | BT_ASSERT(ret); |
459 | ||
460 | error: | |
461 | return ret; | |
462 | } | |
463 | ||
464 | static inline | |
094ff7c0 | 465 | struct bt_field_common *bt_field_common_structure_borrow_field_by_index( |
3dca2276 PP |
466 | struct bt_field_common *field, uint64_t index) |
467 | { | |
468 | struct bt_field_common_structure *structure = BT_FROM_COMMON(field); | |
469 | ||
470 | BT_ASSERT_PRE_NON_NULL(field, "Structure field"); | |
471 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field, | |
472 | BT_FIELD_TYPE_ID_STRUCT, "Field"); | |
473 | BT_ASSERT_PRE(index < structure->fields->len, | |
474 | "Index is out of bound: %![struct-field-]+_f, " | |
475 | "index=%" PRIu64 ", count=%u", field, index, | |
476 | structure->fields->len); | |
094ff7c0 | 477 | return structure->fields->pdata[index]; |
3dca2276 PP |
478 | } |
479 | ||
3dca2276 | 480 | static inline |
094ff7c0 | 481 | struct bt_field_common *bt_field_common_array_borrow_field( |
312c056a | 482 | struct bt_field_common *field, uint64_t index) |
3dca2276 | 483 | { |
3dca2276 PP |
484 | struct bt_field_common_array *array = BT_FROM_COMMON(field); |
485 | ||
486 | BT_ASSERT_PRE_NON_NULL(field, "Array field"); | |
312c056a PP |
487 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_ARRAY, |
488 | "Field"); | |
3dca2276 PP |
489 | BT_ASSERT_PRE(index < array->elements->len, |
490 | "Index is out of bound: %![array-field-]+_f, " | |
491 | "index=%" PRIu64 ", count=%u", field, | |
492 | index, array->elements->len); | |
312c056a | 493 | return array->elements->pdata[(size_t) index]; |
3dca2276 PP |
494 | } |
495 | ||
496 | static inline | |
094ff7c0 | 497 | struct bt_field_common *bt_field_common_sequence_borrow_field( |
312c056a | 498 | struct bt_field_common *field, uint64_t index) |
3dca2276 | 499 | { |
3dca2276 PP |
500 | struct bt_field_common_sequence *sequence = BT_FROM_COMMON(field); |
501 | ||
502 | BT_ASSERT_PRE_NON_NULL(field, "Sequence field"); | |
503 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_SEQUENCE, | |
504 | "Field"); | |
312c056a | 505 | BT_ASSERT_PRE(index < sequence->length, |
3dca2276 PP |
506 | "Index is out of bound: %![seq-field-]+_f, " |
507 | "index=%" PRIu64 ", count=%u", field, index, | |
508 | sequence->elements->len); | |
312c056a | 509 | return sequence->elements->pdata[(size_t) index]; |
3dca2276 PP |
510 | } |
511 | ||
512 | static inline | |
312c056a PP |
513 | int bt_field_variant_common_set_tag(struct bt_field_common *variant_field, |
514 | uint64_t tag_uval, bool is_signed) | |
3dca2276 | 515 | { |
312c056a PP |
516 | int ret = 0; |
517 | int64_t choice_index; | |
518 | struct bt_field_common_variant *variant = BT_FROM_COMMON(variant_field); | |
3dca2276 | 519 | |
312c056a PP |
520 | BT_ASSERT_PRE_NON_NULL(variant_field, "Variant field"); |
521 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(variant_field, | |
522 | BT_FIELD_TYPE_ID_VARIANT, "Field"); | |
3dca2276 | 523 | |
312c056a PP |
524 | /* Find matching index in variant field's type */ |
525 | choice_index = bt_field_type_common_variant_find_choice_index( | |
526 | variant_field->type, tag_uval, is_signed); | |
527 | if (choice_index < 0) { | |
528 | ret = -1; | |
3dca2276 PP |
529 | goto end; |
530 | } | |
531 | ||
312c056a PP |
532 | /* Select corresponding field */ |
533 | BT_ASSERT(choice_index < variant->fields->len); | |
534 | variant->current_field = variant->fields->pdata[choice_index]; | |
535 | variant->tag_value.u = tag_uval; | |
3dca2276 PP |
536 | |
537 | end: | |
312c056a | 538 | return ret; |
3dca2276 PP |
539 | } |
540 | ||
541 | static inline | |
094ff7c0 | 542 | struct bt_field_common *bt_field_common_variant_borrow_current_field( |
3dca2276 PP |
543 | struct bt_field_common *variant_field) |
544 | { | |
545 | struct bt_field_common_variant *variant = BT_FROM_COMMON(variant_field); | |
546 | ||
547 | BT_ASSERT_PRE_NON_NULL(variant_field, "Variant field"); | |
548 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(variant_field, | |
549 | BT_FIELD_TYPE_ID_VARIANT, "Field"); | |
312c056a PP |
550 | BT_ASSERT_PRE(variant->current_field, |
551 | "Variant field has no current field: %!+_f", variant_field); | |
552 | return variant->current_field; | |
3dca2276 PP |
553 | } |
554 | ||
555 | static inline | |
312c056a PP |
556 | int bt_field_common_variant_get_tag_signed(struct bt_field_common *variant_field, |
557 | int64_t *tag) | |
3dca2276 PP |
558 | { |
559 | struct bt_field_common_variant *variant = BT_FROM_COMMON(variant_field); | |
560 | ||
561 | BT_ASSERT_PRE_NON_NULL(variant_field, "Variant field"); | |
562 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(variant_field, | |
563 | BT_FIELD_TYPE_ID_VARIANT, "Field"); | |
312c056a PP |
564 | BT_ASSERT_PRE(variant->current_field, |
565 | "Variant field has no current field: %!+_f", variant_field); | |
566 | *tag = variant->tag_value.i; | |
3dca2276 PP |
567 | return 0; |
568 | } | |
569 | ||
3dca2276 | 570 | static inline |
312c056a PP |
571 | int bt_field_common_variant_get_tag_unsigned(struct bt_field_common *variant_field, |
572 | uint64_t *tag) | |
3dca2276 | 573 | { |
312c056a | 574 | struct bt_field_common_variant *variant = BT_FROM_COMMON(variant_field); |
3dca2276 | 575 | |
312c056a PP |
576 | BT_ASSERT_PRE_NON_NULL(variant_field, "Variant field"); |
577 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(variant_field, | |
578 | BT_FIELD_TYPE_ID_VARIANT, "Field"); | |
579 | BT_ASSERT_PRE(variant->current_field, | |
580 | "Variant field has no current field: %!+_f", variant_field); | |
581 | *tag = variant->tag_value.u; | |
3dca2276 PP |
582 | return 0; |
583 | } | |
584 | ||
585 | static inline | |
586 | struct bt_field_type_enumeration_mapping_iterator * | |
587 | bt_field_common_enumeration_get_mappings(struct bt_field_common *field, | |
312c056a PP |
588 | bt_field_common_create_func field_create_func, |
589 | uint64_t uval) | |
3dca2276 | 590 | { |
312c056a | 591 | struct bt_field_type_common_enumeration *enum_type = NULL; |
3dca2276 PP |
592 | struct bt_field_type_common_integer *integer_type = NULL; |
593 | struct bt_field_type_enumeration_mapping_iterator *iter = NULL; | |
594 | ||
312c056a PP |
595 | BT_ASSERT(field); |
596 | BT_ASSERT(field->type->id == BT_FIELD_TYPE_ID_ENUM); | |
597 | BT_ASSERT(field->payload_set); | |
598 | enum_type = BT_FROM_COMMON(field->type); | |
599 | integer_type = enum_type->container_ft; | |
3dca2276 PP |
600 | |
601 | if (!integer_type->is_signed) { | |
3dca2276 | 602 | iter = bt_field_type_common_enumeration_unsigned_find_mappings_by_value( |
312c056a | 603 | field->type, uval); |
3dca2276 | 604 | } else { |
3dca2276 | 605 | iter = bt_field_type_common_enumeration_signed_find_mappings_by_value( |
312c056a | 606 | field->type, (int64_t) uval); |
3dca2276 PP |
607 | } |
608 | ||
3dca2276 PP |
609 | return iter; |
610 | } | |
611 | ||
612 | static inline | |
613 | int bt_field_common_floating_point_get_value(struct bt_field_common *field, | |
614 | double *value) | |
615 | { | |
616 | struct bt_field_common_floating_point *floating_point = | |
617 | BT_FROM_COMMON(field); | |
618 | ||
619 | BT_ASSERT_PRE_NON_NULL(field, "Floating point number field"); | |
620 | BT_ASSERT_PRE_NON_NULL(value, "Value"); | |
621 | BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field, "Floating point number field"); | |
622 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field, | |
623 | BT_FIELD_TYPE_ID_FLOAT, "Field"); | |
624 | *value = floating_point->payload; | |
625 | return 0; | |
626 | } | |
627 | ||
628 | static inline | |
629 | int bt_field_common_floating_point_set_value(struct bt_field_common *field, | |
630 | double value) | |
631 | { | |
632 | struct bt_field_common_floating_point *floating_point = | |
633 | BT_FROM_COMMON(field); | |
634 | ||
635 | BT_ASSERT_PRE_NON_NULL(field, "Floating point number field"); | |
636 | BT_ASSERT_PRE_FIELD_COMMON_HOT(field, "Floating point number field"); | |
637 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field, | |
638 | BT_FIELD_TYPE_ID_FLOAT, "Field"); | |
639 | floating_point->payload = value; | |
640 | bt_field_common_set(field, true); | |
641 | return 0; | |
642 | } | |
643 | ||
644 | static inline | |
645 | const char *bt_field_common_string_get_value(struct bt_field_common *field) | |
646 | { | |
647 | struct bt_field_common_string *string = BT_FROM_COMMON(field); | |
648 | ||
649 | BT_ASSERT_PRE_NON_NULL(field, "String field"); | |
650 | BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field, "String field"); | |
651 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field, | |
652 | BT_FIELD_TYPE_ID_STRING, "Field"); | |
4d4b475d | 653 | return (const char *) string->buf->data; |
3dca2276 PP |
654 | } |
655 | ||
656 | static inline | |
657 | int bt_field_common_string_set_value(struct bt_field_common *field, | |
658 | const char *value) | |
659 | { | |
660 | struct bt_field_common_string *string = BT_FROM_COMMON(field); | |
4d4b475d | 661 | size_t str_len; |
3dca2276 PP |
662 | |
663 | BT_ASSERT_PRE_NON_NULL(field, "String field"); | |
664 | BT_ASSERT_PRE_NON_NULL(value, "Value"); | |
665 | BT_ASSERT_PRE_FIELD_COMMON_HOT(field, "String field"); | |
666 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field, | |
667 | BT_FIELD_TYPE_ID_STRING, "Field"); | |
668 | ||
4d4b475d | 669 | str_len = strlen(value); |
3dca2276 | 670 | |
4d4b475d PP |
671 | if (str_len + 1 > string->buf->len) { |
672 | g_array_set_size(string->buf, str_len + 1); | |
3dca2276 PP |
673 | } |
674 | ||
4d4b475d PP |
675 | memcpy(string->buf->data, value, str_len); |
676 | ((char *) string->buf->data)[str_len] = '\0'; | |
677 | string->size = str_len; | |
3dca2276 PP |
678 | bt_field_common_set(field, true); |
679 | return 0; | |
680 | } | |
681 | ||
682 | static inline | |
683 | int bt_field_common_string_append_len(struct bt_field_common *field, | |
684 | const char *value, unsigned int length) | |
685 | { | |
686 | struct bt_field_common_string *string_field = BT_FROM_COMMON(field); | |
4d4b475d PP |
687 | char *data; |
688 | size_t new_size; | |
3dca2276 PP |
689 | |
690 | BT_ASSERT_PRE_NON_NULL(field, "String field"); | |
691 | BT_ASSERT_PRE_NON_NULL(value, "Value"); | |
692 | BT_ASSERT_PRE_FIELD_COMMON_HOT(field, "String field"); | |
693 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field, | |
694 | BT_FIELD_TYPE_ID_STRING, "Field"); | |
695 | ||
4d4b475d | 696 | /* Make sure no null bytes are appended */ |
3dca2276 PP |
697 | BT_ASSERT_PRE(memchr(value, '\0', length) == NULL, |
698 | "String value to append contains a null character: " | |
699 | "partial-value=\"%.32s\", length=%u", value, length); | |
700 | ||
4d4b475d PP |
701 | new_size = string_field->size + length; |
702 | ||
703 | if (new_size + 1 > string_field->buf->len) { | |
704 | g_array_set_size(string_field->buf, new_size + 1); | |
3dca2276 PP |
705 | } |
706 | ||
4d4b475d PP |
707 | data = string_field->buf->data; |
708 | memcpy(data + string_field->size, value, length); | |
709 | ((char *) string_field->buf->data)[new_size] = '\0'; | |
710 | string_field->size = new_size; | |
3dca2276 PP |
711 | bt_field_common_set(field, true); |
712 | return 0; | |
713 | } | |
714 | ||
4d4b475d PP |
715 | static inline |
716 | int bt_field_common_string_append(struct bt_field_common *field, | |
717 | const char *value) | |
718 | { | |
719 | BT_ASSERT_PRE_NON_NULL(value, "Value"); | |
720 | ||
721 | return bt_field_common_string_append_len(field, value, | |
722 | strlen(value)); | |
723 | } | |
724 | ||
312c056a PP |
725 | static inline |
726 | int bt_field_common_string_clear(struct bt_field_common *field) | |
727 | { | |
728 | struct bt_field_common_string *string_field = BT_FROM_COMMON(field); | |
729 | ||
730 | BT_ASSERT_PRE_NON_NULL(field, "String field"); | |
731 | BT_ASSERT_PRE_FIELD_COMMON_HOT(field, "String field"); | |
732 | BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field, | |
733 | BT_FIELD_TYPE_ID_STRING, "Field"); | |
4d4b475d | 734 | string_field->size = 0; |
312c056a PP |
735 | bt_field_common_set(field, true); |
736 | return 0; | |
737 | } | |
738 | ||
3dca2276 PP |
739 | static inline |
740 | int _bt_field_validate_recursive(struct bt_field *field) | |
741 | { | |
742 | return _bt_field_common_validate_recursive((void *) field); | |
743 | } | |
744 | ||
745 | static inline | |
312c056a | 746 | void _bt_field_set_is_frozen_recursive(struct bt_field *field, bool is_frozen) |
3dca2276 | 747 | { |
312c056a PP |
748 | return _bt_field_common_set_is_frozen_recursive((void *) field, |
749 | is_frozen); | |
3dca2276 PP |
750 | } |
751 | ||
752 | static inline | |
753 | bt_bool _bt_field_is_set_recursive(struct bt_field *field) | |
754 | { | |
755 | return _bt_field_common_is_set_recursive((void *) field); | |
756 | } | |
757 | ||
758 | static inline | |
759 | void _bt_field_reset_recursive(struct bt_field *field) | |
760 | { | |
761 | _bt_field_common_reset_recursive((void *) field); | |
762 | } | |
763 | ||
764 | static inline | |
765 | void _bt_field_set(struct bt_field *field, bool value) | |
766 | { | |
767 | _bt_field_common_set((void *) field, value); | |
768 | } | |
2e8876d3 | 769 | |
312c056a PP |
770 | static inline |
771 | void bt_field_common_finalize(struct bt_field_common *field) | |
772 | { | |
773 | BT_ASSERT(field); | |
774 | BT_LOGD_STR("Putting field's type."); | |
775 | bt_put(field->type); | |
776 | } | |
777 | ||
778 | static inline | |
779 | void bt_field_common_integer_finalize(struct bt_field_common *field) | |
780 | { | |
781 | BT_ASSERT(field); | |
782 | BT_LOGD("Finalizing common integer field object: addr=%p", field); | |
783 | bt_field_common_finalize(field); | |
784 | } | |
785 | ||
786 | static inline | |
787 | void bt_field_common_floating_point_finalize(struct bt_field_common *field) | |
788 | { | |
789 | BT_ASSERT(field); | |
790 | BT_LOGD("Finalizing common floating point number field object: addr=%p", field); | |
791 | bt_field_common_finalize(field); | |
792 | } | |
793 | ||
794 | static inline | |
795 | void bt_field_common_structure_finalize_recursive(struct bt_field_common *field) | |
796 | { | |
797 | struct bt_field_common_structure *structure = BT_FROM_COMMON(field); | |
798 | ||
799 | BT_ASSERT(field); | |
800 | BT_LOGD("Finalizing common structure field object: addr=%p", field); | |
801 | bt_field_common_finalize(field); | |
802 | ||
803 | if (structure->fields) { | |
804 | g_ptr_array_free(structure->fields, TRUE); | |
805 | } | |
806 | } | |
807 | ||
808 | static inline | |
809 | void bt_field_common_variant_finalize_recursive(struct bt_field_common *field) | |
810 | { | |
811 | struct bt_field_common_variant *variant = BT_FROM_COMMON(field); | |
812 | ||
813 | BT_ASSERT(field); | |
814 | BT_LOGD("Finalizing common variant field object: addr=%p", field); | |
815 | bt_field_common_finalize(field); | |
816 | ||
817 | if (variant->fields) { | |
818 | g_ptr_array_free(variant->fields, TRUE); | |
819 | } | |
820 | } | |
821 | ||
822 | static inline | |
823 | void bt_field_common_array_finalize_recursive(struct bt_field_common *field) | |
824 | { | |
825 | struct bt_field_common_array *array = BT_FROM_COMMON(field); | |
826 | ||
827 | BT_ASSERT(field); | |
828 | BT_LOGD("Finalizing common array field object: addr=%p", field); | |
829 | bt_field_common_finalize(field); | |
830 | ||
831 | if (array->elements) { | |
832 | g_ptr_array_free(array->elements, TRUE); | |
833 | } | |
834 | } | |
835 | ||
836 | static inline | |
837 | void bt_field_common_sequence_finalize_recursive(struct bt_field_common *field) | |
838 | { | |
839 | struct bt_field_common_sequence *sequence = BT_FROM_COMMON(field); | |
840 | ||
841 | BT_ASSERT(field); | |
842 | BT_LOGD("Finalizing common sequence field object: addr=%p", field); | |
843 | bt_field_common_finalize(field); | |
844 | ||
845 | if (sequence->elements) { | |
846 | g_ptr_array_free(sequence->elements, TRUE); | |
847 | } | |
848 | } | |
849 | ||
850 | static inline | |
851 | void bt_field_common_string_finalize(struct bt_field_common *field) | |
852 | { | |
853 | struct bt_field_common_string *string = BT_FROM_COMMON(field); | |
854 | ||
855 | BT_ASSERT(field); | |
856 | BT_LOGD("Finalizing common string field object: addr=%p", field); | |
857 | bt_field_common_finalize(field); | |
858 | ||
4d4b475d PP |
859 | if (string->buf) { |
860 | g_array_free(string->buf, TRUE); | |
312c056a PP |
861 | } |
862 | } | |
863 | ||
864 | BT_ASSERT_PRE_FUNC | |
865 | static inline bool value_is_in_range_signed(unsigned int size, int64_t value) | |
866 | { | |
867 | bool ret = true; | |
868 | int64_t min_value, max_value; | |
869 | ||
870 | min_value = -(1ULL << (size - 1)); | |
871 | max_value = (1ULL << (size - 1)) - 1; | |
872 | if (value < min_value || value > max_value) { | |
873 | BT_LOGF("Value is out of bounds: value=%" PRId64 ", " | |
874 | "min-value=%" PRId64 ", max-value=%" PRId64, | |
875 | value, min_value, max_value); | |
876 | ret = false; | |
877 | } | |
878 | ||
879 | return ret; | |
880 | } | |
881 | ||
882 | BT_ASSERT_PRE_FUNC | |
883 | static inline bool value_is_in_range_unsigned(unsigned int size, uint64_t value) | |
884 | { | |
885 | bool ret = true; | |
886 | int64_t max_value; | |
887 | ||
888 | max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1; | |
889 | if (value > max_value) { | |
890 | BT_LOGF("Value is out of bounds: value=%" PRIu64 ", " | |
891 | "max-value=%" PRIu64, | |
892 | value, max_value); | |
893 | ret = false; | |
894 | } | |
895 | ||
896 | return ret; | |
897 | } | |
898 | ||
899 | BT_HIDDEN | |
900 | struct bt_field *bt_field_create_recursive(struct bt_field_type *type); | |
901 | ||
902 | BT_HIDDEN | |
903 | void bt_field_destroy_recursive(struct bt_field *field); | |
904 | ||
2e33ac5a | 905 | #endif /* BABELTRACE_CTF_IR_FIELDS_INTERNAL_H */ |