From 445c347168f99d59d70373b79b81618ede74ba94 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Sat, 30 Jan 2016 01:27:18 -0500 Subject: [PATCH] ir: add user byte order to integer/float types MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The `byte_order` field of an integer/float field type gets replaced by `BIG_ENDIAN` or `LITTLE_ENDIAN` if it's set to 0 (native) once the type becomes the descendant of a trace. However, once this is set, there is no way to know that the user intended this field type's byte order to be native. The metadata string, for example, will never contain a byte order set to `native` with this behaviour. This patch adds a `user_byte_order` field to the internal integer and floating point number field type structures. This field is the one set by and returned to the user using the CTF IR API. Internally, the declaration's `byte_order` field is still used for caching the resolved byte order. This patch also modifies bt_ctf_stream_class_set_byte_order() so that it cannot fail. This is an internal, hidden function which should not be called with invalid parameters. Assertions are inserted to verify this. Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- formats/ctf/ir/event-types.c | 97 +++++++++++++------ formats/ctf/ir/event.c | 3 + formats/ctf/ir/stream-class.c | 45 +++------ formats/ctf/ir/trace.c | 7 +- .../babeltrace/ctf-ir/event-types-internal.h | 16 +++ .../babeltrace/ctf-ir/stream-class-internal.h | 4 +- 6 files changed, 99 insertions(+), 73 deletions(-) diff --git a/formats/ctf/ir/event-types.c b/formats/ctf/ir/event-types.c index 61c0404d..db144a3f 100644 --- a/formats/ctf/ir/event-types.c +++ b/formats/ctf/ir/event-types.c @@ -1867,7 +1867,6 @@ enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order( struct bt_ctf_field_type *type) { enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN; - int internal_byte_order = -1; if (!type) { goto end; @@ -1878,7 +1877,7 @@ enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order( { struct bt_ctf_field_type_integer *integer = container_of( type, struct bt_ctf_field_type_integer, parent); - internal_byte_order = integer->declaration.byte_order; + ret = integer->user_byte_order; break; } case CTF_TYPE_FLOAT: @@ -1887,26 +1886,18 @@ enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order( container_of(type, struct bt_ctf_field_type_floating_point, parent); - internal_byte_order = floating_point->declaration.byte_order; + ret = floating_point->user_byte_order; break; } default: goto end; } - switch (internal_byte_order) { - case LITTLE_ENDIAN: - ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN; - break; - case BIG_ENDIAN: - ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN; - break; - case 0: - ret = BT_CTF_BYTE_ORDER_NATIVE; - break; - default: - ret = BT_CTF_BYTE_ORDER_UNKNOWN; - } + assert(ret == BT_CTF_BYTE_ORDER_NATIVE || + ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN || + ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN || + ret == BT_CTF_BYTE_ORDER_NETWORK); + end: return ret; } @@ -2942,6 +2933,33 @@ int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type, return 0; } +static +enum bt_ctf_byte_order get_ctf_ir_byte_order(int byte_order) { + enum bt_ctf_byte_order ret; + + switch (byte_order) { + case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN: + case LITTLE_ENDIAN: + ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN; + break; + case BT_CTF_BYTE_ORDER_BIG_ENDIAN: + case BIG_ENDIAN: + ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN; + break; + case BT_CTF_BYTE_ORDER_NETWORK: + ret = BT_CTF_BYTE_ORDER_NETWORK; + break; + case BT_CTF_BYTE_ORDER_NATIVE: + ret = BT_CTF_BYTE_ORDER_NATIVE; + break; + default: + ret = BT_CTF_BYTE_ORDER_UNKNOWN; + break; + } + + return ret; +} + static void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type, int byte_order, int set_native) @@ -2950,10 +2968,17 @@ void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type, struct bt_ctf_field_type_integer, parent); if (set_native) { - integer_type->declaration.byte_order = - integer_type->declaration.byte_order == 0 ? - byte_order : integer_type->declaration.byte_order; + if (integer_type->user_byte_order == BT_CTF_BYTE_ORDER_NATIVE) { + /* + * User byte order is native, so we can set + * the real byte order. + */ + integer_type->declaration.byte_order = + byte_order; + } } else { + integer_type->user_byte_order = + get_ctf_ir_byte_order(byte_order); integer_type->declaration.byte_order = byte_order; } } @@ -2979,20 +3004,24 @@ void bt_ctf_field_type_floating_point_set_byte_order( parent); if (set_native) { - floating_point_type->declaration.byte_order = - floating_point_type->declaration.byte_order == 0 ? - byte_order : - floating_point_type->declaration.byte_order; - floating_point_type->sign.byte_order = - floating_point_type->sign.byte_order == 0 ? - byte_order : floating_point_type->sign.byte_order; - floating_point_type->mantissa.byte_order = - floating_point_type->mantissa.byte_order == 0 ? - byte_order : floating_point_type->mantissa.byte_order; - floating_point_type->exp.byte_order = - floating_point_type->exp.byte_order == 0 ? - byte_order : floating_point_type->exp.byte_order; + if (floating_point_type->user_byte_order == + BT_CTF_BYTE_ORDER_NATIVE) { + /* + * User byte order is native, so we can set + * the real byte order. + */ + floating_point_type->declaration.byte_order = + byte_order; + floating_point_type->sign.byte_order = + byte_order; + floating_point_type->mantissa.byte_order = + byte_order; + floating_point_type->exp.byte_order = + byte_order; + } } else { + floating_point_type->user_byte_order = + get_ctf_ir_byte_order(byte_order); floating_point_type->declaration.byte_order = byte_order; floating_point_type->sign.byte_order = byte_order; floating_point_type->mantissa.byte_order = byte_order; @@ -3092,6 +3121,9 @@ struct bt_ctf_field_type *bt_ctf_field_type_integer_copy( bt_get(integer->mapped_clock); copy_integer->mapped_clock = integer->mapped_clock; } + + copy_integer->user_byte_order = integer->user_byte_order; + end: return copy; } @@ -3165,6 +3197,7 @@ struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy( copy_float->sign = floating_point->sign; copy_float->mantissa = floating_point->mantissa; copy_float->exp = floating_point->exp; + copy_float->user_byte_order = floating_point->user_byte_order; end: return copy; } diff --git a/formats/ctf/ir/event.c b/formats/ctf/ir/event.c index eaa72552..14e605f0 100644 --- a/formats/ctf/ir/event.c +++ b/formats/ctf/ir/event.c @@ -1049,6 +1049,9 @@ void bt_ctf_event_class_set_native_byte_order( return; } + assert(byte_order == 0 || byte_order == LITTLE_ENDIAN || + byte_order == BIG_ENDIAN); + bt_ctf_field_type_set_native_byte_order(event_class->context, byte_order); bt_ctf_field_type_set_native_byte_order(event_class->fields, diff --git a/formats/ctf/ir/stream-class.c b/formats/ctf/ir/stream-class.c index d88b6179..14f7a618 100644 --- a/formats/ctf/ir/stream-class.c +++ b/formats/ctf/ir/stream-class.c @@ -630,52 +630,31 @@ void bt_ctf_stream_class_freeze(struct bt_ctf_stream_class *stream_class) } BT_HIDDEN -int bt_ctf_stream_class_set_byte_order(struct bt_ctf_stream_class *stream_class, - enum bt_ctf_byte_order byte_order) +void bt_ctf_stream_class_set_byte_order( + struct bt_ctf_stream_class *stream_class, int byte_order) { - int i, ret = 0; - int internal_byte_order; + int i; - /* Note that "NATIVE" means the trace's endianness, not the host's. */ - if (!stream_class || byte_order <= BT_CTF_BYTE_ORDER_UNKNOWN || - byte_order > BT_CTF_BYTE_ORDER_NETWORK) { - ret = -1; - goto end; - } - - switch (byte_order) { - case BT_CTF_BYTE_ORDER_NETWORK: - case BT_CTF_BYTE_ORDER_BIG_ENDIAN: - internal_byte_order = BIG_ENDIAN; - break; - case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN: - internal_byte_order = LITTLE_ENDIAN; - break; - default: - ret = -1; - goto end; - } - - stream_class->byte_order = internal_byte_order; + assert(stream_class); + assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN); + stream_class->byte_order = byte_order; /* Set native byte order to little or big endian */ bt_ctf_field_type_set_native_byte_order( - stream_class->event_header_type, stream_class->byte_order); + stream_class->event_header_type, byte_order); bt_ctf_field_type_set_native_byte_order( - stream_class->packet_context_type, stream_class->byte_order); + stream_class->packet_context_type, byte_order); bt_ctf_field_type_set_native_byte_order( - stream_class->event_context_type, stream_class->byte_order); + stream_class->event_context_type, byte_order); /* Set all events' native byte order */ for (i = 0; i < stream_class->event_classes->len; i++) { - struct bt_ctf_event_class *event_class; + struct bt_ctf_event_class *event_class = + g_ptr_array_index(stream_class->event_classes, i); - event_class = g_ptr_array_index(stream_class->event_classes, i); bt_ctf_event_class_set_native_byte_order(event_class, - stream_class->byte_order); + byte_order); } -end: - return ret; } BT_HIDDEN diff --git a/formats/ctf/ir/trace.c b/formats/ctf/ir/trace.c index 70ac2b45..21718ac9 100644 --- a/formats/ctf/ir/trace.c +++ b/formats/ctf/ir/trace.c @@ -473,12 +473,7 @@ int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace, */ bt_ctf_field_type_set_native_byte_order(trace->packet_header_type, trace->byte_order); - ret = bt_ctf_stream_class_set_byte_order(stream_class, - trace->byte_order == LITTLE_ENDIAN ? - BT_CTF_BYTE_ORDER_LITTLE_ENDIAN : BT_CTF_BYTE_ORDER_BIG_ENDIAN); - if (ret) { - goto end; - } + bt_ctf_stream_class_set_byte_order(stream_class, trace->byte_order); bt_ctf_stream_class_freeze(stream_class); if (!trace->frozen) { diff --git a/include/babeltrace/ctf-ir/event-types-internal.h b/include/babeltrace/ctf-ir/event-types-internal.h index 1dea88d0..d7a3c3b7 100644 --- a/include/babeltrace/ctf-ir/event-types-internal.h +++ b/include/babeltrace/ctf-ir/event-types-internal.h @@ -77,6 +77,14 @@ struct bt_ctf_field_type_integer { struct bt_ctf_field_type parent; struct declaration_integer declaration; struct bt_ctf_clock *mapped_clock; + + /* + * This is what the user sets and is never modified by internal + * code. + * + * This field must contain a `BT_CTF_BYTE_ORDER_*` value. + */ + enum bt_ctf_byte_order user_byte_order; }; struct enumeration_mapping { @@ -105,6 +113,14 @@ struct bt_ctf_field_type_floating_point { struct declaration_integer sign; struct declaration_integer mantissa; struct declaration_integer exp; + + /* + * This is what the user sets and is never modified by internal + * code. + * + * This field must contain a `BT_CTF_BYTE_ORDER_*` value. + */ + enum bt_ctf_byte_order user_byte_order; }; struct structure_field { diff --git a/include/babeltrace/ctf-ir/stream-class-internal.h b/include/babeltrace/ctf-ir/stream-class-internal.h index 88d38c21..94dc6206 100644 --- a/include/babeltrace/ctf-ir/stream-class-internal.h +++ b/include/babeltrace/ctf-ir/stream-class-internal.h @@ -60,8 +60,8 @@ int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class, struct metadata_context *context); BT_HIDDEN -int bt_ctf_stream_class_set_byte_order(struct bt_ctf_stream_class *stream_class, - enum bt_ctf_byte_order byte_order); +void bt_ctf_stream_class_set_byte_order( + struct bt_ctf_stream_class *stream_class, int byte_order); /* Set stream_class id without checking if the stream class is frozen */ BT_HIDDEN -- 2.34.1