Implement bt_ctf_trace stream class accessors
[babeltrace.git] / formats / ctf / ir / trace.c
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>
30 #include <babeltrace/ctf-ir/clock-internal.h>
31 #include <babeltrace/ctf-ir/stream-internal.h>
32 #include <babeltrace/ctf-ir/stream-class-internal.h>
33 #include <babeltrace/ctf-writer/functor-internal.h>
34 #include <babeltrace/ctf-ir/event-types-internal.h>
35 #include <babeltrace/ctf-ir/utils.h>
36 #include <babeltrace/compiler.h>
37
38 #define DEFAULT_IDENTIFIER_SIZE 128
39 #define DEFAULT_METADATA_STRING_SIZE 4096
40
41 static
42 void environment_variable_destroy(struct environment_variable *var);
43 static
44 void bt_ctf_trace_destroy(struct bt_ctf_ref *ref);
45 static
46 int init_trace_packet_header(struct bt_ctf_trace *trace);
47
48 static
49 const unsigned int field_type_aliases_alignments[] = {
50 [FIELD_TYPE_ALIAS_UINT5_T] = 1,
51 [FIELD_TYPE_ALIAS_UINT8_T ... FIELD_TYPE_ALIAS_UINT16_T] = 8,
52 [FIELD_TYPE_ALIAS_UINT27_T] = 1,
53 [FIELD_TYPE_ALIAS_UINT32_T ... FIELD_TYPE_ALIAS_UINT64_T] = 8,
54 };
55
56 static
57 const unsigned int field_type_aliases_sizes[] = {
58 [FIELD_TYPE_ALIAS_UINT5_T] = 5,
59 [FIELD_TYPE_ALIAS_UINT8_T] = 8,
60 [FIELD_TYPE_ALIAS_UINT16_T] = 16,
61 [FIELD_TYPE_ALIAS_UINT27_T] = 27,
62 [FIELD_TYPE_ALIAS_UINT32_T] = 32,
63 [FIELD_TYPE_ALIAS_UINT64_T] = 64,
64 };
65
66 struct bt_ctf_trace *bt_ctf_trace_create(void)
67 {
68 struct bt_ctf_trace *trace = NULL;
69
70 trace = g_new0(struct bt_ctf_trace, 1);
71 if (!trace) {
72 goto error;
73 }
74
75 bt_ctf_trace_set_byte_order(trace, BT_CTF_BYTE_ORDER_NATIVE);
76 bt_ctf_ref_init(&trace->ref_count);
77 trace->environment = g_ptr_array_new_with_free_func(
78 (GDestroyNotify)environment_variable_destroy);
79 trace->clocks = g_ptr_array_new_with_free_func(
80 (GDestroyNotify)bt_ctf_clock_put);
81 trace->streams = g_ptr_array_new_with_free_func(
82 (GDestroyNotify)bt_ctf_stream_put);
83 trace->stream_classes = g_ptr_array_new_with_free_func(
84 (GDestroyNotify)bt_ctf_stream_class_put);
85 if (!trace->environment || !trace->clocks ||
86 !trace->stream_classes || !trace->streams) {
87 goto error_destroy;
88 }
89
90 /* Generate a trace UUID */
91 uuid_generate(trace->uuid);
92 if (init_trace_packet_header(trace)) {
93 goto error_destroy;
94 }
95
96 return trace;
97
98 error_destroy:
99 bt_ctf_trace_destroy(&trace->ref_count);
100 trace = NULL;
101 error:
102 return trace;
103 }
104
105 void bt_ctf_trace_destroy(struct bt_ctf_ref *ref)
106 {
107 struct bt_ctf_trace *trace;
108
109 if (!ref) {
110 return;
111 }
112
113 trace = container_of(ref, struct bt_ctf_trace, ref_count);
114 if (trace->environment) {
115 g_ptr_array_free(trace->environment, TRUE);
116 }
117
118 if (trace->clocks) {
119 g_ptr_array_free(trace->clocks, TRUE);
120 }
121
122 if (trace->streams) {
123 g_ptr_array_free(trace->streams, TRUE);
124 }
125
126 if (trace->stream_classes) {
127 g_ptr_array_free(trace->stream_classes, TRUE);
128 }
129
130 bt_ctf_field_type_put(trace->packet_header_type);
131 g_free(trace);
132 }
133
134 struct bt_ctf_stream *bt_ctf_trace_create_stream(struct bt_ctf_trace *trace,
135 struct bt_ctf_stream_class *stream_class)
136 {
137 int ret;
138 int stream_class_found = 0;
139 size_t i;
140 struct bt_ctf_stream *stream = NULL;
141
142 if (!trace || !stream_class) {
143 goto error;
144 }
145
146 stream = bt_ctf_stream_create(stream_class, trace);
147 if (!stream) {
148 goto error;
149 }
150
151 for (i = 0; i < trace->stream_classes->len; i++) {
152 if (trace->stream_classes->pdata[i] == stream_class) {
153 stream_class_found = 1;
154 }
155 }
156
157 if (!stream_class_found) {
158 ret = bt_ctf_trace_add_stream_class(trace, stream_class);
159 if (ret) {
160 goto error;
161 }
162 }
163
164 bt_ctf_stream_get(stream);
165 g_ptr_array_add(trace->streams, stream);
166
167 return stream;
168 error:
169 bt_ctf_stream_put(stream);
170 return NULL;
171 }
172
173 int bt_ctf_trace_add_environment_field(struct bt_ctf_trace *trace,
174 const char *name,
175 const char *value)
176 {
177 struct environment_variable *var = NULL;
178 char *escaped_value = NULL;
179 int ret = 0;
180
181 if (!trace || !name || !value || bt_ctf_validate_identifier(name)) {
182 ret = -1;
183 goto error;
184 }
185
186 if (strchr(name, ' ')) {
187 ret = -1;
188 goto error;
189 }
190
191 var = g_new0(struct environment_variable, 1);
192 if (!var) {
193 ret = -1;
194 goto error;
195 }
196
197 var->type = BT_ENVIRONMENT_FIELD_TYPE_STRING;
198 escaped_value = g_strescape(value, NULL);
199 if (!escaped_value) {
200 ret = -1;
201 goto error;
202 }
203
204 var->name = g_string_new(name);
205 var->value.string = g_string_new(escaped_value);
206 g_free(escaped_value);
207 if (!var->name || !var->value.string) {
208 ret = -1;
209 goto error;
210 }
211
212 g_ptr_array_add(trace->environment, var);
213 return ret;
214
215 error:
216 if (var && var->name) {
217 g_string_free(var->name, TRUE);
218 }
219
220 if (var && var->value.string) {
221 g_string_free(var->value.string, TRUE);
222 }
223
224 g_free(var);
225 return ret;
226 }
227
228 int bt_ctf_trace_add_environment_field_integer(struct bt_ctf_trace *trace,
229 const char *name,
230 int64_t value)
231 {
232 struct environment_variable *var = NULL;
233 int ret = 0;
234
235 if (!trace || !name) {
236 ret = -1;
237 goto error;
238 }
239
240 var = g_new0(struct environment_variable, 1);
241 if (!var) {
242 ret = -1;
243 goto error;
244 }
245
246 var->type = BT_ENVIRONMENT_FIELD_TYPE_INTEGER;
247 var->name = g_string_new(name);
248 var->value.integer = value;
249 if (!var->name) {
250 ret = -1;
251 goto error;
252 }
253
254 g_ptr_array_add(trace->environment, var);
255 return ret;
256
257 error:
258 if (var && var->name) {
259 g_string_free(var->name, TRUE);
260 }
261
262 g_free(var);
263 return ret;
264 }
265
266 int bt_ctf_trace_get_environment_field_count(struct bt_ctf_trace *trace)
267 {
268 int ret = 0;
269
270 if (!trace) {
271 ret = -1;
272 goto end;
273 }
274
275 ret = trace->environment->len;
276 end:
277 return ret;
278 }
279
280 enum bt_environment_field_type
281 bt_ctf_trace_get_environment_field_type(struct bt_ctf_trace *trace, int index)
282 {
283 struct environment_variable *var;
284 enum bt_environment_field_type type = BT_ENVIRONMENT_FIELD_TYPE_UNKNOWN;
285
286 if (!trace || index < 0 || index >= trace->environment->len) {
287 goto end;
288 }
289
290 var = g_ptr_array_index(trace->environment, index);
291 type = var->type;
292 end:
293 return type;
294 }
295
296 const char *
297 bt_ctf_trace_get_environment_field_name(struct bt_ctf_trace *trace,
298 int index)
299 {
300 struct environment_variable *var;
301 const char *ret = NULL;
302
303 if (!trace || index < 0 || index >= trace->environment->len) {
304 goto end;
305 }
306
307 var = g_ptr_array_index(trace->environment, index);
308 ret = var->name->str;
309 end:
310 return ret;
311 }
312
313 const char *
314 bt_ctf_trace_get_environment_field_value_string(struct bt_ctf_trace *trace,
315 int index)
316 {
317 struct environment_variable *var;
318 const char *ret = NULL;
319
320 if (!trace || index < 0 || index >= trace->environment->len) {
321 goto end;
322 }
323
324 var = g_ptr_array_index(trace->environment, index);
325 if (var->type != BT_ENVIRONMENT_FIELD_TYPE_STRING) {
326 goto end;
327 }
328 ret = var->value.string->str;
329 end:
330 return ret;
331 }
332
333 int
334 bt_ctf_trace_get_environment_field_value_integer(struct bt_ctf_trace *trace,
335 int index, int64_t *value)
336 {
337 struct environment_variable *var;
338 int ret = 0;
339
340 if (!trace || !value || index < 0 || index >= trace->environment->len) {
341 ret = -1;
342 goto end;
343 }
344
345 var = g_ptr_array_index(trace->environment, index);
346 if (var->type != BT_ENVIRONMENT_FIELD_TYPE_INTEGER) {
347 ret = -1;
348 goto end;
349 }
350 *value = var->value.integer;
351 end:
352 return ret;
353 }
354
355 int bt_ctf_trace_add_clock(struct bt_ctf_trace *trace,
356 struct bt_ctf_clock *clock)
357 {
358 int ret = 0;
359 struct search_query query = { .value = clock, .found = 0 };
360
361 if (!trace || !clock) {
362 ret = -1;
363 goto end;
364 }
365
366 /* Check for duplicate clocks */
367 g_ptr_array_foreach(trace->clocks, value_exists, &query);
368 if (query.found) {
369 ret = -1;
370 goto end;
371 }
372
373 bt_ctf_clock_get(clock);
374 g_ptr_array_add(trace->clocks, clock);
375 end:
376 return ret;
377 }
378
379 int bt_ctf_trace_get_clock_count(struct bt_ctf_trace *trace)
380 {
381 int ret = -1;
382
383 if (!trace) {
384 goto end;
385 }
386
387 ret = trace->clocks->len;
388 end:
389 return ret;
390 }
391
392 struct bt_ctf_clock *bt_ctf_trace_get_clock(struct bt_ctf_trace *trace,
393 int index)
394 {
395 struct bt_ctf_clock *clock = NULL;
396
397 if (!trace || index < 0 || index >= trace->clocks->len) {
398 goto end;
399 }
400
401 clock = g_ptr_array_index(trace->clocks, index);
402 bt_ctf_clock_get(clock);
403 end:
404 return clock;
405 }
406
407 int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace,
408 struct bt_ctf_stream_class *stream_class)
409 {
410 int ret, i;
411 int64_t stream_id;
412
413 if (!trace || !stream_class) {
414 ret = -1;
415 goto end;
416 }
417
418 for (i = 0; i < trace->stream_classes->len; i++) {
419 if (trace->stream_classes->pdata[i] == stream_class) {
420 ret = -1;
421 goto end;
422 }
423 }
424
425 stream_id = bt_ctf_stream_class_get_id(stream_class);
426 if (stream_id < 0) {
427 stream_id = trace->next_stream_id++;
428
429 /* Try to assign a new stream id */
430 for (i = 0; i < trace->stream_classes->len; i++) {
431 if (stream_id == bt_ctf_stream_class_get_id(
432 trace->stream_classes->pdata[i])) {
433 /* Duplicate stream id found */
434 ret = -1;
435 goto end;
436 }
437 }
438
439 if (_bt_ctf_stream_class_set_id(stream_class,
440 trace->next_stream_id++)) {
441 /* TODO Should retry with a different stream id */
442 ret = -1;
443 goto end;
444 }
445 }
446
447 bt_ctf_stream_class_get(stream_class);
448 g_ptr_array_add(trace->stream_classes, stream_class);
449
450 /*
451 * Freeze the trace and its packet header.
452 *
453 * All field type byte orders set as "native" byte ordering can now be
454 * safely set to trace's own endianness, including the stream class'.
455 */
456 bt_ctf_field_type_set_native_byte_order(trace->packet_header_type,
457 trace->byte_order);
458 ret = bt_ctf_stream_class_set_byte_order(stream_class,
459 trace->byte_order == LITTLE_ENDIAN ?
460 BT_CTF_BYTE_ORDER_LITTLE_ENDIAN : BT_CTF_BYTE_ORDER_BIG_ENDIAN);
461 if (ret) {
462 goto end;
463 }
464 bt_ctf_stream_class_freeze(stream_class);
465 trace->frozen = 1;
466
467 end:
468 return ret;
469 }
470
471 int bt_ctf_trace_get_stream_class_count(struct bt_ctf_trace *trace)
472 {
473 int ret;
474
475 if (!trace) {
476 ret = -1;
477 goto end;
478 }
479
480 ret = trace->stream_classes->len;
481 end:
482 return ret;
483 }
484
485 struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class(
486 struct bt_ctf_trace *trace, int index)
487 {
488 struct bt_ctf_stream_class *stream_class = NULL;
489
490 if (!trace || index < 0 || index >= trace->stream_classes->len) {
491 goto end;
492 }
493
494 stream_class = g_ptr_array_index(trace->stream_classes, index);
495 bt_ctf_stream_class_get(stream_class);
496 end:
497 return stream_class;
498 }
499
500 BT_HIDDEN
501 const char *get_byte_order_string(int byte_order)
502 {
503 const char *string;
504
505 switch (byte_order) {
506 case LITTLE_ENDIAN:
507 string = "le";
508 break;
509 case BIG_ENDIAN:
510 string = "be";
511 break;
512 default:
513 string = "unknown";
514 break;
515 }
516
517 return string;
518 }
519
520 static
521 int append_trace_metadata(struct bt_ctf_trace *trace,
522 struct metadata_context *context)
523 {
524 unsigned char *uuid = trace->uuid;
525 int ret;
526
527 g_string_append(context->string, "trace {\n");
528
529 g_string_append(context->string, "\tmajor = 1;\n");
530 g_string_append(context->string, "\tminor = 8;\n");
531
532 g_string_append_printf(context->string,
533 "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
534 uuid[0], uuid[1], uuid[2], uuid[3],
535 uuid[4], uuid[5], uuid[6], uuid[7],
536 uuid[8], uuid[9], uuid[10], uuid[11],
537 uuid[12], uuid[13], uuid[14], uuid[15]);
538 g_string_append_printf(context->string, "\tbyte_order = %s;\n",
539 get_byte_order_string(trace->byte_order));
540
541 g_string_append(context->string, "\tpacket.header := ");
542 context->current_indentation_level++;
543 g_string_assign(context->field_name, "");
544 ret = bt_ctf_field_type_serialize(trace->packet_header_type,
545 context);
546 if (ret) {
547 goto end;
548 }
549 context->current_indentation_level--;
550
551 g_string_append(context->string, ";\n};\n\n");
552 end:
553 return ret;
554 }
555
556 static
557 void append_env_field_metadata(struct environment_variable *var,
558 struct metadata_context *context)
559 {
560 switch (var->type) {
561 case BT_ENVIRONMENT_FIELD_TYPE_STRING:
562 g_string_append_printf(context->string, "\t%s = \"%s\";\n",
563 var->name->str, var->value.string->str);
564 break;
565 case BT_ENVIRONMENT_FIELD_TYPE_INTEGER:
566 g_string_append_printf(context->string, "\t%s = %" PRId64 ";\n",
567 var->name->str, var->value.integer);
568 break;
569 default:
570 assert(0);
571 }
572 }
573
574 static
575 void append_env_metadata(struct bt_ctf_trace *trace,
576 struct metadata_context *context)
577 {
578 if (trace->environment->len == 0) {
579 return;
580 }
581
582 g_string_append(context->string, "env {\n");
583 g_ptr_array_foreach(trace->environment,
584 (GFunc)append_env_field_metadata, context);
585 g_string_append(context->string, "};\n\n");
586 }
587
588 char *bt_ctf_trace_get_metadata_string(struct bt_ctf_trace *trace)
589 {
590 char *metadata = NULL;
591 struct metadata_context *context = NULL;
592 int err = 0;
593 size_t i;
594
595 if (!trace) {
596 goto end;
597 }
598
599 context = g_new0(struct metadata_context, 1);
600 if (!context) {
601 goto end;
602 }
603
604 context->field_name = g_string_sized_new(DEFAULT_IDENTIFIER_SIZE);
605 context->string = g_string_sized_new(DEFAULT_METADATA_STRING_SIZE);
606 g_string_append(context->string, "/* CTF 1.8 */\n\n");
607 if (append_trace_metadata(trace, context)) {
608 goto error;
609 }
610 append_env_metadata(trace, context);
611 g_ptr_array_foreach(trace->clocks,
612 (GFunc)bt_ctf_clock_serialize, context);
613
614 for (i = 0; i < trace->stream_classes->len; i++) {
615 err = bt_ctf_stream_class_serialize(
616 trace->stream_classes->pdata[i], context);
617 if (err) {
618 goto error;
619 }
620 }
621
622 metadata = context->string->str;
623 error:
624 g_string_free(context->string, err ? TRUE : FALSE);
625 g_string_free(context->field_name, TRUE);
626 g_free(context);
627 end:
628 return metadata;
629 }
630
631 enum bt_ctf_byte_order bt_ctf_trace_get_byte_order(struct bt_ctf_trace *trace)
632 {
633 enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
634
635 if (!trace) {
636 goto end;
637 }
638
639 switch (trace->byte_order) {
640 case BIG_ENDIAN:
641 ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
642 break;
643 case LITTLE_ENDIAN:
644 ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
645 break;
646 default:
647 break;
648 }
649 end:
650 return ret;
651 }
652
653 int bt_ctf_trace_set_byte_order(struct bt_ctf_trace *trace,
654 enum bt_ctf_byte_order byte_order)
655 {
656 int ret = 0;
657 int internal_byte_order;
658
659 if (!trace || trace->frozen) {
660 ret = -1;
661 goto end;
662 }
663
664 switch (byte_order) {
665 case BT_CTF_BYTE_ORDER_NATIVE:
666 /*
667 * This doesn't make sense since the CTF specification defines
668 * the "native" byte order as "the byte order described in the
669 * trace description". However, this behavior had been
670 * implemented as part of v1.2 and is kept to maintain
671 * compatibility.
672 *
673 * This may be changed on a major version bump only.
674 */
675 internal_byte_order = (G_BYTE_ORDER == G_LITTLE_ENDIAN) ?
676 LITTLE_ENDIAN : BIG_ENDIAN;
677 break;
678 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
679 internal_byte_order = LITTLE_ENDIAN;
680 break;
681 case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
682 case BT_CTF_BYTE_ORDER_NETWORK:
683 internal_byte_order = BIG_ENDIAN;
684 break;
685 default:
686 ret = -1;
687 goto end;
688 }
689
690 trace->byte_order = internal_byte_order;
691 end:
692 return ret;
693 }
694
695 struct bt_ctf_field_type *bt_ctf_trace_get_packet_header_type(
696 struct bt_ctf_trace *trace)
697 {
698 struct bt_ctf_field_type *field_type = NULL;
699
700 if (!trace) {
701 goto end;
702 }
703
704 bt_ctf_field_type_get(trace->packet_header_type);
705 field_type = trace->packet_header_type;
706 end:
707 return field_type;
708 }
709
710 int bt_ctf_trace_set_packet_header_type(struct bt_ctf_trace *trace,
711 struct bt_ctf_field_type *packet_header_type)
712 {
713 int ret = 0;
714
715 if (!trace || !packet_header_type || trace->frozen) {
716 ret = -1;
717 goto end;
718 }
719
720 /* packet_header_type must be a structure */
721 if (bt_ctf_field_type_get_type_id(packet_header_type) !=
722 CTF_TYPE_STRUCT) {
723 ret = -1;
724 goto end;
725 }
726
727 bt_ctf_field_type_get(packet_header_type);
728 bt_ctf_field_type_put(trace->packet_header_type);
729 trace->packet_header_type = packet_header_type;
730 end:
731 return ret;
732 }
733
734 void bt_ctf_trace_get(struct bt_ctf_trace *trace)
735 {
736 if (!trace) {
737 return;
738 }
739
740 bt_ctf_ref_get(&trace->ref_count);
741 }
742
743 void bt_ctf_trace_put(struct bt_ctf_trace *trace)
744 {
745 if (!trace) {
746 return;
747 }
748
749 bt_ctf_ref_put(&trace->ref_count, bt_ctf_trace_destroy);
750 }
751
752 BT_HIDDEN
753 struct bt_ctf_field_type *get_field_type(enum field_type_alias alias)
754 {
755 unsigned int alignment, size;
756 struct bt_ctf_field_type *field_type;
757
758 if (alias >= NR_FIELD_TYPE_ALIAS) {
759 return NULL;
760 }
761
762 alignment = field_type_aliases_alignments[alias];
763 size = field_type_aliases_sizes[alias];
764 field_type = bt_ctf_field_type_integer_create(size);
765 bt_ctf_field_type_set_alignment(field_type, alignment);
766 return field_type;
767 }
768
769 static
770 int init_trace_packet_header(struct bt_ctf_trace *trace)
771 {
772 int ret = 0;
773 struct bt_ctf_field *magic = NULL, *uuid_array = NULL;
774 struct bt_ctf_field_type *_uint32_t =
775 get_field_type(FIELD_TYPE_ALIAS_UINT32_T);
776 struct bt_ctf_field_type *_uint8_t =
777 get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
778 struct bt_ctf_field_type *trace_packet_header_type =
779 bt_ctf_field_type_structure_create();
780 struct bt_ctf_field_type *uuid_array_type =
781 bt_ctf_field_type_array_create(_uint8_t, 16);
782
783 if (!trace_packet_header_type || !uuid_array_type) {
784 ret = -1;
785 goto end;
786 }
787
788 ret = bt_ctf_field_type_structure_add_field(trace_packet_header_type,
789 _uint32_t, "magic");
790 if (ret) {
791 goto end;
792 }
793
794 ret = bt_ctf_field_type_structure_add_field(trace_packet_header_type,
795 uuid_array_type, "uuid");
796 if (ret) {
797 goto end;
798 }
799
800 ret = bt_ctf_field_type_structure_add_field(trace_packet_header_type,
801 _uint32_t, "stream_id");
802 if (ret) {
803 goto end;
804 }
805
806 ret = bt_ctf_trace_set_packet_header_type(trace,
807 trace_packet_header_type);
808 if (ret) {
809 goto end;
810 }
811 end:
812 bt_ctf_field_type_put(uuid_array_type);
813 bt_ctf_field_type_put(_uint32_t);
814 bt_ctf_field_type_put(_uint8_t);
815 bt_ctf_field_put(magic);
816 bt_ctf_field_put(uuid_array);
817 bt_ctf_field_type_put(trace_packet_header_type);
818
819 return ret;
820 }
821
822 static
823 void environment_variable_destroy(struct environment_variable *var)
824 {
825 g_string_free(var->name, TRUE);
826 if (var->type == BT_ENVIRONMENT_FIELD_TYPE_STRING) {
827 g_string_free(var->value.string, TRUE);
828 }
829 g_free(var);
830 }
This page took 0.06226 seconds and 4 git commands to generate.