+struct bt_ctf_stream *bt_ctf_stream_create(
+ struct bt_ctf_stream_class *stream_class,
+ const char *name)
+{
+ int ret;
+ struct bt_ctf_stream *stream = NULL;
+ struct bt_ctf_trace *trace = NULL;
+ struct bt_ctf_writer *writer = NULL;
+
+ if (!stream_class) {
+ goto error;
+ }
+
+ trace = bt_ctf_stream_class_get_trace(stream_class);
+ if (!trace) {
+ goto error;
+ }
+
+ stream = g_new0(struct bt_ctf_stream, 1);
+ if (!stream) {
+ goto error;
+ }
+
+ bt_object_init(stream, bt_ctf_stream_destroy);
+ /*
+ * Acquire reference to parent since stream will become publicly
+ * reachable; it needs its parent to remain valid.
+ */
+ bt_object_set_parent(stream, trace);
+ stream->id = stream_class->next_stream_id++;
+ stream->stream_class = stream_class;
+ stream->pos.fd = -1;
+
+ if (name) {
+ stream->name = g_string_new(name);
+ if (!stream->name) {
+ goto error;
+ }
+ }
+
+ if (trace->is_created_by_writer) {
+ int fd;
+ writer = (struct bt_ctf_writer *)
+ bt_object_get_parent(trace);
+
+ assert(writer);
+ stream->packet_context = bt_ctf_field_create(
+ stream_class->packet_context_type);
+ if (!stream->packet_context) {
+ goto error;
+ }
+
+ /* Initialize events_discarded */
+ ret = set_structure_field_integer(stream->packet_context,
+ "events_discarded", 0);
+ if (ret) {
+ goto error;
+ }
+
+ stream->events = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) release_event);
+ if (!stream->events) {
+ goto error;
+ }
+
+ /* A trace is not allowed to have a NULL packet header */
+ assert(trace->packet_header_type);
+ stream->packet_header =
+ bt_ctf_field_create(trace->packet_header_type);
+ if (!stream->packet_header) {
+ goto error;
+ }
+
+ /*
+ * Attempt to populate the default trace packet header fields
+ * (magic, uuid and stream_id). This will _not_ fail shall the
+ * fields not be found or be of an incompatible type; they will
+ * simply not be populated automatically. The user will have to
+ * make sure to set the trace packet header fields himself
+ * before flushing.
+ */
+ ret = set_packet_header(stream);
+ if (ret) {
+ goto error;
+ }
+
+ /* Create file associated with this stream */
+ fd = create_stream_file(writer, stream);
+ if (fd < 0) {
+ goto error;
+ }
+
+ ret = set_stream_fd(stream, fd);
+ if (ret) {
+ goto error;
+ }
+
+ /* Freeze the writer */
+ bt_ctf_writer_freeze(writer);
+ } else {
+ /* Non-writer stream indicated by a negative FD */
+ ret = set_stream_fd(stream, -1);
+ if (ret) {
+ goto error;
+ }
+ }
+
+ /* Add this stream to the trace's streams */
+ g_ptr_array_add(trace->streams, stream);
+
+ BT_PUT(trace);
+ BT_PUT(writer);
+ return stream;
+error:
+ BT_PUT(stream);
+ BT_PUT(trace);
+ BT_PUT(writer);
+ return stream;
+}
+
+struct bt_ctf_stream_class *bt_ctf_stream_get_class(
+ struct bt_ctf_stream *stream)
+{
+ struct bt_ctf_stream_class *stream_class = NULL;
+
+ if (!stream) {
+ goto end;
+ }
+
+ stream_class = stream->stream_class;
+ bt_get(stream_class);
+end:
+ return stream_class;
+}
+