Re-format new C++ files
[babeltrace.git] / src / plugins / ctf / fs-sink / fs-sink-stream.cpp
CommitLineData
15fe47e0 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
15fe47e0 3 *
0235b0db 4 * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
15fe47e0
PP
5 */
6
aa1a7452 7#define BT_COMP_LOG_SELF_COMP (stream->trace->fs_sink->self_comp)
4164020e
SM
8#define BT_LOG_OUTPUT_LEVEL (stream->log_level)
9#define BT_LOG_TAG "PLUGIN/SINK.CTF.FS/STREAM"
d9c39b0a 10#include "logging/comp-logging.h"
15fe47e0 11
3fadfbc0 12#include <babeltrace2/babeltrace.h>
15fe47e0
PP
13#include <stdio.h>
14#include <stdbool.h>
15#include <glib.h>
578e048b
MJ
16#include "common/assert.h"
17#include "ctfser/ctfser.h"
18#include "compat/endian.h"
15fe47e0 19
087cd0f5
SM
20#include "fs-sink.hpp"
21#include "fs-sink-trace.hpp"
22#include "fs-sink-stream.hpp"
23#include "translate-trace-ir-to-ctf-ir.hpp"
15fe47e0
PP
24
25BT_HIDDEN
26void fs_sink_stream_destroy(struct fs_sink_stream *stream)
27{
4164020e
SM
28 if (!stream) {
29 goto end;
30 }
15fe47e0 31
4164020e 32 bt_ctfser_fini(&stream->ctfser);
15fe47e0 33
4164020e
SM
34 if (stream->file_name) {
35 g_string_free(stream->file_name, TRUE);
36 stream->file_name = NULL;
37 }
15fe47e0 38
4164020e
SM
39 bt_packet_put_ref(stream->packet_state.packet);
40 g_free(stream);
15fe47e0
PP
41
42end:
4164020e 43 return;
15fe47e0
PP
44}
45
4164020e 46static bool stream_file_name_exists(struct fs_sink_trace *trace, const char *name)
15fe47e0 47{
4164020e
SM
48 bool exists = false;
49 GHashTableIter iter;
50 gpointer key, value;
15fe47e0 51
4164020e 52 g_hash_table_iter_init(&iter, trace->streams);
15fe47e0 53
4164020e
SM
54 while (g_hash_table_iter_next(&iter, &key, &value)) {
55 struct fs_sink_stream *stream = (fs_sink_stream *) value;
15fe47e0 56
4164020e
SM
57 if (strcmp(name, stream->file_name->str) == 0) {
58 exists = true;
59 goto end;
60 }
61 }
15fe47e0
PP
62
63end:
4164020e 64 return exists;
15fe47e0
PP
65}
66
4164020e 67static GString *sanitize_stream_file_name(const char *file_name)
15fe47e0 68{
4164020e
SM
69 GString *san_file_name = g_string_new(NULL);
70 const char *ch;
71 gchar *basename;
72
73 BT_ASSERT(san_file_name);
74 BT_ASSERT(file_name);
75 basename = g_path_get_basename(file_name);
76
77 for (ch = basename; *ch != '\0'; ch++) {
78 if (*ch == '/') {
79 g_string_append_c(san_file_name, '_');
80 } else {
81 g_string_append_c(san_file_name, *ch);
82 }
83 }
84
85 /* Do not allow `.` and `..` either */
86 if (strcmp(san_file_name->str, ".") == 0 || strcmp(san_file_name->str, "..") == 0) {
87 g_string_assign(san_file_name, "stream");
88 }
89
90 g_free(basename);
91 return san_file_name;
15fe47e0
PP
92}
93
4164020e 94static GString *make_unique_stream_file_name(struct fs_sink_trace *trace, const char *base)
15fe47e0 95{
4164020e
SM
96 GString *san_base = sanitize_stream_file_name(base);
97 GString *name = g_string_new(san_base->str);
98 unsigned int suffix = 0;
15fe47e0 99
4164020e 100 BT_ASSERT(name);
15fe47e0 101
4164020e
SM
102 while (stream_file_name_exists(trace, name->str) || strcmp(name->str, "metadata") == 0) {
103 g_string_printf(name, "%s-%u", san_base->str, suffix);
104 suffix++;
105 }
15fe47e0 106
4164020e
SM
107 g_string_free(san_base, TRUE);
108 return name;
15fe47e0
PP
109}
110
4164020e 111static void set_stream_file_name(struct fs_sink_stream *stream)
15fe47e0 112{
4164020e 113 const char *base_name = bt_stream_get_name(stream->ir_stream);
15fe47e0 114
4164020e
SM
115 if (!base_name) {
116 base_name = "stream";
117 }
15fe47e0 118
4164020e
SM
119 BT_ASSERT(!stream->file_name);
120 stream->file_name = make_unique_stream_file_name(stream->trace, base_name);
15fe47e0
PP
121}
122
123BT_HIDDEN
124struct fs_sink_stream *fs_sink_stream_create(struct fs_sink_trace *trace,
4164020e 125 const bt_stream *ir_stream)
15fe47e0 126{
4164020e
SM
127 struct fs_sink_stream *stream = g_new0(struct fs_sink_stream, 1);
128 int ret;
129 GString *path = g_string_new(trace->path->str);
130
131 if (!stream) {
132 goto end;
133 }
134
135 stream->log_level = trace->log_level;
136 stream->trace = trace;
137 stream->ir_stream = ir_stream;
138 stream->packet_state.beginning_cs = UINT64_C(-1);
139 stream->packet_state.end_cs = UINT64_C(-1);
140 stream->prev_packet_state.end_cs = UINT64_C(-1);
141 stream->prev_packet_state.discarded_events_counter = UINT64_C(-1);
142 stream->prev_packet_state.seq_num = UINT64_C(-1);
143 ret = try_translate_stream_class_trace_ir_to_ctf_ir(
144 trace->fs_sink, trace->trace, bt_stream_borrow_class_const(ir_stream), &stream->sc);
145 if (ret) {
146 goto error;
147 }
148
149 set_stream_file_name(stream);
150 g_string_append_printf(path, "/%s", stream->file_name->str);
151 ret = bt_ctfser_init(&stream->ctfser, path->str, stream->log_level);
152 if (ret) {
153 goto error;
154 }
155
156 g_hash_table_insert(trace->streams, (gpointer) ir_stream, stream);
157 goto end;
15fe47e0
PP
158
159error:
4164020e
SM
160 fs_sink_stream_destroy(stream);
161 stream = NULL;
15fe47e0
PP
162
163end:
4164020e
SM
164 if (path) {
165 g_string_free(path, TRUE);
166 }
15fe47e0 167
4164020e 168 return stream;
15fe47e0
PP
169}
170
4164020e
SM
171static int write_field(struct fs_sink_stream *stream, struct fs_sink_ctf_field_class *fc,
172 const bt_field *field);
15fe47e0 173
4164020e
SM
174static inline int write_bool_field(struct fs_sink_stream *stream,
175 struct fs_sink_ctf_field_class_bool *fc, const bt_field *field)
ecd27ae4 176{
4164020e
SM
177 /*
178 * CTF 1.8 has no boolean field class type, so this component
179 * translates this boolean field to an 8-bit unsigned integer
180 * field which has the value 0 (false) or 1 (true).
181 */
182 return bt_ctfser_write_unsigned_int(&stream->ctfser, bt_field_bool_get_value(field) ? 1 : 0,
183 fc->base.base.alignment, fc->base.size, BYTE_ORDER);
ecd27ae4
PP
184}
185
4164020e
SM
186static inline int write_bit_array_field(struct fs_sink_stream *stream,
187 struct fs_sink_ctf_field_class_bit_array *fc,
188 const bt_field *field)
43a94dc9 189{
4164020e
SM
190 /*
191 * CTF 1.8 has no bit array field class type, so this component
192 * translates this bit array field to an unsigned integer field.
193 */
194 return bt_ctfser_write_unsigned_int(&stream->ctfser,
195 bt_field_bit_array_get_value_as_integer(field),
196 fc->base.alignment, fc->size, BYTE_ORDER);
43a94dc9
PP
197}
198
4164020e
SM
199static inline int write_int_field(struct fs_sink_stream *stream,
200 struct fs_sink_ctf_field_class_int *fc, const bt_field *field)
15fe47e0 201{
4164020e
SM
202 int ret;
203
204 if (fc->is_signed) {
205 ret = bt_ctfser_write_signed_int(&stream->ctfser, bt_field_integer_signed_get_value(field),
206 fc->base.base.alignment, fc->base.size, BYTE_ORDER);
207 } else {
208 ret = bt_ctfser_write_unsigned_int(&stream->ctfser,
209 bt_field_integer_unsigned_get_value(field),
210 fc->base.base.alignment, fc->base.size, BYTE_ORDER);
211 }
212
213 return ret;
15fe47e0
PP
214}
215
4164020e
SM
216static inline int write_float_field(struct fs_sink_stream *stream,
217 struct fs_sink_ctf_field_class_float *fc, const bt_field *field)
15fe47e0 218{
4164020e
SM
219 int ret;
220 double val;
221
222 if (fc->base.size == 32) {
223 val = (double) bt_field_real_single_precision_get_value(field);
224 ret = bt_ctfser_write_float32(&stream->ctfser, val, fc->base.base.alignment, BYTE_ORDER);
225 } else {
226 val = bt_field_real_double_precision_get_value(field);
227 ret = bt_ctfser_write_float64(&stream->ctfser, val, fc->base.base.alignment, BYTE_ORDER);
228 }
229
230 return ret;
15fe47e0
PP
231}
232
4164020e
SM
233static inline int write_string_field(struct fs_sink_stream *stream,
234 struct fs_sink_ctf_field_class_string *fc,
235 const bt_field *field)
15fe47e0 236{
4164020e 237 return bt_ctfser_write_string(&stream->ctfser, bt_field_string_get_value(field));
15fe47e0
PP
238}
239
4164020e
SM
240static inline int write_array_base_field_elements(struct fs_sink_stream *stream,
241 struct fs_sink_ctf_field_class_array_base *fc,
242 const bt_field *field)
15fe47e0 243{
4164020e
SM
244 uint64_t i;
245 uint64_t len = bt_field_array_get_length(field);
246 int ret = 0;
247
248 for (i = 0; i < len; i++) {
249 const bt_field *elem_field = bt_field_array_borrow_element_field_by_index_const(field, i);
250 ret = write_field(stream, fc->elem_fc, elem_field);
251 if (G_UNLIKELY(ret)) {
252 goto end;
253 }
254 }
15fe47e0
PP
255
256end:
4164020e 257 return ret;
15fe47e0
PP
258}
259
4164020e
SM
260static inline int write_sequence_field(struct fs_sink_stream *stream,
261 struct fs_sink_ctf_field_class_sequence *fc,
262 const bt_field *field)
15fe47e0 263{
4164020e 264 int ret;
15fe47e0 265
4164020e
SM
266 if (fc->length_is_before) {
267 ret = bt_ctfser_write_unsigned_int(&stream->ctfser, bt_field_array_get_length(field), 8, 32,
268 BYTE_ORDER);
269 if (G_UNLIKELY(ret)) {
270 goto end;
271 }
272 }
15fe47e0 273
4164020e 274 ret = write_array_base_field_elements(stream, &fc->base, field);
15fe47e0
PP
275
276end:
4164020e 277 return ret;
15fe47e0
PP
278}
279
4164020e
SM
280static inline int write_struct_field(struct fs_sink_stream *stream,
281 struct fs_sink_ctf_field_class_struct *fc,
282 const bt_field *field, bool align_struct)
15fe47e0 283{
4164020e
SM
284 int ret = 0;
285 uint64_t i;
286
287 if (G_LIKELY(align_struct)) {
288 ret = bt_ctfser_align_offset_in_current_packet(&stream->ctfser, fc->base.alignment);
289 if (G_UNLIKELY(ret)) {
290 goto end;
291 }
292 }
293
294 for (i = 0; i < fc->members->len; i++) {
295 const bt_field *memb_field =
296 bt_field_structure_borrow_member_field_by_index_const(field, i);
297 struct fs_sink_ctf_field_class *member_fc =
298 fs_sink_ctf_field_class_struct_borrow_member_by_index(fc, i)->fc;
299
300 ret = write_field(stream, member_fc, memb_field);
301 if (G_UNLIKELY(ret)) {
302 goto end;
303 }
304 }
15fe47e0
PP
305
306end:
4164020e 307 return ret;
15fe47e0
PP
308}
309
4164020e
SM
310static inline int write_option_field(struct fs_sink_stream *stream,
311 struct fs_sink_ctf_field_class_option *fc,
312 const bt_field *field)
c25f8e53 313{
4164020e
SM
314 int ret;
315 const bt_field *content_field = bt_field_option_borrow_field_const(field);
316
317 ret = bt_ctfser_write_unsigned_int(&stream->ctfser, content_field ? 1 : 0, 8, 8, BYTE_ORDER);
318 if (G_UNLIKELY(ret)) {
319 goto end;
320 }
321
322 /*
323 * CTF 1.8 has no option field class type, so this component
324 * translates the option field class to a variant field class
325 * where the options are:
326 *
327 * * An empty structure field class (field occupies 0 bits).
328 * * The optional field class itself.
329 *
330 * If `content_field` is `NULL`, do not write anything (empty
331 * structure).
332 */
333 if (content_field) {
334 ret = write_field(stream, fc->content_fc, content_field);
335 }
c25f8e53
PP
336
337end:
4164020e 338 return ret;
c25f8e53
PP
339}
340
4164020e
SM
341static inline int write_variant_field(struct fs_sink_stream *stream,
342 struct fs_sink_ctf_field_class_variant *fc,
343 const bt_field *field)
15fe47e0 344{
4164020e
SM
345 uint64_t opt_index = bt_field_variant_get_selected_option_index(field);
346 int ret;
347
348 if (fc->tag_is_before) {
349 ret = bt_ctfser_write_unsigned_int(&stream->ctfser, opt_index, 8, 16, BYTE_ORDER);
350 if (G_UNLIKELY(ret)) {
351 goto end;
352 }
353 }
354
355 ret = write_field(stream,
356 fs_sink_ctf_field_class_variant_borrow_option_by_index(fc, opt_index)->fc,
357 bt_field_variant_borrow_selected_option_field_const(field));
15fe47e0
PP
358
359end:
4164020e 360 return ret;
15fe47e0
PP
361}
362
4164020e
SM
363static int write_field(struct fs_sink_stream *stream, struct fs_sink_ctf_field_class *fc,
364 const bt_field *field)
15fe47e0 365{
4164020e
SM
366 int ret;
367
368 switch (fc->type) {
369 case FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL:
370 ret = write_bool_field(stream, fs_sink_ctf_field_class_as_bool(fc), field);
371 break;
372 case FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY:
373 ret = write_bit_array_field(stream, fs_sink_ctf_field_class_as_bit_array(fc), field);
374 break;
375 case FS_SINK_CTF_FIELD_CLASS_TYPE_INT:
376 ret = write_int_field(stream, fs_sink_ctf_field_class_as_int(fc), field);
377 break;
378 case FS_SINK_CTF_FIELD_CLASS_TYPE_FLOAT:
379 ret = write_float_field(stream, fs_sink_ctf_field_class_as_float(fc), field);
380 break;
381 case FS_SINK_CTF_FIELD_CLASS_TYPE_STRING:
382 ret = write_string_field(stream, fs_sink_ctf_field_class_as_string(fc), field);
383 break;
384 case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT:
385 ret = write_struct_field(stream, fs_sink_ctf_field_class_as_struct(fc), field, true);
386 break;
387 case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY:
388 ret = write_array_base_field_elements(stream, fs_sink_ctf_field_class_as_array_base(fc),
389 field);
390 break;
391 case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE:
392 ret = write_sequence_field(stream, fs_sink_ctf_field_class_as_sequence(fc), field);
393 break;
394 case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION:
395 ret = write_option_field(stream, fs_sink_ctf_field_class_as_option(fc), field);
396 break;
397 case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT:
398 ret = write_variant_field(stream, fs_sink_ctf_field_class_as_variant(fc), field);
399 break;
400 default:
401 bt_common_abort();
402 }
403
404 return ret;
15fe47e0
PP
405}
406
4164020e
SM
407static inline int write_event_header(struct fs_sink_stream *stream, const bt_clock_snapshot *cs,
408 struct fs_sink_ctf_event_class *ec)
15fe47e0 409{
4164020e
SM
410 int ret;
411
412 /* Event class ID */
413 ret = bt_ctfser_write_byte_aligned_unsigned_int(
414 &stream->ctfser, bt_event_class_get_id(ec->ir_ec), 8, 64, BYTE_ORDER);
415 if (G_UNLIKELY(ret)) {
416 goto end;
417 }
418
419 /* Time */
420 if (stream->sc->default_clock_class) {
421 BT_ASSERT_DBG(cs);
422 ret = bt_ctfser_write_byte_aligned_unsigned_int(
423 &stream->ctfser, bt_clock_snapshot_get_value(cs), 8, 64, BYTE_ORDER);
424 if (G_UNLIKELY(ret)) {
425 goto end;
426 }
427 }
15fe47e0
PP
428
429end:
4164020e 430 return ret;
15fe47e0
PP
431}
432
433BT_HIDDEN
4164020e
SM
434int fs_sink_stream_write_event(struct fs_sink_stream *stream, const bt_clock_snapshot *cs,
435 const bt_event *event, struct fs_sink_ctf_event_class *ec)
15fe47e0 436{
4164020e
SM
437 int ret;
438 const bt_field *field;
439
440 /* Header */
441 ret = write_event_header(stream, cs, ec);
442 if (G_UNLIKELY(ret)) {
443 goto end;
444 }
445
446 /* Common context */
447 if (stream->sc->event_common_context_fc) {
448 field = bt_event_borrow_common_context_field_const(event);
449 BT_ASSERT_DBG(field);
450 ret = write_struct_field(
451 stream, fs_sink_ctf_field_class_as_struct(stream->sc->event_common_context_fc), field,
452 true);
453 if (G_UNLIKELY(ret)) {
454 goto end;
455 }
456 }
457
458 /* Specific context */
459 if (ec->spec_context_fc) {
460 field = bt_event_borrow_specific_context_field_const(event);
461 BT_ASSERT_DBG(field);
462 ret = write_struct_field(stream, fs_sink_ctf_field_class_as_struct(ec->spec_context_fc),
463 field, true);
464 if (G_UNLIKELY(ret)) {
465 goto end;
466 }
467 }
468
469 /* Specific context */
470 if (ec->payload_fc) {
471 field = bt_event_borrow_payload_field_const(event);
472 BT_ASSERT_DBG(field);
473 ret = write_struct_field(stream, fs_sink_ctf_field_class_as_struct(ec->payload_fc), field,
474 true);
475 if (G_UNLIKELY(ret)) {
476 goto end;
477 }
478 }
15fe47e0
PP
479
480end:
4164020e 481 return ret;
15fe47e0
PP
482}
483
4164020e 484static int write_packet_context(struct fs_sink_stream *stream)
15fe47e0 485{
4164020e
SM
486 int ret;
487
488 /* Packet total size */
489 ret = bt_ctfser_write_byte_aligned_unsigned_int(
490 &stream->ctfser, stream->packet_state.total_size, 8, 64, BYTE_ORDER);
491 if (ret) {
492 goto end;
493 }
494
495 /* Packet content size */
496 ret = bt_ctfser_write_byte_aligned_unsigned_int(
497 &stream->ctfser, stream->packet_state.content_size, 8, 64, BYTE_ORDER);
498 if (ret) {
499 goto end;
500 }
501
502 if (stream->sc->packets_have_ts_begin) {
503 /* Beginning time */
504 ret = bt_ctfser_write_byte_aligned_unsigned_int(
505 &stream->ctfser, stream->packet_state.beginning_cs, 8, 64, BYTE_ORDER);
506 if (ret) {
507 goto end;
508 }
509 }
510
511 if (stream->sc->packets_have_ts_end) {
512 /* End time */
513 ret = bt_ctfser_write_byte_aligned_unsigned_int(
514 &stream->ctfser, stream->packet_state.end_cs, 8, 64, BYTE_ORDER);
515 if (ret) {
516 goto end;
517 }
518 }
519
520 if (stream->sc->has_discarded_events) {
521 /* Discarded event counter */
522 ret = bt_ctfser_write_byte_aligned_unsigned_int(
523 &stream->ctfser, stream->packet_state.discarded_events_counter, 8, 64, BYTE_ORDER);
524 if (ret) {
525 goto end;
526 }
527 }
528
529 /* Sequence number */
530 ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, stream->packet_state.seq_num,
531 8, 64, BYTE_ORDER);
532 if (ret) {
533 goto end;
534 }
535
536 /* Other members */
537 if (stream->sc->packet_context_fc) {
538 const bt_field *packet_context_field;
539
540 BT_ASSERT(stream->packet_state.packet);
541 packet_context_field = bt_packet_borrow_context_field_const(stream->packet_state.packet);
542 BT_ASSERT(packet_context_field);
543 ret = write_struct_field(stream,
544 fs_sink_ctf_field_class_as_struct(stream->sc->packet_context_fc),
545 packet_context_field, false);
546 if (ret) {
547 goto end;
548 }
549 }
15fe47e0
PP
550
551end:
4164020e 552 return ret;
15fe47e0
PP
553}
554
555BT_HIDDEN
4164020e
SM
556int fs_sink_stream_open_packet(struct fs_sink_stream *stream, const bt_clock_snapshot *cs,
557 const bt_packet *packet)
15fe47e0 558{
4164020e
SM
559 int ret;
560 uint64_t i;
561
562 BT_ASSERT(!stream->packet_state.is_open);
563 bt_packet_put_ref(stream->packet_state.packet);
564 stream->packet_state.packet = packet;
565 bt_packet_get_ref(stream->packet_state.packet);
566 if (cs) {
567 stream->packet_state.beginning_cs = bt_clock_snapshot_get_value(cs);
568 }
569
570 /* Open packet */
571 ret = bt_ctfser_open_packet(&stream->ctfser);
572 if (ret) {
573 /* bt_ctfser_open_packet() logs errors */
574 goto end;
575 }
576
577 /* Packet header: magic */
578 ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser, UINT64_C(0xc1fc1fc1), 8, 32,
579 BYTE_ORDER);
580 if (ret) {
581 BT_COMP_LOGE("Error writing packet header magic: stream-file-name=%s",
582 stream->file_name->str);
583 goto end;
584 }
585
586 /* Packet header: UUID */
587 for (i = 0; i < BT_UUID_LEN; i++) {
588 ret = bt_ctfser_write_byte_aligned_unsigned_int(
589 &stream->ctfser, (uint64_t) stream->sc->trace->uuid[i], 8, 8, BYTE_ORDER);
590 if (ret) {
591 BT_COMP_LOGE("Error writing packet header UUID: stream-file-name=%s",
592 stream->file_name->str);
593 goto end;
594 }
595 }
596
597 /* Packet header: stream class ID */
598 ret = bt_ctfser_write_byte_aligned_unsigned_int(
599 &stream->ctfser, bt_stream_class_get_id(stream->sc->ir_sc), 8, 64, BYTE_ORDER);
600 if (ret) {
601 BT_COMP_LOGE("Error writing packet header stream class id: "
602 "stream-file-name=%s, stream-class-id=%" PRIu64,
603 stream->file_name->str, bt_stream_class_get_id(stream->sc->ir_sc));
604 goto end;
605 }
606
607 /* Packet header: stream ID */
608 ret = bt_ctfser_write_byte_aligned_unsigned_int(
609 &stream->ctfser, bt_stream_get_id(stream->ir_stream), 8, 64, BYTE_ORDER);
610 if (ret) {
611 BT_COMP_LOGE("Error writing packet header stream id: "
612 "stream-file-name=%s, stream-id=%" PRIu64,
613 stream->file_name->str, bt_stream_get_id(stream->ir_stream));
614 goto end;
615 }
616
617 /* Save packet context's offset to rewrite it later */
618 stream->packet_state.context_offset_bits =
619 bt_ctfser_get_offset_in_current_packet_bits(&stream->ctfser);
620
621 /* Write packet context just to advance to content (first event) */
622 ret = write_packet_context(stream);
623 if (ret) {
624 goto end;
625 }
626
627 stream->packet_state.is_open = true;
15fe47e0
PP
628
629end:
4164020e 630 return ret;
15fe47e0
PP
631}
632
633BT_HIDDEN
4164020e 634int fs_sink_stream_close_packet(struct fs_sink_stream *stream, const bt_clock_snapshot *cs)
15fe47e0 635{
4164020e
SM
636 int ret;
637
638 BT_ASSERT(stream->packet_state.is_open);
639
640 if (cs) {
641 stream->packet_state.end_cs = bt_clock_snapshot_get_value(cs);
642 }
643
644 stream->packet_state.content_size =
645 bt_ctfser_get_offset_in_current_packet_bits(&stream->ctfser);
646 stream->packet_state.total_size = (stream->packet_state.content_size + 7) & ~UINT64_C(7);
647
648 /* Rewrite packet context */
649 bt_ctfser_set_offset_in_current_packet_bits(&stream->ctfser,
650 stream->packet_state.context_offset_bits);
651 ret = write_packet_context(stream);
652 if (ret) {
653 goto end;
654 }
655
656 /* Close packet */
657 bt_ctfser_close_current_packet(&stream->ctfser, stream->packet_state.total_size / 8);
658
659 /* Partially copy current packet state to previous packet state */
660 stream->prev_packet_state.end_cs = stream->packet_state.end_cs;
661 stream->prev_packet_state.discarded_events_counter =
662 stream->packet_state.discarded_events_counter;
663 stream->prev_packet_state.seq_num = stream->packet_state.seq_num;
664
665 /* Reset current packet state */
666 stream->packet_state.beginning_cs = UINT64_C(-1);
667 stream->packet_state.end_cs = UINT64_C(-1);
668 stream->packet_state.content_size = 0;
669 stream->packet_state.total_size = 0;
670 stream->packet_state.seq_num += 1;
671 stream->packet_state.context_offset_bits = 0;
672 stream->packet_state.is_open = false;
673 BT_PACKET_PUT_REF_AND_RESET(stream->packet_state.packet);
15fe47e0
PP
674
675end:
4164020e 676 return ret;
15fe47e0 677}
This page took 0.090813 seconds and 4 git commands to generate.