+int bt_ctf_trace_get_clock_count(struct bt_ctf_trace *trace)
+{
+ int ret = -1;
+
+ if (!trace) {
+ goto end;
+ }
+
+ ret = trace->clocks->len;
+end:
+ return ret;
+}
+
+struct bt_ctf_clock *bt_ctf_trace_get_clock(struct bt_ctf_trace *trace,
+ int index)
+{
+ struct bt_ctf_clock *clock = NULL;
+
+ if (!trace || index < 0 || index >= trace->clocks->len) {
+ goto end;
+ }
+
+ clock = g_ptr_array_index(trace->clocks, index);
+ bt_get(clock);
+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) {
+ /* Stream already registered to the trace */
+ ret = -1;
+ goto end;
+ }
+ }
+
+ ret = bt_ctf_stream_class_resolve_types(stream_class, trace);
+ if (ret) {
+ 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_no_check(stream_class,
+ stream_id)) {
+ /* TODO Should retry with a different stream id */
+ ret = -1;
+ goto end;
+ }
+ }
+
+ bt_object_set_parent(stream_class, trace);
+ 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);
+ if (!trace->frozen) {
+ ret = bt_ctf_trace_freeze(trace);
+ }
+end:
+ if (ret) {
+ bt_object_set_parent(stream_class, NULL);
+ }
+ 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_get(stream_class);
+end:
+ return stream_class;
+}
+
+struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_id(
+ struct bt_ctf_trace *trace, uint32_t id)
+{
+ int i;
+ struct bt_ctf_stream_class *stream_class = NULL;
+
+ if (!trace) {
+ goto end;
+ }
+
+ for (i = 0; i < trace->stream_classes->len; ++i) {
+ struct bt_ctf_stream_class *stream_class_candidate;
+
+ stream_class_candidate =
+ g_ptr_array_index(trace->stream_classes, i);
+
+ if (bt_ctf_stream_class_get_id(stream_class_candidate) ==
+ (int64_t) id) {
+ stream_class = stream_class_candidate;
+ bt_get(stream_class);
+ goto end;
+ }
+ }
+
+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_get(clock);
+ goto end;
+ }
+ }
+
+end:
+ return clock;
+}
+