+#include <stdint.h>
+#include <unistd.h>
+
+BT_HIDDEN
+void bt_ctf_stream_common_finalize(struct bt_ctf_stream_common *stream)
+{
+ BT_LOGD("Finalizing common stream object: addr=%p, name=\"%s\"",
+ stream, bt_ctf_stream_common_get_name(stream));
+
+ if (stream->name) {
+ g_string_free(stream->name, TRUE);
+ }
+}
+
+BT_HIDDEN
+int bt_ctf_stream_common_initialize(
+ struct bt_ctf_stream_common *stream,
+ struct bt_ctf_stream_class_common *stream_class, const char *name,
+ uint64_t id, bt_ctf_object_release_func release_func)
+{
+ int ret = 0;
+ struct bt_ctf_trace_common *trace = NULL;
+
+ bt_ctf_object_init_shared_with_parent(&stream->base, release_func);
+
+ if (!stream_class) {
+ BT_LOGW_STR("Invalid parameter: stream class is NULL.");
+ goto error;
+ }
+
+ BT_LOGD("Initializing common stream object: stream-class-addr=%p, "
+ "stream-class-name=\"%s\", stream-name=\"%s\", "
+ "stream-id=%" PRIu64,
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ name, id);
+ trace = bt_ctf_stream_class_common_borrow_trace(stream_class);
+ if (!trace) {
+ BT_LOGW("Invalid parameter: cannot create stream from a stream class which is not part of trace: "
+ "stream-class-addr=%p, stream-class-name=\"%s\", "
+ "stream-name=\"%s\"",
+ stream_class,
+ bt_ctf_stream_class_common_get_name(stream_class), name);
+ goto error;
+ }
+
+ if (id != -1ULL) {
+ /*
+ * Validate that the given ID is unique amongst all the
+ * existing trace's streams created from the same stream
+ * class.
+ */
+ size_t i;
+
+ for (i = 0; i < trace->streams->len; i++) {
+ struct bt_ctf_stream_common *trace_stream =
+ g_ptr_array_index(trace->streams, i);
+
+ if (trace_stream->stream_class != (void *) stream_class) {
+ continue;
+ }
+
+ if (trace_stream->id == id) {
+ BT_LOGW_STR("Invalid parameter: another stream in the same trace already has this ID.");
+ goto error;
+ }
+ }
+ }
+
+ /*
+ * Acquire reference to parent since stream will become publicly
+ * reachable; it needs its parent to remain valid.
+ */
+ bt_ctf_object_set_parent(&stream->base, &trace->base);
+ stream->stream_class = stream_class;
+ stream->id = (int64_t) id;
+
+ if (name) {
+ stream->name = g_string_new(name);
+ if (!stream->name) {
+ BT_LOGE_STR("Failed to allocate a GString.");
+ goto error;
+ }
+ }
+
+ BT_LOGD("Set common stream's trace parent: trace-addr=%p", trace);
+
+ /* Add this stream to the trace's streams */
+ BT_LOGD("Created common stream object: addr=%p", stream);
+ goto end;
+
+error:
+ ret = -1;
+
+end:
+ return ret;
+}