Add stream packet header accessors
[babeltrace.git] / formats / ctf / ir / stream.c
index e618251e577a3d6e5614b475faa8b1d30c926385..9b0be90b7b2e97ad96f36e670060cb51192e33a9 100644 (file)
@@ -48,6 +48,7 @@ BT_HIDDEN
 struct bt_ctf_stream *bt_ctf_stream_create(
                struct bt_ctf_stream_class *stream_class)
 {
+       int ret;
        struct bt_ctf_stream *stream = NULL;
 
        if (!stream_class) {
@@ -60,6 +61,19 @@ struct bt_ctf_stream *bt_ctf_stream_create(
        }
 
        bt_ctf_ref_init(&stream->ref_count);
+       stream->packet_context = bt_ctf_field_create(
+               stream_class->packet_context_type);
+       if (!stream->packet_context) {
+               goto error_destroy;
+       }
+
+       /* Initialize events_discarded*/
+       ret = set_structure_field_integer(stream->packet_context,
+               "events_discarded", 0);
+       if (ret) {
+               goto error_destroy;
+       }
+
        stream->pos.fd = -1;
        stream->id = stream_class->next_stream_id++;
        stream->stream_class = stream_class;
@@ -69,6 +83,9 @@ struct bt_ctf_stream *bt_ctf_stream_create(
                (GDestroyNotify)bt_ctf_event_put);
 end:
        return stream;
+error_destroy:
+       bt_ctf_stream_destroy(&stream->ref_count);
+       return NULL;
 }
 
 BT_HIDDEN
@@ -107,25 +124,127 @@ int bt_ctf_stream_get_discarded_events_count(
                struct bt_ctf_stream *stream, uint64_t *count)
 {
        int64_t ret = 0;
+       int field_signed;
+       struct bt_ctf_field *events_discarded_field = NULL;
+       struct bt_ctf_field_type *events_discarded_field_type = NULL;
 
-       if (!stream || !count) {
+       if (!stream || !count || !stream->packet_context) {
                ret = -1;
                goto end;
        }
 
-       *count = stream->events_discarded;
+       events_discarded_field = bt_ctf_field_structure_get_field(
+               stream->packet_context, "events_discarded");
+       if (!events_discarded_field) {
+               ret = -1;
+               goto end;
+       }
+
+       events_discarded_field_type = bt_ctf_field_get_type(
+               events_discarded_field);
+       if (!events_discarded_field_type) {
+               ret = -1;
+               goto end;
+       }
+
+       field_signed = bt_ctf_field_type_integer_get_signed(
+               events_discarded_field_type);
+       if (field_signed < 0) {
+               ret = field_signed;
+               goto end;
+       }
+
+       if (field_signed) {
+               int64_t signed_count;
+
+               ret = bt_ctf_field_signed_integer_get_value(
+                       events_discarded_field, &signed_count);
+               if (ret) {
+                       goto end;
+               }
+               if (signed_count < 0) {
+                       /* Invalid value */
+                       ret = -1;
+                       goto end;
+               }
+               *count = (uint64_t) signed_count;
+       } else {
+               ret = bt_ctf_field_unsigned_integer_get_value(
+                       events_discarded_field, count);
+               if (ret) {
+                       goto end;
+               }
+       }
 end:
+       if (events_discarded_field) {
+               bt_ctf_field_put(events_discarded_field);
+       }
+       if (events_discarded_field_type) {
+               bt_ctf_field_type_put(events_discarded_field_type);
+       }
        return ret;
 }
 
 void bt_ctf_stream_append_discarded_events(struct bt_ctf_stream *stream,
                uint64_t event_count)
 {
-       if (!stream) {
-               return;
+       int ret;
+       int field_signed;
+       uint64_t previous_count;
+       uint64_t new_count;
+       struct bt_ctf_field *events_discarded_field = NULL;
+       struct bt_ctf_field_type *events_discarded_field_type = NULL;
+
+       if (!stream || !stream->packet_context) {
+               goto end;
+       }
+
+       ret = bt_ctf_stream_get_discarded_events_count(stream,
+               &previous_count);
+       if (ret) {
+               goto end;
+       }
+
+       events_discarded_field = bt_ctf_field_structure_get_field(
+               stream->packet_context, "events_discarded");
+       if (!events_discarded_field) {
+               goto end;
+       }
+
+       events_discarded_field_type = bt_ctf_field_get_type(
+               events_discarded_field);
+       if (!events_discarded_field_type) {
+               goto end;
+       }
+
+       field_signed = bt_ctf_field_type_integer_get_signed(
+               events_discarded_field_type);
+       if (field_signed < 0) {
+               goto end;
        }
 
-       stream->events_discarded += event_count;
+       new_count = previous_count + event_count;
+       if (field_signed) {
+               ret = bt_ctf_field_signed_integer_set_value(
+                       events_discarded_field, (int64_t) new_count);
+               if (ret) {
+                       goto end;
+               }
+       } else {
+               ret = bt_ctf_field_unsigned_integer_set_value(
+                       events_discarded_field, new_count);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+end:
+       if (events_discarded_field) {
+               bt_ctf_field_put(events_discarded_field);
+       }
+       if (events_discarded_field_type) {
+               bt_ctf_field_type_put(events_discarded_field_type);
+       }
 }
 
 int bt_ctf_stream_append_event(struct bt_ctf_stream *stream,
@@ -156,11 +275,53 @@ end:
        return ret;
 }
 
+struct bt_ctf_field *bt_ctf_stream_get_packet_context(
+               struct bt_ctf_stream *stream)
+{
+       struct bt_ctf_field *packet_context = NULL;
+
+       if (!stream) {
+               goto end;
+       }
+
+       packet_context = stream->packet_context;
+end:
+       if (packet_context) {
+               bt_ctf_field_get(packet_context);
+       }
+       return packet_context;
+}
+
+int bt_ctf_stream_set_packet_context(struct bt_ctf_stream *stream,
+               struct bt_ctf_field *field)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *field_type;
+
+       if (!stream || !field) {
+               ret = -1;
+               goto end;
+       }
+
+       field_type = bt_ctf_field_get_type(field);
+       if (field_type != stream->stream_class->packet_context_type) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_ctf_field_type_put(field_type);
+       bt_ctf_field_get(field);
+       bt_ctf_field_put(stream->packet_context);
+       stream->packet_context = field;
+end:
+       return ret;
+}
+
 int bt_ctf_stream_flush(struct bt_ctf_stream *stream)
 {
        int ret = 0;
        size_t i;
-       uint64_t timestamp_begin, timestamp_end;
+       uint64_t timestamp_begin, timestamp_end, events_discarded;
        struct bt_ctf_stream_class *stream_class;
        struct bt_ctf_field *integer = NULL;
        struct ctf_stream_pos packet_context_pos;
@@ -183,31 +344,27 @@ int bt_ctf_stream_flush(struct bt_ctf_stream *stream)
                stream->events, 0))->timestamp;
        timestamp_end = ((struct bt_ctf_event *) g_ptr_array_index(
                stream->events, stream->events->len - 1))->timestamp;
-       ret = set_structure_field_integer(stream_class->packet_context,
+
+       /* Set the default context attributes if present and unset. */
+       ret = set_structure_field_integer(stream->packet_context,
                "timestamp_begin", timestamp_begin);
        if (ret) {
                goto end;
        }
 
-       ret = set_structure_field_integer(stream_class->packet_context,
+       ret = set_structure_field_integer(stream->packet_context,
                "timestamp_end", timestamp_end);
        if (ret) {
                goto end;
        }
 
-       ret = set_structure_field_integer(stream_class->packet_context,
-               "events_discarded", stream->events_discarded);
-       if (ret) {
-               goto end;
-       }
-
-       ret = set_structure_field_integer(stream_class->packet_context,
+       ret = set_structure_field_integer(stream->packet_context,
                "content_size", UINT64_MAX);
        if (ret) {
                goto end;
        }
 
-       ret = set_structure_field_integer(stream_class->packet_context,
+       ret = set_structure_field_integer(stream->packet_context,
                "packet_size", UINT64_MAX);
        if (ret) {
                goto end;
@@ -216,12 +373,31 @@ int bt_ctf_stream_flush(struct bt_ctf_stream *stream)
        /* Write packet context */
        memcpy(&packet_context_pos, &stream->pos,
               sizeof(struct ctf_stream_pos));
-       ret = bt_ctf_field_serialize(stream_class->packet_context,
+       ret = bt_ctf_field_serialize(stream->packet_context,
                &stream->pos);
        if (ret) {
                goto end;
        }
 
+       ret = bt_ctf_stream_get_discarded_events_count(stream,
+               &events_discarded);
+       if (ret) {
+               goto end;
+       }
+
+       /* Unset the packet context's fields. */
+       ret = bt_ctf_field_reset(stream->packet_context);
+       if (ret) {
+               goto end;
+       }
+
+       /* Set the previous number of discarded events. */
+       ret = set_structure_field_integer(stream->packet_context,
+               "events_discarded", events_discarded);
+       if (ret) {
+               goto end;
+       }
+
        for (i = 0; i < stream->events->len; i++) {
                struct bt_ctf_event *event = g_ptr_array_index(
                        stream->events, i);
@@ -229,6 +405,11 @@ int bt_ctf_stream_flush(struct bt_ctf_stream *stream)
                        event->event_class);
                uint64_t timestamp = bt_ctf_event_get_timestamp(event);
 
+               ret = bt_ctf_field_reset(stream_class->event_header);
+               if (ret) {
+                       goto end;
+               }
+
                ret = set_structure_field_integer(stream_class->event_header,
                        "id", event_id);
                if (ret) {
@@ -261,19 +442,19 @@ int bt_ctf_stream_flush(struct bt_ctf_stream *stream)
         * packet is resized).
         */
        packet_context_pos.base_mma = stream->pos.base_mma;
-       ret = set_structure_field_integer(stream_class->packet_context,
+       ret = set_structure_field_integer(stream->packet_context,
                "content_size", stream->pos.offset);
        if (ret) {
                goto end;
        }
 
-       ret = set_structure_field_integer(stream_class->packet_context,
+       ret = set_structure_field_integer(stream->packet_context,
                "packet_size", stream->pos.packet_size);
        if (ret) {
                goto end;
        }
 
-       ret = bt_ctf_field_serialize(stream_class->packet_context,
+       ret = bt_ctf_field_serialize(stream->packet_context,
                &packet_context_pos);
        if (ret) {
                goto end;
@@ -318,8 +499,16 @@ void bt_ctf_stream_destroy(struct bt_ctf_ref *ref)
        if (close(stream->pos.fd)) {
                perror("close");
        }
-       bt_ctf_stream_class_put(stream->stream_class);
-       g_ptr_array_free(stream->events, TRUE);
+
+       if (stream->stream_class) {
+               bt_ctf_stream_class_put(stream->stream_class);
+       }
+       if (stream->events) {
+               g_ptr_array_free(stream->events, TRUE);
+       }
+       if (stream->packet_context) {
+               bt_ctf_field_put(stream->packet_context);
+       }
        g_free(stream);
 }
 
@@ -328,14 +517,25 @@ int set_structure_field_integer(struct bt_ctf_field *structure, char *name,
                uint64_t value)
 {
        int ret = 0;
-
        struct bt_ctf_field *integer =
                bt_ctf_field_structure_get_field(structure, name);
-       if (!integer) {
+
+       if (!structure || !name) {
                ret = -1;
                goto end;
        }
 
+       if (!integer) {
+               /* Field not found, not an error. */
+               goto end;
+       }
+
+       /* Make sure the payload has not already been set. */
+       if (!bt_ctf_field_validate(integer)) {
+               /* Payload already set, not an error */
+               goto end;
+       }
+
        ret = bt_ctf_field_unsigned_integer_set_value(integer, value);
 end:
        bt_ctf_field_put(integer);
This page took 0.026609 seconds and 4 git commands to generate.