#include <babeltrace/ctf-writer/stream.h>
#include <babeltrace/ctf-ir/stream-class-internal.h>
#include <babeltrace/ctf-writer/functor-internal.h>
+#include <babeltrace/ctf-ir/utils.h>
#include <babeltrace/compiler.h>
#include <babeltrace/align.h>
static
void bt_ctf_stream_class_destroy(struct bt_ctf_ref *ref);
static
-int init_event_header(struct bt_ctf_stream_class *stream_class,
- enum bt_ctf_byte_order byte_order);
+int init_event_header(struct bt_ctf_stream_class *stream_class);
static
-int init_packet_context(struct bt_ctf_stream_class *stream_class,
- enum bt_ctf_byte_order byte_order);
+int init_packet_context(struct bt_ctf_stream_class *stream_class);
struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name)
{
int ret;
struct bt_ctf_stream_class *stream_class = NULL;
- if (!name || !strlen(name)) {
+ if (name && bt_ctf_validate_identifier(name)) {
goto error;
}
goto error_destroy;
}
- ret = init_packet_context(stream_class, BT_CTF_BYTE_ORDER_NATIVE);
+ ret = init_event_header(stream_class);
+ if (ret) {
+ goto error_destroy;
+ }
+
+ ret = init_packet_context(stream_class);
if (ret) {
goto error_destroy;
}
return name;
}
+int bt_ctf_stream_class_set_name(struct bt_ctf_stream_class *stream_class,
+ const char *name)
+{
+ int ret = 0;
+
+ if (!stream_class || stream_class->frozen) {
+ ret = -1;
+ goto end;
+ }
+
+ g_string_assign(stream_class->name, name);
+end:
+ return ret;
+}
+
struct bt_ctf_clock *bt_ctf_stream_class_get_clock(
struct bt_ctf_stream_class *stream_class)
{
struct bt_ctf_clock *clock)
{
int ret = 0;
+ struct bt_ctf_field_type *timestamp_field = NULL;
if (!stream_class || !clock || stream_class->frozen) {
ret = -1;
goto end;
}
+ /*
+ * Look for a "timestamp" field in the stream class' event header type
+ * and map the stream's clock to that field if no current mapping is
+ * currently set.
+ */
+ timestamp_field = bt_ctf_field_type_structure_get_field_type_by_name(
+ stream_class->event_header_type, "timestamp");
+ if (timestamp_field) {
+ struct bt_ctf_clock *mapped_clock;
+
+ mapped_clock = bt_ctf_field_type_integer_get_mapped_clock(
+ timestamp_field);
+ if (mapped_clock) {
+ bt_ctf_clock_put(mapped_clock);
+ goto end;
+ }
+
+ ret = bt_ctf_field_type_integer_set_mapped_clock(
+ timestamp_field, clock);
+ if (ret) {
+ goto end;
+ }
+ }
+
if (stream_class->clock) {
bt_ctf_clock_put(stream_class->clock);
}
stream_class->clock = clock;
bt_ctf_clock_get(clock);
end:
+ if (timestamp_field) {
+ bt_ctf_field_type_put(timestamp_field);
+ }
return ret;
}
return ret;
}
+BT_HIDDEN
+int _bt_ctf_stream_class_set_id(
+ struct bt_ctf_stream_class *stream_class, uint32_t id)
+{
+ stream_class->id = id;
+ stream_class->id_set = 1;
+ return 0;
+}
+
int bt_ctf_stream_class_set_id(struct bt_ctf_stream_class *stream_class,
uint32_t id)
{
int ret = 0;
- if (!stream_class) {
+ if (!stream_class || stream_class->frozen) {
ret = -1;
goto end;
}
- stream_class->id = id;
- stream_class->id_set = 1;
+ ret = _bt_ctf_stream_class_set_id(stream_class, id);
+ if (ret) {
+ goto end;
+ }
end:
return ret;
}
bt_ctf_event_class_get(event_class);
g_ptr_array_add(stream_class->event_classes, event_class);
+ bt_ctf_event_class_freeze(event_class);
+
+ if (stream_class->byte_order) {
+ /*
+ * Only set native byte order if it has been initialized
+ * when the stream class was added to a trace.
+ *
+ * If not set here, this will be set when the stream
+ * classe will be added to a trace.
+ */
+ bt_ctf_event_class_set_native_byte_order(event_class,
+ stream_class->byte_order);
+ }
end:
return ret;
}
}
assert(stream_class->packet_context_type);
+ if (stream_class->packet_context_type == packet_context_type) {
+ goto end;
+ }
if (bt_ctf_field_type_get_type_id(packet_context_type) !=
CTF_TYPE_STRUCT) {
/* A packet context must be a structure */
return ret;
}
+struct bt_ctf_field_type *bt_ctf_stream_class_get_event_header_type(
+ struct bt_ctf_stream_class *stream_class)
+{
+ struct bt_ctf_field_type *ret = NULL;
+
+ if (!stream_class || !stream_class->event_header_type) {
+ goto end;
+ }
+
+ assert(stream_class->event_header_type);
+ bt_ctf_field_type_get(stream_class->event_header_type);
+ ret = stream_class->event_header_type;
+end:
+ return ret;
+}
+
+int bt_ctf_stream_class_set_event_header_type(
+ struct bt_ctf_stream_class *stream_class,
+ struct bt_ctf_field_type *event_header_type)
+{
+ int ret = 0;
+
+ if (!stream_class || !event_header_type || stream_class->frozen) {
+ ret = -1;
+ goto end;
+ }
+
+ assert(stream_class->event_header_type);
+ if (stream_class->event_header_type == event_header_type) {
+ goto end;
+ }
+ if (bt_ctf_field_type_get_type_id(event_header_type) !=
+ CTF_TYPE_STRUCT) {
+ /* An event header must be a structure */
+ ret = -1;
+ goto end;
+ }
+
+ bt_ctf_field_type_put(stream_class->event_header_type);
+ bt_ctf_field_type_get(event_header_type);
+ stream_class->event_header_type = event_header_type;
+end:
+ return ret;
+}
+
struct bt_ctf_field_type *bt_ctf_stream_class_get_event_context_type(
struct bt_ctf_stream_class *stream_class)
{
}
stream_class->frozen = 1;
+ bt_ctf_field_type_freeze(stream_class->event_header_type);
bt_ctf_field_type_freeze(stream_class->packet_context_type);
bt_ctf_field_type_freeze(stream_class->event_context_type);
bt_ctf_clock_freeze(stream_class->clock);
- g_ptr_array_foreach(stream_class->event_classes,
- (GFunc)bt_ctf_event_class_freeze, NULL);
}
BT_HIDDEN
int bt_ctf_stream_class_set_byte_order(struct bt_ctf_stream_class *stream_class,
enum bt_ctf_byte_order byte_order)
{
- int ret = 0;
+ int i, ret = 0;
+ int internal_byte_order;
- ret = init_event_header(stream_class, byte_order);
- if (ret) {
+ /* 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;
+
+ /* 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);
+ bt_ctf_field_type_set_native_byte_order(
+ stream_class->packet_context_type, stream_class->byte_order);
+ bt_ctf_field_type_set_native_byte_order(
+ stream_class->event_context_type, stream_class->byte_order);
+
+ /* Set all events' native byte order */
+ for (i = 0; i < stream_class->event_classes->len; i++) {
+ bt_ctf_event_class_set_native_byte_order(
+ g_ptr_array_index(stream_class->event_classes, i),
+ stream_class->byte_order);
+ bt_ctf_event_class_freeze(
+ g_ptr_array_index(stream_class->event_classes, i));
+ }
end:
return ret;
}
}
bt_ctf_field_type_put(stream_class->event_header_type);
- bt_ctf_field_put(stream_class->event_header);
bt_ctf_field_type_put(stream_class->packet_context_type);
if (stream_class->event_context_type) {
bt_ctf_field_type_put(stream_class->event_context_type);
}
static
-int init_event_header(struct bt_ctf_stream_class *stream_class,
- enum bt_ctf_byte_order byte_order)
+int init_event_header(struct bt_ctf_stream_class *stream_class)
{
int ret = 0;
struct bt_ctf_field_type *event_header_type =
goto end;
}
- ret = bt_ctf_field_type_set_byte_order(_uint32_t, byte_order);
- if (ret) {
- goto end;
- }
-
- ret = bt_ctf_field_type_set_byte_order(_uint64_t, byte_order);
- if (ret) {
- goto end;
- }
-
ret = bt_ctf_field_type_structure_add_field(event_header_type,
_uint32_t, "id");
if (ret) {
goto end;
}
- stream_class->event_header_type = event_header_type;
- stream_class->event_header = bt_ctf_field_create(
- stream_class->event_header_type);
- if (!stream_class->event_header) {
- ret = -1;
+ if (stream_class->event_header_type) {
+ bt_ctf_field_type_put(stream_class->event_header_type);
}
+ stream_class->event_header_type = event_header_type;
end:
if (ret) {
bt_ctf_field_type_put(event_header_type);
}
static
-int init_packet_context(struct bt_ctf_stream_class *stream_class,
- enum bt_ctf_byte_order byte_order)
+int init_packet_context(struct bt_ctf_stream_class *stream_class)
{
int ret = 0;
struct bt_ctf_field_type *packet_context_type =
* We create a stream packet context as proposed in the CTF
* specification.
*/
- ret = bt_ctf_field_type_set_byte_order(_uint64_t, byte_order);
- if (ret) {
- goto end;
- }
-
ret = bt_ctf_field_type_structure_add_field(packet_context_type,
_uint64_t, "timestamp_begin");
if (ret) {
goto end;
}
+ if (stream_class->packet_context_type) {
+ bt_ctf_field_type_put(stream_class->packet_context_type);
+ }
stream_class->packet_context_type = packet_context_type;
end:
if (ret) {