X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=plugins%2Fctf%2Fcommon%2Fbtr%2Fbtr.c;h=ac6ce1a042180fefb6aaf0ab8c107a7d035b32c9;hb=f6ccaed94e575af57fe6bf38154771bee4871a2a;hp=a74867933fa28d7108fa4b9a80d3593065e853e3;hpb=06a626b83f4426ea5b8d3199d1edf5a07594026e;p=babeltrace.git diff --git a/plugins/ctf/common/btr/btr.c b/plugins/ctf/common/btr/btr.c index a7486793..ac6ce1a0 100644 --- a/plugins/ctf/common/btr/btr.c +++ b/plugins/ctf/common/btr/btr.c @@ -23,24 +23,26 @@ * SOFTWARE. */ +#define BT_LOG_TAG "PLUGIN-CTF-BTR" +#include "logging.h" + +#include #include +#include #include #include #include -#include +#include #include -#include -#include +#include +#include +#include #include -#include +#include #include #include "btr.h" -#define PRINT_ERR_STREAM btr->err_stream -#define PRINT_PREFIX "ctf-btr" -#include "print.h" - #define DIV8(_x) ((_x) >> 3) #define BYTES_TO_BITS(_x) ((_x) * 8) #define BITS_TO_BYTES_FLOOR(_x) DIV8(_x) @@ -59,7 +61,7 @@ struct stack_entry { * * Owned by this. */ - struct bt_ctf_field_type *base_type; + struct bt_field_type *base_type; /* Length of base field (always 1 for variant types) */ int64_t base_len; @@ -85,15 +87,12 @@ enum btr_state { }; /* Binary type reader */ -struct bt_ctf_btr { +struct bt_btr { /* Bisit stack */ struct stack *stack; - /* Error stream */ - FILE *err_stream; - /* Current basic field type */ - struct bt_ctf_field_type *cur_basic_field_type; + struct bt_field_type *cur_basic_field_type; /* Current state */ enum btr_state state; @@ -105,13 +104,13 @@ struct bt_ctf_btr { * types for which the common boundary is not the boundary of * a byte cannot have different byte orders. * - * This is set to BT_CTF_BYTE_ORDER_UNKNOWN on reset and when + * This is set to BT_BYTE_ORDER_UNKNOWN on reset and when * the last basic field type was a string type. */ - enum bt_ctf_byte_order last_bo; + enum bt_byte_order last_bo; /* Current byte order (copied to last_bo after a successful read) */ - enum bt_ctf_byte_order cur_bo; + enum bt_byte_order cur_bo; /* Stitch buffer infos */ struct { @@ -149,13 +148,34 @@ struct bt_ctf_btr { /* User stuff */ struct { /* Callback functions */ - struct bt_ctf_btr_cbs cbs; + struct bt_btr_cbs cbs; /* Private data */ void *data; } user; }; +static inline +const char *btr_state_string(enum btr_state state) +{ + switch (state) { + case BTR_STATE_NEXT_FIELD: + return "BTR_STATE_NEXT_FIELD"; + case BTR_STATE_ALIGN_BASIC: + return "BTR_STATE_ALIGN_BASIC"; + case BTR_STATE_ALIGN_COMPOUND: + return "BTR_STATE_ALIGN_COMPOUND"; + case BTR_STATE_READ_BASIC_BEGIN: + return "BTR_STATE_READ_BASIC_BEGIN"; + case BTR_STATE_READ_BASIC_CONTINUE: + return "BTR_STATE_READ_BASIC_CONTINUE"; + case BTR_STATE_DONE: + return "BTR_STATE_DONE"; + default: + return "(unknown)"; + } +} + static void stack_entry_free_func(gpointer data) { @@ -172,14 +192,17 @@ struct stack *stack_new(void) stack = g_new0(struct stack, 1); if (!stack) { + BT_LOGE_STR("Failed to allocate one stack."); goto error; } stack->entries = g_ptr_array_new_with_free_func(stack_entry_free_func); if (!stack->entries) { + BT_LOGE_STR("Failed to allocate a GPtrArray."); goto error; } + BT_LOGD("Created stack: addr=%p", stack); return stack; error: @@ -195,54 +218,66 @@ void stack_destroy(struct stack *stack) return; } + BT_LOGD("Destroying stack: addr=%p", stack); g_ptr_array_free(stack->entries, TRUE); g_free(stack); } static inline -int64_t get_compound_field_type_length(struct bt_ctf_btr *btr, - struct bt_ctf_field_type *field_type) +int64_t get_compound_field_type_length(struct bt_btr *btr, + struct bt_field_type *field_type) { int64_t length; - switch (bt_ctf_field_type_get_type_id(field_type)) { - case BT_CTF_TYPE_ID_STRUCT: - length = (int64_t) bt_ctf_field_type_structure_get_field_count( + switch (bt_field_type_get_type_id(field_type)) { + case BT_FIELD_TYPE_ID_STRUCT: + length = (int64_t) bt_field_type_structure_get_field_count( field_type); break; - case BT_CTF_TYPE_ID_VARIANT: + case BT_FIELD_TYPE_ID_VARIANT: /* Variant field types always "contain" a single type */ length = 1; break; - case BT_CTF_TYPE_ID_ARRAY: - length = bt_ctf_field_type_array_get_length(field_type); + case BT_FIELD_TYPE_ID_ARRAY: + length = bt_field_type_array_get_length(field_type); break; - case BT_CTF_TYPE_ID_SEQUENCE: + case BT_FIELD_TYPE_ID_SEQUENCE: length = btr->user.cbs.query.get_sequence_length(field_type, btr->user.data); break; default: - PERR("Cannot get length of field type with type ID %d\n", - bt_ctf_field_type_get_type_id(field_type)); - length = BT_CTF_BTR_STATUS_ERROR; + BT_LOGW("Cannot get field type's field count: btr-addr=%p, " + "ft-addr=%p, ft-id=%s", + btr, field_type, + bt_field_type_id_string( + bt_field_type_get_type_id(field_type))); + length = BT_BTR_STATUS_ERROR; } return length; } static -int stack_push(struct stack *stack, struct bt_ctf_field_type *base_type, +int stack_push(struct stack *stack, struct bt_field_type *base_type, size_t base_len) { int ret = 0; struct stack_entry *entry; - assert(stack); - assert(base_type); + BT_ASSERT(stack); + BT_ASSERT(base_type); + BT_LOGV("Pushing field type on stack: stack-addr=%p, " + "ft-addr=%p, ft-id=%s, base-length=%zu, " + "stack-size-before=%u, stack-size-after=%u", + stack, base_type, bt_field_type_id_string( + bt_field_type_get_type_id(base_type)), + base_len, stack->entries->len, stack->entries->len + 1); entry = g_new0(struct stack_entry, 1); if (!entry) { - ret = BT_CTF_BTR_STATUS_ERROR; + BT_LOGE("Failed to allocate one stack entry: stack-addr=%p", + stack); + ret = BT_BTR_STATUS_ERROR; goto end; } @@ -256,15 +291,18 @@ end: } static -int stack_push_with_len(struct bt_ctf_btr *btr, - struct bt_ctf_field_type *base_type) +int stack_push_with_len(struct bt_btr *btr, + struct bt_field_type *base_type) { int ret = 0; int64_t base_len = get_compound_field_type_length(btr, base_type); if (base_len < 0) { - PERR("Failed to get compound field type's length\n"); - ret = BT_CTF_BTR_STATUS_ERROR; + BT_LOGW("Cannot get compound field type's field count: " + "btr-addr=%p, ft-addr=%p, ft-id=%s", + btr, base_type, bt_field_type_id_string( + bt_field_type_get_type_id(base_type))); + ret = BT_BTR_STATUS_ERROR; goto end; } @@ -277,7 +315,7 @@ end: static inline unsigned int stack_size(struct stack *stack) { - assert(stack); + BT_ASSERT(stack); return stack->entries->len; } @@ -285,8 +323,11 @@ unsigned int stack_size(struct stack *stack) static void stack_pop(struct stack *stack) { - assert(stack); - assert(stack_size(stack)); + BT_ASSERT(stack); + BT_ASSERT(stack_size(stack)); + BT_LOGV("Popping from stack: " + "stack-addr=%p, stack-size-before=%u, stack-size-after=%u", + stack, stack->entries->len, stack->entries->len - 1); g_ptr_array_remove_index(stack->entries, stack->entries->len - 1); } @@ -299,56 +340,58 @@ bool stack_empty(struct stack *stack) static void stack_clear(struct stack *stack) { - assert(stack); + BT_ASSERT(stack); if (!stack_empty(stack)) { g_ptr_array_remove_range(stack->entries, 0, stack_size(stack)); } - assert(stack_empty(stack)); + BT_ASSERT(stack_empty(stack)); } static inline struct stack_entry *stack_top(struct stack *stack) { - assert(stack); - assert(stack_size(stack)); + BT_ASSERT(stack); + BT_ASSERT(stack_size(stack)); return g_ptr_array_index(stack->entries, stack->entries->len - 1); } static inline -size_t available_bits(struct bt_ctf_btr *btr) +size_t available_bits(struct bt_btr *btr) { return btr->buf.sz - btr->buf.at; } static inline -void consume_bits(struct bt_ctf_btr *btr, size_t incr) +void consume_bits(struct bt_btr *btr, size_t incr) { + BT_LOGV("Advancing cursor: btr-addr=%p, cur-before=%zu, cur-after=%zu", + btr, btr->buf.at, btr->buf.at + incr); btr->buf.at += incr; } static inline -bool has_enough_bits(struct bt_ctf_btr *btr, size_t sz) +bool has_enough_bits(struct bt_btr *btr, size_t sz) { return available_bits(btr) >= sz; } static inline -bool at_least_one_bit_left(struct bt_ctf_btr *btr) +bool at_least_one_bit_left(struct bt_btr *btr) { return has_enough_bits(btr, 1); } static inline -size_t packet_at(struct bt_ctf_btr *btr) +size_t packet_at(struct bt_btr *btr) { return btr->buf.packet_offset + btr->buf.at; } static inline -size_t buf_at_from_addr(struct bt_ctf_btr *btr) +size_t buf_at_from_addr(struct bt_btr *btr) { /* * Considering this: @@ -367,73 +410,64 @@ size_t buf_at_from_addr(struct bt_ctf_btr *btr) } static inline -int get_basic_field_type_size(struct bt_ctf_btr *btr, - struct bt_ctf_field_type *field_type) +int get_basic_field_type_size(struct bt_btr *btr, + struct bt_field_type *field_type) { int size; - switch (bt_ctf_field_type_get_type_id(field_type)) { - case BT_CTF_TYPE_ID_INTEGER: - size = bt_ctf_field_type_integer_get_size(field_type); + switch (bt_field_type_get_type_id(field_type)) { + case BT_FIELD_TYPE_ID_INTEGER: + size = bt_field_type_integer_get_size(field_type); break; - case BT_CTF_TYPE_ID_FLOAT: + case BT_FIELD_TYPE_ID_FLOAT: { int exp_dig, mant_dig; exp_dig = - bt_ctf_field_type_floating_point_get_exponent_digits( + bt_field_type_floating_point_get_exponent_digits( field_type); mant_dig = - bt_ctf_field_type_floating_point_get_mantissa_digits( + bt_field_type_floating_point_get_mantissa_digits( field_type); - if (exp_dig < 0 || mant_dig < 0) { - PERR("Failed to get floating point number type's sizes\n"); - size = BT_CTF_BTR_STATUS_ERROR; - } - + BT_ASSERT(exp_dig >= 0); + BT_ASSERT(mant_dig >= 0); size = exp_dig + mant_dig; break; } - case BT_CTF_TYPE_ID_ENUM: + case BT_FIELD_TYPE_ID_ENUM: { - struct bt_ctf_field_type *int_type; + struct bt_field_type *int_type; - int_type = bt_ctf_field_type_enumeration_get_container_type( + int_type = bt_field_type_enumeration_get_container_type( field_type); - if (!int_type) { - PERR("Failed to get enumeration type's container type\n"); - size = BT_CTF_BTR_STATUS_ERROR; - goto end; - } - + BT_ASSERT(int_type); size = get_basic_field_type_size(btr, int_type); BT_PUT(int_type); break; } default: - size = BT_CTF_BTR_STATUS_ERROR; + size = BT_BTR_STATUS_ERROR; break; } -end: return size; } static -void stitch_reset(struct bt_ctf_btr *btr) +void stitch_reset(struct bt_btr *btr) { btr->stitch.offset = 0; btr->stitch.at = 0; } static inline -size_t stitch_at_from_addr(struct bt_ctf_btr *btr) +size_t stitch_at_from_addr(struct bt_btr *btr) { return btr->stitch.offset + btr->stitch.at; } static -void stitch_append_from_buf(struct bt_ctf_btr *btr, size_t sz) +void stitch_append_from_buf(struct bt_btr *btr, size_t sz) { size_t stitch_byte_at; size_t buf_byte_at; @@ -447,7 +481,8 @@ void stitch_append_from_buf(struct bt_ctf_btr *btr, size_t sz) BITS_TO_BYTES_FLOOR(stitch_at_from_addr(btr)); buf_byte_at = BITS_TO_BYTES_FLOOR(buf_at_from_addr(btr)); nb_bytes = BITS_TO_BYTES_CEIL(sz); - assert(nb_bytes > 0); + BT_ASSERT(nb_bytes > 0); + BT_ASSERT(btr->buf.addr); memcpy(&btr->stitch.buf[stitch_byte_at], &btr->buf.addr[buf_byte_at], nb_bytes); btr->stitch.at += sz; @@ -455,13 +490,13 @@ void stitch_append_from_buf(struct bt_ctf_btr *btr, size_t sz) } static -void stitch_append_from_remaining_buf(struct bt_ctf_btr *btr) +void stitch_append_from_remaining_buf(struct bt_btr *btr) { stitch_append_from_buf(btr, available_bits(btr)); } static -void stitch_set_from_remaining_buf(struct bt_ctf_btr *btr) +void stitch_set_from_remaining_buf(struct bt_btr *btr) { stitch_reset(btr); btr->stitch.offset = IN_BYTE_OFFSET(buf_at_from_addr(btr)); @@ -469,55 +504,63 @@ void stitch_set_from_remaining_buf(struct bt_ctf_btr *btr) } static inline -enum bt_ctf_btr_status read_unsigned_bitfield(const uint8_t *buf, size_t at, - int64_t field_size, enum bt_ctf_byte_order bo, uint64_t *v) +enum bt_btr_status read_unsigned_bitfield(const uint8_t *buf, size_t at, + int64_t field_size, enum bt_byte_order bo, uint64_t *v) { - enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK; + enum bt_btr_status status = BT_BTR_STATUS_OK; switch (bo) { - case BT_CTF_BYTE_ORDER_BIG_ENDIAN: - case BT_CTF_BYTE_ORDER_NETWORK: + case BT_BYTE_ORDER_BIG_ENDIAN: + case BT_BYTE_ORDER_NETWORK: bt_bitfield_read_be(buf, uint8_t, at, field_size, v); break; - case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN: + case BT_BYTE_ORDER_LITTLE_ENDIAN: bt_bitfield_read_le(buf, uint8_t, at, field_size, v); break; default: - status = BT_CTF_BTR_STATUS_ERROR; + BT_LOGF("Cannot read unsigned bit array: unknown byte order: bo=%d", bo); + abort(); } + BT_LOGV("Read unsigned bit array: cur=%zu, size=%" PRId64 ", " + "bo=%s, val=%" PRIu64, at, field_size, + bt_byte_order_string(bo), *v); return status; } static inline -enum bt_ctf_btr_status read_signed_bitfield(const uint8_t *buf, size_t at, - int64_t field_size, enum bt_ctf_byte_order bo, int64_t *v) +enum bt_btr_status read_signed_bitfield(const uint8_t *buf, size_t at, + int64_t field_size, enum bt_byte_order bo, int64_t *v) { - enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK; + enum bt_btr_status status = BT_BTR_STATUS_OK; switch (bo) { - case BT_CTF_BYTE_ORDER_BIG_ENDIAN: - case BT_CTF_BYTE_ORDER_NETWORK: + case BT_BYTE_ORDER_BIG_ENDIAN: + case BT_BYTE_ORDER_NETWORK: bt_bitfield_read_be(buf, uint8_t, at, field_size, v); break; - case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN: + case BT_BYTE_ORDER_LITTLE_ENDIAN: bt_bitfield_read_le(buf, uint8_t, at, field_size, v); break; default: - status = BT_CTF_BTR_STATUS_ERROR; + BT_LOGF("Cannot read signed bit array: unknown byte order: bo=%d", bo); + abort(); } + BT_LOGV("Read signed bit array: cur=%zu, size=%" PRId64 ", " + "bo=%s, val=%" PRId64, at, field_size, + bt_byte_order_string(bo), *v); return status; } -typedef enum bt_ctf_btr_status (* read_basic_and_call_cb_t)(struct bt_ctf_btr *, - const uint8_t *, size_t); +typedef enum bt_btr_status (* read_basic_and_call_cb_t)(struct bt_btr *, + const uint8_t *, size_t); static inline -enum bt_ctf_btr_status validate_contiguous_bo(struct bt_ctf_btr *btr, - enum bt_ctf_byte_order next_bo) +enum bt_btr_status validate_contiguous_bo(struct bt_btr *btr, + enum bt_byte_order next_bo) { - enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK; + enum bt_btr_status status = BT_BTR_STATUS_OK; /* Always valid when at a byte boundary */ if (packet_at(btr) % 8 == 0) { @@ -525,49 +568,56 @@ enum bt_ctf_btr_status validate_contiguous_bo(struct bt_ctf_btr *btr, } /* Always valid if last byte order is unknown */ - if (btr->last_bo == BT_CTF_BYTE_ORDER_UNKNOWN) { + if (btr->last_bo == BT_BYTE_ORDER_UNKNOWN) { goto end; } /* Always valid if next byte order is unknown */ - if (next_bo == BT_CTF_BYTE_ORDER_UNKNOWN) { + if (next_bo == BT_BYTE_ORDER_UNKNOWN) { goto end; } /* Make sure last byte order is compatible with the next byte order */ switch (btr->last_bo) { - case BT_CTF_BYTE_ORDER_BIG_ENDIAN: - case BT_CTF_BYTE_ORDER_NETWORK: - if (next_bo != BT_CTF_BYTE_ORDER_BIG_ENDIAN && - next_bo != BT_CTF_BYTE_ORDER_NETWORK) { - status = BT_CTF_BTR_STATUS_ERROR; + case BT_BYTE_ORDER_BIG_ENDIAN: + case BT_BYTE_ORDER_NETWORK: + if (next_bo != BT_BYTE_ORDER_BIG_ENDIAN && + next_bo != BT_BYTE_ORDER_NETWORK) { + status = BT_BTR_STATUS_ERROR; } break; - case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN: - if (next_bo != BT_CTF_BYTE_ORDER_LITTLE_ENDIAN) { - status = BT_CTF_BTR_STATUS_ERROR; + case BT_BYTE_ORDER_LITTLE_ENDIAN: + if (next_bo != BT_BYTE_ORDER_LITTLE_ENDIAN) { + status = BT_BTR_STATUS_ERROR; } break; default: - status = BT_CTF_BTR_STATUS_ERROR; + status = BT_BTR_STATUS_ERROR; } end: + if (status < 0) { + BT_LOGW("Cannot read bit array: two different byte orders not at a byte boundary: " + "btr-addr=%p, last-bo=%s, next-bo=%s", + btr, bt_byte_order_string(btr->last_bo), + bt_byte_order_string(next_bo)); + } + return status; } static -enum bt_ctf_btr_status read_basic_float_and_call_cb(struct bt_ctf_btr *btr, - const uint8_t *buf, size_t at) +enum bt_btr_status read_basic_float_and_call_cb(struct bt_btr *btr, + const uint8_t *buf, size_t at) { int ret; double dblval; int64_t field_size; - enum bt_ctf_byte_order bo; - enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK; + enum bt_byte_order bo; + enum bt_btr_status status = BT_BTR_STATUS_OK; field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type); - bo = bt_ctf_field_type_get_byte_order(btr->cur_basic_field_type); + bo = bt_field_type_get_byte_order(btr->cur_basic_field_type); btr->cur_bo = bo; switch (field_size) { @@ -579,15 +629,17 @@ enum bt_ctf_btr_status read_basic_float_and_call_cb(struct bt_ctf_btr *btr, float f; } f32; - ret = bt_ctf_field_type_floating_point_get_mantissa_digits( + ret = bt_field_type_floating_point_get_mantissa_digits( btr->cur_basic_field_type); - assert(ret == 24); - ret = bt_ctf_field_type_floating_point_get_exponent_digits( + BT_ASSERT(ret == 24); + ret = bt_field_type_floating_point_get_exponent_digits( btr->cur_basic_field_type); - assert(ret == 8); + BT_ASSERT(ret == 8); status = read_unsigned_bitfield(buf, at, field_size, bo, &v); - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("Failed to reader unsigned bitfield\n"); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("Cannot read unsigned 32-bit bit array for floating point number field: " + "btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); goto end; } @@ -602,16 +654,18 @@ enum bt_ctf_btr_status read_basic_float_and_call_cb(struct bt_ctf_btr *btr, double d; } f64; - ret = bt_ctf_field_type_floating_point_get_mantissa_digits( + ret = bt_field_type_floating_point_get_mantissa_digits( btr->cur_basic_field_type); - assert(ret == 53); - ret = bt_ctf_field_type_floating_point_get_exponent_digits( + BT_ASSERT(ret == 53); + ret = bt_field_type_floating_point_get_exponent_digits( btr->cur_basic_field_type); - assert(ret == 11); + BT_ASSERT(ret == 11); status = read_unsigned_bitfield(buf, at, field_size, bo, &f64.u); - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("Failed to reader unsigned bitfield\n"); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("Cannot read unsigned 64-bit bit array for floating point number field: " + "btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); goto end; } @@ -620,13 +674,25 @@ enum bt_ctf_btr_status read_basic_float_and_call_cb(struct bt_ctf_btr *btr, } default: /* Only 32-bit and 64-bit fields are supported currently */ - status = BT_CTF_BTR_STATUS_ERROR; + BT_LOGW("Only 32-bit and 64-bit floating point number fields are supported: " + "btr-addr=%p", btr); + status = BT_BTR_STATUS_ERROR; goto end; } + BT_LOGV("Read floating point number value: btr=%p, cur=%zu, val=%f", + btr, at, dblval); + if (btr->user.cbs.types.floating_point) { + BT_LOGV("Calling user function (floating point number)."); status = btr->user.cbs.types.floating_point(dblval, btr->cur_basic_field_type, btr->user.data); + BT_LOGV("User function returned: status=%s", + bt_btr_status_string(status)); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("User function failed: btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); + } } end: @@ -634,24 +700,27 @@ end: } static inline -enum bt_ctf_btr_status read_basic_int_and_call(struct bt_ctf_btr *btr, - const uint8_t *buf, size_t at, struct bt_ctf_field_type *int_type, - struct bt_ctf_field_type *orig_type) +enum bt_btr_status read_basic_int_and_call(struct bt_btr *btr, + const uint8_t *buf, size_t at, + struct bt_field_type *int_type, + struct bt_field_type *orig_type) { - int signd; + bt_bool signd; int64_t field_size; - enum bt_ctf_byte_order bo; - enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK; + enum bt_byte_order bo; + enum bt_btr_status status = BT_BTR_STATUS_OK; - signd = bt_ctf_field_type_integer_get_signed(int_type); + signd = bt_field_type_integer_is_signed(int_type); field_size = get_basic_field_type_size(btr, int_type); if (field_size < 1) { - PERR("Failed to get basic field type's size\n"); - status = BT_CTF_BTR_STATUS_ERROR; + BT_LOGW("Cannot get integer field type's size: " + "btr=%p, at=%zu, ft-addr=%p", + btr, at, int_type); + status = BT_BTR_STATUS_ERROR; goto end; } - bo = bt_ctf_field_type_get_byte_order(int_type); + bo = bt_field_type_get_byte_order(int_type); /* * Update current byte order now because we could be reading @@ -664,27 +733,47 @@ enum bt_ctf_btr_status read_basic_int_and_call(struct bt_ctf_btr *btr, int64_t v; status = read_signed_bitfield(buf, at, field_size, bo, &v); - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("Failed to reader signed bitfield\n"); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("Cannot read signed bit array for signed integer field: " + "btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); goto end; } if (btr->user.cbs.types.signed_int) { + BT_LOGV("Calling user function (signed integer)."); status = btr->user.cbs.types.signed_int(v, btr->cur_basic_field_type, btr->user.data); + BT_LOGV("User function returned: status=%s", + bt_btr_status_string(status)); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("User function failed: " + "btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); + } } } else { uint64_t v; status = read_unsigned_bitfield(buf, at, field_size, bo, &v); - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("Failed to reader unsigned bitfield\n"); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("Cannot read unsigned bit array for unsigned integer field: " + "btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); goto end; } if (btr->user.cbs.types.unsigned_int) { + BT_LOGV("Calling user function (unsigned integer)."); status = btr->user.cbs.types.unsigned_int(v, btr->cur_basic_field_type, btr->user.data); + BT_LOGV("User function returned: status=%s", + bt_btr_status_string(status)); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("User function failed: " + "btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); + } } } @@ -693,67 +782,69 @@ end: } static -enum bt_ctf_btr_status read_basic_int_and_call_cb(struct bt_ctf_btr *btr, - const uint8_t *buf, size_t at) +enum bt_btr_status read_basic_int_and_call_cb(struct bt_btr *btr, + const uint8_t *buf, size_t at) { return read_basic_int_and_call(btr, buf, at, btr->cur_basic_field_type, btr->cur_basic_field_type); } static -enum bt_ctf_btr_status read_basic_enum_and_call_cb(struct bt_ctf_btr *btr, - const uint8_t *buf, size_t at) +enum bt_btr_status read_basic_enum_and_call_cb(struct bt_btr *btr, + const uint8_t *buf, size_t at) { - struct bt_ctf_field_type *int_field_type; - enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK; + struct bt_field_type *int_field_type; + enum bt_btr_status status = BT_BTR_STATUS_OK; - int_field_type = bt_ctf_field_type_enumeration_get_container_type( + int_field_type = bt_field_type_enumeration_get_container_type( btr->cur_basic_field_type); - if (!int_field_type) { - PERR("Failed to get enumeration type's container type\n"); - status = BT_CTF_BTR_STATUS_ERROR; - goto end; - } - + BT_ASSERT(int_field_type); status = read_basic_int_and_call(btr, buf, at, int_field_type, btr->cur_basic_field_type); - -end: - BT_PUT(int_field_type); - + bt_put(int_field_type); return status; } static inline -enum bt_ctf_btr_status read_basic_type_and_call_continue(struct bt_ctf_btr *btr, - read_basic_and_call_cb_t read_basic_and_call_cb) +enum bt_btr_status read_basic_type_and_call_continue(struct bt_btr *btr, + read_basic_and_call_cb_t read_basic_and_call_cb) { size_t available; int64_t field_size; int64_t needed_bits; - enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK; + enum bt_btr_status status = BT_BTR_STATUS_OK; if (!at_least_one_bit_left(btr)) { - status = BT_CTF_BTR_STATUS_EOF; + BT_LOGV("Reached end of data: btr-addr=%p", btr); + status = BT_BTR_STATUS_EOF; goto end; } field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type); if (field_size < 1) { - PERR("Failed to get basic field type's size\n"); - status = BT_CTF_BTR_STATUS_ERROR; + BT_LOGW("Cannot get basic field type's size: " + "btr-addr=%p, ft-addr=%p", + btr, btr->cur_basic_field_type); + status = BT_BTR_STATUS_ERROR; goto end; } available = available_bits(btr); needed_bits = field_size - btr->stitch.at; + BT_LOGV("Continuing basic field decoding: " + "btr-addr=%p, field-size=%" PRId64 ", needed-size=%" PRId64 ", " + "available-size=%zu", + btr, field_size, needed_bits, available); if (needed_bits <= available) { /* We have all the bits; append to stitch, then decode */ stitch_append_from_buf(btr, needed_bits); status = read_basic_and_call_cb(btr, btr->stitch.buf, btr->stitch.offset); - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("Failed to read basic field\n"); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("Cannot read basic field: " + "btr-addr=%p, ft-addr=%p, status=%s", + btr, btr->cur_basic_field_type, + bt_btr_status_string(status)); goto end; } @@ -770,40 +861,42 @@ enum bt_ctf_btr_status read_basic_type_and_call_continue(struct bt_ctf_btr *btr, } /* We are here; it means we don't have enough data to decode this */ + BT_LOGV_STR("Not enough data to read the next basic field: appending to stitch buffer."); stitch_append_from_remaining_buf(btr); - status = BT_CTF_BTR_STATUS_EOF; + status = BT_BTR_STATUS_EOF; end: return status; } static inline -enum bt_ctf_btr_status read_basic_type_and_call_begin(struct bt_ctf_btr *btr, - read_basic_and_call_cb_t read_basic_and_call_cb) +enum bt_btr_status read_basic_type_and_call_begin(struct bt_btr *btr, + read_basic_and_call_cb_t read_basic_and_call_cb) { size_t available; int64_t field_size; - enum bt_ctf_byte_order bo; - enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK; + enum bt_byte_order bo; + enum bt_btr_status status = BT_BTR_STATUS_OK; if (!at_least_one_bit_left(btr)) { - status = BT_CTF_BTR_STATUS_EOF; + BT_LOGV("Reached end of data: btr-addr=%p", btr); + status = BT_BTR_STATUS_EOF; goto end; } field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type); - if (field_size < 1) { - PERR("Failed to get basic field type's size\n"); - status = BT_CTF_BTR_STATUS_ERROR; + BT_LOGW("Cannot get basic field type's size: " + "btr-addr=%p, ft-addr=%p", + btr, btr->cur_basic_field_type); + status = BT_BTR_STATUS_ERROR; goto end; } - bo = bt_ctf_field_type_get_byte_order(btr->cur_basic_field_type); + bo = bt_field_type_get_byte_order(btr->cur_basic_field_type); status = validate_contiguous_bo(btr, bo); - - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("Invalid contiguous byte orders\n"); + if (status != BT_BTR_STATUS_OK) { + /* validate_contiguous_bo() logs errors */ goto end; } @@ -811,11 +904,14 @@ enum bt_ctf_btr_status read_basic_type_and_call_begin(struct bt_ctf_btr *btr, if (field_size <= available) { /* We have all the bits; decode and set now */ + BT_ASSERT(btr->buf.addr); status = read_basic_and_call_cb(btr, btr->buf.addr, buf_at_from_addr(btr)); - - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("Failed to read basic type\n"); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("Cannot read basic field: " + "btr-addr=%p, ft-addr=%p, status=%s", + btr, btr->cur_basic_field_type, + bt_btr_status_string(status)); goto end; } @@ -835,88 +931,94 @@ enum bt_ctf_btr_status read_basic_type_and_call_begin(struct bt_ctf_btr *btr, } /* We are here; it means we don't have enough data to decode this */ + BT_LOGV_STR("Not enough data to read the next basic field: setting stitch buffer."); stitch_set_from_remaining_buf(btr); btr->state = BTR_STATE_READ_BASIC_CONTINUE; - status = BT_CTF_BTR_STATUS_EOF; + status = BT_BTR_STATUS_EOF; end: return status; } static inline -enum bt_ctf_btr_status read_basic_int_type_and_call_begin( - struct bt_ctf_btr *btr) +enum bt_btr_status read_basic_int_type_and_call_begin( + struct bt_btr *btr) { return read_basic_type_and_call_begin(btr, read_basic_int_and_call_cb); } static inline -enum bt_ctf_btr_status read_basic_int_type_and_call_continue( - struct bt_ctf_btr *btr) +enum bt_btr_status read_basic_int_type_and_call_continue( + struct bt_btr *btr) { return read_basic_type_and_call_continue(btr, read_basic_int_and_call_cb); } static inline -enum bt_ctf_btr_status read_basic_float_type_and_call_begin( - struct bt_ctf_btr *btr) +enum bt_btr_status read_basic_float_type_and_call_begin( + struct bt_btr *btr) { return read_basic_type_and_call_begin(btr, read_basic_float_and_call_cb); } static inline -enum bt_ctf_btr_status read_basic_float_type_and_call_continue( - struct bt_ctf_btr *btr) +enum bt_btr_status read_basic_float_type_and_call_continue( + struct bt_btr *btr) { return read_basic_type_and_call_continue(btr, read_basic_float_and_call_cb); } static inline -enum bt_ctf_btr_status read_basic_enum_type_and_call_begin( - struct bt_ctf_btr *btr) +enum bt_btr_status read_basic_enum_type_and_call_begin( + struct bt_btr *btr) { return read_basic_type_and_call_begin(btr, read_basic_enum_and_call_cb); } static inline -enum bt_ctf_btr_status read_basic_enum_type_and_call_continue( - struct bt_ctf_btr *btr) +enum bt_btr_status read_basic_enum_type_and_call_continue( + struct bt_btr *btr) { return read_basic_type_and_call_continue(btr, read_basic_enum_and_call_cb); } static inline -enum bt_ctf_btr_status read_basic_string_type_and_call( - struct bt_ctf_btr *btr, bool begin) +enum bt_btr_status read_basic_string_type_and_call( + struct bt_btr *btr, bool begin) { size_t buf_at_bytes; const uint8_t *result; size_t available_bytes; const uint8_t *first_chr; - enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK; + enum bt_btr_status status = BT_BTR_STATUS_OK; if (!at_least_one_bit_left(btr)) { - status = BT_CTF_BTR_STATUS_EOF; + BT_LOGV("Reached end of data: btr-addr=%p", btr); + status = BT_BTR_STATUS_EOF; goto end; } - assert(buf_at_from_addr(btr) % 8 == 0); + BT_ASSERT(buf_at_from_addr(btr) % 8 == 0); available_bytes = BITS_TO_BYTES_FLOOR(available_bits(btr)); buf_at_bytes = BITS_TO_BYTES_FLOOR(buf_at_from_addr(btr)); + BT_ASSERT(btr->buf.addr); first_chr = &btr->buf.addr[buf_at_bytes]; result = memchr(first_chr, '\0', available_bytes); if (begin && btr->user.cbs.types.string_begin) { + BT_LOGV("Calling user function (string, beginning)."); status = btr->user.cbs.types.string_begin( btr->cur_basic_field_type, btr->user.data); - - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("string_begin() user callback function failed\n"); + BT_LOGV("User function returned: status=%s", + bt_btr_status_string(status)); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("User function failed: btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); goto end; } } @@ -924,39 +1026,54 @@ enum bt_ctf_btr_status read_basic_string_type_and_call( if (!result) { /* No null character yet */ if (btr->user.cbs.types.string) { + BT_LOGV("Calling user function (substring)."); status = btr->user.cbs.types.string( (const char *) first_chr, available_bytes, btr->cur_basic_field_type, btr->user.data); - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("string() user callback function failed\n"); + BT_LOGV("User function returned: status=%s", + bt_btr_status_string(status)); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("User function failed: " + "btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); goto end; } } consume_bits(btr, BYTES_TO_BITS(available_bytes)); btr->state = BTR_STATE_READ_BASIC_CONTINUE; - status = BT_CTF_BTR_STATUS_EOF; + status = BT_BTR_STATUS_EOF; } else { /* Found the null character */ size_t result_len = (size_t) (result - first_chr); if (btr->user.cbs.types.string && result_len) { + BT_LOGV("Calling user function (substring)."); status = btr->user.cbs.types.string( (const char *) first_chr, result_len, btr->cur_basic_field_type, btr->user.data); - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("string() user callback function failed\n"); + BT_LOGV("User function returned: status=%s", + bt_btr_status_string(status)); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("User function failed: " + "btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); goto end; } } if (btr->user.cbs.types.string_end) { + BT_LOGV("Calling user function (string, end)."); status = btr->user.cbs.types.string_end( btr->cur_basic_field_type, btr->user.data); - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("string_end() user callback function failed\n"); + BT_LOGV("User function returned: status=%s", + bt_btr_status_string(status)); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("User function failed: " + "btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); goto end; } } @@ -979,82 +1096,97 @@ end: } static inline -enum bt_ctf_btr_status read_basic_begin_state(struct bt_ctf_btr *btr) +enum bt_btr_status read_basic_begin_state(struct bt_btr *btr) { - enum bt_ctf_btr_status status; + enum bt_btr_status status; - assert(btr->cur_basic_field_type); + BT_ASSERT(btr->cur_basic_field_type); - switch (bt_ctf_field_type_get_type_id(btr->cur_basic_field_type)) { - case BT_CTF_TYPE_ID_INTEGER: + switch (bt_field_type_get_type_id(btr->cur_basic_field_type)) { + case BT_FIELD_TYPE_ID_INTEGER: status = read_basic_int_type_and_call_begin(btr); break; - case BT_CTF_TYPE_ID_FLOAT: + case BT_FIELD_TYPE_ID_FLOAT: status = read_basic_float_type_and_call_begin(btr); break; - case BT_CTF_TYPE_ID_ENUM: + case BT_FIELD_TYPE_ID_ENUM: status = read_basic_enum_type_and_call_begin(btr); break; - case BT_CTF_TYPE_ID_STRING: + case BT_FIELD_TYPE_ID_STRING: status = read_basic_string_type_and_call(btr, true); break; default: - assert(false); + BT_LOGF("Unknown basic field type ID: " + "btr-addr=%p, ft-addr=%p, ft-id=%s", + btr, btr->cur_basic_field_type, + bt_field_type_id_string( + bt_field_type_get_type_id( + btr->cur_basic_field_type))); + abort(); } return status; } static inline -enum bt_ctf_btr_status read_basic_continue_state(struct bt_ctf_btr *btr) +enum bt_btr_status read_basic_continue_state(struct bt_btr *btr) { - enum bt_ctf_btr_status status; + enum bt_btr_status status; - assert(btr->cur_basic_field_type); + BT_ASSERT(btr->cur_basic_field_type); - switch (bt_ctf_field_type_get_type_id(btr->cur_basic_field_type)) { - case BT_CTF_TYPE_ID_INTEGER: + switch (bt_field_type_get_type_id(btr->cur_basic_field_type)) { + case BT_FIELD_TYPE_ID_INTEGER: status = read_basic_int_type_and_call_continue(btr); break; - case BT_CTF_TYPE_ID_FLOAT: + case BT_FIELD_TYPE_ID_FLOAT: status = read_basic_float_type_and_call_continue(btr); break; - case BT_CTF_TYPE_ID_ENUM: + case BT_FIELD_TYPE_ID_ENUM: status = read_basic_enum_type_and_call_continue(btr); break; - case BT_CTF_TYPE_ID_STRING: + case BT_FIELD_TYPE_ID_STRING: status = read_basic_string_type_and_call(btr, false); break; default: - assert(false); + BT_LOGF("Unknown basic field type ID: " + "btr-addr=%p, ft-addr=%p, ft-id=%s", + btr, btr->cur_basic_field_type, + bt_field_type_id_string( + bt_field_type_get_type_id( + btr->cur_basic_field_type))); + abort(); } return status; } static inline -size_t bits_to_skip_to_align_to(struct bt_ctf_btr *btr, size_t align) +size_t bits_to_skip_to_align_to(struct bt_btr *btr, size_t align) { size_t aligned_packet_at; aligned_packet_at = ALIGN(packet_at(btr), align); - return aligned_packet_at - packet_at(btr); } static inline -enum bt_ctf_btr_status align_type_state(struct bt_ctf_btr *btr, - struct bt_ctf_field_type *field_type, enum btr_state next_state) +enum bt_btr_status align_type_state(struct bt_btr *btr, + struct bt_field_type *field_type, enum btr_state next_state) { int field_alignment; size_t skip_bits; - enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK; + enum bt_btr_status status = BT_BTR_STATUS_OK; /* Get field's alignment */ - field_alignment = bt_ctf_field_type_get_alignment(field_type); + field_alignment = bt_field_type_get_alignment(field_type); if (field_alignment < 0) { - PERR("Failed to get type alignment\n"); - status = BT_CTF_BTR_STATUS_ERROR; + BT_LOGW("Cannot get field type's alignment: " + "btr-addr=%p, ft-addr=%p, ft-id=%s", + btr, field_type, + bt_field_type_id_string( + bt_field_type_get_type_id(field_type))); + status = BT_BTR_STATUS_ERROR; goto end; } @@ -1077,7 +1209,7 @@ enum bt_ctf_btr_status align_type_state(struct bt_ctf_btr *btr, /* Make sure there's at least one bit left */ if (!at_least_one_bit_left(btr)) { - status = BT_CTF_BTR_STATUS_EOF; + status = BT_BTR_STATUS_EOF; goto end; } @@ -1086,14 +1218,14 @@ enum bt_ctf_btr_status align_type_state(struct bt_ctf_btr *btr, /* Are we done now? */ skip_bits = bits_to_skip_to_align_to(btr, field_alignment); - if (skip_bits == 0) { /* Yes: go to next state */ btr->state = next_state; goto end; } else { /* No: need more data */ - status = BT_CTF_BTR_STATUS_EOF; + BT_LOGV("Reached end of data when aligning: btr-addr=%p", btr); + status = BT_BTR_STATUS_EOF; } end: @@ -1101,21 +1233,21 @@ end: } static inline -bool is_compound_type(struct bt_ctf_field_type *field_type) +bool is_compound_type(struct bt_field_type *field_type) { - enum bt_ctf_type_id id = bt_ctf_field_type_get_type_id(field_type); + enum bt_field_type_id id = bt_field_type_get_type_id(field_type); - return id == BT_CTF_TYPE_ID_STRUCT || id == BT_CTF_TYPE_ID_ARRAY || - id == BT_CTF_TYPE_ID_SEQUENCE || id == BT_CTF_TYPE_ID_VARIANT; + return id == BT_FIELD_TYPE_ID_STRUCT || id == BT_FIELD_TYPE_ID_ARRAY || + id == BT_FIELD_TYPE_ID_SEQUENCE || id == BT_FIELD_TYPE_ID_VARIANT; } static inline -enum bt_ctf_btr_status next_field_state(struct bt_ctf_btr *btr) +enum bt_btr_status next_field_state(struct bt_btr *btr) { int ret; struct stack_entry *top; - struct bt_ctf_field_type *next_field_type = NULL; - enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK; + struct bt_field_type *next_field_type = NULL; + enum bt_btr_status status = BT_BTR_STATUS_OK; if (stack_empty(btr->stack)) { goto end; @@ -1126,10 +1258,14 @@ enum bt_ctf_btr_status next_field_state(struct bt_ctf_btr *btr) /* Are we done with this base type? */ while (top->index == top->base_len) { if (btr->user.cbs.types.compound_end) { + BT_LOGV("Calling user function (compound, end)."); status = btr->user.cbs.types.compound_end( top->base_type, btr->user.data); - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("compound_end() user callback function failed\n"); + BT_LOGV("User function returned: status=%s", + bt_btr_status_string(status)); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("User function failed: btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); goto end; } } @@ -1147,26 +1283,26 @@ enum bt_ctf_btr_status next_field_state(struct bt_ctf_btr *btr) } /* Get next field's type */ - switch (bt_ctf_field_type_get_type_id(top->base_type)) { - case BT_CTF_TYPE_ID_STRUCT: - ret = bt_ctf_field_type_structure_get_field( + switch (bt_field_type_get_type_id(top->base_type)) { + case BT_FIELD_TYPE_ID_STRUCT: + ret = bt_field_type_structure_get_field_by_index( top->base_type, NULL, &next_field_type, top->index); if (ret) { next_field_type = NULL; } break; - case BT_CTF_TYPE_ID_ARRAY: + case BT_FIELD_TYPE_ID_ARRAY: next_field_type = - bt_ctf_field_type_array_get_element_type( + bt_field_type_array_get_element_type( top->base_type); break; - case BT_CTF_TYPE_ID_SEQUENCE: + case BT_FIELD_TYPE_ID_SEQUENCE: next_field_type = - bt_ctf_field_type_sequence_get_element_type( + bt_field_type_sequence_get_element_type( top->base_type); break; - case BT_CTF_TYPE_ID_VARIANT: + case BT_FIELD_TYPE_ID_VARIANT: /* Variant types are dynamic: query the user, he should know! */ next_field_type = btr->user.cbs.query.get_variant_type( @@ -1177,25 +1313,35 @@ enum bt_ctf_btr_status next_field_state(struct bt_ctf_btr *btr) } if (!next_field_type) { - PERR("Failed to get next field's type\n"); - status = BT_CTF_BTR_STATUS_ERROR; + BT_LOGW("Cannot get the field type of the next field: " + "btr-addr=%p, base-ft-addr=%p, base-ft-id=%s, " + "index=%" PRId64, + btr, top->base_type, + bt_field_type_id_string( + bt_field_type_get_type_id(top->base_type)), + top->index); + status = BT_BTR_STATUS_ERROR; goto end; } if (is_compound_type(next_field_type)) { if (btr->user.cbs.types.compound_begin) { + BT_LOGV("Calling user function (compound, begin)."); status = btr->user.cbs.types.compound_begin( next_field_type, btr->user.data); - if (status != BT_CTF_BTR_STATUS_OK) { - PERR("compound_begin() user callback function failed\n"); + BT_LOGV("User function returned: status=%s", + bt_btr_status_string(status)); + if (status != BT_BTR_STATUS_OK) { + BT_LOGW("User function failed: btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); goto end; } } ret = stack_push_with_len(btr, next_field_type); if (ret) { - PERR("Failed to push compound type onto the stack\n"); - status = BT_CTF_BTR_STATUS_ERROR; + /* stack_push_with_len() logs errors */ + status = BT_BTR_STATUS_ERROR; goto end; } @@ -1203,6 +1349,10 @@ enum bt_ctf_btr_status next_field_state(struct bt_ctf_btr *btr) btr->state = BTR_STATE_ALIGN_COMPOUND; } else { /* Replace current basic field type */ + BT_LOGV("Replacing current basic field type: " + "btr-addr=%p, cur-basic-ft-addr=%p, " + "next-basic-ft-addr=%p", + btr, btr->cur_basic_field_type, next_field_type); BT_MOVE(btr->cur_basic_field_type, next_field_type); /* Next state: align a basic type */ @@ -1216,9 +1366,12 @@ end: } static inline -enum bt_ctf_btr_status handle_state(struct bt_ctf_btr *btr) +enum bt_btr_status handle_state(struct bt_btr *btr) { - enum bt_ctf_btr_status status = BT_CTF_BTR_STATUS_OK; + enum bt_btr_status status = BT_BTR_STATUS_OK; + + BT_LOGV("Handling state: btr-addr=%p, state=%s", + btr, btr_state_string(btr->state)); switch (btr->state) { case BTR_STATE_NEXT_FIELD: @@ -1242,24 +1395,26 @@ enum bt_ctf_btr_status handle_state(struct bt_ctf_btr *btr) break; } + BT_LOGV("Handled state: btr-addr=%p, status=%s", + btr, bt_btr_status_string(status)); return status; } -struct bt_ctf_btr *bt_ctf_btr_create(struct bt_ctf_btr_cbs cbs, void *data, - FILE *err_stream) +struct bt_btr *bt_btr_create(struct bt_btr_cbs cbs, void *data) { - struct bt_ctf_btr *btr; + struct bt_btr *btr; - btr = g_new0(struct bt_ctf_btr, 1); + BT_LOGD_STR("Creating binary type reader (BTR)."); + btr = g_new0(struct bt_btr, 1); if (!btr) { - PERR("Failed to allocate memory for binary type reader\n"); + BT_LOGE_STR("Failed to allocate one binary type reader."); goto end; } btr->stack = stack_new(); if (!btr->stack) { - PERR("Failed to create stack\n"); - bt_ctf_btr_destroy(btr); + BT_LOGE_STR("Cannot create BTR's stack."); + bt_btr_destroy(btr); btr = NULL; goto end; } @@ -1267,41 +1422,51 @@ struct bt_ctf_btr *bt_ctf_btr_create(struct bt_ctf_btr_cbs cbs, void *data, btr->state = BTR_STATE_NEXT_FIELD; btr->user.cbs = cbs; btr->user.data = data; - btr->err_stream = err_stream; + BT_LOGD("Created BTR: addr=%p", btr); end: return btr; } -void bt_ctf_btr_destroy(struct bt_ctf_btr *btr) +void bt_btr_destroy(struct bt_btr *btr) { if (btr->stack) { stack_destroy(btr->stack); } + BT_LOGD("Destroying BTR: addr=%p", btr); BT_PUT(btr->cur_basic_field_type); g_free(btr); } static -void reset(struct bt_ctf_btr *btr) +void reset(struct bt_btr *btr) { + BT_LOGD("Resetting BTR: addr=%p", btr); stack_clear(btr->stack); BT_PUT(btr->cur_basic_field_type); stitch_reset(btr); btr->buf.addr = NULL; - btr->last_bo = BT_CTF_BYTE_ORDER_UNKNOWN; + btr->last_bo = BT_BYTE_ORDER_UNKNOWN; } -size_t bt_ctf_btr_start(struct bt_ctf_btr *btr, - struct bt_ctf_field_type *type, const uint8_t *buf, +static +void update_packet_offset(struct bt_btr *btr) +{ + BT_LOGV("Updating packet offset for next call: " + "btr-addr=%p, cur-packet-offset=%zu, next-packet-offset=%zu", + btr, btr->buf.packet_offset, + btr->buf.packet_offset + btr->buf.at); + btr->buf.packet_offset += btr->buf.at; +} + +size_t bt_btr_start(struct bt_btr *btr, + struct bt_field_type *type, const uint8_t *buf, size_t offset, size_t packet_offset, size_t sz, - enum bt_ctf_btr_status *status) + enum bt_btr_status *status) { - assert(btr); - assert(buf); - assert(sz > 0); - assert(BYTES_TO_BITS(sz) > offset); + BT_ASSERT(btr); + BT_ASSERT(BYTES_TO_BITS(sz) >= offset); reset(btr); btr->buf.addr = buf; btr->buf.offset = offset; @@ -1309,7 +1474,12 @@ size_t bt_ctf_btr_start(struct bt_ctf_btr *btr, btr->buf.packet_offset = packet_offset; btr->buf.buf_sz = sz; btr->buf.sz = BYTES_TO_BITS(sz) - offset; - *status = BT_CTF_BTR_STATUS_OK; + *status = BT_BTR_STATUS_OK; + + BT_LOGV("Starting decoding: btr-addr=%p, ft-addr=%p, " + "buf-addr=%p, buf-size=%zu, offset=%zu, " + "packet-offset=%zu", + btr, type, buf, sz, offset, packet_offset); /* Set root type */ if (is_compound_type(type)) { @@ -1317,18 +1487,22 @@ size_t bt_ctf_btr_start(struct bt_ctf_btr *btr, int stack_ret; if (btr->user.cbs.types.compound_begin) { + BT_LOGV("Calling user function (compound, begin)."); *status = btr->user.cbs.types.compound_begin( type, btr->user.data); - if (*status != BT_CTF_BTR_STATUS_OK) { - PERR("compound_begin() user callback function failed\n"); + BT_LOGV("User function returned: status=%s", + bt_btr_status_string(*status)); + if (*status != BT_BTR_STATUS_OK) { + BT_LOGW("User function failed: btr-addr=%p, status=%s", + btr, bt_btr_status_string(*status)); goto end; } } stack_ret = stack_push_with_len(btr, type); if (stack_ret) { - PERR("Failed to push initial compound type onto the stack\n"); - *status = BT_CTF_BTR_STATUS_ERROR; + /* stack_push_with_len() logs errors */ + *status = BT_BTR_STATUS_ERROR; goto end; } @@ -1341,48 +1515,52 @@ size_t bt_ctf_btr_start(struct bt_ctf_btr *btr, } /* Run the machine! */ + BT_LOGV_STR("Running the state machine."); + while (true) { *status = handle_state(btr); - if (*status != BT_CTF_BTR_STATUS_OK) { - break; - } else if (btr->state == BTR_STATE_DONE) { + if (*status != BT_BTR_STATUS_OK || + btr->state == BTR_STATE_DONE) { break; } } /* Update packet offset for next time */ - btr->buf.packet_offset += btr->buf.at; + update_packet_offset(btr); end: return btr->buf.at; } -size_t bt_ctf_btr_continue(struct bt_ctf_btr *btr, +size_t bt_btr_continue(struct bt_btr *btr, const uint8_t *buf, size_t sz, - enum bt_ctf_btr_status *status) + enum bt_btr_status *status) { - assert(btr); - assert(buf); - assert(sz > 0); + BT_ASSERT(btr); + BT_ASSERT(buf); + BT_ASSERT(sz > 0); btr->buf.addr = buf; btr->buf.offset = 0; btr->buf.at = 0; btr->buf.buf_sz = sz; btr->buf.sz = BYTES_TO_BITS(sz); - *status = BT_CTF_BTR_STATUS_OK; + *status = BT_BTR_STATUS_OK; + + BT_LOGV("Continuing decoding: btr-addr=%p, buf-addr=%p, buf-size=%zu", + btr, buf, sz); /* Continue running the machine */ + BT_LOGV_STR("Running the state machine."); + while (true) { *status = handle_state(btr); - if (*status != BT_CTF_BTR_STATUS_OK) { - break; - } else if (btr->state == BTR_STATE_DONE) { + if (*status != BT_BTR_STATUS_OK || + btr->state == BTR_STATE_DONE) { break; } } /* Update packet offset for next time */ - btr->buf.packet_offset += btr->buf.at; - + update_packet_offset(btr); return btr->buf.at; }