2 * Babeltrace - CTF binary type reader (BTR)
4 * Copyright (c) 2015-2016 EfficiOS Inc. and Linux Foundation
5 * Copyright (c) 2015-2016 Philippe Proulx <pproulx@efficios.com>
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 #include <babeltrace/bitfield-internal.h>
34 #include <babeltrace/ctf-ir/field-types.h>
35 #include <babeltrace/ref.h>
36 #include <babeltrace/align-internal.h>
41 #define PRINT_ERR_STREAM (btr ? btr->err_stream : stderr)
42 #define PRINT_PREFIX "ctf-btr"
45 #define DIV8(_x) ((_x) >> 3)
46 #define BYTES_TO_BITS(_x) ((_x) * 8)
47 #define BITS_TO_BYTES_FLOOR(_x) DIV8(_x)
48 #define BITS_TO_BYTES_CEIL(_x) DIV8((_x) + 7)
49 #define IN_BYTE_OFFSET(_at) ((_at) & 7)
51 /* A visit stack entry */
54 * Current type of base field, one of:
63 struct bt_ctf_field_type
*base_type
;
65 /* Length of base field (always 1 for variant types) */
68 /* Lndex of next field to read */
74 /* Entries (struct stack_entry *) (top is last element) */
81 BTR_STATE_ALIGN_BASIC
,
82 BTR_STATE_ALIGN_COMPOUND
,
83 BTR_STATE_READ_BASIC_BEGIN
,
84 BTR_STATE_READ_BASIC_CONTINUE
,
88 /* Binary type reader */
96 /* Current basic field type */
97 struct bt_ctf_field_type
*cur_basic_field_type
;
100 enum btr_state state
;
103 * Last basic field type's byte order.
105 * This is used to detect errors since two contiguous basic
106 * types for which the common boundary is not the boundary of
107 * a byte cannot have different byte orders.
109 * This is set to BT_CTF_BYTE_ORDER_UNKNOWN on reset and when
110 * the last basic field type was a string type.
112 enum bt_ctf_byte_order last_bo
;
114 /* Current byte order (copied to last_bo after a successful read) */
115 enum bt_ctf_byte_order cur_bo
;
117 /* Stitch buffer infos */
122 /* Offset, within stitch buffer, of first bit */
125 /* Length (bits) of data in stitch buffer from offset */
129 /* User buffer infos */
134 /* Offset of data from address (bits) */
137 /* Current position from offset (bits) */
140 /* Offset of offset within whole packet (bits) */
141 size_t packet_offset
;
143 /* Data size in buffer (bits) */
146 /* Buffer size (bytes) */
152 /* Callback functions */
153 struct bt_ctf_btr_cbs cbs
;
161 void stack_entry_free_func(gpointer data
)
163 struct stack_entry
*entry
= data
;
165 BT_PUT(entry
->base_type
);
170 struct stack
*stack_new(void)
172 struct stack
*stack
= NULL
;
174 stack
= g_new0(struct stack
, 1);
179 stack
->entries
= g_ptr_array_new_with_free_func(stack_entry_free_func
);
180 if (!stack
->entries
) {
193 void stack_destroy(struct stack
*stack
)
199 g_ptr_array_free(stack
->entries
, TRUE
);
204 int64_t get_compound_field_type_length(struct bt_ctf_btr
*btr
,
205 struct bt_ctf_field_type
*field_type
)
209 switch (bt_ctf_field_type_get_type_id(field_type
)) {
210 case BT_CTF_FIELD_TYPE_ID_STRUCT
:
211 length
= (int64_t) bt_ctf_field_type_structure_get_field_count(
214 case BT_CTF_FIELD_TYPE_ID_VARIANT
:
215 /* Variant field types always "contain" a single type */
218 case BT_CTF_FIELD_TYPE_ID_ARRAY
:
219 length
= bt_ctf_field_type_array_get_length(field_type
);
221 case BT_CTF_FIELD_TYPE_ID_SEQUENCE
:
222 length
= btr
->user
.cbs
.query
.get_sequence_length(field_type
,
226 PERR("Cannot get length of field type with type ID %d\n",
227 bt_ctf_field_type_get_type_id(field_type
));
228 length
= BT_CTF_BTR_STATUS_ERROR
;
235 int stack_push(struct stack
*stack
, struct bt_ctf_field_type
*base_type
,
239 struct stack_entry
*entry
;
244 entry
= g_new0(struct stack_entry
, 1);
246 ret
= BT_CTF_BTR_STATUS_ERROR
;
250 entry
->base_type
= base_type
;
251 bt_get(entry
->base_type
);
252 entry
->base_len
= base_len
;
253 g_ptr_array_add(stack
->entries
, entry
);
260 int stack_push_with_len(struct bt_ctf_btr
*btr
,
261 struct bt_ctf_field_type
*base_type
)
264 int64_t base_len
= get_compound_field_type_length(btr
, base_type
);
267 PERR("Failed to get compound field type's length\n");
268 ret
= BT_CTF_BTR_STATUS_ERROR
;
272 ret
= stack_push(btr
->stack
, base_type
, (size_t) base_len
);
279 unsigned int stack_size(struct stack
*stack
)
283 return stack
->entries
->len
;
287 void stack_pop(struct stack
*stack
)
290 assert(stack_size(stack
));
291 g_ptr_array_remove_index(stack
->entries
, stack
->entries
->len
- 1);
295 bool stack_empty(struct stack
*stack
)
297 return stack_size(stack
) == 0;
301 void stack_clear(struct stack
*stack
)
305 if (!stack_empty(stack
)) {
306 g_ptr_array_remove_range(stack
->entries
, 0, stack_size(stack
));
309 assert(stack_empty(stack
));
313 struct stack_entry
*stack_top(struct stack
*stack
)
316 assert(stack_size(stack
));
318 return g_ptr_array_index(stack
->entries
, stack
->entries
->len
- 1);
322 size_t available_bits(struct bt_ctf_btr
*btr
)
324 return btr
->buf
.sz
- btr
->buf
.at
;
328 void consume_bits(struct bt_ctf_btr
*btr
, size_t incr
)
334 bool has_enough_bits(struct bt_ctf_btr
*btr
, size_t sz
)
336 return available_bits(btr
) >= sz
;
340 bool at_least_one_bit_left(struct bt_ctf_btr
*btr
)
342 return has_enough_bits(btr
, 1);
346 size_t packet_at(struct bt_ctf_btr
*btr
)
348 return btr
->buf
.packet_offset
+ btr
->buf
.at
;
352 size_t buf_at_from_addr(struct bt_ctf_btr
*btr
)
357 * ====== offset ===== (17)
359 * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
361 * addr (0) ==== at ==== (12)
365 * =============================== (29)
367 return btr
->buf
.offset
+ btr
->buf
.at
;
371 int get_basic_field_type_size(struct bt_ctf_btr
*btr
,
372 struct bt_ctf_field_type
*field_type
)
376 switch (bt_ctf_field_type_get_type_id(field_type
)) {
377 case BT_CTF_FIELD_TYPE_ID_INTEGER
:
378 size
= bt_ctf_field_type_integer_get_size(field_type
);
380 case BT_CTF_FIELD_TYPE_ID_FLOAT
:
382 int exp_dig
, mant_dig
;
385 bt_ctf_field_type_floating_point_get_exponent_digits(
388 bt_ctf_field_type_floating_point_get_mantissa_digits(
390 if (exp_dig
< 0 || mant_dig
< 0) {
391 PERR("Failed to get floating point number type's sizes\n");
392 size
= BT_CTF_BTR_STATUS_ERROR
;
395 size
= exp_dig
+ mant_dig
;
398 case BT_CTF_FIELD_TYPE_ID_ENUM
:
400 struct bt_ctf_field_type
*int_type
;
402 int_type
= bt_ctf_field_type_enumeration_get_container_type(
405 PERR("Failed to get enumeration type's container type\n");
406 size
= BT_CTF_BTR_STATUS_ERROR
;
410 size
= get_basic_field_type_size(btr
, int_type
);
415 size
= BT_CTF_BTR_STATUS_ERROR
;
424 void stitch_reset(struct bt_ctf_btr
*btr
)
426 btr
->stitch
.offset
= 0;
431 size_t stitch_at_from_addr(struct bt_ctf_btr
*btr
)
433 return btr
->stitch
.offset
+ btr
->stitch
.at
;
437 void stitch_append_from_buf(struct bt_ctf_btr
*btr
, size_t sz
)
439 size_t stitch_byte_at
;
448 BITS_TO_BYTES_FLOOR(stitch_at_from_addr(btr
));
449 buf_byte_at
= BITS_TO_BYTES_FLOOR(buf_at_from_addr(btr
));
450 nb_bytes
= BITS_TO_BYTES_CEIL(sz
);
451 assert(nb_bytes
> 0);
452 memcpy(&btr
->stitch
.buf
[stitch_byte_at
], &btr
->buf
.addr
[buf_byte_at
],
454 btr
->stitch
.at
+= sz
;
455 consume_bits(btr
, sz
);
459 void stitch_append_from_remaining_buf(struct bt_ctf_btr
*btr
)
461 stitch_append_from_buf(btr
, available_bits(btr
));
465 void stitch_set_from_remaining_buf(struct bt_ctf_btr
*btr
)
468 btr
->stitch
.offset
= IN_BYTE_OFFSET(buf_at_from_addr(btr
));
469 stitch_append_from_remaining_buf(btr
);
473 enum bt_ctf_btr_status
read_unsigned_bitfield(const uint8_t *buf
, size_t at
,
474 int64_t field_size
, enum bt_ctf_byte_order bo
, uint64_t *v
)
476 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
479 case BT_CTF_BYTE_ORDER_BIG_ENDIAN
:
480 case BT_CTF_BYTE_ORDER_NETWORK
:
481 bt_bitfield_read_be(buf
, uint8_t, at
, field_size
, v
);
483 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
484 bt_bitfield_read_le(buf
, uint8_t, at
, field_size
, v
);
487 status
= BT_CTF_BTR_STATUS_ERROR
;
494 enum bt_ctf_btr_status
read_signed_bitfield(const uint8_t *buf
, size_t at
,
495 int64_t field_size
, enum bt_ctf_byte_order bo
, int64_t *v
)
497 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
500 case BT_CTF_BYTE_ORDER_BIG_ENDIAN
:
501 case BT_CTF_BYTE_ORDER_NETWORK
:
502 bt_bitfield_read_be(buf
, uint8_t, at
, field_size
, v
);
504 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
505 bt_bitfield_read_le(buf
, uint8_t, at
, field_size
, v
);
508 status
= BT_CTF_BTR_STATUS_ERROR
;
514 typedef enum bt_ctf_btr_status (* read_basic_and_call_cb_t
)(struct bt_ctf_btr
*,
515 const uint8_t *, size_t);
518 enum bt_ctf_btr_status
validate_contiguous_bo(struct bt_ctf_btr
*btr
,
519 enum bt_ctf_byte_order next_bo
)
521 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
523 /* Always valid when at a byte boundary */
524 if (packet_at(btr
) % 8 == 0) {
528 /* Always valid if last byte order is unknown */
529 if (btr
->last_bo
== BT_CTF_BYTE_ORDER_UNKNOWN
) {
533 /* Always valid if next byte order is unknown */
534 if (next_bo
== BT_CTF_BYTE_ORDER_UNKNOWN
) {
538 /* Make sure last byte order is compatible with the next byte order */
539 switch (btr
->last_bo
) {
540 case BT_CTF_BYTE_ORDER_BIG_ENDIAN
:
541 case BT_CTF_BYTE_ORDER_NETWORK
:
542 if (next_bo
!= BT_CTF_BYTE_ORDER_BIG_ENDIAN
&&
543 next_bo
!= BT_CTF_BYTE_ORDER_NETWORK
) {
544 status
= BT_CTF_BTR_STATUS_ERROR
;
547 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
548 if (next_bo
!= BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
) {
549 status
= BT_CTF_BTR_STATUS_ERROR
;
553 status
= BT_CTF_BTR_STATUS_ERROR
;
561 enum bt_ctf_btr_status
read_basic_float_and_call_cb(struct bt_ctf_btr
*btr
,
562 const uint8_t *buf
, size_t at
)
567 enum bt_ctf_byte_order bo
;
568 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
570 field_size
= get_basic_field_type_size(btr
, btr
->cur_basic_field_type
);
571 bo
= bt_ctf_field_type_get_byte_order(btr
->cur_basic_field_type
);
574 switch (field_size
) {
583 ret
= bt_ctf_field_type_floating_point_get_mantissa_digits(
584 btr
->cur_basic_field_type
);
586 ret
= bt_ctf_field_type_floating_point_get_exponent_digits(
587 btr
->cur_basic_field_type
);
589 status
= read_unsigned_bitfield(buf
, at
, field_size
, bo
, &v
);
590 if (status
!= BT_CTF_BTR_STATUS_OK
) {
591 PERR("Failed to reader unsigned bitfield\n");
595 f32
.u
= (uint32_t) v
;
596 dblval
= (double) f32
.f
;
606 ret
= bt_ctf_field_type_floating_point_get_mantissa_digits(
607 btr
->cur_basic_field_type
);
609 ret
= bt_ctf_field_type_floating_point_get_exponent_digits(
610 btr
->cur_basic_field_type
);
612 status
= read_unsigned_bitfield(buf
, at
, field_size
, bo
,
614 if (status
!= BT_CTF_BTR_STATUS_OK
) {
615 PERR("Failed to reader unsigned bitfield\n");
623 /* Only 32-bit and 64-bit fields are supported currently */
624 status
= BT_CTF_BTR_STATUS_ERROR
;
628 if (btr
->user
.cbs
.types
.floating_point
) {
629 status
= btr
->user
.cbs
.types
.floating_point(dblval
,
630 btr
->cur_basic_field_type
, btr
->user
.data
);
638 enum bt_ctf_btr_status
read_basic_int_and_call(struct bt_ctf_btr
*btr
,
639 const uint8_t *buf
, size_t at
, struct bt_ctf_field_type
*int_type
,
640 struct bt_ctf_field_type
*orig_type
)
644 enum bt_ctf_byte_order bo
;
645 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
647 signd
= bt_ctf_field_type_integer_get_signed(int_type
);
648 field_size
= get_basic_field_type_size(btr
, int_type
);
649 if (field_size
< 1) {
650 PERR("Failed to get basic field type's size\n");
651 status
= BT_CTF_BTR_STATUS_ERROR
;
655 bo
= bt_ctf_field_type_get_byte_order(int_type
);
658 * Update current byte order now because we could be reading
659 * the integer value of an enumeration type, and thus we know
660 * here the actual supporting integer type's byte order.
667 status
= read_signed_bitfield(buf
, at
, field_size
, bo
, &v
);
668 if (status
!= BT_CTF_BTR_STATUS_OK
) {
669 PERR("Failed to reader signed bitfield\n");
673 if (btr
->user
.cbs
.types
.signed_int
) {
674 status
= btr
->user
.cbs
.types
.signed_int(v
,
675 btr
->cur_basic_field_type
, btr
->user
.data
);
680 status
= read_unsigned_bitfield(buf
, at
, field_size
, bo
, &v
);
681 if (status
!= BT_CTF_BTR_STATUS_OK
) {
682 PERR("Failed to reader unsigned bitfield\n");
686 if (btr
->user
.cbs
.types
.unsigned_int
) {
687 status
= btr
->user
.cbs
.types
.unsigned_int(v
,
688 btr
->cur_basic_field_type
, btr
->user
.data
);
697 enum bt_ctf_btr_status
read_basic_int_and_call_cb(struct bt_ctf_btr
*btr
,
698 const uint8_t *buf
, size_t at
)
700 return read_basic_int_and_call(btr
, buf
, at
, btr
->cur_basic_field_type
,
701 btr
->cur_basic_field_type
);
705 enum bt_ctf_btr_status
read_basic_enum_and_call_cb(struct bt_ctf_btr
*btr
,
706 const uint8_t *buf
, size_t at
)
708 struct bt_ctf_field_type
*int_field_type
;
709 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
711 int_field_type
= bt_ctf_field_type_enumeration_get_container_type(
712 btr
->cur_basic_field_type
);
713 if (!int_field_type
) {
714 PERR("Failed to get enumeration type's container type\n");
715 status
= BT_CTF_BTR_STATUS_ERROR
;
719 status
= read_basic_int_and_call(btr
, buf
, at
,
720 int_field_type
, btr
->cur_basic_field_type
);
723 BT_PUT(int_field_type
);
729 enum bt_ctf_btr_status
read_basic_type_and_call_continue(struct bt_ctf_btr
*btr
,
730 read_basic_and_call_cb_t read_basic_and_call_cb
)
735 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
737 if (!at_least_one_bit_left(btr
)) {
738 status
= BT_CTF_BTR_STATUS_EOF
;
742 field_size
= get_basic_field_type_size(btr
, btr
->cur_basic_field_type
);
743 if (field_size
< 1) {
744 PERR("Failed to get basic field type's size\n");
745 status
= BT_CTF_BTR_STATUS_ERROR
;
749 available
= available_bits(btr
);
750 needed_bits
= field_size
- btr
->stitch
.at
;
751 if (needed_bits
<= available
) {
752 /* We have all the bits; append to stitch, then decode */
753 stitch_append_from_buf(btr
, needed_bits
);
754 status
= read_basic_and_call_cb(btr
, btr
->stitch
.buf
,
756 if (status
!= BT_CTF_BTR_STATUS_OK
) {
757 PERR("Failed to read basic field\n");
761 if (stack_empty(btr
->stack
)) {
762 /* Root is a basic type */
763 btr
->state
= BTR_STATE_DONE
;
765 /* Go to next field */
766 stack_top(btr
->stack
)->index
++;
767 btr
->state
= BTR_STATE_NEXT_FIELD
;
768 btr
->last_bo
= btr
->cur_bo
;
773 /* We are here; it means we don't have enough data to decode this */
774 stitch_append_from_remaining_buf(btr
);
775 status
= BT_CTF_BTR_STATUS_EOF
;
782 enum bt_ctf_btr_status
read_basic_type_and_call_begin(struct bt_ctf_btr
*btr
,
783 read_basic_and_call_cb_t read_basic_and_call_cb
)
787 enum bt_ctf_byte_order bo
;
788 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
790 if (!at_least_one_bit_left(btr
)) {
791 status
= BT_CTF_BTR_STATUS_EOF
;
795 field_size
= get_basic_field_type_size(btr
, btr
->cur_basic_field_type
);
797 if (field_size
< 1) {
798 PERR("Failed to get basic field type's size\n");
799 status
= BT_CTF_BTR_STATUS_ERROR
;
803 bo
= bt_ctf_field_type_get_byte_order(btr
->cur_basic_field_type
);
804 status
= validate_contiguous_bo(btr
, bo
);
806 if (status
!= BT_CTF_BTR_STATUS_OK
) {
807 PERR("Invalid contiguous byte orders\n");
811 available
= available_bits(btr
);
813 if (field_size
<= available
) {
814 /* We have all the bits; decode and set now */
815 status
= read_basic_and_call_cb(btr
, btr
->buf
.addr
,
816 buf_at_from_addr(btr
));
818 if (status
!= BT_CTF_BTR_STATUS_OK
) {
819 PERR("Failed to read basic type\n");
823 consume_bits(btr
, field_size
);
825 if (stack_empty(btr
->stack
)) {
826 /* Root is a basic type */
827 btr
->state
= BTR_STATE_DONE
;
829 /* Go to next field */
830 stack_top(btr
->stack
)->index
++;
831 btr
->state
= BTR_STATE_NEXT_FIELD
;
832 btr
->last_bo
= btr
->cur_bo
;
838 /* We are here; it means we don't have enough data to decode this */
839 stitch_set_from_remaining_buf(btr
);
840 btr
->state
= BTR_STATE_READ_BASIC_CONTINUE
;
841 status
= BT_CTF_BTR_STATUS_EOF
;
848 enum bt_ctf_btr_status
read_basic_int_type_and_call_begin(
849 struct bt_ctf_btr
*btr
)
851 return read_basic_type_and_call_begin(btr
, read_basic_int_and_call_cb
);
855 enum bt_ctf_btr_status
read_basic_int_type_and_call_continue(
856 struct bt_ctf_btr
*btr
)
858 return read_basic_type_and_call_continue(btr
,
859 read_basic_int_and_call_cb
);
863 enum bt_ctf_btr_status
read_basic_float_type_and_call_begin(
864 struct bt_ctf_btr
*btr
)
866 return read_basic_type_and_call_begin(btr
,
867 read_basic_float_and_call_cb
);
871 enum bt_ctf_btr_status
read_basic_float_type_and_call_continue(
872 struct bt_ctf_btr
*btr
)
874 return read_basic_type_and_call_continue(btr
,
875 read_basic_float_and_call_cb
);
879 enum bt_ctf_btr_status
read_basic_enum_type_and_call_begin(
880 struct bt_ctf_btr
*btr
)
882 return read_basic_type_and_call_begin(btr
,
883 read_basic_enum_and_call_cb
);
887 enum bt_ctf_btr_status
read_basic_enum_type_and_call_continue(
888 struct bt_ctf_btr
*btr
)
890 return read_basic_type_and_call_continue(btr
,
891 read_basic_enum_and_call_cb
);
895 enum bt_ctf_btr_status
read_basic_string_type_and_call(
896 struct bt_ctf_btr
*btr
, bool begin
)
899 const uint8_t *result
;
900 size_t available_bytes
;
901 const uint8_t *first_chr
;
902 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
904 if (!at_least_one_bit_left(btr
)) {
905 status
= BT_CTF_BTR_STATUS_EOF
;
909 assert(buf_at_from_addr(btr
) % 8 == 0);
910 available_bytes
= BITS_TO_BYTES_FLOOR(available_bits(btr
));
911 buf_at_bytes
= BITS_TO_BYTES_FLOOR(buf_at_from_addr(btr
));
912 first_chr
= &btr
->buf
.addr
[buf_at_bytes
];
913 result
= memchr(first_chr
, '\0', available_bytes
);
915 if (begin
&& btr
->user
.cbs
.types
.string_begin
) {
916 status
= btr
->user
.cbs
.types
.string_begin(
917 btr
->cur_basic_field_type
, btr
->user
.data
);
919 if (status
!= BT_CTF_BTR_STATUS_OK
) {
920 PERR("string_begin() user callback function failed\n");
926 /* No null character yet */
927 if (btr
->user
.cbs
.types
.string
) {
928 status
= btr
->user
.cbs
.types
.string(
929 (const char *) first_chr
,
930 available_bytes
, btr
->cur_basic_field_type
,
932 if (status
!= BT_CTF_BTR_STATUS_OK
) {
933 PERR("string() user callback function failed\n");
938 consume_bits(btr
, BYTES_TO_BITS(available_bytes
));
939 btr
->state
= BTR_STATE_READ_BASIC_CONTINUE
;
940 status
= BT_CTF_BTR_STATUS_EOF
;
942 /* Found the null character */
943 size_t result_len
= (size_t) (result
- first_chr
);
945 if (btr
->user
.cbs
.types
.string
&& result_len
) {
946 status
= btr
->user
.cbs
.types
.string(
947 (const char *) first_chr
,
948 result_len
, btr
->cur_basic_field_type
,
950 if (status
!= BT_CTF_BTR_STATUS_OK
) {
951 PERR("string() user callback function failed\n");
956 if (btr
->user
.cbs
.types
.string_end
) {
957 status
= btr
->user
.cbs
.types
.string_end(
958 btr
->cur_basic_field_type
, btr
->user
.data
);
959 if (status
!= BT_CTF_BTR_STATUS_OK
) {
960 PERR("string_end() user callback function failed\n");
965 consume_bits(btr
, BYTES_TO_BITS(result_len
+ 1));
967 if (stack_empty(btr
->stack
)) {
968 /* Root is a basic type */
969 btr
->state
= BTR_STATE_DONE
;
971 /* Go to next field */
972 stack_top(btr
->stack
)->index
++;
973 btr
->state
= BTR_STATE_NEXT_FIELD
;
974 btr
->last_bo
= btr
->cur_bo
;
983 enum bt_ctf_btr_status
read_basic_begin_state(struct bt_ctf_btr
*btr
)
985 enum bt_ctf_btr_status status
;
987 assert(btr
->cur_basic_field_type
);
989 switch (bt_ctf_field_type_get_type_id(btr
->cur_basic_field_type
)) {
990 case BT_CTF_FIELD_TYPE_ID_INTEGER
:
991 status
= read_basic_int_type_and_call_begin(btr
);
993 case BT_CTF_FIELD_TYPE_ID_FLOAT
:
994 status
= read_basic_float_type_and_call_begin(btr
);
996 case BT_CTF_FIELD_TYPE_ID_ENUM
:
997 status
= read_basic_enum_type_and_call_begin(btr
);
999 case BT_CTF_FIELD_TYPE_ID_STRING
:
1000 status
= read_basic_string_type_and_call(btr
, true);
1010 enum bt_ctf_btr_status
read_basic_continue_state(struct bt_ctf_btr
*btr
)
1012 enum bt_ctf_btr_status status
;
1014 assert(btr
->cur_basic_field_type
);
1016 switch (bt_ctf_field_type_get_type_id(btr
->cur_basic_field_type
)) {
1017 case BT_CTF_FIELD_TYPE_ID_INTEGER
:
1018 status
= read_basic_int_type_and_call_continue(btr
);
1020 case BT_CTF_FIELD_TYPE_ID_FLOAT
:
1021 status
= read_basic_float_type_and_call_continue(btr
);
1023 case BT_CTF_FIELD_TYPE_ID_ENUM
:
1024 status
= read_basic_enum_type_and_call_continue(btr
);
1026 case BT_CTF_FIELD_TYPE_ID_STRING
:
1027 status
= read_basic_string_type_and_call(btr
, false);
1037 size_t bits_to_skip_to_align_to(struct bt_ctf_btr
*btr
, size_t align
)
1039 size_t aligned_packet_at
;
1041 aligned_packet_at
= ALIGN(packet_at(btr
), align
);
1043 return aligned_packet_at
- packet_at(btr
);
1047 enum bt_ctf_btr_status
align_type_state(struct bt_ctf_btr
*btr
,
1048 struct bt_ctf_field_type
*field_type
, enum btr_state next_state
)
1050 int field_alignment
;
1052 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
1054 /* Get field's alignment */
1055 field_alignment
= bt_ctf_field_type_get_alignment(field_type
);
1056 if (field_alignment
< 0) {
1057 PERR("Failed to get type alignment\n");
1058 status
= BT_CTF_BTR_STATUS_ERROR
;
1063 * 0 means "undefined" for variants; what we really want is 1
1066 if (field_alignment
== 0) {
1067 field_alignment
= 1;
1070 /* Compute how many bits we need to skip */
1071 skip_bits
= bits_to_skip_to_align_to(btr
, field_alignment
);
1073 /* Nothing to skip? aligned */
1074 if (skip_bits
== 0) {
1075 btr
->state
= next_state
;
1079 /* Make sure there's at least one bit left */
1080 if (!at_least_one_bit_left(btr
)) {
1081 status
= BT_CTF_BTR_STATUS_EOF
;
1085 /* Consume as many bits as possible in what's left */
1086 consume_bits(btr
, MIN(available_bits(btr
), skip_bits
));
1088 /* Are we done now? */
1089 skip_bits
= bits_to_skip_to_align_to(btr
, field_alignment
);
1091 if (skip_bits
== 0) {
1092 /* Yes: go to next state */
1093 btr
->state
= next_state
;
1096 /* No: need more data */
1097 status
= BT_CTF_BTR_STATUS_EOF
;
1105 bool is_compound_type(struct bt_ctf_field_type
*field_type
)
1107 enum bt_ctf_field_type_id id
= bt_ctf_field_type_get_type_id(field_type
);
1109 return id
== BT_CTF_FIELD_TYPE_ID_STRUCT
|| id
== BT_CTF_FIELD_TYPE_ID_ARRAY
||
1110 id
== BT_CTF_FIELD_TYPE_ID_SEQUENCE
|| id
== BT_CTF_FIELD_TYPE_ID_VARIANT
;
1114 enum bt_ctf_btr_status
next_field_state(struct bt_ctf_btr
*btr
)
1117 struct stack_entry
*top
;
1118 struct bt_ctf_field_type
*next_field_type
= NULL
;
1119 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
1121 if (stack_empty(btr
->stack
)) {
1125 top
= stack_top(btr
->stack
);
1127 /* Are we done with this base type? */
1128 while (top
->index
== top
->base_len
) {
1129 if (btr
->user
.cbs
.types
.compound_end
) {
1130 status
= btr
->user
.cbs
.types
.compound_end(
1131 top
->base_type
, btr
->user
.data
);
1132 if (status
!= BT_CTF_BTR_STATUS_OK
) {
1133 PERR("compound_end() user callback function failed\n");
1138 stack_pop(btr
->stack
);
1140 /* Are we done with the root type? */
1141 if (stack_empty(btr
->stack
)) {
1142 btr
->state
= BTR_STATE_DONE
;
1146 top
= stack_top(btr
->stack
);
1150 /* Get next field's type */
1151 switch (bt_ctf_field_type_get_type_id(top
->base_type
)) {
1152 case BT_CTF_FIELD_TYPE_ID_STRUCT
:
1153 ret
= bt_ctf_field_type_structure_get_field(
1154 top
->base_type
, NULL
, &next_field_type
,
1157 next_field_type
= NULL
;
1160 case BT_CTF_FIELD_TYPE_ID_ARRAY
:
1162 bt_ctf_field_type_array_get_element_type(
1165 case BT_CTF_FIELD_TYPE_ID_SEQUENCE
:
1167 bt_ctf_field_type_sequence_get_element_type(
1170 case BT_CTF_FIELD_TYPE_ID_VARIANT
:
1171 /* Variant types are dynamic: query the user, he should know! */
1173 btr
->user
.cbs
.query
.get_variant_type(
1174 top
->base_type
, btr
->user
.data
);
1180 if (!next_field_type
) {
1181 PERR("Failed to get next field's type\n");
1182 status
= BT_CTF_BTR_STATUS_ERROR
;
1186 if (is_compound_type(next_field_type
)) {
1187 if (btr
->user
.cbs
.types
.compound_begin
) {
1188 status
= btr
->user
.cbs
.types
.compound_begin(
1189 next_field_type
, btr
->user
.data
);
1190 if (status
!= BT_CTF_BTR_STATUS_OK
) {
1191 PERR("compound_begin() user callback function failed\n");
1196 ret
= stack_push_with_len(btr
, next_field_type
);
1198 PERR("Failed to push compound type onto the stack\n");
1199 status
= BT_CTF_BTR_STATUS_ERROR
;
1203 /* Next state: align a compound type */
1204 btr
->state
= BTR_STATE_ALIGN_COMPOUND
;
1206 /* Replace current basic field type */
1207 BT_MOVE(btr
->cur_basic_field_type
, next_field_type
);
1209 /* Next state: align a basic type */
1210 btr
->state
= BTR_STATE_ALIGN_BASIC
;
1214 BT_PUT(next_field_type
);
1220 enum bt_ctf_btr_status
handle_state(struct bt_ctf_btr
*btr
)
1222 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
1224 switch (btr
->state
) {
1225 case BTR_STATE_NEXT_FIELD
:
1226 status
= next_field_state(btr
);
1228 case BTR_STATE_ALIGN_BASIC
:
1229 status
= align_type_state(btr
, btr
->cur_basic_field_type
,
1230 BTR_STATE_READ_BASIC_BEGIN
);
1232 case BTR_STATE_ALIGN_COMPOUND
:
1233 status
= align_type_state(btr
, stack_top(btr
->stack
)->base_type
,
1234 BTR_STATE_NEXT_FIELD
);
1236 case BTR_STATE_READ_BASIC_BEGIN
:
1237 status
= read_basic_begin_state(btr
);
1239 case BTR_STATE_READ_BASIC_CONTINUE
:
1240 status
= read_basic_continue_state(btr
);
1242 case BTR_STATE_DONE
:
1249 struct bt_ctf_btr
*bt_ctf_btr_create(struct bt_ctf_btr_cbs cbs
, void *data
,
1252 struct bt_ctf_btr
*btr
;
1254 btr
= g_new0(struct bt_ctf_btr
, 1);
1256 PERR("Failed to allocate memory for binary type reader\n");
1260 btr
->stack
= stack_new();
1262 PERR("Failed to create stack\n");
1263 bt_ctf_btr_destroy(btr
);
1268 btr
->state
= BTR_STATE_NEXT_FIELD
;
1269 btr
->user
.cbs
= cbs
;
1270 btr
->user
.data
= data
;
1271 btr
->err_stream
= err_stream
;
1277 void bt_ctf_btr_destroy(struct bt_ctf_btr
*btr
)
1280 stack_destroy(btr
->stack
);
1283 BT_PUT(btr
->cur_basic_field_type
);
1288 void reset(struct bt_ctf_btr
*btr
)
1290 stack_clear(btr
->stack
);
1291 BT_PUT(btr
->cur_basic_field_type
);
1293 btr
->buf
.addr
= NULL
;
1294 btr
->last_bo
= BT_CTF_BYTE_ORDER_UNKNOWN
;
1297 size_t bt_ctf_btr_start(struct bt_ctf_btr
*btr
,
1298 struct bt_ctf_field_type
*type
, const uint8_t *buf
,
1299 size_t offset
, size_t packet_offset
, size_t sz
,
1300 enum bt_ctf_btr_status
*status
)
1305 assert(BYTES_TO_BITS(sz
) > offset
);
1307 btr
->buf
.addr
= buf
;
1308 btr
->buf
.offset
= offset
;
1310 btr
->buf
.packet_offset
= packet_offset
;
1311 btr
->buf
.buf_sz
= sz
;
1312 btr
->buf
.sz
= BYTES_TO_BITS(sz
) - offset
;
1313 *status
= BT_CTF_BTR_STATUS_OK
;
1316 if (is_compound_type(type
)) {
1317 /* Compound type: push on visit stack */
1320 if (btr
->user
.cbs
.types
.compound_begin
) {
1321 *status
= btr
->user
.cbs
.types
.compound_begin(
1322 type
, btr
->user
.data
);
1323 if (*status
!= BT_CTF_BTR_STATUS_OK
) {
1324 PERR("compound_begin() user callback function failed\n");
1329 stack_ret
= stack_push_with_len(btr
, type
);
1331 PERR("Failed to push initial compound type onto the stack\n");
1332 *status
= BT_CTF_BTR_STATUS_ERROR
;
1336 btr
->state
= BTR_STATE_ALIGN_COMPOUND
;
1338 /* Basic type: set as current basic type */
1339 btr
->cur_basic_field_type
= type
;
1340 bt_get(btr
->cur_basic_field_type
);
1341 btr
->state
= BTR_STATE_ALIGN_BASIC
;
1344 /* Run the machine! */
1346 *status
= handle_state(btr
);
1347 if (*status
!= BT_CTF_BTR_STATUS_OK
) {
1349 } else if (btr
->state
== BTR_STATE_DONE
) {
1354 /* Update packet offset for next time */
1355 btr
->buf
.packet_offset
+= btr
->buf
.at
;
1361 size_t bt_ctf_btr_continue(struct bt_ctf_btr
*btr
,
1362 const uint8_t *buf
, size_t sz
,
1363 enum bt_ctf_btr_status
*status
)
1368 btr
->buf
.addr
= buf
;
1369 btr
->buf
.offset
= 0;
1371 btr
->buf
.buf_sz
= sz
;
1372 btr
->buf
.sz
= BYTES_TO_BITS(sz
);
1373 *status
= BT_CTF_BTR_STATUS_OK
;
1375 /* Continue running the machine */
1377 *status
= handle_state(btr
);
1378 if (*status
!= BT_CTF_BTR_STATUS_OK
) {
1380 } else if (btr
->state
== BTR_STATE_DONE
) {
1385 /* Update packet offset for next time */
1386 btr
->buf
.packet_offset
+= btr
->buf
.at
;