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
32 #include <babeltrace/bitfield.h>
33 #include <babeltrace/ctf-ir/field-types.h>
34 #include <babeltrace/ref.h>
35 #include <babeltrace/align.h>
40 #define PRINT_ERR_STREAM btr->err_stream
41 #define PRINT_PREFIX "ctf-btr"
44 #define DIV8(_x) ((_x) >> 3)
45 #define BYTES_TO_BITS(_x) ((_x) * 8)
46 #define BITS_TO_BYTES_FLOOR(_x) DIV8(_x)
47 #define BITS_TO_BYTES_CEIL(_x) DIV8((_x) + 7)
48 #define IN_BYTE_OFFSET(_at) ((_at) & 7)
50 /* A visit stack entry */
53 * Current type of base field, one of:
62 struct bt_ctf_field_type
*base_type
;
64 /* Length of base field (always 1 for variant types) */
67 /* Lndex of next field to read */
73 /* Entries (struct stack_entry *) (top is last element) */
80 BTR_STATE_ALIGN_BASIC
,
81 BTR_STATE_ALIGN_COMPOUND
,
82 BTR_STATE_READ_BASIC_BEGIN
,
83 BTR_STATE_READ_BASIC_CONTINUE
,
87 /* Binary type reader */
95 /* Current basic field type */
96 struct bt_ctf_field_type
*cur_basic_field_type
;
102 * Last basic field type's byte order.
104 * This is used to detect errors since two contiguous basic
105 * types for which the common boundary is not the boundary of
106 * a byte cannot have different byte orders.
108 * This is set to BT_CTF_BYTE_ORDER_UNKNOWN on reset and when
109 * the last basic field type was a string type.
111 enum bt_ctf_byte_order last_bo
;
113 /* Current byte order (copied to last_bo after a successful read) */
114 enum bt_ctf_byte_order cur_bo
;
116 /* Stitch buffer infos */
121 /* Offset, within stitch buffer, of first bit */
124 /* Length (bits) of data in stitch buffer from offset */
128 /* User buffer infos */
133 /* Offset of data from address (bits) */
136 /* Current position from offset (bits) */
139 /* Offset of offset within whole packet (bits) */
140 size_t packet_offset
;
142 /* Data size in buffer (bits) */
145 /* Buffer size (bytes) */
151 /* Callback functions */
152 struct bt_ctf_btr_cbs cbs
;
160 void stack_entry_free_func(gpointer data
)
162 struct stack_entry
*entry
= data
;
164 BT_PUT(entry
->base_type
);
169 struct stack
*stack_new(void)
171 struct stack
*stack
= NULL
;
173 stack
= g_new0(struct stack
, 1);
178 stack
->entries
= g_ptr_array_new_with_free_func(stack_entry_free_func
);
179 if (!stack
->entries
) {
192 void stack_destroy(struct stack
*stack
)
198 g_ptr_array_free(stack
->entries
, TRUE
);
203 int64_t get_compound_field_type_length(struct bt_ctf_btr
*btr
,
204 struct bt_ctf_field_type
*field_type
)
208 switch (bt_ctf_field_type_get_type_id(field_type
)) {
209 case BT_CTF_FIELD_TYPE_ID_STRUCT
:
210 length
= (int64_t) bt_ctf_field_type_structure_get_field_count(
213 case BT_CTF_FIELD_TYPE_ID_VARIANT
:
214 /* Variant field types always "contain" a single type */
217 case BT_CTF_FIELD_TYPE_ID_ARRAY
:
218 length
= bt_ctf_field_type_array_get_length(field_type
);
220 case BT_CTF_FIELD_TYPE_ID_SEQUENCE
:
221 length
= btr
->user
.cbs
.query
.get_sequence_length(field_type
,
225 PERR("Cannot get length of field type with type ID %d\n",
226 bt_ctf_field_type_get_type_id(field_type
));
227 length
= BT_CTF_BTR_STATUS_ERROR
;
234 int stack_push(struct stack
*stack
, struct bt_ctf_field_type
*base_type
,
238 struct stack_entry
*entry
;
243 entry
= g_new0(struct stack_entry
, 1);
245 ret
= BT_CTF_BTR_STATUS_ERROR
;
249 entry
->base_type
= base_type
;
250 bt_get(entry
->base_type
);
251 entry
->base_len
= base_len
;
252 g_ptr_array_add(stack
->entries
, entry
);
259 int stack_push_with_len(struct bt_ctf_btr
*btr
,
260 struct bt_ctf_field_type
*base_type
)
263 int64_t base_len
= get_compound_field_type_length(btr
, base_type
);
266 PERR("Failed to get compound field type's length\n");
267 ret
= BT_CTF_BTR_STATUS_ERROR
;
271 ret
= stack_push(btr
->stack
, base_type
, (size_t) base_len
);
278 unsigned int stack_size(struct stack
*stack
)
282 return stack
->entries
->len
;
286 void stack_pop(struct stack
*stack
)
289 assert(stack_size(stack
));
290 g_ptr_array_remove_index(stack
->entries
, stack
->entries
->len
- 1);
294 bool stack_empty(struct stack
*stack
)
296 return stack_size(stack
) == 0;
300 void stack_clear(struct stack
*stack
)
304 if (!stack_empty(stack
)) {
305 g_ptr_array_remove_range(stack
->entries
, 0, stack_size(stack
));
308 assert(stack_empty(stack
));
312 struct stack_entry
*stack_top(struct stack
*stack
)
315 assert(stack_size(stack
));
317 return g_ptr_array_index(stack
->entries
, stack
->entries
->len
- 1);
321 size_t available_bits(struct bt_ctf_btr
*btr
)
323 return btr
->buf
.sz
- btr
->buf
.at
;
327 void consume_bits(struct bt_ctf_btr
*btr
, size_t incr
)
333 bool has_enough_bits(struct bt_ctf_btr
*btr
, size_t sz
)
335 return available_bits(btr
) >= sz
;
339 bool at_least_one_bit_left(struct bt_ctf_btr
*btr
)
341 return has_enough_bits(btr
, 1);
345 size_t packet_at(struct bt_ctf_btr
*btr
)
347 return btr
->buf
.packet_offset
+ btr
->buf
.at
;
351 size_t buf_at_from_addr(struct bt_ctf_btr
*btr
)
356 * ====== offset ===== (17)
358 * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
360 * addr (0) ==== at ==== (12)
364 * =============================== (29)
366 return btr
->buf
.offset
+ btr
->buf
.at
;
370 int get_basic_field_type_size(struct bt_ctf_btr
*btr
,
371 struct bt_ctf_field_type
*field_type
)
375 switch (bt_ctf_field_type_get_type_id(field_type
)) {
376 case BT_CTF_FIELD_TYPE_ID_INTEGER
:
377 size
= bt_ctf_field_type_integer_get_size(field_type
);
379 case BT_CTF_FIELD_TYPE_ID_FLOAT
:
381 int exp_dig
, mant_dig
;
384 bt_ctf_field_type_floating_point_get_exponent_digits(
387 bt_ctf_field_type_floating_point_get_mantissa_digits(
389 if (exp_dig
< 0 || mant_dig
< 0) {
390 PERR("Failed to get floating point number type's sizes\n");
391 size
= BT_CTF_BTR_STATUS_ERROR
;
394 size
= exp_dig
+ mant_dig
;
397 case BT_CTF_FIELD_TYPE_ID_ENUM
:
399 struct bt_ctf_field_type
*int_type
;
401 int_type
= bt_ctf_field_type_enumeration_get_container_type(
404 PERR("Failed to get enumeration type's container type\n");
405 size
= BT_CTF_BTR_STATUS_ERROR
;
409 size
= get_basic_field_type_size(btr
, int_type
);
414 size
= BT_CTF_BTR_STATUS_ERROR
;
423 void stitch_reset(struct bt_ctf_btr
*btr
)
425 btr
->stitch
.offset
= 0;
430 size_t stitch_at_from_addr(struct bt_ctf_btr
*btr
)
432 return btr
->stitch
.offset
+ btr
->stitch
.at
;
436 void stitch_append_from_buf(struct bt_ctf_btr
*btr
, size_t sz
)
438 size_t stitch_byte_at
;
447 BITS_TO_BYTES_FLOOR(stitch_at_from_addr(btr
));
448 buf_byte_at
= BITS_TO_BYTES_FLOOR(buf_at_from_addr(btr
));
449 nb_bytes
= BITS_TO_BYTES_CEIL(sz
);
450 assert(nb_bytes
> 0);
451 memcpy(&btr
->stitch
.buf
[stitch_byte_at
], &btr
->buf
.addr
[buf_byte_at
],
453 btr
->stitch
.at
+= sz
;
454 consume_bits(btr
, sz
);
458 void stitch_append_from_remaining_buf(struct bt_ctf_btr
*btr
)
460 stitch_append_from_buf(btr
, available_bits(btr
));
464 void stitch_set_from_remaining_buf(struct bt_ctf_btr
*btr
)
467 btr
->stitch
.offset
= IN_BYTE_OFFSET(buf_at_from_addr(btr
));
468 stitch_append_from_remaining_buf(btr
);
472 enum bt_ctf_btr_status
read_unsigned_bitfield(const uint8_t *buf
, size_t at
,
473 int64_t field_size
, enum bt_ctf_byte_order bo
, uint64_t *v
)
475 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
478 case BT_CTF_BYTE_ORDER_BIG_ENDIAN
:
479 case BT_CTF_BYTE_ORDER_NETWORK
:
480 bt_bitfield_read_be(buf
, uint8_t, at
, field_size
, v
);
482 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
483 bt_bitfield_read_le(buf
, uint8_t, at
, field_size
, v
);
486 status
= BT_CTF_BTR_STATUS_ERROR
;
493 enum bt_ctf_btr_status
read_signed_bitfield(const uint8_t *buf
, size_t at
,
494 int64_t field_size
, enum bt_ctf_byte_order bo
, int64_t *v
)
496 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
499 case BT_CTF_BYTE_ORDER_BIG_ENDIAN
:
500 case BT_CTF_BYTE_ORDER_NETWORK
:
501 bt_bitfield_read_be(buf
, uint8_t, at
, field_size
, v
);
503 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
504 bt_bitfield_read_le(buf
, uint8_t, at
, field_size
, v
);
507 status
= BT_CTF_BTR_STATUS_ERROR
;
513 typedef enum bt_ctf_btr_status (* read_basic_and_call_cb_t
)(struct bt_ctf_btr
*,
514 const uint8_t *, size_t);
517 enum bt_ctf_btr_status
validate_contiguous_bo(struct bt_ctf_btr
*btr
,
518 enum bt_ctf_byte_order next_bo
)
520 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
522 /* Always valid when at a byte boundary */
523 if (packet_at(btr
) % 8 == 0) {
527 /* Always valid if last byte order is unknown */
528 if (btr
->last_bo
== BT_CTF_BYTE_ORDER_UNKNOWN
) {
532 /* Always valid if next byte order is unknown */
533 if (next_bo
== BT_CTF_BYTE_ORDER_UNKNOWN
) {
537 /* Make sure last byte order is compatible with the next byte order */
538 switch (btr
->last_bo
) {
539 case BT_CTF_BYTE_ORDER_BIG_ENDIAN
:
540 case BT_CTF_BYTE_ORDER_NETWORK
:
541 if (next_bo
!= BT_CTF_BYTE_ORDER_BIG_ENDIAN
&&
542 next_bo
!= BT_CTF_BYTE_ORDER_NETWORK
) {
543 status
= BT_CTF_BTR_STATUS_ERROR
;
546 case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
:
547 if (next_bo
!= BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
) {
548 status
= BT_CTF_BTR_STATUS_ERROR
;
552 status
= BT_CTF_BTR_STATUS_ERROR
;
560 enum bt_ctf_btr_status
read_basic_float_and_call_cb(struct bt_ctf_btr
*btr
,
561 const uint8_t *buf
, size_t at
)
566 enum bt_ctf_byte_order bo
;
567 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
569 field_size
= get_basic_field_type_size(btr
, btr
->cur_basic_field_type
);
570 bo
= bt_ctf_field_type_get_byte_order(btr
->cur_basic_field_type
);
573 switch (field_size
) {
582 ret
= bt_ctf_field_type_floating_point_get_mantissa_digits(
583 btr
->cur_basic_field_type
);
585 ret
= bt_ctf_field_type_floating_point_get_exponent_digits(
586 btr
->cur_basic_field_type
);
588 status
= read_unsigned_bitfield(buf
, at
, field_size
, bo
, &v
);
589 if (status
!= BT_CTF_BTR_STATUS_OK
) {
590 PERR("Failed to reader unsigned bitfield\n");
594 f32
.u
= (uint32_t) v
;
595 dblval
= (double) f32
.f
;
605 ret
= bt_ctf_field_type_floating_point_get_mantissa_digits(
606 btr
->cur_basic_field_type
);
608 ret
= bt_ctf_field_type_floating_point_get_exponent_digits(
609 btr
->cur_basic_field_type
);
611 status
= read_unsigned_bitfield(buf
, at
, field_size
, bo
,
613 if (status
!= BT_CTF_BTR_STATUS_OK
) {
614 PERR("Failed to reader unsigned bitfield\n");
622 /* Only 32-bit and 64-bit fields are supported currently */
623 status
= BT_CTF_BTR_STATUS_ERROR
;
627 if (btr
->user
.cbs
.types
.floating_point
) {
628 status
= btr
->user
.cbs
.types
.floating_point(dblval
,
629 btr
->cur_basic_field_type
, btr
->user
.data
);
637 enum bt_ctf_btr_status
read_basic_int_and_call(struct bt_ctf_btr
*btr
,
638 const uint8_t *buf
, size_t at
, struct bt_ctf_field_type
*int_type
,
639 struct bt_ctf_field_type
*orig_type
)
643 enum bt_ctf_byte_order bo
;
644 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
646 signd
= bt_ctf_field_type_integer_get_signed(int_type
);
647 field_size
= get_basic_field_type_size(btr
, int_type
);
648 if (field_size
< 1) {
649 PERR("Failed to get basic field type's size\n");
650 status
= BT_CTF_BTR_STATUS_ERROR
;
654 bo
= bt_ctf_field_type_get_byte_order(int_type
);
657 * Update current byte order now because we could be reading
658 * the integer value of an enumeration type, and thus we know
659 * here the actual supporting integer type's byte order.
666 status
= read_signed_bitfield(buf
, at
, field_size
, bo
, &v
);
667 if (status
!= BT_CTF_BTR_STATUS_OK
) {
668 PERR("Failed to reader signed bitfield\n");
672 if (btr
->user
.cbs
.types
.signed_int
) {
673 status
= btr
->user
.cbs
.types
.signed_int(v
,
674 btr
->cur_basic_field_type
, btr
->user
.data
);
679 status
= read_unsigned_bitfield(buf
, at
, field_size
, bo
, &v
);
680 if (status
!= BT_CTF_BTR_STATUS_OK
) {
681 PERR("Failed to reader unsigned bitfield\n");
685 if (btr
->user
.cbs
.types
.unsigned_int
) {
686 status
= btr
->user
.cbs
.types
.unsigned_int(v
,
687 btr
->cur_basic_field_type
, btr
->user
.data
);
696 enum bt_ctf_btr_status
read_basic_int_and_call_cb(struct bt_ctf_btr
*btr
,
697 const uint8_t *buf
, size_t at
)
699 return read_basic_int_and_call(btr
, buf
, at
, btr
->cur_basic_field_type
,
700 btr
->cur_basic_field_type
);
704 enum bt_ctf_btr_status
read_basic_enum_and_call_cb(struct bt_ctf_btr
*btr
,
705 const uint8_t *buf
, size_t at
)
707 struct bt_ctf_field_type
*int_field_type
;
708 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
710 int_field_type
= bt_ctf_field_type_enumeration_get_container_type(
711 btr
->cur_basic_field_type
);
712 if (!int_field_type
) {
713 PERR("Failed to get enumeration type's container type\n");
714 status
= BT_CTF_BTR_STATUS_ERROR
;
718 status
= read_basic_int_and_call(btr
, buf
, at
,
719 int_field_type
, btr
->cur_basic_field_type
);
722 BT_PUT(int_field_type
);
728 enum bt_ctf_btr_status
read_basic_type_and_call_continue(struct bt_ctf_btr
*btr
,
729 read_basic_and_call_cb_t read_basic_and_call_cb
)
734 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
736 if (!at_least_one_bit_left(btr
)) {
737 status
= BT_CTF_BTR_STATUS_EOF
;
741 field_size
= get_basic_field_type_size(btr
, btr
->cur_basic_field_type
);
742 if (field_size
< 1) {
743 PERR("Failed to get basic field type's size\n");
744 status
= BT_CTF_BTR_STATUS_ERROR
;
748 available
= available_bits(btr
);
749 needed_bits
= field_size
- btr
->stitch
.at
;
750 if (needed_bits
<= available
) {
751 /* We have all the bits; append to stitch, then decode */
752 stitch_append_from_buf(btr
, needed_bits
);
753 status
= read_basic_and_call_cb(btr
, btr
->stitch
.buf
,
755 if (status
!= BT_CTF_BTR_STATUS_OK
) {
756 PERR("Failed to read basic field\n");
760 if (stack_empty(btr
->stack
)) {
761 /* Root is a basic type */
762 btr
->state
= BTR_STATE_DONE
;
764 /* Go to next field */
765 stack_top(btr
->stack
)->index
++;
766 btr
->state
= BTR_STATE_NEXT_FIELD
;
767 btr
->last_bo
= btr
->cur_bo
;
772 /* We are here; it means we don't have enough data to decode this */
773 stitch_append_from_remaining_buf(btr
);
774 status
= BT_CTF_BTR_STATUS_EOF
;
781 enum bt_ctf_btr_status
read_basic_type_and_call_begin(struct bt_ctf_btr
*btr
,
782 read_basic_and_call_cb_t read_basic_and_call_cb
)
786 enum bt_ctf_byte_order bo
;
787 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
789 if (!at_least_one_bit_left(btr
)) {
790 status
= BT_CTF_BTR_STATUS_EOF
;
794 field_size
= get_basic_field_type_size(btr
, btr
->cur_basic_field_type
);
796 if (field_size
< 1) {
797 PERR("Failed to get basic field type's size\n");
798 status
= BT_CTF_BTR_STATUS_ERROR
;
802 bo
= bt_ctf_field_type_get_byte_order(btr
->cur_basic_field_type
);
803 status
= validate_contiguous_bo(btr
, bo
);
805 if (status
!= BT_CTF_BTR_STATUS_OK
) {
806 PERR("Invalid contiguous byte orders\n");
810 available
= available_bits(btr
);
812 if (field_size
<= available
) {
813 /* We have all the bits; decode and set now */
814 status
= read_basic_and_call_cb(btr
, btr
->buf
.addr
,
815 buf_at_from_addr(btr
));
817 if (status
!= BT_CTF_BTR_STATUS_OK
) {
818 PERR("Failed to read basic type\n");
822 consume_bits(btr
, field_size
);
824 if (stack_empty(btr
->stack
)) {
825 /* Root is a basic type */
826 btr
->state
= BTR_STATE_DONE
;
828 /* Go to next field */
829 stack_top(btr
->stack
)->index
++;
830 btr
->state
= BTR_STATE_NEXT_FIELD
;
831 btr
->last_bo
= btr
->cur_bo
;
837 /* We are here; it means we don't have enough data to decode this */
838 stitch_set_from_remaining_buf(btr
);
839 btr
->state
= BTR_STATE_READ_BASIC_CONTINUE
;
840 status
= BT_CTF_BTR_STATUS_EOF
;
847 enum bt_ctf_btr_status
read_basic_int_type_and_call_begin(
848 struct bt_ctf_btr
*btr
)
850 return read_basic_type_and_call_begin(btr
, read_basic_int_and_call_cb
);
854 enum bt_ctf_btr_status
read_basic_int_type_and_call_continue(
855 struct bt_ctf_btr
*btr
)
857 return read_basic_type_and_call_continue(btr
,
858 read_basic_int_and_call_cb
);
862 enum bt_ctf_btr_status
read_basic_float_type_and_call_begin(
863 struct bt_ctf_btr
*btr
)
865 return read_basic_type_and_call_begin(btr
,
866 read_basic_float_and_call_cb
);
870 enum bt_ctf_btr_status
read_basic_float_type_and_call_continue(
871 struct bt_ctf_btr
*btr
)
873 return read_basic_type_and_call_continue(btr
,
874 read_basic_float_and_call_cb
);
878 enum bt_ctf_btr_status
read_basic_enum_type_and_call_begin(
879 struct bt_ctf_btr
*btr
)
881 return read_basic_type_and_call_begin(btr
,
882 read_basic_enum_and_call_cb
);
886 enum bt_ctf_btr_status
read_basic_enum_type_and_call_continue(
887 struct bt_ctf_btr
*btr
)
889 return read_basic_type_and_call_continue(btr
,
890 read_basic_enum_and_call_cb
);
894 enum bt_ctf_btr_status
read_basic_string_type_and_call(
895 struct bt_ctf_btr
*btr
, bool begin
)
898 const uint8_t *result
;
899 size_t available_bytes
;
900 const uint8_t *first_chr
;
901 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
903 if (!at_least_one_bit_left(btr
)) {
904 status
= BT_CTF_BTR_STATUS_EOF
;
908 assert(buf_at_from_addr(btr
) % 8 == 0);
909 available_bytes
= BITS_TO_BYTES_FLOOR(available_bits(btr
));
910 buf_at_bytes
= BITS_TO_BYTES_FLOOR(buf_at_from_addr(btr
));
911 first_chr
= &btr
->buf
.addr
[buf_at_bytes
];
912 result
= memchr(first_chr
, '\0', available_bytes
);
914 if (begin
&& btr
->user
.cbs
.types
.string_begin
) {
915 status
= btr
->user
.cbs
.types
.string_begin(
916 btr
->cur_basic_field_type
, btr
->user
.data
);
918 if (status
!= BT_CTF_BTR_STATUS_OK
) {
919 PERR("string_begin() user callback function failed\n");
925 /* No null character yet */
926 if (btr
->user
.cbs
.types
.string
) {
927 status
= btr
->user
.cbs
.types
.string(
928 (const char *) first_chr
,
929 available_bytes
, btr
->cur_basic_field_type
,
931 if (status
!= BT_CTF_BTR_STATUS_OK
) {
932 PERR("string() user callback function failed\n");
937 consume_bits(btr
, BYTES_TO_BITS(available_bytes
));
938 btr
->state
= BTR_STATE_READ_BASIC_CONTINUE
;
939 status
= BT_CTF_BTR_STATUS_EOF
;
941 /* Found the null character */
942 size_t result_len
= (size_t) (result
- first_chr
);
944 if (btr
->user
.cbs
.types
.string
&& result_len
) {
945 status
= btr
->user
.cbs
.types
.string(
946 (const char *) first_chr
,
947 result_len
, btr
->cur_basic_field_type
,
949 if (status
!= BT_CTF_BTR_STATUS_OK
) {
950 PERR("string() user callback function failed\n");
955 if (btr
->user
.cbs
.types
.string_end
) {
956 status
= btr
->user
.cbs
.types
.string_end(
957 btr
->cur_basic_field_type
, btr
->user
.data
);
958 if (status
!= BT_CTF_BTR_STATUS_OK
) {
959 PERR("string_end() user callback function failed\n");
964 consume_bits(btr
, BYTES_TO_BITS(result_len
+ 1));
966 if (stack_empty(btr
->stack
)) {
967 /* Root is a basic type */
968 btr
->state
= BTR_STATE_DONE
;
970 /* Go to next field */
971 stack_top(btr
->stack
)->index
++;
972 btr
->state
= BTR_STATE_NEXT_FIELD
;
973 btr
->last_bo
= btr
->cur_bo
;
982 enum bt_ctf_btr_status
read_basic_begin_state(struct bt_ctf_btr
*btr
)
984 enum bt_ctf_btr_status status
;
986 assert(btr
->cur_basic_field_type
);
988 switch (bt_ctf_field_type_get_type_id(btr
->cur_basic_field_type
)) {
989 case BT_CTF_FIELD_TYPE_ID_INTEGER
:
990 status
= read_basic_int_type_and_call_begin(btr
);
992 case BT_CTF_FIELD_TYPE_ID_FLOAT
:
993 status
= read_basic_float_type_and_call_begin(btr
);
995 case BT_CTF_FIELD_TYPE_ID_ENUM
:
996 status
= read_basic_enum_type_and_call_begin(btr
);
998 case BT_CTF_FIELD_TYPE_ID_STRING
:
999 status
= read_basic_string_type_and_call(btr
, true);
1009 enum bt_ctf_btr_status
read_basic_continue_state(struct bt_ctf_btr
*btr
)
1011 enum bt_ctf_btr_status status
;
1013 assert(btr
->cur_basic_field_type
);
1015 switch (bt_ctf_field_type_get_type_id(btr
->cur_basic_field_type
)) {
1016 case BT_CTF_FIELD_TYPE_ID_INTEGER
:
1017 status
= read_basic_int_type_and_call_continue(btr
);
1019 case BT_CTF_FIELD_TYPE_ID_FLOAT
:
1020 status
= read_basic_float_type_and_call_continue(btr
);
1022 case BT_CTF_FIELD_TYPE_ID_ENUM
:
1023 status
= read_basic_enum_type_and_call_continue(btr
);
1025 case BT_CTF_FIELD_TYPE_ID_STRING
:
1026 status
= read_basic_string_type_and_call(btr
, false);
1036 size_t bits_to_skip_to_align_to(struct bt_ctf_btr
*btr
, size_t align
)
1038 size_t aligned_packet_at
;
1040 aligned_packet_at
= ALIGN(packet_at(btr
), align
);
1042 return aligned_packet_at
- packet_at(btr
);
1046 enum bt_ctf_btr_status
align_type_state(struct bt_ctf_btr
*btr
,
1047 struct bt_ctf_field_type
*field_type
, enum btr_state next_state
)
1049 int field_alignment
;
1051 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
1053 /* Get field's alignment */
1054 field_alignment
= bt_ctf_field_type_get_alignment(field_type
);
1055 if (field_alignment
< 0) {
1056 PERR("Failed to get type alignment\n");
1057 status
= BT_CTF_BTR_STATUS_ERROR
;
1062 * 0 means "undefined" for variants; what we really want is 1
1065 if (field_alignment
== 0) {
1066 field_alignment
= 1;
1069 /* Compute how many bits we need to skip */
1070 skip_bits
= bits_to_skip_to_align_to(btr
, field_alignment
);
1072 /* Nothing to skip? aligned */
1073 if (skip_bits
== 0) {
1074 btr
->state
= next_state
;
1078 /* Make sure there's at least one bit left */
1079 if (!at_least_one_bit_left(btr
)) {
1080 status
= BT_CTF_BTR_STATUS_EOF
;
1084 /* Consume as many bits as possible in what's left */
1085 consume_bits(btr
, MIN(available_bits(btr
), skip_bits
));
1087 /* Are we done now? */
1088 skip_bits
= bits_to_skip_to_align_to(btr
, field_alignment
);
1090 if (skip_bits
== 0) {
1091 /* Yes: go to next state */
1092 btr
->state
= next_state
;
1095 /* No: need more data */
1096 status
= BT_CTF_BTR_STATUS_EOF
;
1104 bool is_compound_type(struct bt_ctf_field_type
*field_type
)
1106 enum bt_ctf_field_type_id id
= bt_ctf_field_type_get_type_id(field_type
);
1108 return id
== BT_CTF_FIELD_TYPE_ID_STRUCT
|| id
== BT_CTF_FIELD_TYPE_ID_ARRAY
||
1109 id
== BT_CTF_FIELD_TYPE_ID_SEQUENCE
|| id
== BT_CTF_FIELD_TYPE_ID_VARIANT
;
1113 enum bt_ctf_btr_status
next_field_state(struct bt_ctf_btr
*btr
)
1116 struct stack_entry
*top
;
1117 struct bt_ctf_field_type
*next_field_type
= NULL
;
1118 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
1120 if (stack_empty(btr
->stack
)) {
1124 top
= stack_top(btr
->stack
);
1126 /* Are we done with this base type? */
1127 while (top
->index
== top
->base_len
) {
1128 if (btr
->user
.cbs
.types
.compound_end
) {
1129 status
= btr
->user
.cbs
.types
.compound_end(
1130 top
->base_type
, btr
->user
.data
);
1131 if (status
!= BT_CTF_BTR_STATUS_OK
) {
1132 PERR("compound_end() user callback function failed\n");
1137 stack_pop(btr
->stack
);
1139 /* Are we done with the root type? */
1140 if (stack_empty(btr
->stack
)) {
1141 btr
->state
= BTR_STATE_DONE
;
1145 top
= stack_top(btr
->stack
);
1149 /* Get next field's type */
1150 switch (bt_ctf_field_type_get_type_id(top
->base_type
)) {
1151 case BT_CTF_FIELD_TYPE_ID_STRUCT
:
1152 ret
= bt_ctf_field_type_structure_get_field(
1153 top
->base_type
, NULL
, &next_field_type
,
1156 next_field_type
= NULL
;
1159 case BT_CTF_FIELD_TYPE_ID_ARRAY
:
1161 bt_ctf_field_type_array_get_element_type(
1164 case BT_CTF_FIELD_TYPE_ID_SEQUENCE
:
1166 bt_ctf_field_type_sequence_get_element_type(
1169 case BT_CTF_FIELD_TYPE_ID_VARIANT
:
1170 /* Variant types are dynamic: query the user, he should know! */
1172 btr
->user
.cbs
.query
.get_variant_type(
1173 top
->base_type
, btr
->user
.data
);
1179 if (!next_field_type
) {
1180 PERR("Failed to get next field's type\n");
1181 status
= BT_CTF_BTR_STATUS_ERROR
;
1185 if (is_compound_type(next_field_type
)) {
1186 if (btr
->user
.cbs
.types
.compound_begin
) {
1187 status
= btr
->user
.cbs
.types
.compound_begin(
1188 next_field_type
, btr
->user
.data
);
1189 if (status
!= BT_CTF_BTR_STATUS_OK
) {
1190 PERR("compound_begin() user callback function failed\n");
1195 ret
= stack_push_with_len(btr
, next_field_type
);
1197 PERR("Failed to push compound type onto the stack\n");
1198 status
= BT_CTF_BTR_STATUS_ERROR
;
1202 /* Next state: align a compound type */
1203 btr
->state
= BTR_STATE_ALIGN_COMPOUND
;
1205 /* Replace current basic field type */
1206 BT_MOVE(btr
->cur_basic_field_type
, next_field_type
);
1208 /* Next state: align a basic type */
1209 btr
->state
= BTR_STATE_ALIGN_BASIC
;
1213 BT_PUT(next_field_type
);
1219 enum bt_ctf_btr_status
handle_state(struct bt_ctf_btr
*btr
)
1221 enum bt_ctf_btr_status status
= BT_CTF_BTR_STATUS_OK
;
1223 switch (btr
->state
) {
1224 case BTR_STATE_NEXT_FIELD
:
1225 status
= next_field_state(btr
);
1227 case BTR_STATE_ALIGN_BASIC
:
1228 status
= align_type_state(btr
, btr
->cur_basic_field_type
,
1229 BTR_STATE_READ_BASIC_BEGIN
);
1231 case BTR_STATE_ALIGN_COMPOUND
:
1232 status
= align_type_state(btr
, stack_top(btr
->stack
)->base_type
,
1233 BTR_STATE_NEXT_FIELD
);
1235 case BTR_STATE_READ_BASIC_BEGIN
:
1236 status
= read_basic_begin_state(btr
);
1238 case BTR_STATE_READ_BASIC_CONTINUE
:
1239 status
= read_basic_continue_state(btr
);
1241 case BTR_STATE_DONE
:
1248 struct bt_ctf_btr
*bt_ctf_btr_create(struct bt_ctf_btr_cbs cbs
, void *data
,
1251 struct bt_ctf_btr
*btr
;
1253 btr
= g_new0(struct bt_ctf_btr
, 1);
1255 PERR("Failed to allocate memory for binary type reader\n");
1259 btr
->stack
= stack_new();
1261 PERR("Failed to create stack\n");
1262 bt_ctf_btr_destroy(btr
);
1267 btr
->state
= BTR_STATE_NEXT_FIELD
;
1268 btr
->user
.cbs
= cbs
;
1269 btr
->user
.data
= data
;
1270 btr
->err_stream
= err_stream
;
1276 void bt_ctf_btr_destroy(struct bt_ctf_btr
*btr
)
1279 stack_destroy(btr
->stack
);
1282 BT_PUT(btr
->cur_basic_field_type
);
1287 void reset(struct bt_ctf_btr
*btr
)
1289 stack_clear(btr
->stack
);
1290 BT_PUT(btr
->cur_basic_field_type
);
1292 btr
->buf
.addr
= NULL
;
1293 btr
->last_bo
= BT_CTF_BYTE_ORDER_UNKNOWN
;
1296 size_t bt_ctf_btr_start(struct bt_ctf_btr
*btr
,
1297 struct bt_ctf_field_type
*type
, const uint8_t *buf
,
1298 size_t offset
, size_t packet_offset
, size_t sz
,
1299 enum bt_ctf_btr_status
*status
)
1304 assert(BYTES_TO_BITS(sz
) > offset
);
1306 btr
->buf
.addr
= buf
;
1307 btr
->buf
.offset
= offset
;
1309 btr
->buf
.packet_offset
= packet_offset
;
1310 btr
->buf
.buf_sz
= sz
;
1311 btr
->buf
.sz
= BYTES_TO_BITS(sz
) - offset
;
1312 *status
= BT_CTF_BTR_STATUS_OK
;
1315 if (is_compound_type(type
)) {
1316 /* Compound type: push on visit stack */
1319 if (btr
->user
.cbs
.types
.compound_begin
) {
1320 *status
= btr
->user
.cbs
.types
.compound_begin(
1321 type
, btr
->user
.data
);
1322 if (*status
!= BT_CTF_BTR_STATUS_OK
) {
1323 PERR("compound_begin() user callback function failed\n");
1328 stack_ret
= stack_push_with_len(btr
, type
);
1330 PERR("Failed to push initial compound type onto the stack\n");
1331 *status
= BT_CTF_BTR_STATUS_ERROR
;
1335 btr
->state
= BTR_STATE_ALIGN_COMPOUND
;
1337 /* Basic type: set as current basic type */
1338 btr
->cur_basic_field_type
= type
;
1339 bt_get(btr
->cur_basic_field_type
);
1340 btr
->state
= BTR_STATE_ALIGN_BASIC
;
1343 /* Run the machine! */
1345 *status
= handle_state(btr
);
1346 if (*status
!= BT_CTF_BTR_STATUS_OK
) {
1348 } else if (btr
->state
== BTR_STATE_DONE
) {
1353 /* Update packet offset for next time */
1354 btr
->buf
.packet_offset
+= btr
->buf
.at
;
1360 size_t bt_ctf_btr_continue(struct bt_ctf_btr
*btr
,
1361 const uint8_t *buf
, size_t sz
,
1362 enum bt_ctf_btr_status
*status
)
1367 btr
->buf
.addr
= buf
;
1368 btr
->buf
.offset
= 0;
1370 btr
->buf
.buf_sz
= sz
;
1371 btr
->buf
.sz
= BYTES_TO_BITS(sz
);
1372 *status
= BT_CTF_BTR_STATUS_OK
;
1374 /* Continue running the machine */
1376 *status
= handle_state(btr
);
1377 if (*status
!= BT_CTF_BTR_STATUS_OK
) {
1379 } else if (btr
->state
== BTR_STATE_DONE
) {
1384 /* Update packet offset for next time */
1385 btr
->buf
.packet_offset
+= btr
->buf
.at
;