1 #ifndef BABELTRACE_CTF_WRITER_FIELDS_INTERNAL_H
2 #define BABELTRACE_CTF_WRITER_FIELDS_INTERNAL_H
5 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * The Common Trace Format (CTF) Specification is available at
28 * http://www.efficios.com/ctf
38 #include <babeltrace2-ctf-writer/fields.h>
39 #include <babeltrace2/types.h>
41 #include "common/macros.h"
42 #include "common/common.h"
43 #include "ctfser/ctfser.h"
45 #include "assert-pre.h"
46 #include "field-types.h"
50 #define BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(_field, _type_id, _name) \
51 BT_CTF_ASSERT_PRE((_field)->type->id == ((int) (_type_id)), \
52 _name " has the wrong type ID: expected-type-id=%s, " \
54 bt_ctf_field_type_id_string((int) (_type_id)), (_field))
56 #define BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(_field, _name) \
57 BT_CTF_ASSERT_PRE(bt_ctf_field_common_is_set_recursive(_field), \
58 _name " is not set: field-addr=%p", (_field))
60 #define BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(_field, _name) \
61 BT_CTF_ASSERT_PRE_HOT((_field), (_name), ": field-addr=%p", (_field))
63 struct bt_ctf_field_common
;
65 typedef void (*bt_ctf_field_common_method_set_is_frozen
)(struct bt_ctf_field_common
*,
67 typedef int (*bt_ctf_field_common_method_validate
)(struct bt_ctf_field_common
*);
68 typedef struct bt_ctf_field_common
*(*bt_ctf_field_common_method_copy
)(
69 struct bt_ctf_field_common
*);
70 typedef bt_ctf_bool (*bt_ctf_field_common_method_is_set
)(struct bt_ctf_field_common
*);
71 typedef void (*bt_ctf_field_common_method_reset
)(struct bt_ctf_field_common
*);
73 struct bt_ctf_field_common_methods
{
74 bt_ctf_field_common_method_set_is_frozen set_is_frozen
;
75 bt_ctf_field_common_method_validate validate
;
76 bt_ctf_field_common_method_copy copy
;
77 bt_ctf_field_common_method_is_set is_set
;
78 bt_ctf_field_common_method_reset reset
;
81 struct bt_ctf_field_common
{
82 struct bt_ctf_object base
;
83 struct bt_ctf_field_type_common
*type
;
84 struct bt_ctf_field_common_methods
*methods
;
89 * Specialized data for either CTF IR or CTF writer APIs.
90 * See comment in `field-types.h` for more details.
101 struct bt_ctf_field_common_integer
{
102 struct bt_ctf_field_common common
;
109 struct bt_ctf_field_common_floating_point
{
110 struct bt_ctf_field_common common
;
114 struct bt_ctf_field_common_structure
{
115 struct bt_ctf_field_common common
;
117 /* Array of `struct bt_ctf_field_common *`, owned by this */
121 struct bt_ctf_field_common_variant
{
122 struct bt_ctf_field_common common
;
129 /* Weak: belongs to `choices` below */
130 struct bt_ctf_field_common
*current_field
;
132 /* Array of `struct bt_ctf_field_common *`, owned by this */
136 struct bt_ctf_field_common_array
{
137 struct bt_ctf_field_common common
;
139 /* Array of `struct bt_ctf_field_common *`, owned by this */
143 struct bt_ctf_field_common_sequence
{
144 struct bt_ctf_field_common common
;
147 * This is the true sequence field's length: its value can be
148 * less than `elements->len` below because we never shrink the
149 * array of elements to avoid reallocation.
153 /* Array of `struct bt_ctf_field_common *`, owned by this */
157 struct bt_ctf_field_common_string
{
158 struct bt_ctf_field_common common
;
164 struct bt_ctf_field_common
*bt_ctf_field_common_copy(struct bt_ctf_field_common
*field
);
167 int bt_ctf_field_common_structure_initialize(struct bt_ctf_field_common
*field
,
168 struct bt_ctf_field_type_common
*type
,
169 bool is_shared
, bt_ctf_object_release_func release_func
,
170 struct bt_ctf_field_common_methods
*methods
,
171 bt_ctf_field_common_create_func field_create_func
,
172 GDestroyNotify field_release_func
);
175 int bt_ctf_field_common_array_initialize(struct bt_ctf_field_common
*field
,
176 struct bt_ctf_field_type_common
*type
,
177 bool is_shared
, bt_ctf_object_release_func release_func
,
178 struct bt_ctf_field_common_methods
*methods
,
179 bt_ctf_field_common_create_func field_create_func
,
180 GDestroyNotify field_destroy_func
);
183 int bt_ctf_field_common_sequence_initialize(struct bt_ctf_field_common
*field
,
184 struct bt_ctf_field_type_common
*type
,
185 bool is_shared
, bt_ctf_object_release_func release_func
,
186 struct bt_ctf_field_common_methods
*methods
,
187 GDestroyNotify field_destroy_func
);
190 int bt_ctf_field_common_variant_initialize(struct bt_ctf_field_common
*field
,
191 struct bt_ctf_field_type_common
*type
,
192 bool is_shared
, bt_ctf_object_release_func release_func
,
193 struct bt_ctf_field_common_methods
*methods
,
194 bt_ctf_field_common_create_func field_create_func
,
195 GDestroyNotify field_release_func
);
198 int bt_ctf_field_common_string_initialize(struct bt_ctf_field_common
*field
,
199 struct bt_ctf_field_type_common
*type
,
200 bool is_shared
, bt_ctf_object_release_func release_func
,
201 struct bt_ctf_field_common_methods
*methods
);
204 int bt_ctf_field_common_generic_validate(struct bt_ctf_field_common
*field
);
207 int bt_ctf_field_common_structure_validate_recursive(struct bt_ctf_field_common
*field
);
210 int bt_ctf_field_common_variant_validate_recursive(struct bt_ctf_field_common
*field
);
213 int bt_ctf_field_common_array_validate_recursive(struct bt_ctf_field_common
*field
);
216 int bt_ctf_field_common_sequence_validate_recursive(struct bt_ctf_field_common
*field
);
219 void bt_ctf_field_common_generic_reset(struct bt_ctf_field_common
*field
);
222 void bt_ctf_field_common_structure_reset_recursive(struct bt_ctf_field_common
*field
);
225 void bt_ctf_field_common_variant_reset_recursive(struct bt_ctf_field_common
*field
);
228 void bt_ctf_field_common_array_reset_recursive(struct bt_ctf_field_common
*field
);
231 void bt_ctf_field_common_sequence_reset_recursive(struct bt_ctf_field_common
*field
);
234 void bt_ctf_field_common_generic_set_is_frozen(struct bt_ctf_field_common
*field
,
238 void bt_ctf_field_common_structure_set_is_frozen_recursive(
239 struct bt_ctf_field_common
*field
, bool is_frozen
);
242 void bt_ctf_field_common_variant_set_is_frozen_recursive(
243 struct bt_ctf_field_common
*field
, bool is_frozen
);
246 void bt_ctf_field_common_array_set_is_frozen_recursive(
247 struct bt_ctf_field_common
*field
, bool is_frozen
);
250 void bt_ctf_field_common_sequence_set_is_frozen_recursive(
251 struct bt_ctf_field_common
*field
, bool is_frozen
);
254 void _bt_ctf_field_common_set_is_frozen_recursive(struct bt_ctf_field_common
*field
,
258 bt_ctf_bool
bt_ctf_field_common_generic_is_set(struct bt_ctf_field_common
*field
);
261 bt_ctf_bool
bt_ctf_field_common_structure_is_set_recursive(
262 struct bt_ctf_field_common
*field
);
265 bt_ctf_bool
bt_ctf_field_common_variant_is_set_recursive(struct bt_ctf_field_common
*field
);
268 bt_ctf_bool
bt_ctf_field_common_array_is_set_recursive(struct bt_ctf_field_common
*field
);
271 bt_ctf_bool
bt_ctf_field_common_sequence_is_set_recursive(struct bt_ctf_field_common
*field
);
274 # define bt_ctf_field_common_validate_recursive _bt_ctf_field_common_validate_recursive
275 # define bt_ctf_field_common_set_is_frozen_recursive _bt_ctf_field_common_set_is_frozen_recursive
276 # define bt_ctf_field_common_is_set_recursive _bt_ctf_field_common_is_set_recursive
277 # define bt_ctf_field_common_reset_recursive _bt_ctf_field_common_reset_recursive
278 # define bt_ctf_field_common_set _bt_ctf_field_common_set
280 # define bt_ctf_field_common_validate_recursive(_field) (-1)
281 # define bt_ctf_field_common_set_is_frozen_recursive(_field, _is_frozen)
282 # define bt_ctf_field_common_is_set_recursive(_field) (BT_CTF_FALSE)
283 # define bt_ctf_field_common_reset_recursive(_field)
284 # define bt_ctf_field_common_set(_field, _val)
288 static inline bool field_type_common_has_known_id(
289 struct bt_ctf_field_type_common
*ft
)
291 return (int) ft
->id
> BT_CTF_FIELD_TYPE_ID_UNKNOWN
||
292 (int) ft
->id
< BT_CTF_FIELD_TYPE_ID_NR
;
296 int _bt_ctf_field_common_validate_recursive(struct bt_ctf_field_common
*field
)
301 BT_CTF_ASSERT_PRE_MSG("%s", "Invalid field: field is NULL.");
306 BT_ASSERT_DBG(field_type_common_has_known_id(field
->type
));
308 if (field
->methods
->validate
) {
309 ret
= field
->methods
->validate(field
);
317 void _bt_ctf_field_common_reset_recursive(struct bt_ctf_field_common
*field
)
319 BT_ASSERT_DBG(field
);
320 BT_ASSERT_DBG(field
->methods
->reset
);
321 field
->methods
->reset(field
);
325 void _bt_ctf_field_common_set(struct bt_ctf_field_common
*field
, bool value
)
327 BT_ASSERT_DBG(field
);
328 field
->payload_set
= value
;
332 bt_ctf_bool
_bt_ctf_field_common_is_set_recursive(struct bt_ctf_field_common
*field
)
334 bt_ctf_bool is_set
= BT_CTF_FALSE
;
340 BT_ASSERT_DBG(field_type_common_has_known_id(field
->type
));
341 BT_ASSERT_DBG(field
->methods
->is_set
);
342 is_set
= field
->methods
->is_set(field
);
349 void bt_ctf_field_common_initialize(struct bt_ctf_field_common
*field
,
350 struct bt_ctf_field_type_common
*ft
, bool is_shared
,
351 bt_ctf_object_release_func release_func
,
352 struct bt_ctf_field_common_methods
*methods
)
354 BT_ASSERT_DBG(field
);
356 bt_ctf_object_init(&field
->base
, is_shared
, release_func
);
357 field
->methods
= methods
;
358 field
->type
= (void *) bt_ctf_object_get_ref(ft
);
362 struct bt_ctf_field_type_common
*bt_ctf_field_common_borrow_type(
363 struct bt_ctf_field_common
*field
)
365 struct bt_ctf_field_type_common
*ret
= NULL
;
367 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Field");
373 int64_t bt_ctf_field_common_sequence_get_length(struct bt_ctf_field_common
*field
)
375 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
377 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Sequence field");
378 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field
, BT_CTF_FIELD_TYPE_ID_SEQUENCE
,
380 return (int64_t) sequence
->length
;
384 int bt_ctf_field_common_sequence_set_length(struct bt_ctf_field_common
*field
,
385 uint64_t length
, bt_ctf_field_common_create_func field_create_func
)
388 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
390 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Sequence field");
391 BT_CTF_ASSERT_PRE(((int64_t) length
) >= 0,
392 "Invalid sequence length (too large): length=%" PRId64
,
394 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field
, "Sequence field");
396 if (G_UNLIKELY(length
> sequence
->elements
->len
)) {
398 struct bt_ctf_field_type_common_sequence
*sequence_ft
;
399 uint64_t cur_len
= sequence
->elements
->len
;
402 g_ptr_array_set_size(sequence
->elements
, length
);
403 sequence_ft
= BT_CTF_FROM_COMMON(sequence
->common
.type
);
405 for (i
= cur_len
; i
< sequence
->elements
->len
; i
++) {
406 struct bt_ctf_field_common
*elem_field
=
407 field_create_func(sequence_ft
->element_ft
);
414 BT_ASSERT_DBG(!sequence
->elements
->pdata
[i
]);
415 sequence
->elements
->pdata
[i
] = elem_field
;
419 sequence
->length
= length
;
426 struct bt_ctf_field_common
*bt_ctf_field_common_structure_borrow_field_by_name(
427 struct bt_ctf_field_common
*field
, const char *name
)
429 struct bt_ctf_field_common
*ret
= NULL
;
431 struct bt_ctf_field_type_common_structure
*structure_ft
;
432 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
434 GHashTable
*field_name_to_index
;
436 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Structure field");
437 BT_CTF_ASSERT_PRE_NON_NULL(name
, "Field name");
438 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field
,
439 BT_CTF_FIELD_TYPE_ID_STRUCT
, "Field");
440 structure_ft
= BT_CTF_FROM_COMMON(field
->type
);
441 field_name_to_index
= structure_ft
->field_name_to_index
;
442 field_quark
= g_quark_from_string(name
);
443 if (!g_hash_table_lookup_extended(field_name_to_index
,
444 GUINT_TO_POINTER(field_quark
),
445 NULL
, (gpointer
*) &index
)) {
446 BT_LOGT("Invalid parameter: no such field in structure field's type: "
447 "struct-field-addr=%p, struct-ft-addr=%p, name=\"%s\"",
448 field
, field
->type
, name
);
452 ret
= structure
->fields
->pdata
[index
];
460 struct bt_ctf_field_common
*bt_ctf_field_common_structure_borrow_field_by_index(
461 struct bt_ctf_field_common
*field
, uint64_t index
)
463 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
465 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Structure field");
466 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field
,
467 BT_CTF_FIELD_TYPE_ID_STRUCT
, "Field");
468 BT_CTF_ASSERT_PRE(index
< structure
->fields
->len
,
469 "Index is out of bound: struct-field-addr=%p, "
470 "index=%" PRIu64
", count=%u", field
, index
,
471 structure
->fields
->len
);
472 return structure
->fields
->pdata
[index
];
476 struct bt_ctf_field_common
*bt_ctf_field_common_array_borrow_field(
477 struct bt_ctf_field_common
*field
, uint64_t index
)
479 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
481 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Array field");
482 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field
, BT_CTF_FIELD_TYPE_ID_ARRAY
,
484 BT_CTF_ASSERT_PRE(index
< array
->elements
->len
,
485 "Index is out of bound: array-field-addr=%p, "
486 "index=%" PRIu64
", count=%u", field
,
487 index
, array
->elements
->len
);
488 return array
->elements
->pdata
[(size_t) index
];
492 struct bt_ctf_field_common
*bt_ctf_field_common_sequence_borrow_field(
493 struct bt_ctf_field_common
*field
, uint64_t index
)
495 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
497 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Sequence field");
498 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field
, BT_CTF_FIELD_TYPE_ID_SEQUENCE
,
500 BT_CTF_ASSERT_PRE(index
< sequence
->length
,
501 "Index is out of bound: seq-field-addr=%p, "
502 "index=%" PRIu64
", count=%u", field
, index
,
503 sequence
->elements
->len
);
504 return sequence
->elements
->pdata
[(size_t) index
];
508 int bt_ctf_field_common_variant_set_tag(struct bt_ctf_field_common
*variant_field
,
509 uint64_t tag_uval
, bool is_signed
)
512 int64_t choice_index
;
513 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(variant_field
);
515 BT_CTF_ASSERT_PRE_NON_NULL(variant_field
, "Variant field");
516 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(variant_field
,
517 BT_CTF_FIELD_TYPE_ID_VARIANT
, "Field");
519 /* Find matching index in variant field's type */
520 choice_index
= bt_ctf_field_type_common_variant_find_choice_index(
521 variant_field
->type
, tag_uval
, is_signed
);
522 if (choice_index
< 0) {
527 /* Select corresponding field */
528 BT_ASSERT_DBG(choice_index
< variant
->fields
->len
);
529 variant
->current_field
= variant
->fields
->pdata
[choice_index
];
530 variant
->tag_value
.u
= tag_uval
;
537 struct bt_ctf_field_common
*bt_ctf_field_common_variant_borrow_current_field(
538 struct bt_ctf_field_common
*variant_field
)
540 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(variant_field
);
542 BT_CTF_ASSERT_PRE_NON_NULL(variant_field
, "Variant field");
543 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(variant_field
,
544 BT_CTF_FIELD_TYPE_ID_VARIANT
, "Field");
545 BT_CTF_ASSERT_PRE(variant
->current_field
,
546 "Variant field has no current field: field-addr=%p", variant_field
);
547 return variant
->current_field
;
551 int bt_ctf_field_common_variant_get_tag_signed(struct bt_ctf_field_common
*variant_field
,
554 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(variant_field
);
556 BT_CTF_ASSERT_PRE_NON_NULL(variant_field
, "Variant field");
557 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(variant_field
,
558 BT_CTF_FIELD_TYPE_ID_VARIANT
, "Field");
559 BT_CTF_ASSERT_PRE(variant
->current_field
,
560 "Variant field has no current field: field-addr=%p", variant_field
);
561 *tag
= variant
->tag_value
.i
;
566 int bt_ctf_field_common_variant_get_tag_unsigned(struct bt_ctf_field_common
*variant_field
,
569 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(variant_field
);
571 BT_CTF_ASSERT_PRE_NON_NULL(variant_field
, "Variant field");
572 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(variant_field
,
573 BT_CTF_FIELD_TYPE_ID_VARIANT
, "Field");
574 BT_CTF_ASSERT_PRE(variant
->current_field
,
575 "Variant field has no current field: field-addr=%p", variant_field
);
576 *tag
= variant
->tag_value
.u
;
581 int bt_ctf_field_common_floating_point_get_value(struct bt_ctf_field_common
*field
,
584 struct bt_ctf_field_common_floating_point
*floating_point
=
585 BT_CTF_FROM_COMMON(field
);
587 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Floating point number field");
588 BT_CTF_ASSERT_PRE_NON_NULL(value
, "Value");
589 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field
, "Floating point number field");
590 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field
,
591 BT_CTF_FIELD_TYPE_ID_FLOAT
, "Field");
592 *value
= floating_point
->payload
;
597 int bt_ctf_field_common_floating_point_set_value(struct bt_ctf_field_common
*field
,
600 struct bt_ctf_field_common_floating_point
*floating_point
=
601 BT_CTF_FROM_COMMON(field
);
603 BT_CTF_ASSERT_PRE_NON_NULL(field
, "Floating point number field");
604 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field
, "Floating point number field");
605 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field
,
606 BT_CTF_FIELD_TYPE_ID_FLOAT
, "Field");
607 floating_point
->payload
= value
;
608 bt_ctf_field_common_set(field
, true);
613 const char *bt_ctf_field_common_string_get_value(struct bt_ctf_field_common
*field
)
615 struct bt_ctf_field_common_string
*string
= BT_CTF_FROM_COMMON(field
);
617 BT_CTF_ASSERT_PRE_NON_NULL(field
, "String field");
618 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field
, "String field");
619 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field
,
620 BT_CTF_FIELD_TYPE_ID_STRING
, "Field");
621 return (const char *) string
->buf
->data
;
625 int bt_ctf_field_common_string_clear(struct bt_ctf_field_common
*field
)
627 struct bt_ctf_field_common_string
*string_field
= BT_CTF_FROM_COMMON(field
);
629 BT_CTF_ASSERT_PRE_NON_NULL(field
, "String field");
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 string_field
->size
= 0;
634 bt_ctf_field_common_set(field
, true);
639 int bt_ctf_field_common_string_append_len(struct bt_ctf_field_common
*field
,
640 const char *value
, unsigned int length
)
642 struct bt_ctf_field_common_string
*string_field
= BT_CTF_FROM_COMMON(field
);
646 BT_CTF_ASSERT_PRE_NON_NULL(field
, "String field");
647 BT_CTF_ASSERT_PRE_NON_NULL(value
, "Value");
648 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field
, "String field");
649 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field
,
650 BT_CTF_FIELD_TYPE_ID_STRING
, "Field");
652 /* Make sure no null bytes are appended */
653 BT_CTF_ASSERT_PRE(!memchr(value
, '\0', length
),
654 "String value to append contains a null character: "
655 "partial-value=\"%.32s\", length=%u", value
, length
);
657 new_size
= string_field
->size
+ length
;
659 if (G_UNLIKELY(new_size
+ 1 > string_field
->buf
->len
)) {
660 g_array_set_size(string_field
->buf
, new_size
+ 1);
663 data
= string_field
->buf
->data
;
664 memcpy(data
+ string_field
->size
, value
, length
);
665 ((char *) string_field
->buf
->data
)[new_size
] = '\0';
666 string_field
->size
= new_size
;
667 bt_ctf_field_common_set(field
, true);
672 int bt_ctf_field_common_string_append(struct bt_ctf_field_common
*field
,
675 BT_CTF_ASSERT_PRE_NON_NULL(value
, "Value");
676 return bt_ctf_field_common_string_append_len(field
, value
,
681 int bt_ctf_field_common_string_set_value(struct bt_ctf_field_common
*field
,
684 BT_CTF_ASSERT_PRE_NON_NULL(field
, "String field");
685 BT_CTF_ASSERT_PRE_NON_NULL(value
, "Value");
686 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field
, "String field");
687 BT_CTF_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field
,
688 BT_CTF_FIELD_TYPE_ID_STRING
, "Field");
689 bt_ctf_field_common_string_clear(field
);
690 return bt_ctf_field_common_string_append_len(field
,
691 value
, strlen(value
));
695 void bt_ctf_field_common_finalize(struct bt_ctf_field_common
*field
)
697 BT_ASSERT_DBG(field
);
698 BT_LOGD_STR("Putting field's type.");
699 bt_ctf_object_put_ref(field
->type
);
703 void bt_ctf_field_common_integer_finalize(struct bt_ctf_field_common
*field
)
705 BT_ASSERT_DBG(field
);
706 BT_LOGD("Finalizing common integer field object: addr=%p", field
);
707 bt_ctf_field_common_finalize(field
);
711 void bt_ctf_field_common_floating_point_finalize(struct bt_ctf_field_common
*field
)
713 BT_ASSERT_DBG(field
);
714 BT_LOGD("Finalizing common floating point number field object: addr=%p", field
);
715 bt_ctf_field_common_finalize(field
);
719 void bt_ctf_field_common_structure_finalize_recursive(struct bt_ctf_field_common
*field
)
721 struct bt_ctf_field_common_structure
*structure
= BT_CTF_FROM_COMMON(field
);
723 BT_ASSERT_DBG(field
);
724 BT_LOGD("Finalizing common structure field object: addr=%p", field
);
725 bt_ctf_field_common_finalize(field
);
727 if (structure
->fields
) {
728 g_ptr_array_free(structure
->fields
, TRUE
);
733 void bt_ctf_field_common_variant_finalize_recursive(struct bt_ctf_field_common
*field
)
735 struct bt_ctf_field_common_variant
*variant
= BT_CTF_FROM_COMMON(field
);
737 BT_ASSERT_DBG(field
);
738 BT_LOGD("Finalizing common variant field object: addr=%p", field
);
739 bt_ctf_field_common_finalize(field
);
741 if (variant
->fields
) {
742 g_ptr_array_free(variant
->fields
, TRUE
);
747 void bt_ctf_field_common_array_finalize_recursive(struct bt_ctf_field_common
*field
)
749 struct bt_ctf_field_common_array
*array
= BT_CTF_FROM_COMMON(field
);
751 BT_ASSERT_DBG(field
);
752 BT_LOGD("Finalizing common array field object: addr=%p", field
);
753 bt_ctf_field_common_finalize(field
);
755 if (array
->elements
) {
756 g_ptr_array_free(array
->elements
, TRUE
);
761 void bt_ctf_field_common_sequence_finalize_recursive(struct bt_ctf_field_common
*field
)
763 struct bt_ctf_field_common_sequence
*sequence
= BT_CTF_FROM_COMMON(field
);
765 BT_ASSERT_DBG(field
);
766 BT_LOGD("Finalizing common sequence field object: addr=%p", field
);
767 bt_ctf_field_common_finalize(field
);
769 if (sequence
->elements
) {
770 g_ptr_array_free(sequence
->elements
, TRUE
);
775 void bt_ctf_field_common_string_finalize(struct bt_ctf_field_common
*field
)
777 struct bt_ctf_field_common_string
*string
= BT_CTF_FROM_COMMON(field
);
779 BT_ASSERT_DBG(field
);
780 BT_LOGD("Finalizing common string field object: addr=%p", field
);
781 bt_ctf_field_common_finalize(field
);
784 g_array_free(string
->buf
, TRUE
);
788 BT_CTF_ASSERT_PRE_FUNC
789 static inline bool value_is_in_range_signed(unsigned int size
, int64_t value
)
792 int64_t min_value
, max_value
;
794 min_value
= -(1ULL << (size
- 1));
795 max_value
= (1ULL << (size
- 1)) - 1;
796 if (value
< min_value
|| value
> max_value
) {
797 BT_LOGF("Value is out of bounds: value=%" PRId64
", "
798 "min-value=%" PRId64
", max-value=%" PRId64
,
799 value
, min_value
, max_value
);
806 BT_CTF_ASSERT_PRE_FUNC
807 static inline bool value_is_in_range_unsigned(unsigned int size
, uint64_t value
)
812 max_value
= (size
== 64) ? UINT64_MAX
: ((uint64_t) 1 << size
) - 1;
813 if (value
> max_value
) {
814 BT_LOGF("Value is out of bounds: value=%" PRIu64
", "
815 "max-value=%" PRIu64
,
823 struct bt_ctf_field_enumeration
{
824 struct bt_ctf_field_common common
;
825 struct bt_ctf_field_common_integer
*container
;
828 struct bt_ctf_field_variant
{
829 struct bt_ctf_field_common_variant common
;
830 struct bt_ctf_field_enumeration
*tag
;
834 int bt_ctf_field_serialize_recursive(struct bt_ctf_field
*field
,
835 struct bt_ctfser
*ctfser
,
836 enum bt_ctf_byte_order native_byte_order
);
839 int bt_ctf_field_structure_set_field_by_name(struct bt_ctf_field
*field
,
840 const char *name
, struct bt_ctf_field
*value
);
843 struct bt_ctf_field
*bt_ctf_field_enumeration_borrow_container(
844 struct bt_ctf_field
*field
);
847 bt_ctf_bool
bt_ctf_field_is_set_recursive(struct bt_ctf_field
*field
)
849 return bt_ctf_field_common_is_set_recursive((void *) field
);
852 #endif /* BABELTRACE_CTF_WRITER_FIELDS_INTERNAL_H */