Rename bt_ctf_trace_get_byte_order() -> bt_ctf_trace_get_native_byte_order()
[babeltrace.git] / lib / ctf-ir / trace.c
CommitLineData
bc37ae52
JG
1/*
2 * trace.c
3 *
4 * Babeltrace CTF IR - Trace
5 *
6 * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29#include <babeltrace/ctf-ir/trace-internal.h>
ac0c6bdd 30#include <babeltrace/ctf-ir/clock-class-internal.h>
bc37ae52
JG
31#include <babeltrace/ctf-ir/stream-internal.h>
32#include <babeltrace/ctf-ir/stream-class-internal.h>
09840de5 33#include <babeltrace/ctf-ir/event-internal.h>
272df73e
PP
34#include <babeltrace/ctf-ir/event-class.h>
35#include <babeltrace/ctf-ir/event-class-internal.h>
bc37ae52 36#include <babeltrace/ctf-writer/functor-internal.h>
ac0c6bdd 37#include <babeltrace/ctf-writer/clock-internal.h>
2e33ac5a 38#include <babeltrace/ctf-ir/field-types-internal.h>
44e0a4f5 39#include <babeltrace/ctf-ir/attributes-internal.h>
09840de5 40#include <babeltrace/ctf-ir/validation-internal.h>
8bf65fbd 41#include <babeltrace/ctf-ir/visitor-internal.h>
654c1444 42#include <babeltrace/ctf-ir/utils.h>
3d9990ac 43#include <babeltrace/compiler-internal.h>
dac5c838 44#include <babeltrace/values.h>
83509119 45#include <babeltrace/ref.h>
3d9990ac 46#include <babeltrace/endian-internal.h>
dc3fffef 47#include <inttypes.h>
544d0515 48#include <stdint.h>
4a32fda0 49#include <string.h>
bc37ae52
JG
50
51#define DEFAULT_IDENTIFIER_SIZE 128
52#define DEFAULT_METADATA_STRING_SIZE 4096
53
50ad4244
JG
54struct listener_wrapper {
55 bt_ctf_listener_cb listener;
2204c381
JG
56 void *data;
57};
58
bc37ae52 59static
83509119 60void bt_ctf_trace_destroy(struct bt_object *obj);
bc37ae52
JG
61static
62int init_trace_packet_header(struct bt_ctf_trace *trace);
f67f3a6e 63static
09840de5 64void bt_ctf_trace_freeze(struct bt_ctf_trace *trace);
bc37ae52 65
bc37ae52
JG
66static
67const unsigned int field_type_aliases_alignments[] = {
68 [FIELD_TYPE_ALIAS_UINT5_T] = 1,
69 [FIELD_TYPE_ALIAS_UINT8_T ... FIELD_TYPE_ALIAS_UINT16_T] = 8,
70 [FIELD_TYPE_ALIAS_UINT27_T] = 1,
71 [FIELD_TYPE_ALIAS_UINT32_T ... FIELD_TYPE_ALIAS_UINT64_T] = 8,
72};
73
74static
75const unsigned int field_type_aliases_sizes[] = {
76 [FIELD_TYPE_ALIAS_UINT5_T] = 5,
77 [FIELD_TYPE_ALIAS_UINT8_T] = 8,
78 [FIELD_TYPE_ALIAS_UINT16_T] = 16,
79 [FIELD_TYPE_ALIAS_UINT27_T] = 27,
80 [FIELD_TYPE_ALIAS_UINT32_T] = 32,
81 [FIELD_TYPE_ALIAS_UINT64_T] = 64,
82};
83
bc37ae52
JG
84struct bt_ctf_trace *bt_ctf_trace_create(void)
85{
86 struct bt_ctf_trace *trace = NULL;
87
88 trace = g_new0(struct bt_ctf_trace, 1);
89 if (!trace) {
90 goto error;
91 }
92
391c8f0d 93 trace->native_byte_order = BT_CTF_BYTE_ORDER_NATIVE;
83509119 94 bt_object_init(trace, bt_ctf_trace_destroy);
bc37ae52 95 trace->clocks = g_ptr_array_new_with_free_func(
83509119 96 (GDestroyNotify) bt_put);
bc37ae52 97 trace->streams = g_ptr_array_new_with_free_func(
e6a8e8e4 98 (GDestroyNotify) bt_object_release);
bc37ae52 99 trace->stream_classes = g_ptr_array_new_with_free_func(
e6a8e8e4 100 (GDestroyNotify) bt_object_release);
7f800dc7 101 if (!trace->clocks || !trace->stream_classes || !trace->streams) {
83509119 102 goto error;
bc37ae52
JG
103 }
104
bc37ae52 105 if (init_trace_packet_header(trace)) {
83509119 106 goto error;
bc37ae52
JG
107 }
108
7f800dc7
PP
109 /* Create the environment array object */
110 trace->environment = bt_ctf_attributes_create();
111 if (!trace->environment) {
83509119 112 goto error;
7f800dc7
PP
113 }
114
9b888ff3
JG
115 trace->listeners = g_ptr_array_new_with_free_func(
116 (GDestroyNotify) g_free);
117 if (!trace->listeners) {
118 goto error;
119 }
120
bc37ae52
JG
121 return trace;
122
bc37ae52 123error:
83509119 124 BT_PUT(trace);
bc37ae52
JG
125 return trace;
126}
127
e96045d4
JG
128const char *bt_ctf_trace_get_name(struct bt_ctf_trace *trace)
129{
130 const char *name = NULL;
131
132 if (!trace || !trace->name) {
133 goto end;
134 }
135
136 name = trace->name->str;
137end:
138 return name;
139}
140
141int bt_ctf_trace_set_name(struct bt_ctf_trace *trace, const char *name)
142{
143 int ret = 0;
144
145 if (!trace || !name || trace->frozen) {
146 ret = -1;
147 goto end;
148 }
149
150 trace->name = trace->name ? g_string_assign(trace->name, name) :
151 g_string_new(name);
152 if (!trace->name) {
153 ret = -1;
154 goto end;
155 }
156end:
157 return ret;
158}
159
4a32fda0
PP
160const unsigned char *bt_ctf_trace_get_uuid(struct bt_ctf_trace *trace)
161{
162 return trace && trace->uuid_set ? trace->uuid : NULL;
163}
164
165int bt_ctf_trace_set_uuid(struct bt_ctf_trace *trace, const unsigned char *uuid)
166{
167 int ret = 0;
168
169 if (!trace || !uuid || trace->frozen) {
170 ret = -1;
171 goto end;
172 }
173
174 memcpy(trace->uuid, uuid, sizeof(uuid_t));
175 trace->uuid_set = true;
176
177end:
178 return ret;
179}
180
83509119 181void bt_ctf_trace_destroy(struct bt_object *obj)
bc37ae52
JG
182{
183 struct bt_ctf_trace *trace;
bc37ae52 184
83509119 185 trace = container_of(obj, struct bt_ctf_trace, base);
bc37ae52 186 if (trace->environment) {
7f800dc7 187 bt_ctf_attributes_destroy(trace->environment);
bc37ae52
JG
188 }
189
e96045d4
JG
190 if (trace->name) {
191 g_string_free(trace->name, TRUE);
192 }
193
bc37ae52
JG
194 if (trace->clocks) {
195 g_ptr_array_free(trace->clocks, TRUE);
196 }
197
198 if (trace->streams) {
199 g_ptr_array_free(trace->streams, TRUE);
200 }
201
202 if (trace->stream_classes) {
203 g_ptr_array_free(trace->stream_classes, TRUE);
204 }
205
9b888ff3
JG
206 if (trace->listeners) {
207 g_ptr_array_free(trace->listeners, TRUE);
208 }
209
83509119 210 bt_put(trace->packet_header_type);
bc37ae52
JG
211 g_free(trace);
212}
213
7f800dc7 214int bt_ctf_trace_set_environment_field(struct bt_ctf_trace *trace,
dac5c838 215 const char *name, struct bt_value *value)
bc37ae52 216{
bc37ae52
JG
217 int ret = 0;
218
a0d12916 219 if (!trace || !name || !value ||
7f800dc7 220 bt_ctf_validate_identifier(name) ||
dac5c838 221 !(bt_value_is_integer(value) || bt_value_is_string(value))) {
bc37ae52 222 ret = -1;
7f800dc7 223 goto end;
bc37ae52
JG
224 }
225
226 if (strchr(name, ' ')) {
227 ret = -1;
7f800dc7 228 goto end;
bc37ae52
JG
229 }
230
a0d12916
JG
231 if (trace->frozen) {
232 /*
233 * New environment fields may be added to a frozen trace,
234 * but existing fields may not be changed.
235 *
236 * The object passed is frozen like all other attributes.
237 */
dac5c838 238 struct bt_value *attribute =
a0d12916
JG
239 bt_ctf_attributes_get_field_value_by_name(
240 trace->environment, name);
241
242 if (attribute) {
83509119 243 BT_PUT(attribute);
a0d12916
JG
244 ret = -1;
245 goto end;
246 }
247
dac5c838 248 bt_value_freeze(value);
a0d12916
JG
249 }
250
7f800dc7
PP
251 ret = bt_ctf_attributes_set_field_value(trace->environment, name,
252 value);
bc37ae52 253
7f800dc7
PP
254end:
255 return ret;
256}
bc37ae52 257
7f800dc7
PP
258int bt_ctf_trace_set_environment_field_string(struct bt_ctf_trace *trace,
259 const char *name, const char *value)
260{
261 int ret = 0;
dac5c838 262 struct bt_value *env_value_string_obj = NULL;
7f800dc7
PP
263
264 if (!trace || !name || !value) {
bc37ae52 265 ret = -1;
7f800dc7 266 goto end;
bc37ae52
JG
267 }
268
a0d12916
JG
269 if (trace->frozen) {
270 /*
271 * New environment fields may be added to a frozen trace,
272 * but existing fields may not be changed.
273 */
dac5c838 274 struct bt_value *attribute =
a0d12916
JG
275 bt_ctf_attributes_get_field_value_by_name(
276 trace->environment, name);
277
278 if (attribute) {
83509119 279 BT_PUT(attribute);
a0d12916
JG
280 ret = -1;
281 goto end;
282 }
283 }
284
dac5c838 285 env_value_string_obj = bt_value_string_create_init(value);
bc37ae52 286
7f800dc7
PP
287 if (!env_value_string_obj) {
288 ret = -1;
289 goto end;
bc37ae52
JG
290 }
291
a0d12916 292 if (trace->frozen) {
dac5c838 293 bt_value_freeze(env_value_string_obj);
a0d12916 294 }
7f800dc7
PP
295 ret = bt_ctf_trace_set_environment_field(trace, name,
296 env_value_string_obj);
297
298end:
83509119 299 BT_PUT(env_value_string_obj);
3487c9f3
JG
300 return ret;
301}
302
7f800dc7
PP
303int bt_ctf_trace_set_environment_field_integer(struct bt_ctf_trace *trace,
304 const char *name, int64_t value)
3487c9f3 305{
3487c9f3 306 int ret = 0;
dac5c838 307 struct bt_value *env_value_integer_obj = NULL;
3487c9f3
JG
308
309 if (!trace || !name) {
310 ret = -1;
7f800dc7 311 goto end;
3487c9f3
JG
312 }
313
a0d12916
JG
314 if (trace->frozen) {
315 /*
316 * New environment fields may be added to a frozen trace,
317 * but existing fields may not be changed.
318 */
dac5c838 319 struct bt_value *attribute =
a0d12916
JG
320 bt_ctf_attributes_get_field_value_by_name(
321 trace->environment, name);
322
323 if (attribute) {
83509119 324 BT_PUT(attribute);
a0d12916
JG
325 ret = -1;
326 goto end;
327 }
328 }
329
dac5c838 330 env_value_integer_obj = bt_value_integer_create_init(value);
7f800dc7 331 if (!env_value_integer_obj) {
3487c9f3 332 ret = -1;
7f800dc7 333 goto end;
3487c9f3
JG
334 }
335
7f800dc7
PP
336 ret = bt_ctf_trace_set_environment_field(trace, name,
337 env_value_integer_obj);
a0d12916 338 if (trace->frozen) {
dac5c838 339 bt_value_freeze(env_value_integer_obj);
a0d12916 340 }
7f800dc7 341end:
83509119 342 BT_PUT(env_value_integer_obj);
bc37ae52
JG
343 return ret;
344}
345
544d0515 346int64_t bt_ctf_trace_get_environment_field_count(struct bt_ctf_trace *trace)
e6fa2160 347{
544d0515 348 int64_t ret = 0;
e6fa2160
JG
349
350 if (!trace) {
9ac68eb1 351 ret = (int64_t) -1;
e6fa2160
JG
352 goto end;
353 }
354
7f800dc7 355 ret = bt_ctf_attributes_get_count(trace->environment);
e6fa2160 356
e6fa2160 357end:
7f800dc7 358 return ret;
e6fa2160
JG
359}
360
361const char *
9ac68eb1
PP
362bt_ctf_trace_get_environment_field_name_by_index(struct bt_ctf_trace *trace,
363 uint64_t index)
e6fa2160 364{
e6fa2160
JG
365 const char *ret = NULL;
366
7f800dc7 367 if (!trace) {
e6fa2160
JG
368 goto end;
369 }
370
7f800dc7
PP
371 ret = bt_ctf_attributes_get_field_name(trace->environment, index);
372
e6fa2160
JG
373end:
374 return ret;
375}
376
9ac68eb1
PP
377struct bt_value *bt_ctf_trace_get_environment_field_value_by_index(
378 struct bt_ctf_trace *trace, uint64_t index)
e6fa2160 379{
dac5c838 380 struct bt_value *ret = NULL;
e6fa2160 381
7f800dc7 382 if (!trace) {
e6fa2160
JG
383 goto end;
384 }
385
7f800dc7
PP
386 ret = bt_ctf_attributes_get_field_value(trace->environment, index);
387
e6fa2160
JG
388end:
389 return ret;
390}
391
dac5c838 392struct bt_value *bt_ctf_trace_get_environment_field_value_by_name(
7f800dc7 393 struct bt_ctf_trace *trace, const char *name)
e6fa2160 394{
dac5c838 395 struct bt_value *ret = NULL;
e6fa2160 396
7f800dc7 397 if (!trace || !name) {
e6fa2160
JG
398 goto end;
399 }
400
7f800dc7
PP
401 ret = bt_ctf_attributes_get_field_value_by_name(trace->environment,
402 name);
403
e6fa2160
JG
404end:
405 return ret;
406}
407
ac0c6bdd
PP
408int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace,
409 struct bt_ctf_clock_class *clock_class)
bc37ae52
JG
410{
411 int ret = 0;
bc37ae52 412
5acf2ae6
PP
413 if (!trace || trace->is_static ||
414 !bt_ctf_clock_class_is_valid(clock_class)) {
bc37ae52
JG
415 ret = -1;
416 goto end;
417 }
418
ac0c6bdd 419 /* Check for duplicate clock classes */
c9d90a34 420 if (bt_ctf_trace_has_clock_class(trace, clock_class)) {
bc37ae52
JG
421 ret = -1;
422 goto end;
423 }
424
ac0c6bdd
PP
425 bt_get(clock_class);
426 g_ptr_array_add(trace->clocks, clock_class);
cfeb617e 427
6474e016 428 if (trace->frozen) {
ac0c6bdd 429 bt_ctf_clock_class_freeze(clock_class);
6474e016 430 }
bc37ae52
JG
431end:
432 return ret;
433}
434
544d0515 435int64_t bt_ctf_trace_get_clock_class_count(struct bt_ctf_trace *trace)
884cd6c3 436{
9ac68eb1 437 int64_t ret = (int64_t) -1;
884cd6c3
JG
438
439 if (!trace) {
440 goto end;
441 }
442
443 ret = trace->clocks->len;
444end:
445 return ret;
446}
447
9ac68eb1
PP
448struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_index(
449 struct bt_ctf_trace *trace, uint64_t index)
884cd6c3 450{
ac0c6bdd 451 struct bt_ctf_clock_class *clock_class = NULL;
884cd6c3 452
9ac68eb1 453 if (!trace || index >= trace->clocks->len) {
884cd6c3
JG
454 goto end;
455 }
456
ac0c6bdd
PP
457 clock_class = g_ptr_array_index(trace->clocks, index);
458 bt_get(clock_class);
884cd6c3 459end:
ac0c6bdd 460 return clock_class;
884cd6c3
JG
461}
462
ef0c4a15
JG
463int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace,
464 struct bt_ctf_stream_class *stream_class)
465{
544d0515
PP
466 int ret;
467 int64_t i;
ef0c4a15 468 int64_t stream_id;
09840de5
PP
469 struct bt_ctf_validation_output trace_sc_validation_output = { 0 };
470 struct bt_ctf_validation_output *ec_validation_outputs = NULL;
471 const enum bt_ctf_validation_flag trace_sc_validation_flags =
472 BT_CTF_VALIDATION_FLAG_TRACE |
473 BT_CTF_VALIDATION_FLAG_STREAM;
474 const enum bt_ctf_validation_flag ec_validation_flags =
475 BT_CTF_VALIDATION_FLAG_EVENT;
476 struct bt_ctf_field_type *packet_header_type = NULL;
477 struct bt_ctf_field_type *packet_context_type = NULL;
478 struct bt_ctf_field_type *event_header_type = NULL;
479 struct bt_ctf_field_type *stream_event_ctx_type = NULL;
544d0515 480 int64_t event_class_count;
2789e5d9 481 struct bt_ctf_trace *current_parent_trace = NULL;
ef0c4a15 482
5acf2ae6 483 if (!trace || !stream_class || trace->is_static) {
ef0c4a15
JG
484 ret = -1;
485 goto end;
486 }
487
d490fcbe
PP
488 /*
489 * At the end of this function we freeze the trace, so its
490 * native byte order must NOT be BT_CTF_BYTE_ORDER_NATIVE.
491 */
492 if (trace->native_byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
493 ret = -1;
494 goto end;
495 }
496
2789e5d9
JG
497 current_parent_trace = bt_ctf_stream_class_get_trace(stream_class);
498 if (current_parent_trace) {
499 /* Stream class is already associated to a trace, abort. */
500 ret = -1;
501 goto end;
502 }
503
09840de5
PP
504 event_class_count =
505 bt_ctf_stream_class_get_event_class_count(stream_class);
506 assert(event_class_count >= 0);
507
508 /* Check for duplicate stream classes */
ef0c4a15
JG
509 for (i = 0; i < trace->stream_classes->len; i++) {
510 if (trace->stream_classes->pdata[i] == stream_class) {
09840de5 511 /* Stream class already registered to the trace */
ef0c4a15
JG
512 ret = -1;
513 goto end;
514 }
515 }
516
fe13b5c0 517 if (stream_class->clock) {
ac0c6bdd
PP
518 struct bt_ctf_clock_class *stream_clock_class =
519 stream_class->clock->clock_class;
520
521 if (trace->is_created_by_writer) {
522 /*
523 * Make sure this clock was also added to the
524 * trace (potentially through its CTF writer
525 * owner).
526 */
527 size_t i;
528
529 for (i = 0; i < trace->clocks->len; i++) {
530 if (trace->clocks->pdata[i] ==
531 stream_clock_class) {
532 /* Found! */
533 break;
534 }
535 }
536
537 if (i == trace->clocks->len) {
538 /* Not found */
fe13b5c0
PP
539 ret = -1;
540 goto end;
541 }
542 } else {
ac0c6bdd
PP
543 /*
544 * This trace was NOT created by a CTF writer,
545 * thus do not allow the stream class to add to
546 * have a clock at all. Those are two
547 * independent APIs (non-writer and writer
548 * APIs), and isolating them simplifies things.
549 */
550 ret = -1;
551 goto end;
fe13b5c0
PP
552 }
553 }
554
09840de5
PP
555 /*
556 * We're about to freeze both the trace and the stream class.
557 * Also, each event class contained in this stream class are
558 * already frozen.
559 *
560 * This trace, this stream class, and all its event classes
561 * should be valid at this point.
562 *
563 * Validate trace and stream class first, then each event
564 * class of this stream class can be validated individually.
565 */
566 packet_header_type =
567 bt_ctf_trace_get_packet_header_type(trace);
568 packet_context_type =
569 bt_ctf_stream_class_get_packet_context_type(stream_class);
570 event_header_type =
571 bt_ctf_stream_class_get_event_header_type(stream_class);
572 stream_event_ctx_type =
573 bt_ctf_stream_class_get_event_context_type(stream_class);
574 ret = bt_ctf_validate_class_types(trace->environment,
575 packet_header_type, packet_context_type, event_header_type,
576 stream_event_ctx_type, NULL, NULL, trace->valid,
577 stream_class->valid, 1, &trace_sc_validation_output,
578 trace_sc_validation_flags);
579 BT_PUT(packet_header_type);
580 BT_PUT(packet_context_type);
581 BT_PUT(event_header_type);
582 BT_PUT(stream_event_ctx_type);
583
2bd7f864 584 if (ret) {
09840de5
PP
585 /*
586 * This means something went wrong during the validation
587 * process, not that the objects are invalid.
588 */
2bd7f864
JG
589 goto end;
590 }
591
09840de5
PP
592 if ((trace_sc_validation_output.valid_flags &
593 trace_sc_validation_flags) !=
594 trace_sc_validation_flags) {
595 /* Invalid trace/stream class */
596 ret = -1;
597 goto end;
598 }
599
600 if (event_class_count > 0) {
601 ec_validation_outputs = g_new0(struct bt_ctf_validation_output,
602 event_class_count);
603 if (!ec_validation_outputs) {
604 ret = -1;
605 goto end;
606 }
607 }
608
609 /* Validate each event class individually */
6474e016 610 for (i = 0; i < event_class_count; i++) {
09840de5 611 struct bt_ctf_event_class *event_class =
9ac68eb1
PP
612 bt_ctf_stream_class_get_event_class_by_index(
613 stream_class, i);
09840de5
PP
614 struct bt_ctf_field_type *event_context_type = NULL;
615 struct bt_ctf_field_type *event_payload_type = NULL;
616
617 event_context_type =
618 bt_ctf_event_class_get_context_type(event_class);
619 event_payload_type =
620 bt_ctf_event_class_get_payload_type(event_class);
621
622 /*
623 * It is important to use the field types returned by
624 * the previous trace and stream class validation here
625 * because copies could have been made.
626 */
627 ret = bt_ctf_validate_class_types(trace->environment,
628 trace_sc_validation_output.packet_header_type,
629 trace_sc_validation_output.packet_context_type,
630 trace_sc_validation_output.event_header_type,
631 trace_sc_validation_output.stream_event_ctx_type,
632 event_context_type, event_payload_type,
633 1, 1, event_class->valid, &ec_validation_outputs[i],
634 ec_validation_flags);
635 BT_PUT(event_context_type);
636 BT_PUT(event_payload_type);
637 BT_PUT(event_class);
638
639 if (ret) {
640 goto end;
641 }
642
643 if ((ec_validation_outputs[i].valid_flags &
644 ec_validation_flags) != ec_validation_flags) {
645 /* Invalid event class */
646 ret = -1;
647 goto end;
648 }
649 }
650
ef0c4a15
JG
651 stream_id = bt_ctf_stream_class_get_id(stream_class);
652 if (stream_id < 0) {
653 stream_id = trace->next_stream_id++;
9ac68eb1
PP
654 if (stream_id < 0) {
655 ret = -1;
656 goto end;
657 }
ef0c4a15
JG
658
659 /* Try to assign a new stream id */
660 for (i = 0; i < trace->stream_classes->len; i++) {
661 if (stream_id == bt_ctf_stream_class_get_id(
662 trace->stream_classes->pdata[i])) {
663 /* Duplicate stream id found */
664 ret = -1;
665 goto end;
666 }
667 }
668
0ddffae5
JG
669 if (bt_ctf_stream_class_set_id_no_check(stream_class,
670 stream_id)) {
ef0c4a15
JG
671 /* TODO Should retry with a different stream id */
672 ret = -1;
673 goto end;
674 }
675 }
676
e6a8e8e4 677 bt_object_set_parent(stream_class, trace);
ef0c4a15
JG
678 g_ptr_array_add(trace->stream_classes, stream_class);
679
680 /*
09840de5
PP
681 * At this point we know that the function will be successful.
682 * Therefore we can replace the trace and stream class field
683 * types with what's in their validation output structure and
684 * mark them as valid. We can also replace the field types of
685 * all the event classes of the stream class and mark them as
686 * valid.
687 */
688 bt_ctf_validation_replace_types(trace, stream_class, NULL,
689 &trace_sc_validation_output, trace_sc_validation_flags);
690 trace->valid = 1;
691 stream_class->valid = 1;
692
693 /*
694 * Put what was not moved in bt_ctf_validation_replace_types().
695 */
696 bt_ctf_validation_output_put_types(&trace_sc_validation_output);
697
6474e016 698 for (i = 0; i < event_class_count; i++) {
09840de5 699 struct bt_ctf_event_class *event_class =
9ac68eb1
PP
700 bt_ctf_stream_class_get_event_class_by_index(
701 stream_class, i);
09840de5
PP
702
703 bt_ctf_validation_replace_types(NULL, NULL, event_class,
704 &ec_validation_outputs[i], ec_validation_flags);
705 event_class->valid = 1;
706 BT_PUT(event_class);
707
708 /*
709 * Put what was not moved in
710 * bt_ctf_validation_replace_types().
711 */
712 bt_ctf_validation_output_put_types(&ec_validation_outputs[i]);
713 }
714
09840de5
PP
715 /*
716 * Freeze the trace and the stream class.
717 */
f67f3a6e 718 bt_ctf_stream_class_freeze(stream_class);
09840de5
PP
719 bt_ctf_trace_freeze(trace);
720
9b888ff3
JG
721 /* Notifiy listeners of the trace's schema modification. */
722 bt_ctf_stream_class_visit(stream_class,
d9a13d86 723 bt_ctf_trace_object_modification, trace);
ef0c4a15 724end:
d3814b54 725 if (ret) {
e6a8e8e4 726 bt_object_set_parent(stream_class, NULL);
09840de5
PP
727
728 if (ec_validation_outputs) {
6474e016 729 for (i = 0; i < event_class_count; i++) {
09840de5
PP
730 bt_ctf_validation_output_put_types(
731 &ec_validation_outputs[i]);
732 }
733 }
d3814b54 734 }
09840de5
PP
735
736 g_free(ec_validation_outputs);
737 bt_ctf_validation_output_put_types(&trace_sc_validation_output);
2789e5d9 738 bt_put(current_parent_trace);
09840de5
PP
739 assert(!packet_header_type);
740 assert(!packet_context_type);
741 assert(!event_header_type);
742 assert(!stream_event_ctx_type);
743
ef0c4a15
JG
744 return ret;
745}
746
544d0515 747int64_t bt_ctf_trace_get_stream_count(struct bt_ctf_trace *trace)
c1e730fe 748{
544d0515 749 int64_t ret;
c1e730fe
PP
750
751 if (!trace) {
9ac68eb1 752 ret = (int64_t) -1;
c1e730fe
PP
753 goto end;
754 }
755
9ac68eb1 756 ret = (int64_t) trace->streams->len;
c1e730fe
PP
757
758end:
759 return ret;
760}
761
9ac68eb1
PP
762struct bt_ctf_stream *bt_ctf_trace_get_stream_by_index(
763 struct bt_ctf_trace *trace,
764 uint64_t index)
c1e730fe
PP
765{
766 struct bt_ctf_stream *stream = NULL;
767
768 if (!trace || index >= trace->streams->len) {
769 goto end;
770 }
771
772 stream = bt_get(g_ptr_array_index(trace->streams, index));
773
774end:
775 return stream;
776}
777
544d0515 778int64_t bt_ctf_trace_get_stream_class_count(struct bt_ctf_trace *trace)
ef0c4a15 779{
544d0515 780 int64_t ret;
ef0c4a15
JG
781
782 if (!trace) {
9ac68eb1 783 ret = (int64_t) -1;
ef0c4a15
JG
784 goto end;
785 }
786
9ac68eb1 787 ret = (int64_t) trace->stream_classes->len;
ef0c4a15
JG
788end:
789 return ret;
790}
791
9ac68eb1
PP
792struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_index(
793 struct bt_ctf_trace *trace, uint64_t index)
ef0c4a15
JG
794{
795 struct bt_ctf_stream_class *stream_class = NULL;
796
9ac68eb1 797 if (!trace || index >= trace->stream_classes->len) {
ef0c4a15
JG
798 goto end;
799 }
800
801 stream_class = g_ptr_array_index(trace->stream_classes, index);
83509119 802 bt_get(stream_class);
ef0c4a15
JG
803end:
804 return stream_class;
805}
806
4841ccc1 807struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_id(
9ac68eb1 808 struct bt_ctf_trace *trace, uint64_t id_param)
4841ccc1
PP
809{
810 int i;
811 struct bt_ctf_stream_class *stream_class = NULL;
9ac68eb1 812 int64_t id = (int64_t) id_param;
4841ccc1 813
9ac68eb1 814 if (!trace || id < 0) {
4841ccc1
PP
815 goto end;
816 }
817
6474e016 818 for (i = 0; i < trace->stream_classes->len; i++) {
4841ccc1
PP
819 struct bt_ctf_stream_class *stream_class_candidate;
820
821 stream_class_candidate =
822 g_ptr_array_index(trace->stream_classes, i);
823
824 if (bt_ctf_stream_class_get_id(stream_class_candidate) ==
825 (int64_t) id) {
826 stream_class = stream_class_candidate;
83509119 827 bt_get(stream_class);
4841ccc1
PP
828 goto end;
829 }
830 }
831
832end:
833 return stream_class;
834}
835
ac0c6bdd 836struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_name(
7e4347a3
PP
837 struct bt_ctf_trace *trace, const char *name)
838{
839 size_t i;
ac0c6bdd 840 struct bt_ctf_clock_class *clock_class = NULL;
7e4347a3
PP
841
842 if (!trace || !name) {
843 goto end;
844 }
845
6474e016 846 for (i = 0; i < trace->clocks->len; i++) {
ac0c6bdd 847 struct bt_ctf_clock_class *cur_clk =
7e4347a3 848 g_ptr_array_index(trace->clocks, i);
ac0c6bdd 849 const char *cur_clk_name = bt_ctf_clock_class_get_name(cur_clk);
7e4347a3
PP
850
851 if (!cur_clk_name) {
852 goto end;
853 }
854
855 if (!strcmp(cur_clk_name, name)) {
ac0c6bdd
PP
856 clock_class = cur_clk;
857 bt_get(clock_class);
7e4347a3
PP
858 goto end;
859 }
860 }
861
862end:
ac0c6bdd 863 return clock_class;
7e4347a3
PP
864}
865
c9d90a34
PP
866BT_HIDDEN
867bool bt_ctf_trace_has_clock_class(struct bt_ctf_trace *trace,
868 struct bt_ctf_clock_class *clock_class)
869{
870 struct search_query query = { .value = clock_class, .found = 0 };
871
872 assert(trace);
873 assert(clock_class);
874
875 g_ptr_array_foreach(trace->clocks, value_exists, &query);
876 return query.found;
877}
878
bc37ae52 879BT_HIDDEN
dc3fffef 880const char *get_byte_order_string(enum bt_ctf_byte_order byte_order)
bc37ae52
JG
881{
882 const char *string;
883
884 switch (byte_order) {
dc3fffef 885 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
bc37ae52
JG
886 string = "le";
887 break;
dc3fffef 888 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
bc37ae52
JG
889 string = "be";
890 break;
dc3fffef
PP
891 case BT_CTF_BYTE_ORDER_NATIVE:
892 string = "native";
bc37ae52 893 break;
dc3fffef
PP
894 default:
895 assert(false);
bc37ae52
JG
896 }
897
898 return string;
899}
900
901static
902int append_trace_metadata(struct bt_ctf_trace *trace,
903 struct metadata_context *context)
904{
905 unsigned char *uuid = trace->uuid;
906 int ret;
907
4a32fda0
PP
908 if (trace->native_byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
909 ret = -1;
910 goto end;
911 }
bc37ae52 912
4a32fda0 913 g_string_append(context->string, "trace {\n");
bc37ae52
JG
914 g_string_append(context->string, "\tmajor = 1;\n");
915 g_string_append(context->string, "\tminor = 8;\n");
dc3fffef
PP
916 assert(trace->native_byte_order == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
917 trace->native_byte_order == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
918 trace->native_byte_order == BT_CTF_BYTE_ORDER_NETWORK);
4a32fda0
PP
919
920 if (trace->uuid_set) {
921 g_string_append_printf(context->string,
922 "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
923 uuid[0], uuid[1], uuid[2], uuid[3],
924 uuid[4], uuid[5], uuid[6], uuid[7],
925 uuid[8], uuid[9], uuid[10], uuid[11],
926 uuid[12], uuid[13], uuid[14], uuid[15]);
927 }
928
bc37ae52 929 g_string_append_printf(context->string, "\tbyte_order = %s;\n",
dc3fffef 930 get_byte_order_string(trace->native_byte_order));
bc37ae52
JG
931
932 g_string_append(context->string, "\tpacket.header := ");
933 context->current_indentation_level++;
934 g_string_assign(context->field_name, "");
d246b111 935 ret = bt_ctf_field_type_serialize(trace->packet_header_type,
bc37ae52
JG
936 context);
937 if (ret) {
938 goto end;
939 }
940 context->current_indentation_level--;
941
942 g_string_append(context->string, ";\n};\n\n");
943end:
944 return ret;
945}
946
bc37ae52
JG
947static
948void append_env_metadata(struct bt_ctf_trace *trace,
949 struct metadata_context *context)
950{
544d0515
PP
951 int64_t i;
952 int64_t env_size;
7f800dc7
PP
953
954 env_size = bt_ctf_attributes_get_count(trace->environment);
955
956 if (env_size <= 0) {
bc37ae52
JG
957 return;
958 }
959
960 g_string_append(context->string, "env {\n");
7f800dc7 961
6474e016 962 for (i = 0; i < env_size; i++) {
dac5c838 963 struct bt_value *env_field_value_obj = NULL;
7f800dc7 964 const char *entry_name;
7f800dc7
PP
965
966 entry_name = bt_ctf_attributes_get_field_name(
967 trace->environment, i);
968 env_field_value_obj = bt_ctf_attributes_get_field_value(
969 trace->environment, i);
970
971 if (!entry_name || !env_field_value_obj) {
972 goto loop_next;
973 }
974
dac5c838
PP
975 switch (bt_value_get_type(env_field_value_obj)) {
976 case BT_VALUE_TYPE_INTEGER:
b8248cc0
PP
977 {
978 int ret;
979 int64_t int_value;
980
dac5c838 981 ret = bt_value_integer_get(env_field_value_obj,
7f800dc7
PP
982 &int_value);
983
984 if (ret) {
985 goto loop_next;
986 }
987
988 g_string_append_printf(context->string,
989 "\t%s = %" PRId64 ";\n", entry_name,
990 int_value);
991 break;
b8248cc0 992 }
dac5c838 993 case BT_VALUE_TYPE_STRING:
7f800dc7
PP
994 {
995 int ret;
996 const char *str_value;
997 char *escaped_str = NULL;
998
dac5c838 999 ret = bt_value_string_get(env_field_value_obj,
7f800dc7
PP
1000 &str_value);
1001
1002 if (ret) {
1003 goto loop_next;
1004 }
1005
1006 escaped_str = g_strescape(str_value, NULL);
1007
1008 if (!escaped_str) {
1009 goto loop_next;
1010 }
1011
1012 g_string_append_printf(context->string,
1013 "\t%s = \"%s\";\n", entry_name, escaped_str);
1014 free(escaped_str);
1015 break;
1016 }
1017
1018 default:
1019 goto loop_next;
1020 }
1021
1022loop_next:
83509119 1023 BT_PUT(env_field_value_obj);
7f800dc7
PP
1024 }
1025
bc37ae52
JG
1026 g_string_append(context->string, "};\n\n");
1027}
1028
1029char *bt_ctf_trace_get_metadata_string(struct bt_ctf_trace *trace)
1030{
1031 char *metadata = NULL;
1032 struct metadata_context *context = NULL;
1033 int err = 0;
1034 size_t i;
1035
1036 if (!trace) {
1037 goto end;
1038 }
1039
1040 context = g_new0(struct metadata_context, 1);
1041 if (!context) {
1042 goto end;
1043 }
1044
1045 context->field_name = g_string_sized_new(DEFAULT_IDENTIFIER_SIZE);
1046 context->string = g_string_sized_new(DEFAULT_METADATA_STRING_SIZE);
1047 g_string_append(context->string, "/* CTF 1.8 */\n\n");
1048 if (append_trace_metadata(trace, context)) {
1049 goto error;
1050 }
1051 append_env_metadata(trace, context);
1052 g_ptr_array_foreach(trace->clocks,
ac0c6bdd 1053 (GFunc)bt_ctf_clock_class_serialize, context);
bc37ae52
JG
1054
1055 for (i = 0; i < trace->stream_classes->len; i++) {
1056 err = bt_ctf_stream_class_serialize(
1057 trace->stream_classes->pdata[i], context);
1058 if (err) {
1059 goto error;
1060 }
1061 }
1062
1063 metadata = context->string->str;
1064error:
1065 g_string_free(context->string, err ? TRUE : FALSE);
1066 g_string_free(context->field_name, TRUE);
1067 g_free(context);
1068end:
1069 return metadata;
1070}
1071
8a716c8d
PP
1072enum bt_ctf_byte_order bt_ctf_trace_get_native_byte_order(
1073 struct bt_ctf_trace *trace)
4ed90fb3
JG
1074{
1075 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
1076
1077 if (!trace) {
1078 goto end;
1079 }
1080
dc3fffef
PP
1081 ret = trace->native_byte_order;
1082
4ed90fb3
JG
1083end:
1084 return ret;
1085}
1086
391c8f0d 1087int bt_ctf_trace_set_native_byte_order(struct bt_ctf_trace *trace,
bc37ae52
JG
1088 enum bt_ctf_byte_order byte_order)
1089{
1090 int ret = 0;
bc37ae52
JG
1091
1092 if (!trace || trace->frozen) {
1093 ret = -1;
1094 goto end;
1095 }
1096
dc3fffef
PP
1097 if (byte_order != BT_CTF_BYTE_ORDER_LITTLE_ENDIAN &&
1098 byte_order != BT_CTF_BYTE_ORDER_BIG_ENDIAN &&
1099 byte_order != BT_CTF_BYTE_ORDER_NETWORK) {
bc37ae52
JG
1100 ret = -1;
1101 goto end;
1102 }
1103
dc3fffef
PP
1104 trace->native_byte_order = byte_order;
1105
bc37ae52
JG
1106end:
1107 return ret;
1108}
1109
d246b111
JG
1110struct bt_ctf_field_type *bt_ctf_trace_get_packet_header_type(
1111 struct bt_ctf_trace *trace)
1112{
1113 struct bt_ctf_field_type *field_type = NULL;
1114
1115 if (!trace) {
1116 goto end;
1117 }
1118
83509119 1119 bt_get(trace->packet_header_type);
d246b111
JG
1120 field_type = trace->packet_header_type;
1121end:
1122 return field_type;
1123}
1124
1125int bt_ctf_trace_set_packet_header_type(struct bt_ctf_trace *trace,
1126 struct bt_ctf_field_type *packet_header_type)
1127{
1128 int ret = 0;
1129
835b2d10 1130 if (!trace || trace->frozen) {
d246b111
JG
1131 ret = -1;
1132 goto end;
1133 }
1134
835b2d10
JG
1135 /* packet_header_type must be a structure. */
1136 if (packet_header_type &&
1137 bt_ctf_field_type_get_type_id(packet_header_type) !=
1487a16a 1138 BT_CTF_FIELD_TYPE_ID_STRUCT) {
d246b111
JG
1139 ret = -1;
1140 goto end;
1141 }
1142
83509119 1143 bt_put(trace->packet_header_type);
835b2d10 1144 trace->packet_header_type = bt_get(packet_header_type);
d246b111
JG
1145end:
1146 return ret;
1147}
1148
8bf65fbd 1149static
544d0515 1150int64_t get_stream_class_count(void *element)
8bf65fbd
JG
1151{
1152 return bt_ctf_trace_get_stream_class_count(
1153 (struct bt_ctf_trace *) element);
1154}
1155
1156static
1157void *get_stream_class(void *element, int i)
1158{
9ac68eb1 1159 return bt_ctf_trace_get_stream_class_by_index(
8bf65fbd
JG
1160 (struct bt_ctf_trace *) element, i);
1161}
1162
1163static
d9a13d86 1164int visit_stream_class(void *object, bt_ctf_visitor visitor,void *data)
8bf65fbd 1165{
d9a13d86 1166 return bt_ctf_stream_class_visit(object, visitor, data);
8bf65fbd
JG
1167}
1168
1169int bt_ctf_trace_visit(struct bt_ctf_trace *trace,
d9a13d86 1170 bt_ctf_visitor visitor, void *data)
8bf65fbd
JG
1171{
1172 int ret;
d9a13d86
PP
1173 struct bt_ctf_object obj =
1174 { .object = trace, .type = BT_CTF_OBJECT_TYPE_TRACE };
8bf65fbd
JG
1175
1176 if (!trace || !visitor) {
1177 ret = -1;
1178 goto end;
1179 }
1180
d9a13d86 1181 ret = visitor_helper(&obj, get_stream_class_count,
8bf65fbd
JG
1182 get_stream_class, visit_stream_class, visitor, data);
1183end:
1184 return ret;
1185}
1186
1187static
d9a13d86 1188int invoke_listener(struct bt_ctf_object *object, void *data)
8bf65fbd 1189{
9b888ff3 1190 struct listener_wrapper *listener_wrapper = data;
8bf65fbd 1191
d9a13d86 1192 listener_wrapper->listener(object, listener_wrapper->data);
9b888ff3 1193 return 0;
8bf65fbd
JG
1194}
1195
50ad4244
JG
1196int bt_ctf_trace_add_listener(struct bt_ctf_trace *trace,
1197 bt_ctf_listener_cb listener, void *listener_data)
2204c381
JG
1198{
1199 int ret = 0;
50ad4244
JG
1200 struct listener_wrapper *listener_wrapper =
1201 g_new0(struct listener_wrapper, 1);
2204c381 1202
50ad4244 1203 if (!trace || !listener || !listener_wrapper) {
2204c381
JG
1204 ret = -1;
1205 goto error;
1206 }
1207
50ad4244
JG
1208 listener_wrapper->listener = listener;
1209 listener_wrapper->data = listener_data;
8bf65fbd 1210
50ad4244 1211 /* Visit the current schema. */
9b888ff3 1212 ret = bt_ctf_trace_visit(trace, invoke_listener, listener_wrapper);
8bf65fbd
JG
1213 if (ret) {
1214 goto error;
1215 }
1216
50ad4244
JG
1217 /*
1218 * Add listener to the array of callbacks which will be invoked on
1219 * schema changes.
1220 */
1221 g_ptr_array_add(trace->listeners, listener_wrapper);
2204c381
JG
1222 return ret;
1223error:
50ad4244 1224 g_free(listener_wrapper);
2204c381
JG
1225 return ret;
1226}
1227
bc37ae52 1228BT_HIDDEN
d9a13d86 1229int bt_ctf_trace_object_modification(struct bt_ctf_object *object,
9b888ff3
JG
1230 void *trace_ptr)
1231{
1232 size_t i;
1233 struct bt_ctf_trace *trace = trace_ptr;
1234
1235 assert(trace);
d9a13d86 1236 assert(object);
9b888ff3
JG
1237
1238 if (trace->listeners->len == 0) {
1239 goto end;
1240 }
1241
1242 for (i = 0; i < trace->listeners->len; i++) {
1243 struct listener_wrapper *listener =
1244 g_ptr_array_index(trace->listeners, i);
1245
d9a13d86 1246 listener->listener(object, listener->data);
9b888ff3
JG
1247 }
1248end:
1249 return 0;
1250}
1251
1252BT_HIDDEN
bc37ae52
JG
1253struct bt_ctf_field_type *get_field_type(enum field_type_alias alias)
1254{
a25e0d14 1255 int ret;
bc37ae52 1256 unsigned int alignment, size;
8bdcb82e 1257 struct bt_ctf_field_type *field_type = NULL;
bc37ae52
JG
1258
1259 if (alias >= NR_FIELD_TYPE_ALIAS) {
8bdcb82e 1260 goto end;
bc37ae52
JG
1261 }
1262
1263 alignment = field_type_aliases_alignments[alias];
1264 size = field_type_aliases_sizes[alias];
1265 field_type = bt_ctf_field_type_integer_create(size);
a25e0d14
JG
1266 ret = bt_ctf_field_type_set_alignment(field_type, alignment);
1267 if (ret) {
1268 BT_PUT(field_type);
1269 }
8bdcb82e 1270end:
bc37ae52
JG
1271 return field_type;
1272}
1273
f67f3a6e 1274static
09840de5 1275void bt_ctf_trace_freeze(struct bt_ctf_trace *trace)
f67f3a6e 1276{
6474e016
PP
1277 int i;
1278
09840de5 1279 bt_ctf_field_type_freeze(trace->packet_header_type);
f67f3a6e 1280 bt_ctf_attributes_freeze(trace->environment);
6474e016
PP
1281
1282 for (i = 0; i < trace->clocks->len; i++) {
ac0c6bdd 1283 struct bt_ctf_clock_class *clock_class =
6474e016
PP
1284 g_ptr_array_index(trace->clocks, i);
1285
ac0c6bdd 1286 bt_ctf_clock_class_freeze(clock_class);
6474e016
PP
1287 }
1288
f67f3a6e
JG
1289 trace->frozen = 1;
1290}
1291
bc37ae52
JG
1292static
1293int init_trace_packet_header(struct bt_ctf_trace *trace)
1294{
bc37ae52 1295 int ret = 0;
d246b111 1296 struct bt_ctf_field *magic = NULL, *uuid_array = NULL;
bc37ae52
JG
1297 struct bt_ctf_field_type *_uint32_t =
1298 get_field_type(FIELD_TYPE_ALIAS_UINT32_T);
1299 struct bt_ctf_field_type *_uint8_t =
1300 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
1301 struct bt_ctf_field_type *trace_packet_header_type =
1302 bt_ctf_field_type_structure_create();
1303 struct bt_ctf_field_type *uuid_array_type =
1304 bt_ctf_field_type_array_create(_uint8_t, 16);
1305
1306 if (!trace_packet_header_type || !uuid_array_type) {
1307 ret = -1;
1308 goto end;
1309 }
1310
bc37ae52
JG
1311 ret = bt_ctf_field_type_structure_add_field(trace_packet_header_type,
1312 _uint32_t, "magic");
1313 if (ret) {
1314 goto end;
1315 }
1316
1317 ret = bt_ctf_field_type_structure_add_field(trace_packet_header_type,
1318 uuid_array_type, "uuid");
1319 if (ret) {
1320 goto end;
1321 }
1322
1323 ret = bt_ctf_field_type_structure_add_field(trace_packet_header_type,
1324 _uint32_t, "stream_id");
1325 if (ret) {
1326 goto end;
1327 }
1328
662e778c
JG
1329 ret = bt_ctf_trace_set_packet_header_type(trace,
1330 trace_packet_header_type);
1331 if (ret) {
1332 goto end;
1333 }
bc37ae52 1334end:
83509119
JG
1335 bt_put(uuid_array_type);
1336 bt_put(_uint32_t);
1337 bt_put(_uint8_t);
1338 bt_put(magic);
1339 bt_put(uuid_array);
1340 bt_put(trace_packet_header_type);
bc37ae52
JG
1341 return ret;
1342}
5acf2ae6
PP
1343
1344bool bt_ctf_trace_is_static(struct bt_ctf_trace *trace)
1345{
1346 bool is_static = false;
1347
1348 if (!trace) {
1349 goto end;
1350 }
1351
1352 is_static = trace->is_static;
1353
1354end:
1355 return is_static;
1356}
1357
1358int bt_ctf_trace_set_is_static(struct bt_ctf_trace *trace)
1359{
1360 int ret = 0;
1361
1362 if (!trace) {
1363 ret = -1;
1364 goto end;
1365 }
1366
1367 trace->is_static = true;
1368 bt_ctf_trace_freeze(trace);
1369
1370end:
1371 return ret;
1372}
This page took 0.102247 seconds and 4 git commands to generate.