Move to kernel style SPDX license identifiers
[babeltrace.git] / src / ctf-writer / fields.h
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 *
6 * The Common Trace Format (CTF) Specification is available at
7 * http://www.efficios.com/ctf
8 */
9
10 #ifndef BABELTRACE_CTF_WRITER_FIELDS_INTERNAL_H
11 #define BABELTRACE_CTF_WRITER_FIELDS_INTERNAL_H
12
13 #include <glib.h>
14 #include <inttypes.h>
15 #include <stdbool.h>
16 #include <stddef.h>
17 #include <stdint.h>
18 #include <string.h>
19
20 #include <babeltrace2-ctf-writer/fields.h>
21 #include <babeltrace2/types.h>
22
23 #include "common/macros.h"
24 #include "common/common.h"
25 #include "ctfser/ctfser.h"
26
27 #include "assert-pre.h"
28 #include "field-types.h"
29 #include "object.h"
30 #include "utils.h"
31
32 #define BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(_field, _type_id, _name) \
33 BT_CTF_ASSERT_PRE((_field)->type->id == ((int) (_type_id)), \
34 _name " has the wrong type ID: expected-type-id=%s, " \
35 "field-addr=%p", \
36 bt_ctf_field_type_id_string((int) (_type_id)), (_field))
37
38 #define BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(_field, _name) \
39 BT_CTF_ASSERT_PRE(bt_ctf_field_common_is_set_recursive(_field), \
40 _name " is not set: field-addr=%p", (_field))
41
42 #define BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(_field, _name) \
43 BT_CTF_ASSERT_PRE_HOT((_field), (_name), ": field-addr=%p", (_field))
44
45 struct bt_ctf_field_common;
46
47 typedef void (*bt_ctf_field_common_method_set_is_frozen)(struct bt_ctf_field_common *,
48 bool);
49 typedef int (*bt_ctf_field_common_method_validate)(struct bt_ctf_field_common *);
50 typedef struct bt_ctf_field_common *(*bt_ctf_field_common_method_copy)(
51 struct bt_ctf_field_common *);
52 typedef bt_ctf_bool (*bt_ctf_field_common_method_is_set)(struct bt_ctf_field_common *);
53 typedef void (*bt_ctf_field_common_method_reset)(struct bt_ctf_field_common *);
54
55 struct bt_ctf_field_common_methods {
56 bt_ctf_field_common_method_set_is_frozen set_is_frozen;
57 bt_ctf_field_common_method_validate validate;
58 bt_ctf_field_common_method_copy copy;
59 bt_ctf_field_common_method_is_set is_set;
60 bt_ctf_field_common_method_reset reset;
61 };
62
63 struct bt_ctf_field_common {
64 struct bt_ctf_object base;
65 struct bt_ctf_field_type_common *type;
66 struct bt_ctf_field_common_methods *methods;
67 bool payload_set;
68 bool frozen;
69
70 /*
71 * Specialized data for either CTF IR or CTF writer APIs.
72 * See comment in `field-types.h` for more details.
73 */
74 union {
75 struct {
76 } ir;
77 struct {
78 void *serialize_func;
79 } writer;
80 } spec;
81 };
82
83 struct bt_ctf_field_common_integer {
84 struct bt_ctf_field_common common;
85 union {
86 int64_t signd;
87 uint64_t unsignd;
88 } payload;
89 };
90
91 struct bt_ctf_field_common_floating_point {
92 struct bt_ctf_field_common common;
93 double payload;
94 };
95
96 struct bt_ctf_field_common_structure {
97 struct bt_ctf_field_common common;
98
99 /* Array of `struct bt_ctf_field_common *`, owned by this */
100 GPtrArray *fields;
101 };
102
103 struct bt_ctf_field_common_variant {
104 struct bt_ctf_field_common common;
105
106 union {
107 uint64_t u;
108 int64_t i;
109 } tag_value;
110
111 /* Weak: belongs to `choices` below */
112 struct bt_ctf_field_common *current_field;
113
114 /* Array of `struct bt_ctf_field_common *`, owned by this */
115 GPtrArray *fields;
116 };
117
118 struct bt_ctf_field_common_array {
119 struct bt_ctf_field_common common;
120
121 /* Array of `struct bt_ctf_field_common *`, owned by this */
122 GPtrArray *elements;
123 };
124
125 struct bt_ctf_field_common_sequence {
126 struct bt_ctf_field_common common;
127
128 /*
129 * This is the true sequence field's length: its value can be
130 * less than `elements->len` below because we never shrink the
131 * array of elements to avoid reallocation.
132 */
133 uint64_t length;
134
135 /* Array of `struct bt_ctf_field_common *`, owned by this */
136 GPtrArray *elements;
137 };
138
139 struct bt_ctf_field_common_string {
140 struct bt_ctf_field_common common;
141 GArray *buf;
142 size_t size;
143 };
144
145 BT_HIDDEN
146 struct bt_ctf_field_common *bt_ctf_field_common_copy(struct bt_ctf_field_common *field);
147
148 BT_HIDDEN
149 int bt_ctf_field_common_structure_initialize(struct bt_ctf_field_common *field,
150 struct bt_ctf_field_type_common *type,
151 bool is_shared, bt_ctf_object_release_func release_func,
152 struct bt_ctf_field_common_methods *methods,
153 bt_ctf_field_common_create_func field_create_func,
154 GDestroyNotify field_release_func);
155
156 BT_HIDDEN
157 int bt_ctf_field_common_array_initialize(struct bt_ctf_field_common *field,
158 struct bt_ctf_field_type_common *type,
159 bool is_shared, bt_ctf_object_release_func release_func,
160 struct bt_ctf_field_common_methods *methods,
161 bt_ctf_field_common_create_func field_create_func,
162 GDestroyNotify field_destroy_func);
163
164 BT_HIDDEN
165 int bt_ctf_field_common_sequence_initialize(struct bt_ctf_field_common *field,
166 struct bt_ctf_field_type_common *type,
167 bool is_shared, bt_ctf_object_release_func release_func,
168 struct bt_ctf_field_common_methods *methods,
169 GDestroyNotify field_destroy_func);
170
171 BT_HIDDEN
172 int bt_ctf_field_common_variant_initialize(struct bt_ctf_field_common *field,
173 struct bt_ctf_field_type_common *type,
174 bool is_shared, bt_ctf_object_release_func release_func,
175 struct bt_ctf_field_common_methods *methods,
176 bt_ctf_field_common_create_func field_create_func,
177 GDestroyNotify field_release_func);
178
179 BT_HIDDEN
180 int bt_ctf_field_common_string_initialize(struct bt_ctf_field_common *field,
181 struct bt_ctf_field_type_common *type,
182 bool is_shared, bt_ctf_object_release_func release_func,
183 struct bt_ctf_field_common_methods *methods);
184
185 BT_HIDDEN
186 int bt_ctf_field_common_generic_validate(struct bt_ctf_field_common *field);
187
188 BT_HIDDEN
189 int bt_ctf_field_common_structure_validate_recursive(struct bt_ctf_field_common *field);
190
191 BT_HIDDEN
192 int bt_ctf_field_common_variant_validate_recursive(struct bt_ctf_field_common *field);
193
194 BT_HIDDEN
195 int bt_ctf_field_common_array_validate_recursive(struct bt_ctf_field_common *field);
196
197 BT_HIDDEN
198 int bt_ctf_field_common_sequence_validate_recursive(struct bt_ctf_field_common *field);
199
200 BT_HIDDEN
201 void bt_ctf_field_common_generic_reset(struct bt_ctf_field_common *field);
202
203 BT_HIDDEN
204 void bt_ctf_field_common_structure_reset_recursive(struct bt_ctf_field_common *field);
205
206 BT_HIDDEN
207 void bt_ctf_field_common_variant_reset_recursive(struct bt_ctf_field_common *field);
208
209 BT_HIDDEN
210 void bt_ctf_field_common_array_reset_recursive(struct bt_ctf_field_common *field);
211
212 BT_HIDDEN
213 void bt_ctf_field_common_sequence_reset_recursive(struct bt_ctf_field_common *field);
214
215 BT_HIDDEN
216 void bt_ctf_field_common_generic_set_is_frozen(struct bt_ctf_field_common *field,
217 bool is_frozen);
218
219 BT_HIDDEN
220 void bt_ctf_field_common_structure_set_is_frozen_recursive(
221 struct bt_ctf_field_common *field, bool is_frozen);
222
223 BT_HIDDEN
224 void bt_ctf_field_common_variant_set_is_frozen_recursive(
225 struct bt_ctf_field_common *field, bool is_frozen);
226
227 BT_HIDDEN
228 void bt_ctf_field_common_array_set_is_frozen_recursive(
229 struct bt_ctf_field_common *field, bool is_frozen);
230
231 BT_HIDDEN
232 void bt_ctf_field_common_sequence_set_is_frozen_recursive(
233 struct bt_ctf_field_common *field, bool is_frozen);
234
235 BT_HIDDEN
236 void _bt_ctf_field_common_set_is_frozen_recursive(struct bt_ctf_field_common *field,
237 bool is_frozen);
238
239 BT_HIDDEN
240 bt_ctf_bool bt_ctf_field_common_generic_is_set(struct bt_ctf_field_common *field);
241
242 BT_HIDDEN
243 bt_ctf_bool bt_ctf_field_common_structure_is_set_recursive(
244 struct bt_ctf_field_common *field);
245
246 BT_HIDDEN
247 bt_ctf_bool bt_ctf_field_common_variant_is_set_recursive(struct bt_ctf_field_common *field);
248
249 BT_HIDDEN
250 bt_ctf_bool bt_ctf_field_common_array_is_set_recursive(struct bt_ctf_field_common *field);
251
252 BT_HIDDEN
253 bt_ctf_bool bt_ctf_field_common_sequence_is_set_recursive(struct bt_ctf_field_common *field);
254
255 #ifdef BT_DEV_MODE
256 # define bt_ctf_field_common_validate_recursive _bt_ctf_field_common_validate_recursive
257 # define bt_ctf_field_common_set_is_frozen_recursive _bt_ctf_field_common_set_is_frozen_recursive
258 # define bt_ctf_field_common_is_set_recursive _bt_ctf_field_common_is_set_recursive
259 # define bt_ctf_field_common_reset_recursive _bt_ctf_field_common_reset_recursive
260 # define bt_ctf_field_common_set _bt_ctf_field_common_set
261 #else
262 # define bt_ctf_field_common_validate_recursive(_field) (-1)
263 # define bt_ctf_field_common_set_is_frozen_recursive(_field, _is_frozen)
264 # define bt_ctf_field_common_is_set_recursive(_field) (BT_CTF_FALSE)
265 # define bt_ctf_field_common_reset_recursive(_field)
266 # define bt_ctf_field_common_set(_field, _val)
267 #endif
268
269 BT_ASSERT_DBG_FUNC
270 static inline bool field_type_common_has_known_id(
271 struct bt_ctf_field_type_common *ft)
272 {
273 return (int) ft->id > BT_CTF_FIELD_TYPE_ID_UNKNOWN &&
274 (int) ft->id < BT_CTF_FIELD_TYPE_ID_NR;
275 }
276
277 static inline
278 int _bt_ctf_field_common_validate_recursive(struct bt_ctf_field_common *field)
279 {
280 int ret = 0;
281
282 if (!field) {
283 BT_CTF_ASSERT_PRE_MSG("%s", "Invalid field: field is NULL.");
284 ret = -1;
285 goto end;
286 }
287
288 BT_ASSERT_DBG(field_type_common_has_known_id(field->type));
289
290 if (field->methods->validate) {
291 ret = field->methods->validate(field);
292 }
293
294 end:
295 return ret;
296 }
297
298 static inline
299 void _bt_ctf_field_common_reset_recursive(struct bt_ctf_field_common *field)
300 {
301 BT_ASSERT_DBG(field);
302 BT_ASSERT_DBG(field->methods->reset);
303 field->methods->reset(field);
304 }
305
306 static inline
307 void _bt_ctf_field_common_set(struct bt_ctf_field_common *field, bool value)
308 {
309 BT_ASSERT_DBG(field);
310 field->payload_set = value;
311 }
312
313 static inline
314 bt_ctf_bool _bt_ctf_field_common_is_set_recursive(struct bt_ctf_field_common *field)
315 {
316 bt_ctf_bool is_set = BT_CTF_FALSE;
317
318 if (!field) {
319 goto end;
320 }
321
322 BT_ASSERT_DBG(field_type_common_has_known_id(field->type));
323 BT_ASSERT_DBG(field->methods->is_set);
324 is_set = field->methods->is_set(field);
325
326 end:
327 return is_set;
328 }
329
330 static inline
331 void bt_ctf_field_common_initialize(struct bt_ctf_field_common *field,
332 struct bt_ctf_field_type_common *ft, bool is_shared,
333 bt_ctf_object_release_func release_func,
334 struct bt_ctf_field_common_methods *methods)
335 {
336 BT_ASSERT_DBG(field);
337 BT_ASSERT_DBG(ft);
338 bt_ctf_object_init(&field->base, is_shared, release_func);
339 field->methods = methods;
340 field->type = (void *) bt_ctf_object_get_ref(ft);
341 }
342
343 static inline
344 struct bt_ctf_field_type_common *bt_ctf_field_common_borrow_type(
345 struct bt_ctf_field_common *field)
346 {
347 struct bt_ctf_field_type_common *ret = NULL;
348
349 BT_CTF_ASSERT_PRE_NON_NULL(field, "Field");
350 ret = field->type;
351 return ret;
352 }
353
354 static inline
355 int64_t bt_ctf_field_common_sequence_get_length(struct bt_ctf_field_common *field)
356 {
357 struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
358
359 BT_CTF_ASSERT_PRE_NON_NULL(field, "Sequence field");
360 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field, BT_CTF_FIELD_TYPE_ID_SEQUENCE,
361 "Field");
362 return (int64_t) sequence->length;
363 }
364
365 static inline
366 int bt_ctf_field_common_sequence_set_length(struct bt_ctf_field_common *field,
367 uint64_t length, bt_ctf_field_common_create_func field_create_func)
368 {
369 int ret = 0;
370 struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
371
372 BT_CTF_ASSERT_PRE_NON_NULL(field, "Sequence field");
373 BT_CTF_ASSERT_PRE(((int64_t) length) >= 0,
374 "Invalid sequence length (too large): length=%" PRId64,
375 length);
376 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field, "Sequence field");
377
378 if (G_UNLIKELY(length > sequence->elements->len)) {
379 /* Make more room */
380 struct bt_ctf_field_type_common_sequence *sequence_ft;
381 uint64_t cur_len = sequence->elements->len;
382 uint64_t i;
383
384 g_ptr_array_set_size(sequence->elements, length);
385 sequence_ft = BT_CTF_FROM_COMMON(sequence->common.type);
386
387 for (i = cur_len; i < sequence->elements->len; i++) {
388 struct bt_ctf_field_common *elem_field =
389 field_create_func(sequence_ft->element_ft);
390
391 if (!elem_field) {
392 ret = -1;
393 goto end;
394 }
395
396 BT_ASSERT_DBG(!sequence->elements->pdata[i]);
397 sequence->elements->pdata[i] = elem_field;
398 }
399 }
400
401 sequence->length = length;
402
403 end:
404 return ret;
405 }
406
407 static inline
408 struct bt_ctf_field_common *bt_ctf_field_common_structure_borrow_field_by_name(
409 struct bt_ctf_field_common *field, const char *name)
410 {
411 struct bt_ctf_field_common *ret = NULL;
412 GQuark field_quark;
413 struct bt_ctf_field_type_common_structure *structure_ft;
414 struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
415 size_t index;
416 GHashTable *field_name_to_index;
417
418 BT_CTF_ASSERT_PRE_NON_NULL(field, "Structure field");
419 BT_CTF_ASSERT_PRE_NON_NULL(name, "Field name");
420 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
421 BT_CTF_FIELD_TYPE_ID_STRUCT, "Field");
422 structure_ft = BT_CTF_FROM_COMMON(field->type);
423 field_name_to_index = structure_ft->field_name_to_index;
424 field_quark = g_quark_from_string(name);
425 if (!g_hash_table_lookup_extended(field_name_to_index,
426 GUINT_TO_POINTER(field_quark),
427 NULL, (gpointer *) &index)) {
428 BT_LOGT("Invalid parameter: no such field in structure field's type: "
429 "struct-field-addr=%p, struct-ft-addr=%p, name=\"%s\"",
430 field, field->type, name);
431 goto error;
432 }
433
434 ret = structure->fields->pdata[index];
435 BT_ASSERT_DBG(ret);
436
437 error:
438 return ret;
439 }
440
441 static inline
442 struct bt_ctf_field_common *bt_ctf_field_common_structure_borrow_field_by_index(
443 struct bt_ctf_field_common *field, uint64_t index)
444 {
445 struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
446
447 BT_CTF_ASSERT_PRE_NON_NULL(field, "Structure field");
448 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
449 BT_CTF_FIELD_TYPE_ID_STRUCT, "Field");
450 BT_CTF_ASSERT_PRE(index < structure->fields->len,
451 "Index is out of bound: struct-field-addr=%p, "
452 "index=%" PRIu64 ", count=%u", field, index,
453 structure->fields->len);
454 return structure->fields->pdata[index];
455 }
456
457 static inline
458 struct bt_ctf_field_common *bt_ctf_field_common_array_borrow_field(
459 struct bt_ctf_field_common *field, uint64_t index)
460 {
461 struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
462
463 BT_CTF_ASSERT_PRE_NON_NULL(field, "Array field");
464 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field, BT_CTF_FIELD_TYPE_ID_ARRAY,
465 "Field");
466 BT_CTF_ASSERT_PRE(index < array->elements->len,
467 "Index is out of bound: array-field-addr=%p, "
468 "index=%" PRIu64 ", count=%u", field,
469 index, array->elements->len);
470 return array->elements->pdata[(size_t) index];
471 }
472
473 static inline
474 struct bt_ctf_field_common *bt_ctf_field_common_sequence_borrow_field(
475 struct bt_ctf_field_common *field, uint64_t index)
476 {
477 struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
478
479 BT_CTF_ASSERT_PRE_NON_NULL(field, "Sequence field");
480 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field, BT_CTF_FIELD_TYPE_ID_SEQUENCE,
481 "Field");
482 BT_CTF_ASSERT_PRE(index < sequence->length,
483 "Index is out of bound: seq-field-addr=%p, "
484 "index=%" PRIu64 ", count=%u", field, index,
485 sequence->elements->len);
486 return sequence->elements->pdata[(size_t) index];
487 }
488
489 static inline
490 int bt_ctf_field_common_variant_set_tag(struct bt_ctf_field_common *variant_field,
491 uint64_t tag_uval, bool is_signed)
492 {
493 int ret = 0;
494 int64_t choice_index;
495 struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(variant_field);
496
497 BT_CTF_ASSERT_PRE_NON_NULL(variant_field, "Variant field");
498 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(variant_field,
499 BT_CTF_FIELD_TYPE_ID_VARIANT, "Field");
500
501 /* Find matching index in variant field's type */
502 choice_index = bt_ctf_field_type_common_variant_find_choice_index(
503 variant_field->type, tag_uval, is_signed);
504 if (choice_index < 0) {
505 ret = -1;
506 goto end;
507 }
508
509 /* Select corresponding field */
510 BT_ASSERT_DBG(choice_index < variant->fields->len);
511 variant->current_field = variant->fields->pdata[choice_index];
512 variant->tag_value.u = tag_uval;
513
514 end:
515 return ret;
516 }
517
518 static inline
519 struct bt_ctf_field_common *bt_ctf_field_common_variant_borrow_current_field(
520 struct bt_ctf_field_common *variant_field)
521 {
522 struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(variant_field);
523
524 BT_CTF_ASSERT_PRE_NON_NULL(variant_field, "Variant field");
525 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(variant_field,
526 BT_CTF_FIELD_TYPE_ID_VARIANT, "Field");
527 BT_CTF_ASSERT_PRE(variant->current_field,
528 "Variant field has no current field: field-addr=%p", variant_field);
529 return variant->current_field;
530 }
531
532 static inline
533 int bt_ctf_field_common_variant_get_tag_signed(struct bt_ctf_field_common *variant_field,
534 int64_t *tag)
535 {
536 struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(variant_field);
537
538 BT_CTF_ASSERT_PRE_NON_NULL(variant_field, "Variant field");
539 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(variant_field,
540 BT_CTF_FIELD_TYPE_ID_VARIANT, "Field");
541 BT_CTF_ASSERT_PRE(variant->current_field,
542 "Variant field has no current field: field-addr=%p", variant_field);
543 *tag = variant->tag_value.i;
544 return 0;
545 }
546
547 static inline
548 int bt_ctf_field_common_variant_get_tag_unsigned(struct bt_ctf_field_common *variant_field,
549 uint64_t *tag)
550 {
551 struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(variant_field);
552
553 BT_CTF_ASSERT_PRE_NON_NULL(variant_field, "Variant field");
554 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(variant_field,
555 BT_CTF_FIELD_TYPE_ID_VARIANT, "Field");
556 BT_CTF_ASSERT_PRE(variant->current_field,
557 "Variant field has no current field: field-addr=%p", variant_field);
558 *tag = variant->tag_value.u;
559 return 0;
560 }
561
562 static inline
563 int bt_ctf_field_common_floating_point_get_value(struct bt_ctf_field_common *field,
564 double *value)
565 {
566 struct bt_ctf_field_common_floating_point *floating_point =
567 BT_CTF_FROM_COMMON(field);
568
569 BT_CTF_ASSERT_PRE_NON_NULL(field, "Floating point number field");
570 BT_CTF_ASSERT_PRE_NON_NULL(value, "Value");
571 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field, "Floating point number field");
572 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
573 BT_CTF_FIELD_TYPE_ID_FLOAT, "Field");
574 *value = floating_point->payload;
575 return 0;
576 }
577
578 static inline
579 int bt_ctf_field_common_floating_point_set_value(struct bt_ctf_field_common *field,
580 double value)
581 {
582 struct bt_ctf_field_common_floating_point *floating_point =
583 BT_CTF_FROM_COMMON(field);
584
585 BT_CTF_ASSERT_PRE_NON_NULL(field, "Floating point number field");
586 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field, "Floating point number field");
587 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
588 BT_CTF_FIELD_TYPE_ID_FLOAT, "Field");
589 floating_point->payload = value;
590 bt_ctf_field_common_set(field, true);
591 return 0;
592 }
593
594 static inline
595 const char *bt_ctf_field_common_string_get_value(struct bt_ctf_field_common *field)
596 {
597 struct bt_ctf_field_common_string *string = BT_CTF_FROM_COMMON(field);
598
599 BT_CTF_ASSERT_PRE_NON_NULL(field, "String field");
600 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field, "String field");
601 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
602 BT_CTF_FIELD_TYPE_ID_STRING, "Field");
603 return (const char *) string->buf->data;
604 }
605
606 static inline
607 int bt_ctf_field_common_string_clear(struct bt_ctf_field_common *field)
608 {
609 struct bt_ctf_field_common_string *string_field = BT_CTF_FROM_COMMON(field);
610
611 BT_CTF_ASSERT_PRE_NON_NULL(field, "String field");
612 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field, "String field");
613 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
614 BT_CTF_FIELD_TYPE_ID_STRING, "Field");
615 string_field->size = 0;
616 bt_ctf_field_common_set(field, true);
617 return 0;
618 }
619
620 static inline
621 int bt_ctf_field_common_string_append_len(struct bt_ctf_field_common *field,
622 const char *value, unsigned int length)
623 {
624 struct bt_ctf_field_common_string *string_field = BT_CTF_FROM_COMMON(field);
625 char *data;
626 size_t new_size;
627
628 BT_CTF_ASSERT_PRE_NON_NULL(field, "String field");
629 BT_CTF_ASSERT_PRE_NON_NULL(value, "Value");
630 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field, "String field");
631 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
632 BT_CTF_FIELD_TYPE_ID_STRING, "Field");
633
634 /* Make sure no null bytes are appended */
635 BT_CTF_ASSERT_PRE(!memchr(value, '\0', length),
636 "String value to append contains a null character: "
637 "partial-value=\"%.32s\", length=%u", value, length);
638
639 new_size = string_field->size + length;
640
641 if (G_UNLIKELY(new_size + 1 > string_field->buf->len)) {
642 g_array_set_size(string_field->buf, new_size + 1);
643 }
644
645 data = string_field->buf->data;
646 memcpy(data + string_field->size, value, length);
647 ((char *) string_field->buf->data)[new_size] = '\0';
648 string_field->size = new_size;
649 bt_ctf_field_common_set(field, true);
650 return 0;
651 }
652
653 static inline
654 int bt_ctf_field_common_string_append(struct bt_ctf_field_common *field,
655 const char *value)
656 {
657 BT_CTF_ASSERT_PRE_NON_NULL(value, "Value");
658 return bt_ctf_field_common_string_append_len(field, value,
659 strlen(value));
660 }
661
662 static inline
663 int bt_ctf_field_common_string_set_value(struct bt_ctf_field_common *field,
664 const char *value)
665 {
666 BT_CTF_ASSERT_PRE_NON_NULL(field, "String field");
667 BT_CTF_ASSERT_PRE_NON_NULL(value, "Value");
668 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field, "String field");
669 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
670 BT_CTF_FIELD_TYPE_ID_STRING, "Field");
671 bt_ctf_field_common_string_clear(field);
672 return bt_ctf_field_common_string_append_len(field,
673 value, strlen(value));
674 }
675
676 static inline
677 void bt_ctf_field_common_finalize(struct bt_ctf_field_common *field)
678 {
679 BT_ASSERT_DBG(field);
680 BT_LOGD_STR("Putting field's type.");
681 bt_ctf_object_put_ref(field->type);
682 }
683
684 static inline
685 void bt_ctf_field_common_integer_finalize(struct bt_ctf_field_common *field)
686 {
687 BT_ASSERT_DBG(field);
688 BT_LOGD("Finalizing common integer field object: addr=%p", field);
689 bt_ctf_field_common_finalize(field);
690 }
691
692 static inline
693 void bt_ctf_field_common_floating_point_finalize(struct bt_ctf_field_common *field)
694 {
695 BT_ASSERT_DBG(field);
696 BT_LOGD("Finalizing common floating point number field object: addr=%p", field);
697 bt_ctf_field_common_finalize(field);
698 }
699
700 static inline
701 void bt_ctf_field_common_structure_finalize_recursive(struct bt_ctf_field_common *field)
702 {
703 struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
704
705 BT_ASSERT_DBG(field);
706 BT_LOGD("Finalizing common structure field object: addr=%p", field);
707 bt_ctf_field_common_finalize(field);
708
709 if (structure->fields) {
710 g_ptr_array_free(structure->fields, TRUE);
711 }
712 }
713
714 static inline
715 void bt_ctf_field_common_variant_finalize_recursive(struct bt_ctf_field_common *field)
716 {
717 struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
718
719 BT_ASSERT_DBG(field);
720 BT_LOGD("Finalizing common variant field object: addr=%p", field);
721 bt_ctf_field_common_finalize(field);
722
723 if (variant->fields) {
724 g_ptr_array_free(variant->fields, TRUE);
725 }
726 }
727
728 static inline
729 void bt_ctf_field_common_array_finalize_recursive(struct bt_ctf_field_common *field)
730 {
731 struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
732
733 BT_ASSERT_DBG(field);
734 BT_LOGD("Finalizing common array field object: addr=%p", field);
735 bt_ctf_field_common_finalize(field);
736
737 if (array->elements) {
738 g_ptr_array_free(array->elements, TRUE);
739 }
740 }
741
742 static inline
743 void bt_ctf_field_common_sequence_finalize_recursive(struct bt_ctf_field_common *field)
744 {
745 struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
746
747 BT_ASSERT_DBG(field);
748 BT_LOGD("Finalizing common sequence field object: addr=%p", field);
749 bt_ctf_field_common_finalize(field);
750
751 if (sequence->elements) {
752 g_ptr_array_free(sequence->elements, TRUE);
753 }
754 }
755
756 static inline
757 void bt_ctf_field_common_string_finalize(struct bt_ctf_field_common *field)
758 {
759 struct bt_ctf_field_common_string *string = BT_CTF_FROM_COMMON(field);
760
761 BT_ASSERT_DBG(field);
762 BT_LOGD("Finalizing common string field object: addr=%p", field);
763 bt_ctf_field_common_finalize(field);
764
765 if (string->buf) {
766 g_array_free(string->buf, TRUE);
767 }
768 }
769
770 BT_CTF_ASSERT_PRE_FUNC
771 static inline bool value_is_in_range_signed(unsigned int size, int64_t value)
772 {
773 bool ret = true;
774 int64_t min_value, max_value;
775
776 min_value = -(1ULL << (size - 1));
777 max_value = (1ULL << (size - 1)) - 1;
778 if (value < min_value || value > max_value) {
779 BT_LOGF("Value is out of bounds: value=%" PRId64 ", "
780 "min-value=%" PRId64 ", max-value=%" PRId64,
781 value, min_value, max_value);
782 ret = false;
783 }
784
785 return ret;
786 }
787
788 BT_CTF_ASSERT_PRE_FUNC
789 static inline bool value_is_in_range_unsigned(unsigned int size, uint64_t value)
790 {
791 bool ret = true;
792 int64_t max_value;
793
794 max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
795 if (value > max_value) {
796 BT_LOGF("Value is out of bounds: value=%" PRIu64 ", "
797 "max-value=%" PRIu64,
798 value, max_value);
799 ret = false;
800 }
801
802 return ret;
803 }
804
805 struct bt_ctf_field_enumeration {
806 struct bt_ctf_field_common common;
807 struct bt_ctf_field_common_integer *container;
808 };
809
810 struct bt_ctf_field_variant {
811 struct bt_ctf_field_common_variant common;
812 struct bt_ctf_field_enumeration *tag;
813 };
814
815 BT_HIDDEN
816 int bt_ctf_field_serialize_recursive(struct bt_ctf_field *field,
817 struct bt_ctfser *ctfser,
818 enum bt_ctf_byte_order native_byte_order);
819
820 BT_HIDDEN
821 int bt_ctf_field_structure_set_field_by_name(struct bt_ctf_field *field,
822 const char *name, struct bt_ctf_field *value);
823
824 BT_HIDDEN
825 struct bt_ctf_field *bt_ctf_field_enumeration_borrow_container(
826 struct bt_ctf_field *field);
827
828 static inline
829 bt_ctf_bool bt_ctf_field_is_set_recursive(struct bt_ctf_field *field)
830 {
831 return bt_ctf_field_common_is_set_recursive((void *) field);
832 }
833
834 #endif /* BABELTRACE_CTF_WRITER_FIELDS_INTERNAL_H */
This page took 0.04653 seconds and 4 git commands to generate.