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