X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=plugins%2Fctf%2Fcommon%2Fbtr%2Fbtr.c;h=848e219198c961541cb8fb820be998f2aeba90c6;hb=44c440bc5fe8219cc17d1b786d91fd83c4c9860a;hp=e393f301d776c4b928fa5a46f79daed9a2a123e5;hpb=50842bdc4c21f3de2b63e29cdac730af8b6dcca6;p=babeltrace.git diff --git a/plugins/ctf/common/btr/btr.c b/plugins/ctf/common/btr/btr.c index e393f301..848e2191 100644 --- a/plugins/ctf/common/btr/btr.c +++ b/plugins/ctf/common/btr/btr.c @@ -32,16 +32,17 @@ #include #include #include -#include +#include #include #include +#include #include -#include #include #include #include #include "btr.h" +#include "../metadata/ctf-meta.h" #define DIV8(_x) ((_x) >> 3) #define BYTES_TO_BITS(_x) ((_x) * 8) @@ -58,22 +59,23 @@ struct stack_entry { * * Array * * Sequence * * Variant - * - * Owned by this. */ - struct bt_field_type *base_type; + struct ctf_field_type *base_type; /* Length of base field (always 1 for variant types) */ int64_t base_len; - /* Lndex of next field to read */ + /* Index of next field to read */ int64_t index; }; /* Visit stack */ struct stack { - /* Entries (struct stack_entry *) (top is last element) */ - GPtrArray *entries; + /* Entries (struct stack_entry) */ + GArray *entries; + + /* Number of active entries */ + size_t size; }; /* Reading states */ @@ -92,7 +94,7 @@ struct bt_btr { struct stack *stack; /* Current basic field type */ - struct bt_field_type *cur_basic_field_type; + struct ctf_field_type *cur_basic_field_type; /* Current state */ enum btr_state state; @@ -104,13 +106,13 @@ struct bt_btr { * types for which the common boundary is not the boundary of * a byte cannot have different byte orders. * - * This is set to BT_BYTE_ORDER_UNKNOWN on reset and when - * the last basic field type was a string type. + * This is set to -1 on reset and when the last basic field type + * was a string type. */ - enum bt_byte_order last_bo; + enum ctf_byte_order last_bo; /* Current byte order (copied to last_bo after a successful read) */ - enum bt_byte_order cur_bo; + enum ctf_byte_order cur_bo; /* Stitch buffer infos */ struct { @@ -176,15 +178,6 @@ const char *btr_state_string(enum btr_state state) } } -static -void stack_entry_free_func(gpointer data) -{ - struct stack_entry *entry = data; - - BT_PUT(entry->base_type); - g_free(entry); -} - static struct stack *stack_new(void) { @@ -196,9 +189,9 @@ struct stack *stack_new(void) goto error; } - stack->entries = g_ptr_array_new_with_free_func(stack_entry_free_func); + stack->entries = g_array_new(FALSE, TRUE, sizeof(struct stack_entry)); if (!stack->entries) { - BT_LOGE_STR("Failed to allocate a GPtrArray."); + BT_LOGE_STR("Failed to allocate a GArray."); goto error; } @@ -207,7 +200,6 @@ struct stack *stack_new(void) error: g_free(stack); - return NULL; } @@ -219,94 +211,93 @@ void stack_destroy(struct stack *stack) } BT_LOGD("Destroying stack: addr=%p", stack); - g_ptr_array_free(stack->entries, TRUE); + + if (stack->entries) { + g_array_free(stack->entries, TRUE); + } + g_free(stack); } +static +int stack_push(struct stack *stack, struct ctf_field_type *base_type, + size_t base_len) +{ + struct stack_entry *entry; + + BT_ASSERT(stack); + BT_ASSERT(base_type); + BT_LOGV("Pushing field type on stack: stack-addr=%p, " + "ft-addr=%p, ft-id=%d, base-length=%zu, " + "stack-size-before=%zu, stack-size-after=%zu", + stack, base_type, base_type->id, + base_len, stack->size, stack->size + 1); + + if (stack->entries->len == stack->size) { + g_array_set_size(stack->entries, stack->size + 1); + } + + entry = &g_array_index(stack->entries, struct stack_entry, stack->size); + entry->base_type = base_type; + entry->base_len = base_len; + entry->index = 0; + stack->size++; + return 0; +} + static inline int64_t get_compound_field_type_length(struct bt_btr *btr, - struct bt_field_type *field_type) + struct ctf_field_type *ft) { int64_t length; - 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); + switch (ft->id) { + case CTF_FIELD_TYPE_ID_STRUCT: + { + struct ctf_field_type_struct *struct_ft = (void *) ft; + + length = (int64_t) struct_ft->members->len; break; - case BT_FIELD_TYPE_ID_VARIANT: + } + case CTF_FIELD_TYPE_ID_VARIANT: + { /* Variant field types always "contain" a single type */ length = 1; break; - case BT_FIELD_TYPE_ID_ARRAY: - length = bt_field_type_array_get_length(field_type); + } + case CTF_FIELD_TYPE_ID_ARRAY: + { + struct ctf_field_type_array *array_ft = (void *) ft; + + length = (int64_t) array_ft->length; break; - case BT_FIELD_TYPE_ID_SEQUENCE: - length = btr->user.cbs.query.get_sequence_length(field_type, + } + case CTF_FIELD_TYPE_ID_SEQUENCE: + length = btr->user.cbs.query.get_sequence_length(ft, btr->user.data); break; default: - 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; + abort(); } return length; } static -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_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) { - BT_LOGE("Failed to allocate one stack entry: stack-addr=%p", - stack); - ret = BT_BTR_STATUS_ERROR; - goto end; - } - - entry->base_type = base_type; - bt_get(entry->base_type); - entry->base_len = base_len; - g_ptr_array_add(stack->entries, entry); - -end: - return ret; -} - -static -int stack_push_with_len(struct bt_btr *btr, - struct bt_field_type *base_type) +int stack_push_with_len(struct bt_btr *btr, struct ctf_field_type *base_type) { - int ret = 0; - int64_t base_len = get_compound_field_type_length(btr, base_type); + int ret; + int64_t length = get_compound_field_type_length(btr, base_type); - if (base_len < 0) { + if (length < 0) { 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))); + "btr-addr=%p, ft-addr=%p, ft-id=%d", + btr, base_type, base_type->id); ret = BT_BTR_STATUS_ERROR; goto end; } - ret = stack_push(btr->stack, base_type, (size_t) base_len); + ret = stack_push(btr->stack, base_type, (size_t) length); end: return ret; @@ -315,20 +306,19 @@ end: static inline unsigned int stack_size(struct stack *stack) { - assert(stack); - - return stack->entries->len; + BT_ASSERT(stack); + return stack->size; } 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); + stack->size--; } static inline @@ -340,22 +330,17 @@ bool stack_empty(struct stack *stack) static void stack_clear(struct stack *stack) { - assert(stack); - - if (!stack_empty(stack)) { - g_ptr_array_remove_range(stack->entries, 0, stack_size(stack)); - } - - assert(stack_empty(stack)); + BT_ASSERT(stack); + stack->size = 0; } static inline struct stack_entry *stack_top(struct stack *stack) { - assert(stack); - assert(stack_size(stack)); - - return g_ptr_array_index(stack->entries, stack->entries->len - 1); + BT_ASSERT(stack); + BT_ASSERT(stack_size(stack)); + return &g_array_index(stack->entries, struct stack_entry, + stack->size - 1); } static inline @@ -409,50 +394,6 @@ size_t buf_at_from_addr(struct bt_btr *btr) return btr->buf.offset + btr->buf.at; } -static inline -int get_basic_field_type_size(struct bt_btr *btr, - struct bt_field_type *field_type) -{ - int size; - - 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_FIELD_TYPE_ID_FLOAT: - { - int exp_dig, mant_dig; - - exp_dig = - bt_field_type_floating_point_get_exponent_digits( - field_type); - mant_dig = - bt_field_type_floating_point_get_mantissa_digits( - field_type); - assert(exp_dig >= 0); - assert(mant_dig >= 0); - size = exp_dig + mant_dig; - break; - } - case BT_FIELD_TYPE_ID_ENUM: - { - struct bt_field_type *int_type; - - int_type = bt_field_type_enumeration_get_container_type( - field_type); - assert(int_type); - size = get_basic_field_type_size(btr, int_type); - BT_PUT(int_type); - break; - } - default: - size = BT_BTR_STATUS_ERROR; - break; - } - - return size; -} - static void stitch_reset(struct bt_btr *btr) { @@ -471,7 +412,7 @@ void stitch_append_from_buf(struct bt_btr *btr, size_t sz) { size_t stitch_byte_at; size_t buf_byte_at; - size_t nb_bytes;; + size_t nb_bytes; if (sz == 0) { return; @@ -481,7 +422,8 @@ void stitch_append_from_buf(struct bt_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; @@ -503,53 +445,42 @@ void stitch_set_from_remaining_buf(struct bt_btr *btr) } static inline -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) +void read_unsigned_bitfield(const uint8_t *buf, size_t at, + unsigned int field_size, enum ctf_byte_order bo, + uint64_t *v) { - enum bt_btr_status status = BT_BTR_STATUS_OK; - switch (bo) { - case BT_BYTE_ORDER_BIG_ENDIAN: - case BT_BYTE_ORDER_NETWORK: + case CTF_BYTE_ORDER_BIG: bt_bitfield_read_be(buf, uint8_t, at, field_size, v); break; - case BT_BYTE_ORDER_LITTLE_ENDIAN: + case CTF_BYTE_ORDER_LITTLE: bt_bitfield_read_le(buf, uint8_t, at, field_size, v); break; default: - 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; + BT_LOGV("Read unsigned bit array: cur=%zu, size=%u, " + "bo=%d, val=%" PRIu64, at, field_size, bo, *v); } static inline -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) +void read_signed_bitfield(const uint8_t *buf, size_t at, + unsigned int field_size, enum ctf_byte_order bo, int64_t *v) { - enum bt_btr_status status = BT_BTR_STATUS_OK; - switch (bo) { - case BT_BYTE_ORDER_BIG_ENDIAN: - case BT_BYTE_ORDER_NETWORK: + case CTF_BYTE_ORDER_BIG: bt_bitfield_read_be(buf, uint8_t, at, field_size, v); break; - case BT_BYTE_ORDER_LITTLE_ENDIAN: + case CTF_BYTE_ORDER_LITTLE: bt_bitfield_read_le(buf, uint8_t, at, field_size, v); break; default: - 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; + BT_LOGV("Read signed bit array: cur=%zu, size=%u, " + "bo=%d, val=%" PRId64, at, field_size, bo, *v); } typedef enum bt_btr_status (* read_basic_and_call_cb_t)(struct bt_btr *, @@ -557,7 +488,7 @@ typedef enum bt_btr_status (* read_basic_and_call_cb_t)(struct bt_btr *, static inline enum bt_btr_status validate_contiguous_bo(struct bt_btr *btr, - enum bt_byte_order next_bo) + enum ctf_byte_order next_bo) { enum bt_btr_status status = BT_BTR_STATUS_OK; @@ -567,26 +498,24 @@ enum bt_btr_status validate_contiguous_bo(struct bt_btr *btr, } /* Always valid if last byte order is unknown */ - if (btr->last_bo == BT_BYTE_ORDER_UNKNOWN) { + if (btr->last_bo == -1) { goto end; } /* Always valid if next byte order is unknown */ - if (next_bo == BT_BYTE_ORDER_UNKNOWN) { + if (next_bo == -1) { goto end; } /* Make sure last byte order is compatible with the next byte order */ switch (btr->last_bo) { - 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) { + case CTF_BYTE_ORDER_BIG: + if (next_bo != CTF_BYTE_ORDER_BIG) { status = BT_BTR_STATUS_ERROR; } break; - case BT_BYTE_ORDER_LITTLE_ENDIAN: - if (next_bo != BT_BYTE_ORDER_LITTLE_ENDIAN) { + case CTF_BYTE_ORDER_LITTLE: + if (next_bo != CTF_BYTE_ORDER_LITTLE) { status = BT_BTR_STATUS_ERROR; } break; @@ -597,9 +526,8 @@ enum bt_btr_status validate_contiguous_bo(struct bt_btr *btr, 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)); + "btr-addr=%p, last-bo=%d, next-bo=%d", + btr, btr->last_bo, next_bo); } return status; @@ -609,14 +537,15 @@ static 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_byte_order bo; + unsigned int field_size; + enum ctf_byte_order bo; enum bt_btr_status status = BT_BTR_STATUS_OK; + struct ctf_field_type_float *ft = (void *) btr->cur_basic_field_type; - field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type); - bo = bt_field_type_get_byte_order(btr->cur_basic_field_type); + BT_ASSERT(ft); + field_size = ft->base.size; + bo = ft->base.byte_order; btr->cur_bo = bo; switch (field_size) { @@ -628,20 +557,7 @@ enum bt_btr_status read_basic_float_and_call_cb(struct bt_btr *btr, float f; } f32; - ret = bt_field_type_floating_point_get_mantissa_digits( - btr->cur_basic_field_type); - assert(ret == 24); - ret = bt_field_type_floating_point_get_exponent_digits( - btr->cur_basic_field_type); - assert(ret == 8); - status = read_unsigned_bitfield(buf, at, field_size, bo, &v); - 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; - } - + read_unsigned_bitfield(buf, at, field_size, bo, &v); f32.u = (uint32_t) v; dblval = (double) f32.f; break; @@ -653,30 +569,13 @@ enum bt_btr_status read_basic_float_and_call_cb(struct bt_btr *btr, double d; } f64; - ret = bt_field_type_floating_point_get_mantissa_digits( - btr->cur_basic_field_type); - assert(ret == 53); - ret = bt_field_type_floating_point_get_exponent_digits( - btr->cur_basic_field_type); - assert(ret == 11); - status = read_unsigned_bitfield(buf, at, field_size, bo, - &f64.u); - 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; - } - + read_unsigned_bitfield(buf, at, field_size, bo, &f64.u); dblval = f64.d; break; } default: /* Only 32-bit and 64-bit fields are supported currently */ - 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; + abort(); } BT_LOGV("Read floating point number value: btr=%p, cur=%zu, val=%f", @@ -694,32 +593,20 @@ enum bt_btr_status read_basic_float_and_call_cb(struct bt_btr *btr, } } -end: return status; } static inline -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) +enum bt_btr_status read_basic_int_and_call_cb(struct bt_btr *btr, + const uint8_t *buf, size_t at) { - bt_bool signd; - int64_t field_size; - enum bt_byte_order bo; + unsigned int field_size; + enum ctf_byte_order bo; enum bt_btr_status status = BT_BTR_STATUS_OK; + struct ctf_field_type_int *ft = (void *) btr->cur_basic_field_type; - signd = bt_field_type_integer_is_signed(int_type); - field_size = get_basic_field_type_size(btr, int_type); - if (field_size < 1) { - 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_field_type_get_byte_order(int_type); + field_size = ft->base.size; + bo = ft->base.byte_order; /* * Update current byte order now because we could be reading @@ -728,16 +615,10 @@ enum bt_btr_status read_basic_int_and_call(struct bt_btr *btr, */ btr->cur_bo = bo; - if (signd) { + if (ft->is_signed) { int64_t v; - status = read_signed_bitfield(buf, at, field_size, bo, &v); - 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; - } + read_signed_bitfield(buf, at, field_size, bo, &v); if (btr->user.cbs.types.signed_int) { BT_LOGV("Calling user function (signed integer)."); @@ -754,13 +635,7 @@ enum bt_btr_status read_basic_int_and_call(struct bt_btr *btr, } else { uint64_t v; - status = read_unsigned_bitfield(buf, at, field_size, bo, &v); - 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; - } + read_unsigned_bitfield(buf, at, field_size, bo, &v); if (btr->user.cbs.types.unsigned_int) { BT_LOGV("Calling user function (unsigned integer)."); @@ -776,42 +651,18 @@ enum bt_btr_status read_basic_int_and_call(struct bt_btr *btr, } } -end: - return status; -} - -static -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_btr_status read_basic_enum_and_call_cb(struct bt_btr *btr, - const uint8_t *buf, size_t at) -{ - struct bt_field_type *int_field_type; - enum bt_btr_status status = BT_BTR_STATUS_OK; - - int_field_type = bt_field_type_enumeration_get_container_type( - btr->cur_basic_field_type); - assert(int_field_type); - status = read_basic_int_and_call(btr, buf, at, - int_field_type, btr->cur_basic_field_type); - bt_put(int_field_type); return status; } static inline -enum bt_btr_status read_basic_type_and_call_continue(struct bt_btr *btr, +enum bt_btr_status read_bit_array_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; + size_t needed_bits; enum bt_btr_status status = BT_BTR_STATUS_OK; + struct ctf_field_type_bit_array *ft = + (void *) btr->cur_basic_field_type; if (!at_least_one_bit_left(btr)) { BT_LOGV("Reached end of data: btr-addr=%p", btr); @@ -819,21 +670,12 @@ enum bt_btr_status read_basic_type_and_call_continue(struct bt_btr *btr, goto end; } - field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type); - if (field_size < 1) { - 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; + needed_bits = ft->size - btr->stitch.at; BT_LOGV("Continuing basic field decoding: " - "btr-addr=%p, field-size=%" PRId64 ", needed-size=%" PRId64 ", " + "btr-addr=%p, field-size=%u, needed-size=%" PRId64 ", " "available-size=%zu", - btr, field_size, needed_bits, available); + btr, ft->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); @@ -869,13 +711,13 @@ end: } static inline -enum bt_btr_status read_basic_type_and_call_begin(struct bt_btr *btr, +enum bt_btr_status read_bit_array_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_byte_order bo; enum bt_btr_status status = BT_BTR_STATUS_OK; + struct ctf_field_type_bit_array *ft = + (void *) btr->cur_basic_field_type; if (!at_least_one_bit_left(btr)) { BT_LOGV("Reached end of data: btr-addr=%p", btr); @@ -883,17 +725,7 @@ enum bt_btr_status read_basic_type_and_call_begin(struct bt_btr *btr, goto end; } - field_size = get_basic_field_type_size(btr, btr->cur_basic_field_type); - if (field_size < 1) { - 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_field_type_get_byte_order(btr->cur_basic_field_type); - status = validate_contiguous_bo(btr, bo); + status = validate_contiguous_bo(btr, ft->byte_order); if (status != BT_BTR_STATUS_OK) { /* validate_contiguous_bo() logs errors */ goto end; @@ -901,8 +733,9 @@ enum bt_btr_status read_basic_type_and_call_begin(struct bt_btr *btr, available = available_bits(btr); - if (field_size <= available) { + if (ft->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_BTR_STATUS_OK) { @@ -913,7 +746,7 @@ enum bt_btr_status read_basic_type_and_call_begin(struct bt_btr *btr, goto end; } - consume_bits(btr, field_size); + consume_bits(btr, ft->size); if (stack_empty(btr->stack)) { /* Root is a basic type */ @@ -942,14 +775,14 @@ static inline 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); + return read_bit_array_type_and_call_begin(btr, read_basic_int_and_call_cb); } static inline enum bt_btr_status read_basic_int_type_and_call_continue( struct bt_btr *btr) { - return read_basic_type_and_call_continue(btr, + return read_bit_array_type_and_call_continue(btr, read_basic_int_and_call_cb); } @@ -957,7 +790,7 @@ static inline enum bt_btr_status read_basic_float_type_and_call_begin( struct bt_btr *btr) { - return read_basic_type_and_call_begin(btr, + return read_bit_array_type_and_call_begin(btr, read_basic_float_and_call_cb); } @@ -965,26 +798,10 @@ static inline enum bt_btr_status read_basic_float_type_and_call_continue( struct bt_btr *btr) { - return read_basic_type_and_call_continue(btr, + return read_bit_array_type_and_call_continue(btr, read_basic_float_and_call_cb); } -static inline -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_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_btr_status read_basic_string_type_and_call( struct bt_btr *btr, bool begin) @@ -1001,9 +818,10 @@ enum bt_btr_status read_basic_string_type_and_call( 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); @@ -1097,28 +915,20 @@ enum bt_btr_status read_basic_begin_state(struct bt_btr *btr) { enum bt_btr_status status; - assert(btr->cur_basic_field_type); + BT_ASSERT(btr->cur_basic_field_type); - switch (bt_field_type_get_type_id(btr->cur_basic_field_type)) { - case BT_FIELD_TYPE_ID_INTEGER: + switch (btr->cur_basic_field_type->id) { + case CTF_FIELD_TYPE_ID_INT: + case CTF_FIELD_TYPE_ID_ENUM: status = read_basic_int_type_and_call_begin(btr); break; - case BT_FIELD_TYPE_ID_FLOAT: + case CTF_FIELD_TYPE_ID_FLOAT: status = read_basic_float_type_and_call_begin(btr); break; - case BT_FIELD_TYPE_ID_ENUM: - status = read_basic_enum_type_and_call_begin(btr); - break; - case BT_FIELD_TYPE_ID_STRING: + case CTF_FIELD_TYPE_ID_STRING: status = read_basic_string_type_and_call(btr, true); break; default: - 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(); } @@ -1130,28 +940,20 @@ enum bt_btr_status read_basic_continue_state(struct bt_btr *btr) { enum bt_btr_status status; - assert(btr->cur_basic_field_type); + BT_ASSERT(btr->cur_basic_field_type); - switch (bt_field_type_get_type_id(btr->cur_basic_field_type)) { - case BT_FIELD_TYPE_ID_INTEGER: + switch (btr->cur_basic_field_type->id) { + case CTF_FIELD_TYPE_ID_INT: + case CTF_FIELD_TYPE_ID_ENUM: status = read_basic_int_type_and_call_continue(btr); break; - case BT_FIELD_TYPE_ID_FLOAT: + case CTF_FIELD_TYPE_ID_FLOAT: status = read_basic_float_type_and_call_continue(btr); break; - case BT_FIELD_TYPE_ID_ENUM: - status = read_basic_enum_type_and_call_continue(btr); - break; - case BT_FIELD_TYPE_ID_STRING: + case CTF_FIELD_TYPE_ID_STRING: status = read_basic_string_type_and_call(btr, false); break; default: - 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(); } @@ -1169,34 +971,23 @@ size_t bits_to_skip_to_align_to(struct bt_btr *btr, size_t align) static inline enum bt_btr_status align_type_state(struct bt_btr *btr, - struct bt_field_type *field_type, enum btr_state next_state) + struct ctf_field_type *field_type, enum btr_state next_state) { - int field_alignment; + unsigned int field_alignment; size_t skip_bits; enum bt_btr_status status = BT_BTR_STATUS_OK; /* Get field's alignment */ - field_alignment = bt_field_type_get_alignment(field_type); - if (field_alignment < 0) { - 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; - } + field_alignment = field_type->alignment; /* * 0 means "undefined" for variants; what we really want is 1 * (always aligned) */ - if (field_alignment == 0) { - field_alignment = 1; - } + BT_ASSERT(field_alignment >= 1); /* Compute how many bits we need to skip */ - skip_bits = bits_to_skip_to_align_to(btr, field_alignment); + skip_bits = bits_to_skip_to_align_to(btr, (size_t) field_alignment); /* Nothing to skip? aligned */ if (skip_bits == 0) { @@ -1229,21 +1020,12 @@ end: return status; } -static inline -bool is_compound_type(struct bt_field_type *field_type) -{ - enum bt_field_type_id id = bt_field_type_get_type_id(field_type); - - 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_btr_status next_field_state(struct bt_btr *btr) { int ret; struct stack_entry *top; - struct bt_field_type *next_field_type = NULL; + struct ctf_field_type *next_field_type = NULL; enum bt_btr_status status = BT_BTR_STATUS_OK; if (stack_empty(btr->stack)) { @@ -1280,29 +1062,24 @@ enum bt_btr_status next_field_state(struct bt_btr *btr) } /* Get next field's type */ - 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_FIELD_TYPE_ID_ARRAY: - next_field_type = - bt_field_type_array_get_element_type( - top->base_type); + switch (top->base_type->id) { + case CTF_FIELD_TYPE_ID_STRUCT: + next_field_type = ctf_field_type_struct_borrow_member_by_index( + (void *) top->base_type, (uint64_t) top->index)->ft; break; - case BT_FIELD_TYPE_ID_SEQUENCE: - next_field_type = - bt_field_type_sequence_get_element_type( - top->base_type); + case CTF_FIELD_TYPE_ID_ARRAY: + case CTF_FIELD_TYPE_ID_SEQUENCE: + { + struct ctf_field_type_array_base *array_ft = + (void *) top->base_type; + + next_field_type = array_ft->elem_ft; break; - case BT_FIELD_TYPE_ID_VARIANT: + } + case CTF_FIELD_TYPE_ID_VARIANT: /* Variant types are dynamic: query the user, he should know! */ next_field_type = - btr->user.cbs.query.get_variant_type( + btr->user.cbs.query.borrow_variant_selected_field_type( top->base_type, btr->user.data); break; default: @@ -1311,17 +1088,14 @@ enum bt_btr_status next_field_state(struct bt_btr *btr) if (!next_field_type) { BT_LOGW("Cannot get the field type of the next field: " - "btr-addr=%p, base-ft-addr=%p, base-ft-id=%s, " + "btr-addr=%p, base-ft-addr=%p, base-ft-id=%d, " "index=%" PRId64, - btr, top->base_type, - bt_field_type_id_string( - bt_field_type_get_type_id(top->base_type)), - top->index); + btr, top->base_type, top->base_type->id, top->index); status = BT_BTR_STATUS_ERROR; goto end; } - if (is_compound_type(next_field_type)) { + if (next_field_type->is_compound) { if (btr->user.cbs.types.compound_begin) { BT_LOGV("Calling user function (compound, begin)."); status = btr->user.cbs.types.compound_begin( @@ -1350,15 +1124,13 @@ enum bt_btr_status next_field_state(struct bt_btr *btr) "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); + btr->cur_basic_field_type = next_field_type; /* Next state: align a basic type */ btr->state = BTR_STATE_ALIGN_BASIC; } end: - BT_PUT(next_field_type); - return status; } @@ -1397,6 +1169,7 @@ enum bt_btr_status handle_state(struct bt_btr *btr) return status; } +BT_HIDDEN struct bt_btr *bt_btr_create(struct bt_btr_cbs cbs, void *data) { struct bt_btr *btr; @@ -1425,6 +1198,7 @@ end: return btr; } +BT_HIDDEN void bt_btr_destroy(struct bt_btr *btr) { if (btr->stack) { @@ -1432,7 +1206,6 @@ void bt_btr_destroy(struct bt_btr *btr) } BT_LOGD("Destroying BTR: addr=%p", btr); - BT_PUT(btr->cur_basic_field_type); g_free(btr); } @@ -1441,10 +1214,9 @@ 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_BYTE_ORDER_UNKNOWN; + btr->last_bo = -1; } static @@ -1457,15 +1229,14 @@ void update_packet_offset(struct bt_btr *btr) btr->buf.packet_offset += btr->buf.at; } +BT_HIDDEN size_t bt_btr_start(struct bt_btr *btr, - struct bt_field_type *type, const uint8_t *buf, + struct ctf_field_type *type, const uint8_t *buf, size_t offset, size_t packet_offset, size_t sz, 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; @@ -1481,7 +1252,7 @@ size_t bt_btr_start(struct bt_btr *btr, btr, type, buf, sz, offset, packet_offset); /* Set root type */ - if (is_compound_type(type)) { + if (type->is_compound) { /* Compound type: push on visit stack */ int stack_ret; @@ -1509,7 +1280,6 @@ size_t bt_btr_start(struct bt_btr *btr, } else { /* Basic type: set as current basic type */ btr->cur_basic_field_type = type; - bt_get(btr->cur_basic_field_type); btr->state = BTR_STATE_ALIGN_BASIC; } @@ -1531,13 +1301,13 @@ end: return btr->buf.at; } -size_t bt_btr_continue(struct bt_btr *btr, - const uint8_t *buf, size_t sz, - enum bt_btr_status *status) +BT_HIDDEN +size_t bt_btr_continue(struct bt_btr *btr, const uint8_t *buf, size_t sz, + 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; @@ -1563,3 +1333,12 @@ size_t bt_btr_continue(struct bt_btr *btr, update_packet_offset(btr); return btr->buf.at; } + +BT_HIDDEN +void bt_btr_set_unsigned_int_cb(struct bt_btr *btr, + bt_btr_unsigned_int_cb_func cb) +{ + BT_ASSERT(btr); + BT_ASSERT(cb); + btr->user.cbs.types.unsigned_int = cb; +}