Override clock fields in copied traces
authorJulien Desfossez <jdesfossez@efficios.com>
Tue, 14 Feb 2017 17:03:00 +0000 (12:03 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 28 May 2017 16:57:39 +0000 (12:57 -0400)
Some tracers like LTTng use a compression scheme on the timestamp field
to avoid writing the full 64-bit timestamp at every event. When the
trace is complete, the reader has all the information to understand this
compression, but if a trace is filtered or truncated, there might be
some state information missing.

Since we don't know in advance if a compression scheme is used in a
trace, we now force the copied traces to have a full 64-bit timestamp.

The user of this library can decide whether or not to override the type
of the clock fields.

Signed-off-by: Julien Desfossez <jdesfossez@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
plugins/libctfcopytrace/Makefile.am
plugins/libctfcopytrace/clock-fields.c [new file with mode: 0644]
plugins/libctfcopytrace/clock-fields.h [new file with mode: 0644]
plugins/libctfcopytrace/ctfcopytrace.c
plugins/libctfcopytrace/ctfcopytrace.h
plugins/writer/write.c

index 2b2b813f3a3297a36ea083354a3f647edbc57d40..3fe8a120445d6dc2198906b06621261a0d0224b3 100644 (file)
@@ -4,7 +4,7 @@ SUBDIRS = .
 
 lib_LTLIBRARIES = libctfcopytrace.la
 
-libctfcopytrace_la_SOURCES = ctfcopytrace.c
+libctfcopytrace_la_SOURCES = ctfcopytrace.c clock-fields.c
 
 libctfcopytrace_la_LDFLAGS = -version-info $(BABELTRACE_LIBRARY_VERSION)
 
@@ -12,4 +12,4 @@ libctfcopytrace_la_LIBADD = \
        $(top_builddir)/lib/libbabeltrace.la \
        $(top_builddir)/formats/ctf/libbabeltrace-ctf.la
 
-noinst_HEADERS = ctfcopytrace.h
+noinst_HEADERS = ctfcopytrace.h clock-fields.h
diff --git a/plugins/libctfcopytrace/clock-fields.c b/plugins/libctfcopytrace/clock-fields.c
new file mode 100644 (file)
index 0000000..86f4f28
--- /dev/null
@@ -0,0 +1,925 @@
+/*
+ * clock-fields.c
+ *
+ * Babeltrace - Update clock fields to write uint64 values
+ *
+ * Copyright 2017 Julien Desfossez <jdesfossez@efficios.com>
+ *
+ * Author: Julien Desfossez <jdesfossez@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/ctf-ir/event.h>
+#include <babeltrace/ctf-ir/packet.h>
+#include <babeltrace/ctf-ir/event-class.h>
+#include <babeltrace/ctf-ir/stream.h>
+#include <babeltrace/ctf-ir/stream-class.h>
+#include <babeltrace/ctf-ir/clock-class.h>
+#include <babeltrace/ctf-ir/fields.h>
+#include <babeltrace/ctf-writer/stream.h>
+#include <babeltrace/ctf-ir/field-types.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "clock-fields.h"
+
+static
+int find_update_struct_clock_fields(FILE *err, struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *writer_clock_class);
+static
+int find_update_array_clock_fields(FILE *err, struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *writer_clock_class);
+static
+int find_update_enum_clock_fields(FILE *err, struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *writer_clock_class);
+static
+int find_update_sequence_clock_fields(FILE *err, struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *writer_clock_class);
+static
+int find_update_variant_clock_fields(FILE *err, struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *writer_clock_class);
+
+static
+int copy_find_clock_int_field(FILE *err,
+               struct bt_ctf_event *event, struct bt_ctf_event *writer_event,
+               struct bt_ctf_field *field, struct bt_ctf_field_type *type,
+               struct bt_ctf_field *copy_field);
+static
+int copy_find_clock_struct_field(FILE *err,
+               struct bt_ctf_event *event, struct bt_ctf_event *writer_event,
+               struct bt_ctf_field *field, struct bt_ctf_field_type *type,
+               struct bt_ctf_field *copy_field);
+static
+int copy_find_clock_array_field(FILE *err,
+               struct bt_ctf_event *event, struct bt_ctf_event *writer_event,
+               struct bt_ctf_field *field, struct bt_ctf_field_type *type,
+               struct bt_ctf_field *copy_field);
+static
+int copy_find_clock_sequence_field(FILE *err,
+               struct bt_ctf_event *event, struct bt_ctf_event *writer_event,
+               struct bt_ctf_field *field, struct bt_ctf_field_type *type,
+               struct bt_ctf_field *copy_field);
+static
+int copy_find_clock_variant_field(FILE *err, struct bt_ctf_event *event,
+               struct bt_ctf_event *writer_event, struct bt_ctf_field *field,
+               struct bt_ctf_field_type *type, struct bt_ctf_field *copy_field);
+static
+int copy_find_clock_enum_field(FILE *err, struct bt_ctf_event *event,
+               struct bt_ctf_event *writer_event, struct bt_ctf_field *field,
+               struct bt_ctf_field_type *type, struct bt_ctf_field *copy_field);
+
+static
+int update_header_clock_int_field_type(FILE *err, struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *writer_clock_class)
+{
+       struct bt_ctf_clock_class *clock;
+       int ret;
+
+       clock = bt_ctf_field_type_integer_get_mapped_clock_class(type);
+       if (!clock) {
+               return 0;
+       }
+       bt_put(clock);
+
+       ret = bt_ctf_field_type_integer_set_size(type, 64);
+       if (ret) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_integer_set_mapped_clock_class(type,
+                       writer_clock_class);
+       if (ret) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+static
+int find_update_clock_fields(FILE *err, struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *writer_clock_class)
+{
+       int ret;
+
+       switch (bt_ctf_field_type_get_type_id(type)) {
+       case BT_CTF_TYPE_ID_INTEGER:
+               return update_header_clock_int_field_type(err, type,
+                               writer_clock_class);
+       case BT_CTF_TYPE_ID_STRUCT:
+               return find_update_struct_clock_fields(err, type,
+                               writer_clock_class);
+       case BT_CTF_TYPE_ID_ARRAY:
+               return find_update_array_clock_fields(err, type,
+                               writer_clock_class);
+       case BT_CTF_TYPE_ID_SEQUENCE:
+               return find_update_sequence_clock_fields(err, type,
+                               writer_clock_class);
+       case BT_CTF_TYPE_ID_UNTAGGED_VARIANT:
+       case BT_CTF_TYPE_ID_VARIANT:
+               return find_update_variant_clock_fields(err, type,
+                               writer_clock_class);
+       case BT_CTF_TYPE_ID_ENUM:
+               return find_update_enum_clock_fields(err, type,
+                               writer_clock_class);
+               break;
+       default:
+               break;
+       }
+
+       ret = 0;
+
+       return ret;
+}
+
+static
+int find_update_variant_clock_fields(FILE *err, struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *writer_clock_class)
+{
+       int count, i, ret;
+
+       count = bt_ctf_field_type_variant_get_field_count(type);
+       for (i = 0; i < count; i++) {
+               struct bt_ctf_field_type *entry_type;
+               const char *entry_name;
+
+               ret = bt_ctf_field_type_variant_get_field(type,
+                               &entry_name, &entry_type, i);
+               if (ret) {
+                       fprintf(err, "[error] %s in %s:%d\n",
+                                       __func__, __FILE__, __LINE__);
+                       ret = -1;
+                       goto end;
+               }
+               ret = find_update_clock_fields(err, entry_type,
+                               writer_clock_class);
+               bt_put(entry_type);
+               if (ret) {
+                       fprintf(err, "[error] %s in %s:%d\n",
+                                       __func__, __FILE__, __LINE__);
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int find_update_struct_clock_fields(FILE *err, struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *writer_clock_class)
+{
+       int count, i, ret;
+
+       count = bt_ctf_field_type_structure_get_field_count(type);
+       for (i = 0; i < count; i++) {
+               struct bt_ctf_field_type *entry_type;
+               const char *entry_name;
+
+               ret = bt_ctf_field_type_structure_get_field(type,
+                               &entry_name, &entry_type, i);
+               if (ret) {
+                       fprintf(err, "[error] %s in %s:%d\n",
+                                       __func__, __FILE__, __LINE__);
+                       ret = -1;
+                       goto end;
+               }
+               ret = find_update_clock_fields(err, entry_type,
+                               writer_clock_class);
+               bt_put(entry_type);
+               if (ret) {
+                       fprintf(err, "[error] %s in %s:%d\n",
+                                       __func__, __FILE__, __LINE__);
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int find_update_sequence_clock_fields(FILE *err, struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *writer_clock_class)
+{
+       int ret;
+       struct bt_ctf_field_type *entry_type;
+
+       entry_type = bt_ctf_field_type_sequence_get_element_type(type);
+       ret = find_update_clock_fields(err, entry_type, writer_clock_class);
+       bt_put(entry_type);
+       if (ret) {
+               fprintf(err, "[error] %s in %s:%d\n",
+                               __func__, __FILE__, __LINE__);
+               ret = -1;
+               goto end;
+       }
+
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int find_update_array_clock_fields(FILE *err, struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *writer_clock_class)
+{
+       int ret;
+       struct bt_ctf_field_type *entry_type;
+
+       entry_type = bt_ctf_field_type_array_get_element_type(type);
+       ret = find_update_clock_fields(err, entry_type, writer_clock_class);
+       bt_put(entry_type);
+       if (ret) {
+               fprintf(err, "[error] %s in %s:%d\n",
+                               __func__, __FILE__, __LINE__);
+               ret = -1;
+               goto end;
+       }
+
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int find_update_enum_clock_fields(FILE *err, struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *writer_clock_class)
+{
+       int ret;
+       struct bt_ctf_field_type *entry_type;
+
+       entry_type = bt_ctf_field_type_enumeration_get_container_type(type);
+       ret = find_update_clock_fields(err, entry_type, writer_clock_class);
+       bt_put(entry_type);
+       if (ret) {
+               fprintf(err, "[error] %s in %s:%d\n",
+                               __func__, __FILE__, __LINE__);
+               ret = -1;
+               goto end;
+       }
+
+       ret = 0;
+
+end:
+       return ret;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type *override_header_type(FILE *err,
+               struct bt_ctf_field_type *type,
+               struct bt_ctf_trace *writer_trace)
+{
+       struct bt_ctf_field_type *new_type = NULL;
+       int ret;
+       struct bt_ctf_clock_class *writer_clock_class;
+
+       /* FIXME multi-clock? */
+       writer_clock_class = bt_ctf_trace_get_clock_class(writer_trace, 0);
+       if (!writer_clock_class) {
+               fprintf(err, "[error] %s in %s:%d\n",
+                               __func__, __FILE__, __LINE__);
+               goto end;
+       }
+
+       new_type = bt_ctf_field_type_copy(type);
+       if (!new_type) {
+               fprintf(err, "[error] %s in %s:%d\n",
+                               __func__, __FILE__, __LINE__);
+               goto end_put;
+       }
+
+       if (bt_ctf_field_type_get_type_id(new_type) != BT_CTF_TYPE_ID_STRUCT) {
+               fprintf(err, "[error] Unexpected header field type\n");
+               goto error;
+       }
+
+       ret = find_update_struct_clock_fields(err, new_type, writer_clock_class);
+       if (ret) {
+               fprintf(err, "[error] %s in %s:%d\n",
+                               __func__, __FILE__, __LINE__);
+               goto error;
+       }
+
+       goto end_put;
+
+error:
+       BT_PUT(new_type);
+end_put:
+       bt_put(writer_clock_class);
+end:
+       return new_type;
+}
+
+static
+int copy_float_field(FILE *err, struct bt_ctf_field *field,
+               struct bt_ctf_field_type *type,
+               struct bt_ctf_field *copy_field)
+{
+       double value;
+       int ret;
+
+       ret = bt_ctf_field_floating_point_get_value(field, &value);
+       if (ret) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__,
+                               __FILE__, __LINE__);
+               goto end;
+       }
+       ret = bt_ctf_field_floating_point_set_value(copy_field, value);
+       if (ret) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__,
+                               __FILE__, __LINE__);
+               goto end;
+       }
+
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int copy_string_field(FILE *err, struct bt_ctf_field *field,
+               struct bt_ctf_field_type *type,
+               struct bt_ctf_field *copy_field)
+{
+       const char *value;
+       int ret;
+
+       value = bt_ctf_field_string_get_value(field);
+       if (!value) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__,
+                               __FILE__, __LINE__);
+               goto end;
+       }
+       ret = bt_ctf_field_string_set_value(copy_field, value);
+       if (ret) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__,
+                               __FILE__, __LINE__);
+               goto end;
+       }
+
+       ret = 0;
+
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int copy_override_field(FILE *err, struct bt_ctf_event *event,
+               struct bt_ctf_event *writer_event, struct bt_ctf_field *field,
+               struct bt_ctf_field *copy_field)
+{
+       struct bt_ctf_field_type *type;
+       int ret;
+
+       type = bt_ctf_field_get_type(field);
+       if (!type) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       switch (bt_ctf_field_type_get_type_id(type)) {
+       case BT_CTF_TYPE_ID_INTEGER:
+               ret = copy_find_clock_int_field(err, event, writer_event,
+                               field, type, copy_field);
+               break;
+       case BT_CTF_TYPE_ID_STRUCT:
+               ret = copy_find_clock_struct_field(err, event, writer_event,
+                               field, type, copy_field);
+               break;
+       case BT_CTF_TYPE_ID_FLOAT:
+               ret = copy_float_field(err, field, type, copy_field);
+               break;
+       case BT_CTF_TYPE_ID_ENUM:
+               ret = copy_find_clock_enum_field(err, event, writer_event,
+                               field, type, copy_field);
+               break;
+       case BT_CTF_TYPE_ID_STRING:
+               ret = copy_string_field(err, field, type, copy_field);
+               break;
+       case BT_CTF_TYPE_ID_ARRAY:
+               ret = copy_find_clock_array_field(err, event, writer_event,
+                               field, type, copy_field);
+               break;
+       case BT_CTF_TYPE_ID_SEQUENCE:
+               ret = copy_find_clock_sequence_field(err, event, writer_event,
+                               field, type, copy_field);
+               break;
+       case BT_CTF_TYPE_ID_UNTAGGED_VARIANT:
+       case BT_CTF_TYPE_ID_VARIANT:
+               ret = copy_find_clock_variant_field(err, event, writer_event,
+                               field, type, copy_field);
+               break;
+       /* No default, we want to catch missing field types. */
+       case BT_CTF_TYPE_ID_UNKNOWN:
+       case BT_CTF_NR_TYPE_IDS:
+               break;
+       }
+
+       ret = 0;
+       bt_put(type);
+
+end:
+       return ret;
+}
+
+static
+int copy_find_clock_enum_field(FILE *err, struct bt_ctf_event *event,
+               struct bt_ctf_event *writer_event, struct bt_ctf_field *field,
+               struct bt_ctf_field_type *type, struct bt_ctf_field *copy_field)
+{
+       int ret;
+       struct bt_ctf_field *container, *copy_container;
+
+       container = bt_ctf_field_enumeration_get_container(field);
+       if (!container) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       copy_container = bt_ctf_field_enumeration_get_container(copy_field);
+       if (!copy_container) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end_put_container;
+       }
+
+       ret = copy_override_field(err, event, writer_event, container,
+                       copy_container);
+       if (ret) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end_put_copy_container;
+       }
+
+end_put_copy_container:
+       bt_put(copy_container);
+end_put_container:
+       bt_put(container);
+end:
+       return ret;
+}
+
+static
+int copy_find_clock_variant_field(FILE *err, struct bt_ctf_event *event,
+               struct bt_ctf_event *writer_event, struct bt_ctf_field *field,
+               struct bt_ctf_field_type *type, struct bt_ctf_field *copy_field)
+{
+       int ret;
+       struct bt_ctf_field *tag;
+       struct bt_ctf_field *variant_field, *copy_variant_field;
+
+       tag = bt_ctf_field_variant_get_tag(field);
+       if (!tag) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       variant_field = bt_ctf_field_variant_get_field(field, tag);
+       if (!variant_field) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end_put_tag;
+       }
+
+       copy_variant_field = bt_ctf_field_variant_get_field(copy_field, tag);
+       if (!copy_variant_field) {
+               bt_put(variant_field);
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end_put_variant_field;
+       }
+
+       ret = copy_override_field(err, event, writer_event, variant_field,
+                       copy_variant_field);
+       if (ret) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end_put_copy_variand_field;
+       }
+
+       ret = 0;
+
+end_put_copy_variand_field:
+       bt_put(copy_variant_field);
+end_put_variant_field:
+       bt_put(variant_field);
+end_put_tag:
+       bt_put(tag);
+end:
+       return ret;
+}
+
+static
+int copy_find_clock_sequence_field(FILE *err,
+               struct bt_ctf_event *event, struct bt_ctf_event *writer_event,
+               struct bt_ctf_field *field, struct bt_ctf_field_type *type,
+               struct bt_ctf_field *copy_field)
+{
+       int ret;
+       uint64_t i, count;
+       struct bt_ctf_field_type *entry_type;
+       struct bt_ctf_field *length_field;
+
+       entry_type = bt_ctf_field_type_sequence_get_element_type(type);
+       if (!entry_type) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       length_field = bt_ctf_field_sequence_get_length(field);
+       if (!length_field) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       ret = bt_ctf_field_unsigned_integer_get_value(length_field, &count);
+       if (ret) {
+               bt_put(length_field);
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       ret = bt_ctf_field_sequence_set_length(copy_field, length_field);
+       bt_put(length_field);
+       if (ret) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       for (i = 0; i < count; i++) {
+               struct bt_ctf_field *entry_field, *entry_copy;
+
+               entry_field = bt_ctf_field_sequence_get_field(field, i);
+               if (!entry_field) {
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                                       __LINE__);
+                       goto end;
+               }
+
+               entry_copy = bt_ctf_field_sequence_get_field(copy_field, i);
+               if (!entry_copy) {
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                                       __LINE__);
+                       goto end;
+               }
+
+               ret = copy_override_field(err, event, writer_event, entry_field,
+                               entry_copy);
+               bt_put(entry_field);
+               bt_put(entry_copy);
+               if (ret) {
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                                       __LINE__);
+                       goto end;
+               }
+       }
+
+       bt_put(entry_type);
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int copy_find_clock_array_field(FILE *err,
+               struct bt_ctf_event *event, struct bt_ctf_event *writer_event,
+               struct bt_ctf_field *field, struct bt_ctf_field_type *type,
+               struct bt_ctf_field *copy_field)
+{
+       int ret, count, i;
+       struct bt_ctf_field_type *entry_type;
+
+       count = bt_ctf_field_type_array_get_length(type);
+       entry_type = bt_ctf_field_type_array_get_element_type(type);
+       if (!entry_type) {
+               ret = -1;
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+       for (i = 0; i < count; i++) {
+               struct bt_ctf_field *entry_field, *entry_copy;
+
+               entry_field = bt_ctf_field_array_get_field(field, i);
+               if (!entry_field) {
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                                       __LINE__);
+                       goto end;
+               }
+
+               entry_copy = bt_ctf_field_array_get_field(copy_field, i);
+               if (!entry_copy) {
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                                       __LINE__);
+                       goto end;
+               }
+
+               ret = copy_override_field(err, event, writer_event, entry_field,
+                               entry_copy);
+               bt_put(entry_field);
+               bt_put(entry_copy);
+               if (ret) {
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                                       __LINE__);
+                       goto end;
+               }
+       }
+
+       bt_put(entry_type);
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int copy_find_clock_struct_field(FILE *err,
+               struct bt_ctf_event *event, struct bt_ctf_event *writer_event,
+               struct bt_ctf_field *field, struct bt_ctf_field_type *type,
+               struct bt_ctf_field *copy_field)
+{
+       int count, i, ret;
+
+       count = bt_ctf_field_type_structure_get_field_count(type);
+       for (i = 0; i < count; i++) {
+               struct bt_ctf_field_type *entry_type;
+               struct bt_ctf_field *entry_field;
+               const char *entry_name;
+               struct bt_ctf_field *entry_copy;
+
+               entry_field = bt_ctf_field_structure_get_field_by_index(field, i);
+               if (!entry_field) {
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                                       __LINE__);
+                       goto end;
+               }
+
+               ret = bt_ctf_field_type_structure_get_field(type, &entry_name,
+                               &entry_type, i);
+               if (ret) {
+                       bt_put(entry_field);
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n",
+                                       __func__, __FILE__, __LINE__);
+                       goto end;
+               }
+
+               entry_copy = bt_ctf_field_structure_get_field_by_index(copy_field, i);
+               if (!entry_copy) {
+                       bt_put(entry_field);
+                       bt_put(entry_type);
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                                       __LINE__);
+                       goto end;
+               }
+
+               ret = copy_override_field(err, event, writer_event, entry_field,
+                               entry_copy);
+
+               bt_put(entry_copy);
+               bt_put(entry_field);
+               bt_put(entry_type);
+               if (ret) {
+                       BT_PUT(entry_copy);
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                                       __LINE__);
+                       goto end;
+               }
+       }
+
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int set_int_value(FILE *err, struct bt_ctf_field *field,
+               struct bt_ctf_field *copy_field,
+               struct bt_ctf_field_type *type)
+{
+       uint64_t uvalue;
+       int64_t value;
+       int ret;
+
+       if (bt_ctf_field_type_integer_get_signed(type)) {
+               ret = bt_ctf_field_signed_integer_get_value(field, &value);
+               if (ret) {
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__,
+                                       __FILE__, __LINE__);
+                       goto end;
+               }
+               printf(" - v(s) = %ld\n", value);
+               ret = bt_ctf_field_signed_integer_set_value(copy_field, value);
+               if (ret) {
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__,
+                                       __FILE__, __LINE__);
+                       goto end;
+               }
+       } else {
+               ret = bt_ctf_field_unsigned_integer_get_value(field,
+                               &uvalue);
+               if (ret) {
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__,
+                                       __FILE__, __LINE__);
+                       goto end;
+               }
+               ret = bt_ctf_field_unsigned_integer_set_value(copy_field, uvalue);
+               if (ret) {
+                       ret = -1;
+                       fprintf(err, "[error] %s in %s:%d\n", __func__,
+                                       __FILE__, __LINE__);
+                       goto end;
+               }
+       }
+       ret = 0;
+
+end:
+       return ret;
+}
+
+struct bt_ctf_clock_class *stream_class_get_clock_class(FILE *err,
+               struct bt_ctf_stream_class *stream_class)
+{
+       struct bt_ctf_trace *trace;
+       struct bt_ctf_clock_class *clock_class = NULL;
+
+       trace = bt_ctf_stream_class_get_trace(stream_class);
+       if (!trace) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       /* FIXME multi-clock? */
+       clock_class = bt_ctf_trace_get_clock_class(trace, 0);
+
+       bt_put(trace);
+end:
+       return clock_class;
+}
+
+struct bt_ctf_clock_class *event_get_clock_class(FILE *err, struct bt_ctf_event *event)
+{
+       struct bt_ctf_event_class *event_class;
+       struct bt_ctf_stream_class *stream_class;
+       struct bt_ctf_clock_class *clock_class = NULL;
+
+       event_class = bt_ctf_event_get_class(event);
+       if (!event_class) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       stream_class = bt_ctf_event_class_get_stream_class(event_class);
+       if (!stream_class) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end_put_event_class;
+       }
+
+       clock_class = stream_class_get_clock_class(err, stream_class);
+       bt_put(stream_class);
+
+end_put_event_class:
+       bt_put(event_class);
+end:
+       return clock_class;
+}
+
+static
+int copy_find_clock_int_field(FILE *err,
+               struct bt_ctf_event *event, struct bt_ctf_event *writer_event,
+               struct bt_ctf_field *field, struct bt_ctf_field_type *type,
+               struct bt_ctf_field *copy_field)
+{
+       struct bt_ctf_clock_class *clock_class, *writer_clock_class;
+       struct bt_ctf_clock_value *clock_value, *writer_clock_value;
+       uint64_t value;
+       int ret;
+
+       clock_class = bt_ctf_field_type_integer_get_mapped_clock_class(type);
+       if (!clock_class) {
+               return set_int_value(err, field, copy_field, type);
+       }
+
+       clock_value = bt_ctf_event_get_clock_value(event, clock_class);
+       bt_put(clock_class);
+       if (!clock_value) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       ret = bt_ctf_clock_value_get_value(clock_value, &value);
+       bt_put(clock_value);
+       if (ret) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       ret = bt_ctf_field_unsigned_integer_set_value(copy_field, value);
+       if (ret) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       writer_clock_class = event_get_clock_class(err, writer_event);
+       if (!writer_clock_class) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       writer_clock_value = bt_ctf_clock_value_create(writer_clock_class, value);
+       bt_put(writer_clock_class);
+       if (!writer_clock_value) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       ret = bt_ctf_event_set_clock_value(writer_event, writer_clock_value);
+       bt_put(writer_clock_value);
+       if (ret) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto end;
+       }
+
+       ret = 0;
+
+end:
+       return ret;
+}
+
diff --git a/plugins/libctfcopytrace/clock-fields.h b/plugins/libctfcopytrace/clock-fields.h
new file mode 100644 (file)
index 0000000..607f9c0
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef BABELTRACE_CLOCK_FIELDS_H
+#define BABELTRACE_CLOCK_FIELDS_H
+
+/*
+ * BabelTrace - Update clock fields to write uint64 values
+ *
+ * Copyright 2017 Julien Desfossez <jdesfossez@efficios.com>
+ *
+ * Author: Julien Desfossez <jdesfossez@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdbool.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/component/component.h>
+#include <babeltrace/ctf-writer/writer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+BT_HIDDEN
+struct bt_ctf_field_type *override_header_type(FILE *err,
+               struct bt_ctf_field_type *type,
+               struct bt_ctf_trace *writer_trace);
+
+BT_HIDDEN
+int copy_override_field(FILE *err, struct bt_ctf_event *event,
+               struct bt_ctf_event *writer_event, struct bt_ctf_field *field,
+               struct bt_ctf_field *copy_field);
+
+BT_HIDDEN
+struct bt_ctf_clock_class *stream_class_get_clock_class(FILE *err,
+               struct bt_ctf_stream_class *stream_class);
+
+BT_HIDDEN
+struct bt_ctf_clock_class *event_get_clock_class(FILE *err,
+               struct bt_ctf_event *event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_CLOCK_FIELDS_H */
index 56aa7e1ddcfccf196c6f701179c8da8343d9da9e..bf120baf8fa6c2a5224adc2ac7668b9a4c57d840 100644 (file)
@@ -37,6 +37,7 @@
 #include <assert.h>
 
 #include "ctfcopytrace.h"
+#include "clock-fields.h"
 
 struct bt_ctf_clock_class *ctf_copy_clock_class(FILE *err,
                struct bt_ctf_clock_class *clock_class)
@@ -161,7 +162,6 @@ enum bt_component_status ctf_copy_clock_classes(FILE *err,
                struct bt_ctf_trace *trace)
 {
        enum bt_component_status ret;
-
        int int_ret, clock_class_count, i;
 
        clock_class_count = bt_ctf_trace_get_clock_class_count(trace);
@@ -196,7 +196,7 @@ enum bt_component_status ctf_copy_clock_classes(FILE *err,
                }
 
                /*
-                * Ownership transferred to the writer and the stream_class.
+                * Ownership transferred to the trace.
                 */
                bt_put(writer_clock_class);
        }
@@ -355,9 +355,11 @@ end:
 }
 
 struct bt_ctf_stream_class *ctf_copy_stream_class(FILE *err,
-               struct bt_ctf_stream_class *stream_class)
+               struct bt_ctf_stream_class *stream_class,
+               struct bt_ctf_trace *writer_trace,
+               bool override_ts64)
 {
-       struct bt_ctf_field_type *type;
+       struct bt_ctf_field_type *type, *new_event_header_type;
        struct bt_ctf_stream_class *writer_stream_class;
        int ret_int;
        const char *name = bt_ctf_stream_class_get_name(stream_class);
@@ -396,8 +398,22 @@ struct bt_ctf_stream_class *ctf_copy_stream_class(FILE *err,
                goto error;
        }
 
+       if (override_ts64) {
+               new_event_header_type = override_header_type(err, type,
+                               writer_trace);
+               bt_put(type);
+               if (!new_event_header_type) {
+                       fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                                       __LINE__);
+                       goto error;
+               }
+       } else {
+               new_event_header_type = type;
+       }
+
        ret_int = bt_ctf_stream_class_set_event_header_type(
-                       writer_stream_class, type);
+                       writer_stream_class, new_event_header_type);
+       bt_put(new_event_header_type);
        if (ret_int < 0) {
                fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
                                __LINE__);
@@ -493,19 +509,18 @@ end:
        return ret;
 }
 
-enum bt_component_status ctf_copy_packet_context(FILE *err,
+struct bt_ctf_field *ctf_copy_packet_context(FILE *err,
                struct bt_ctf_packet *packet,
                struct bt_ctf_stream *writer_stream)
 {
        enum bt_component_status ret;
-       struct bt_ctf_field *packet_context, *writer_packet_context;
+       struct bt_ctf_field *packet_context, *writer_packet_context = NULL;
        struct bt_ctf_field_type *struct_type, *writer_packet_context_type;
        struct bt_ctf_stream_class *writer_stream_class;
-       int nr_fields, i, int_ret;
+       int nr_fields, i;
 
        packet_context = bt_ctf_packet_get_context(packet);
        if (!packet_context) {
-               ret = BT_COMPONENT_STATUS_ERROR;
                fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
                                __LINE__);
                goto end;
@@ -513,7 +528,6 @@ enum bt_component_status ctf_copy_packet_context(FILE *err,
 
        writer_stream_class = bt_ctf_stream_get_class(writer_stream);
        if (!writer_stream_class) {
-               ret = BT_COMPONENT_STATUS_ERROR;
                fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
                                __LINE__);
                goto end_put_packet_context;
@@ -522,7 +536,6 @@ enum bt_component_status ctf_copy_packet_context(FILE *err,
        writer_packet_context_type = bt_ctf_stream_class_get_packet_context_type(
                        writer_stream_class);
        if (!writer_packet_context_type) {
-               ret = BT_COMPONENT_STATUS_ERROR;
                fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
                                __LINE__);
                goto end_put_writer_stream_class;
@@ -530,7 +543,6 @@ enum bt_component_status ctf_copy_packet_context(FILE *err,
 
        struct_type = bt_ctf_field_get_type(packet_context);
        if (!struct_type) {
-               ret = BT_COMPONENT_STATUS_ERROR;
                fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
                                __LINE__);
                goto end_put_writer_packet_context_type;
@@ -538,7 +550,6 @@ enum bt_component_status ctf_copy_packet_context(FILE *err,
 
        writer_packet_context = bt_ctf_field_create(writer_packet_context_type);
        if (!writer_packet_context) {
-               ret = BT_COMPONENT_STATUS_ERROR;
                fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
                                __LINE__);
                goto end_put_struct_type;
@@ -553,18 +564,18 @@ enum bt_component_status ctf_copy_packet_context(FILE *err,
                field =  bt_ctf_field_structure_get_field_by_index(
                                packet_context, i);
                if (!field) {
-                       ret = BT_COMPONENT_STATUS_ERROR;
+                       BT_PUT(writer_packet_context);
                        fprintf(err, "[error] %s in %s:%d\n", __func__,
                                        __FILE__, __LINE__);
-                       goto end_put_writer_packet_context;
+                       goto end_put_struct_type;
                }
                if (bt_ctf_field_type_structure_get_field(struct_type,
                                        &field_name, &field_type, i) < 0) {
-                       ret = BT_COMPONENT_STATUS_ERROR;
                        bt_put(field);
+                       BT_PUT(writer_packet_context);
                        fprintf(err, "[error] %s in %s:%d\n", __func__,
                                        __FILE__, __LINE__);
-                       goto end_put_writer_packet_context;
+                       goto end_put_struct_type;
                }
                if (!strncmp(field_name, "content_size", strlen("content_size")) ||
                                !strncmp(field_name, "packet_size",
@@ -577,8 +588,8 @@ enum bt_component_status ctf_copy_packet_context(FILE *err,
                if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_TYPE_ID_INTEGER) {
                        fprintf(err, "[error] Unexpected packet context field type\n");
                        bt_put(field);
-                       ret = BT_COMPONENT_STATUS_ERROR;
-                       goto end_put_writer_packet_context;
+                       BT_PUT(writer_packet_context);
+                       goto end_put_struct_type;
                }
 
                ret = ctf_copy_packet_context_field(err, field, field_name,
@@ -586,21 +597,13 @@ enum bt_component_status ctf_copy_packet_context(FILE *err,
                bt_put(field_type);
                bt_put(field);
                if (ret != BT_COMPONENT_STATUS_OK) {
+                       BT_PUT(writer_packet_context);
                        fprintf(err, "[error] %s in %s:%d\n", __func__,
                                        __FILE__, __LINE__);
-                       goto end_put_writer_packet_context;
+                       goto end_put_struct_type;
                }
        }
 
-       int_ret = bt_ctf_stream_set_packet_context(writer_stream,
-                       writer_packet_context);
-       if (int_ret < 0) {
-               ret = BT_COMPONENT_STATUS_ERROR;
-               goto end_put_writer_packet_context;
-       }
-
-end_put_writer_packet_context:
-       bt_put(writer_packet_context);
 end_put_struct_type:
        bt_put(struct_type);
 end_put_writer_packet_context_type:
@@ -609,12 +612,75 @@ end_put_writer_stream_class:
        bt_put(writer_stream_class);
 end_put_packet_context:
        bt_put(packet_context);
+end:
+       return writer_packet_context;
+}
+
+static
+int copy_event_header(FILE *err, struct bt_ctf_event *event,
+               struct bt_ctf_event_class *writer_event_class,
+               struct bt_ctf_event *writer_event,
+               struct bt_ctf_field *event_header)
+{
+       struct bt_ctf_clock_class *writer_clock_class;
+       struct bt_ctf_clock_value *clock_value;
+
+       int ret;
+       struct bt_ctf_field *writer_event_header;
+
+       writer_event_header = bt_ctf_field_copy(event_header);
+       if (!writer_event_header) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__,
+                               __FILE__, __LINE__);
+               ret = -1;
+               goto end;
+       }
+
+       writer_clock_class = event_get_clock_class(err, writer_event);
+       if (!writer_clock_class) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto error;
+       }
+
+       clock_value = bt_ctf_event_get_clock_value(event, writer_clock_class);
+       bt_put(writer_clock_class);
+       if (!clock_value) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto error;
+       }
+
+       ret = bt_ctf_event_set_clock_value(writer_event, clock_value);
+       bt_put(clock_value);
+       if (ret) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
+                               __LINE__);
+               goto error;
+       }
+
+       ret = bt_ctf_event_set_header(writer_event, writer_event_header);
+       if (ret < 0) {
+               fprintf(err, "[error] %s in %s:%d\n", __func__,
+                               __FILE__, __LINE__);
+               goto error;
+       }
+       bt_put(writer_event_header);
+
+       ret = 0;
+
+       goto end;
+
+error:
+       BT_PUT(writer_event_header);
+       ret = -1;
 end:
        return ret;
 }
 
 struct bt_ctf_event *ctf_copy_event(FILE *err, struct bt_ctf_event *event,
-               struct bt_ctf_event_class *writer_event_class)
+               struct bt_ctf_event_class *writer_event_class,
+               bool override_ts64)
 {
        struct bt_ctf_event *writer_event;
        struct bt_ctf_field *field, *copy_field;
@@ -635,16 +701,39 @@ struct bt_ctf_event *ctf_copy_event(FILE *err, struct bt_ctf_event *event,
                goto end;
        }
 
-       copy_field = bt_ctf_field_copy(field);
-       bt_put(field);
-       if (copy_field) {
-               ret = bt_ctf_event_set_header(writer_event, copy_field);
-               if (ret < 0) {
+       /*
+        * If override_ts64, we override all integer fields mapped to a clock
+        * to a uint64_t field type, otherwise, we just copy it as is.
+        */
+       if (override_ts64) {
+               copy_field = bt_ctf_event_get_header(writer_event);
+               if (!copy_field) {
+                       BT_PUT(writer_event);
+                       bt_put(field);
                        fprintf(err, "[error] %s in %s:%d\n", __func__,
                                        __FILE__, __LINE__);
-                       goto error;
+                       goto end;
+               }
+
+               ret = copy_override_field(err, event, writer_event, field,
+                               copy_field);
+               bt_put(field);
+               if (ret) {
+                       BT_PUT(writer_event);
+                       BT_PUT(copy_field);
+                       fprintf(err, "[error] %s in %s:%d\n", __func__,
+                                       __FILE__, __LINE__);
+                       goto end;
+               }
+       } else {
+               ret = copy_event_header(err, event, writer_event_class,
+                               writer_event, field);
+               if (ret) {
+                       BT_PUT(writer_event);
+                       fprintf(err, "[error] %s in %s:%d\n", __func__,
+                                       __FILE__, __LINE__);
+                       goto end;
                }
-               bt_put(copy_field);
        }
 
        /* Optional field, so it can fail silently. */
index 344f1727235a3a9d3b3ef53ddbfcf07d93c933f8..004e330a00ac40dd55baf042a513ba9ce35d40c4 100644 (file)
@@ -81,7 +81,9 @@ enum bt_component_status ctf_copy_event_classes(FILE *err,
  * Returns NULL or error.
  */
 struct bt_ctf_stream_class *ctf_copy_stream_class(FILE *err,
-               struct bt_ctf_stream_class *stream_class);
+               struct bt_ctf_stream_class *stream_class,
+               struct bt_ctf_trace *writer_trace,
+               bool override_ts64);
 
 /*
  * Copy the value of a packet context field and add it to the
@@ -104,7 +106,7 @@ enum bt_component_status ctf_copy_packet_context_field(FILE *err,
  * Returns BT_COMPONENT_STATUS_OK on success, and BT_COMPONENT_STATUS_ERROR on
  * error.
  */
-enum bt_component_status ctf_copy_packet_context(FILE *err,
+struct bt_ctf_field *ctf_copy_packet_context(FILE *err,
                struct bt_ctf_packet *packet,
                struct bt_ctf_stream *writer_stream);
 
@@ -115,7 +117,8 @@ enum bt_component_status ctf_copy_packet_context(FILE *err,
  * Returns NULL on error.
  */
 struct bt_ctf_event *ctf_copy_event(FILE *err, struct bt_ctf_event *event,
-               struct bt_ctf_event_class *writer_event_class);
+               struct bt_ctf_event_class *writer_event_class,
+               bool override_ts64);
 
 /*
  * Copy the environment and the packet header from the input trace to the
index 0fa472f3fe014fce4e8b4eb237948ea39e6ca60e..e6684d15efe5101b5217539d3a6629d8ea078ed1 100644 (file)
@@ -46,25 +46,16 @@ struct bt_ctf_stream_class *insert_new_stream_class(
                struct bt_ctf_writer *ctf_writer,
                struct bt_ctf_stream_class *stream_class)
 {
-       struct bt_ctf_stream_class *writer_stream_class;
+       struct bt_ctf_stream_class *writer_stream_class = NULL;
        struct bt_ctf_trace *trace, *writer_trace;
        enum bt_component_status ret;
 
-       writer_stream_class = ctf_copy_stream_class(writer_component->err,
-                       stream_class);
-       if (!writer_stream_class) {
-               fprintf(writer_component->err, "[error] Failed to copy stream class\n");
-               fprintf(writer_component->err, "[error] %s in %s:%d\n",
-                               __func__, __FILE__, __LINE__);
-               goto end;
-       }
-
        trace = bt_ctf_stream_class_get_trace(stream_class);
        if (!trace) {
                fprintf(writer_component->err,
                                "[error] %s in %s:%d\n", __func__, __FILE__,
                                __LINE__);
-               goto error;
+               goto end;
        }
 
        writer_trace = bt_ctf_writer_get_trace(ctf_writer);
@@ -74,20 +65,27 @@ struct bt_ctf_stream_class *insert_new_stream_class(
                                "[error] %s in %s:%d\n", __func__, __FILE__,
                                __LINE__);
                ret = BT_COMPONENT_STATUS_ERROR;
-               goto error;
+               goto end_put_trace;
        }
 
        ret = ctf_copy_clock_classes(writer_component->err, writer_trace,
                        writer_stream_class, trace);
-       bt_put(writer_trace);
        if (ret != BT_COMPONENT_STATUS_OK) {
                bt_put(trace);
                fprintf(writer_component->err,
                                "[error] %s in %s:%d\n", __func__, __FILE__,
                                __LINE__);
-               goto error;
+               goto end_put_writer_trace;
+       }
+
+       writer_stream_class = ctf_copy_stream_class(writer_component->err,
+                       stream_class, writer_trace, true);
+       if (!writer_stream_class) {
+               fprintf(writer_component->err, "[error] Failed to copy stream class\n");
+               fprintf(writer_component->err, "[error] %s in %s:%d\n",
+                               __func__, __FILE__, __LINE__);
+               goto end_put_writer_trace;
        }
-       bt_put(trace);
 
        ret = ctf_copy_event_classes(writer_component->err, stream_class,
                        writer_stream_class);
@@ -101,10 +99,10 @@ struct bt_ctf_stream_class *insert_new_stream_class(
        g_hash_table_insert(writer_component->stream_class_map,
                        (gpointer) stream_class, writer_stream_class);
 
-       goto end;
-
-error:
-       BT_PUT(writer_stream_class);
+end_put_writer_trace:
+       bt_put(writer_trace);
+end_put_trace:
+       bt_put(trace);
 end:
        return writer_stream_class;
 }
@@ -311,7 +309,9 @@ enum bt_component_status writer_new_packet(
                struct bt_ctf_packet *packet)
 {
        struct bt_ctf_stream *stream, *writer_stream;
+       struct bt_ctf_field *writer_packet_context;
        enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+       int int_ret;
 
        stream = bt_ctf_packet_get_stream(packet);
        if (!stream) {
@@ -329,17 +329,28 @@ enum bt_component_status writer_new_packet(
                goto end_put;
        }
 
-       ret = ctf_copy_packet_context(writer_component->err, packet,
-                       writer_stream);
-       if (ret != BT_COMPONENT_STATUS_OK) {
+       writer_packet_context = ctf_copy_packet_context(writer_component->err,
+                       packet, writer_stream);
+       if (!writer_packet_context) {
                ret = BT_COMPONENT_STATUS_ERROR;
                fprintf(writer_component->err, "[error] %s in %s:%d\n",
                                __func__, __FILE__, __LINE__);
                goto end_put;
        }
 
+       int_ret = bt_ctf_stream_set_packet_context(writer_stream,
+                       writer_packet_context);
+       if (int_ret < 0) {
+               ret = BT_COMPONENT_STATUS_ERROR;
+               fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
+                               __FILE__, __LINE__);
+               goto end_put_writer_packet_context;
+       }
+
        bt_put(writer_stream);
 
+end_put_writer_packet_context:
+       bt_put(writer_packet_context);
 end_put:
        bt_put(stream);
 end:
@@ -468,7 +479,8 @@ enum bt_component_status writer_output_event(
                goto end_put_writer_stream_class;
        }
 
-       writer_event = ctf_copy_event(writer_component->err, event, writer_event_class);
+       writer_event = ctf_copy_event(writer_component->err, event,
+                       writer_event_class, true);
        if (!writer_event) {
                ret = BT_COMPONENT_STATUS_ERROR;
                fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
This page took 0.040634 seconds and 4 git commands to generate.