X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=formats%2Fctf%2Fir%2Ftrace.c;h=e7dcfdaede408f32953414c5dfbeae9fdd3633e4;hb=b8248cc00f72ac2448c697c76033c8862d8db673;hp=fb897dabeea5e91ab804c9c1c4a06dcfde75dc21;hpb=4ed90fb3c1b2f7912d65b905d960274ce3738e0d;p=babeltrace.git diff --git a/formats/ctf/ir/trace.c b/formats/ctf/ir/trace.c index fb897dab..e7dcfdae 100644 --- a/formats/ctf/ir/trace.c +++ b/formats/ctf/ir/trace.c @@ -34,12 +34,11 @@ #include #include #include +#include #define DEFAULT_IDENTIFIER_SIZE 128 #define DEFAULT_METADATA_STRING_SIZE 4096 -static -void environment_variable_destroy(struct environment_variable *var); static void bt_ctf_trace_destroy(struct bt_ctf_ref *ref); static @@ -74,16 +73,13 @@ struct bt_ctf_trace *bt_ctf_trace_create(void) bt_ctf_trace_set_byte_order(trace, BT_CTF_BYTE_ORDER_NATIVE); bt_ctf_ref_init(&trace->ref_count); - trace->environment = g_ptr_array_new_with_free_func( - (GDestroyNotify)environment_variable_destroy); trace->clocks = g_ptr_array_new_with_free_func( (GDestroyNotify)bt_ctf_clock_put); trace->streams = g_ptr_array_new_with_free_func( (GDestroyNotify)bt_ctf_stream_put); trace->stream_classes = g_ptr_array_new_with_free_func( (GDestroyNotify)bt_ctf_stream_class_put); - if (!trace->environment || !trace->clocks || - !trace->stream_classes || !trace->streams) { + if (!trace->clocks || !trace->stream_classes || !trace->streams) { goto error_destroy; } @@ -93,6 +89,12 @@ struct bt_ctf_trace *bt_ctf_trace_create(void) goto error_destroy; } + /* Create the environment array object */ + trace->environment = bt_ctf_attributes_create(); + if (!trace->environment) { + goto error_destroy; + } + return trace; error_destroy: @@ -112,7 +114,7 @@ void bt_ctf_trace_destroy(struct bt_ctf_ref *ref) trace = container_of(ref, struct bt_ctf_trace, ref_count); if (trace->environment) { - g_ptr_array_free(trace->environment, TRUE); + bt_ctf_attributes_destroy(trace->environment); } if (trace->clocks) { @@ -155,143 +157,95 @@ struct bt_ctf_stream *bt_ctf_trace_create_stream(struct bt_ctf_trace *trace, } if (!stream_class_found) { - int64_t stream_id = bt_ctf_stream_class_get_id(stream_class); - - if (stream_id < 0) { - /* Try to assign a new stream id */ - if (_bt_ctf_stream_class_set_id(stream->stream_class, - trace->next_stream_id++)) { - goto error; - } - } - - for (i = 0; i < trace->stream_classes->len; i++) { - if (stream_id == bt_ctf_stream_class_get_id( - trace->stream_classes->pdata[i])) { - /* Duplicate stream id found */ - goto error; - } + ret = bt_ctf_trace_add_stream_class(trace, stream_class); + if (ret) { + goto error; } - bt_ctf_stream_class_get(stream->stream_class); - g_ptr_array_add(trace->stream_classes, stream->stream_class); } bt_ctf_stream_get(stream); g_ptr_array_add(trace->streams, stream); - /* - * Freeze the trace and its packet header. - * - * All field type byte orders set as "native" byte ordering can now be - * safely set to trace's own endianness, including the stream class'. - */ - 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 error; - } - - bt_ctf_stream_class_freeze(stream_class); - trace->frozen = 1; return stream; error: bt_ctf_stream_put(stream); return NULL; } -int bt_ctf_trace_add_environment_field(struct bt_ctf_trace *trace, - const char *name, - const char *value) +int bt_ctf_trace_set_environment_field(struct bt_ctf_trace *trace, + const char *name, struct bt_object *value) { - struct environment_variable *var = NULL; - char *escaped_value = NULL; int ret = 0; - if (!trace || !name || !value || bt_ctf_validate_identifier(name)) { + if (!trace || trace->frozen || !name || !value || + bt_ctf_validate_identifier(name) || + !(bt_object_is_integer(value) || bt_object_is_string(value))) { ret = -1; - goto error; + goto end; } if (strchr(name, ' ')) { ret = -1; - goto error; + goto end; } - var = g_new0(struct environment_variable, 1); - if (!var) { - ret = -1; - goto error; - } + ret = bt_ctf_attributes_set_field_value(trace->environment, name, + value); - var->type = BT_ENVIRONMENT_FIELD_TYPE_STRING; - escaped_value = g_strescape(value, NULL); - if (!escaped_value) { - ret = -1; - goto error; - } +end: + return ret; +} - var->name = g_string_new(name); - var->value.string = g_string_new(escaped_value); - g_free(escaped_value); - if (!var->name || !var->value.string) { +int bt_ctf_trace_set_environment_field_string(struct bt_ctf_trace *trace, + const char *name, const char *value) +{ + int ret = 0; + struct bt_object *env_value_string_obj = NULL; + + if (!trace || !name || !value) { ret = -1; - goto error; + goto end; } - g_ptr_array_add(trace->environment, var); - return ret; + env_value_string_obj = bt_object_string_create_init(value); -error: - if (var && var->name) { - g_string_free(var->name, TRUE); + if (!env_value_string_obj) { + ret = -1; + goto end; } - if (var && var->value.string) { - g_string_free(var->value.string, TRUE); - } + ret = bt_ctf_trace_set_environment_field(trace, name, + env_value_string_obj); + +end: + BT_OBJECT_PUT(env_value_string_obj); - g_free(var); return ret; } -int bt_ctf_trace_add_environment_field_integer(struct bt_ctf_trace *trace, - const char *name, - int64_t value) +int bt_ctf_trace_set_environment_field_integer(struct bt_ctf_trace *trace, + const char *name, int64_t value) { - struct environment_variable *var = NULL; int ret = 0; + struct bt_object *env_value_integer_obj = NULL; if (!trace || !name) { ret = -1; - goto error; - } - - var = g_new0(struct environment_variable, 1); - if (!var) { - ret = -1; - goto error; + goto end; } - var->type = BT_ENVIRONMENT_FIELD_TYPE_INTEGER; - var->name = g_string_new(name); - var->value.integer = value; - if (!var->name) { + env_value_integer_obj = bt_object_integer_create_init(value); + if (!env_value_integer_obj) { ret = -1; - goto error; + goto end; } - g_ptr_array_add(trace->environment, var); - return ret; + ret = bt_ctf_trace_set_environment_field(trace, name, + env_value_integer_obj); -error: - if (var && var->name) { - g_string_free(var->name, TRUE); - } +end: + BT_OBJECT_PUT(env_value_integer_obj); - g_free(var); return ret; } @@ -304,82 +258,55 @@ int bt_ctf_trace_get_environment_field_count(struct bt_ctf_trace *trace) goto end; } - ret = trace->environment->len; -end: - return ret; -} - -enum bt_environment_field_type -bt_ctf_trace_get_environment_field_type(struct bt_ctf_trace *trace, int index) -{ - struct environment_variable *var; - enum bt_environment_field_type type = BT_ENVIRONMENT_FIELD_TYPE_UNKNOWN; - - if (!trace || index < 0 || index >= trace->environment->len) { - goto end; - } + ret = bt_ctf_attributes_get_count(trace->environment); - var = g_ptr_array_index(trace->environment, index); - type = var->type; end: - return type; + return ret; } const char * bt_ctf_trace_get_environment_field_name(struct bt_ctf_trace *trace, int index) { - struct environment_variable *var; const char *ret = NULL; - if (!trace || index < 0 || index >= trace->environment->len) { + if (!trace) { goto end; } - var = g_ptr_array_index(trace->environment, index); - ret = var->name->str; + ret = bt_ctf_attributes_get_field_name(trace->environment, index); + end: return ret; } -const char * -bt_ctf_trace_get_environment_field_value_string(struct bt_ctf_trace *trace, - int index) +struct bt_object *bt_ctf_trace_get_environment_field_value( + struct bt_ctf_trace *trace, int index) { - struct environment_variable *var; - const char *ret = NULL; + struct bt_object *ret = NULL; - if (!trace || index < 0 || index >= trace->environment->len) { + if (!trace) { goto end; } - var = g_ptr_array_index(trace->environment, index); - if (var->type != BT_ENVIRONMENT_FIELD_TYPE_STRING) { - goto end; - } - ret = var->value.string->str; + ret = bt_ctf_attributes_get_field_value(trace->environment, index); + end: return ret; } -int -bt_ctf_trace_get_environment_field_value_integer(struct bt_ctf_trace *trace, - int index, int64_t *value) +struct bt_object *bt_ctf_trace_get_environment_field_value_by_name( + struct bt_ctf_trace *trace, const char *name) { - struct environment_variable *var; - int ret = 0; + struct bt_object *ret = NULL; - if (!trace || !value || index < 0 || index >= trace->environment->len) { - ret = -1; + if (!trace || !name) { goto end; } - var = g_ptr_array_index(trace->environment, index); - if (var->type != BT_ENVIRONMENT_FIELD_TYPE_INTEGER) { - ret = -1; - goto end; - } - *value = var->value.integer; + ret = bt_ctf_attributes_get_field_value_by_name(trace->environment, + name); + end: return ret; } @@ -436,6 +363,130 @@ end: return clock; } +int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace, + struct bt_ctf_stream_class *stream_class) +{ + int ret, i; + int64_t stream_id; + + if (!trace || !stream_class) { + ret = -1; + goto end; + } + + for (i = 0; i < trace->stream_classes->len; i++) { + if (trace->stream_classes->pdata[i] == stream_class) { + ret = -1; + goto end; + } + } + + stream_id = bt_ctf_stream_class_get_id(stream_class); + if (stream_id < 0) { + stream_id = trace->next_stream_id++; + + /* Try to assign a new stream id */ + for (i = 0; i < trace->stream_classes->len; i++) { + if (stream_id == bt_ctf_stream_class_get_id( + trace->stream_classes->pdata[i])) { + /* Duplicate stream id found */ + ret = -1; + goto end; + } + } + + if (_bt_ctf_stream_class_set_id(stream_class, + stream_id)) { + /* TODO Should retry with a different stream id */ + ret = -1; + goto end; + } + } + + bt_ctf_stream_class_get(stream_class); + g_ptr_array_add(trace->stream_classes, stream_class); + + /* + * Freeze the trace and its packet header. + * + * All field type byte orders set as "native" byte ordering can now be + * safely set to trace's own endianness, including the stream class'. + */ + 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_freeze(stream_class); + trace->frozen = 1; + bt_ctf_attributes_freeze(trace->environment); + +end: + return ret; +} + +int bt_ctf_trace_get_stream_class_count(struct bt_ctf_trace *trace) +{ + int ret; + + if (!trace) { + ret = -1; + goto end; + } + + ret = trace->stream_classes->len; +end: + return ret; +} + +struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class( + struct bt_ctf_trace *trace, int index) +{ + struct bt_ctf_stream_class *stream_class = NULL; + + if (!trace || index < 0 || index >= trace->stream_classes->len) { + goto end; + } + + stream_class = g_ptr_array_index(trace->stream_classes, index); + bt_ctf_stream_class_get(stream_class); +end: + return stream_class; +} + +struct bt_ctf_clock *bt_ctf_trace_get_clock_by_name( + struct bt_ctf_trace *trace, const char *name) +{ + size_t i; + struct bt_ctf_clock *clock = NULL; + + if (!trace || !name) { + goto end; + } + + for (i = 0; i < trace->clocks->len; ++i) { + struct bt_ctf_clock *cur_clk = + g_ptr_array_index(trace->clocks, i); + const char *cur_clk_name = bt_ctf_clock_get_name(cur_clk); + + if (!cur_clk_name) { + goto end; + } + + if (!strcmp(cur_clk_name, name)) { + clock = cur_clk; + bt_ctf_clock_get(clock); + goto end; + } + } + +end: + return clock; +} + BT_HIDDEN const char *get_byte_order_string(int byte_order) { @@ -492,35 +543,85 @@ end: return ret; } -static -void append_env_field_metadata(struct environment_variable *var, - struct metadata_context *context) -{ - switch (var->type) { - case BT_ENVIRONMENT_FIELD_TYPE_STRING: - g_string_append_printf(context->string, "\t%s = \"%s\";\n", - var->name->str, var->value.string->str); - break; - case BT_ENVIRONMENT_FIELD_TYPE_INTEGER: - g_string_append_printf(context->string, "\t%s = %" PRId64 ";\n", - var->name->str, var->value.integer); - break; - default: - assert(0); - } -} - static void append_env_metadata(struct bt_ctf_trace *trace, struct metadata_context *context) { - if (trace->environment->len == 0) { + int i; + int env_size; + + env_size = bt_ctf_attributes_get_count(trace->environment); + + if (env_size <= 0) { return; } g_string_append(context->string, "env {\n"); - g_ptr_array_foreach(trace->environment, - (GFunc)append_env_field_metadata, context); + + for (i = 0; i < env_size; ++i) { + struct bt_object *env_field_value_obj = NULL; + const char *entry_name; + + entry_name = bt_ctf_attributes_get_field_name( + trace->environment, i); + env_field_value_obj = bt_ctf_attributes_get_field_value( + trace->environment, i); + + if (!entry_name || !env_field_value_obj) { + goto loop_next; + } + + switch (bt_object_get_type(env_field_value_obj)) { + case BT_OBJECT_TYPE_INTEGER: + { + int ret; + int64_t int_value; + + ret = bt_object_integer_get(env_field_value_obj, + &int_value); + + if (ret) { + goto loop_next; + } + + g_string_append_printf(context->string, + "\t%s = %" PRId64 ";\n", entry_name, + int_value); + break; + } + case BT_OBJECT_TYPE_STRING: + { + int ret; + const char *str_value; + char *escaped_str = NULL; + + ret = bt_object_string_get(env_field_value_obj, + &str_value); + + if (ret) { + goto loop_next; + } + + escaped_str = g_strescape(str_value, NULL); + + if (!escaped_str) { + goto loop_next; + } + + g_string_append_printf(context->string, + "\t%s = \"%s\";\n", entry_name, escaped_str); + free(escaped_str); + break; + } + + default: + goto loop_next; + } + +loop_next: + BT_OBJECT_PUT(env_field_value_obj); + } + g_string_append(context->string, "};\n\n"); } @@ -757,13 +858,3 @@ end: return ret; } - -static -void environment_variable_destroy(struct environment_variable *var) -{ - g_string_free(var->name, TRUE); - if (var->type == BT_ENVIRONMENT_FIELD_TYPE_STRING) { - g_string_free(var->value.string, TRUE); - } - g_free(var); -}