/*
- * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * SPDX-License-Identifier: MIT
*
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
+ * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
*/
#define BT_COMP_LOG_SELF_COMP (stream->trace->fs_sink->self_comp)
BT_ASSERT(name);
- while (stream_file_name_exists(trace, name->str) &&
+ while (stream_file_name_exists(trace, name->str) ||
strcmp(name->str, "metadata") == 0) {
g_string_printf(name, "%s-%u", san_base->str, suffix);
suffix++;
int write_field(struct fs_sink_stream *stream,
struct fs_sink_ctf_field_class *fc, const bt_field *field);
+static inline
+int write_bool_field(struct fs_sink_stream *stream,
+ struct fs_sink_ctf_field_class_int *fc, const bt_field *field)
+{
+ /*
+ * CTF 1.8 has no boolean field class type, so this component
+ * translates this boolean field to an 8-bit unsigned integer
+ * field which has the value 0 (false) or 1 (true).
+ */
+ return bt_ctfser_write_unsigned_int(&stream->ctfser,
+ bt_field_bool_get_value(field) ? 1 : 0,
+ fc->base.base.alignment, fc->base.size, BYTE_ORDER);
+}
+
+static inline
+int write_bit_array_field(struct fs_sink_stream *stream,
+ struct fs_sink_ctf_field_class_bit_array *fc,
+ const bt_field *field)
+{
+ /*
+ * CTF 1.8 has no bit array field class type, so this component
+ * translates this bit array field to an unsigned integer field.
+ */
+ return bt_ctfser_write_unsigned_int(&stream->ctfser,
+ bt_field_bit_array_get_value_as_integer(field),
+ fc->base.alignment, fc->size, BYTE_ORDER);
+}
+
static inline
int write_int_field(struct fs_sink_stream *stream,
struct fs_sink_ctf_field_class_int *fc, const bt_field *field)
struct fs_sink_ctf_field_class_float *fc, const bt_field *field)
{
int ret;
- double val = bt_field_real_get_value(field);
+ double val;
if (fc->base.size == 32) {
+ val = (double) bt_field_real_single_precision_get_value(field);
ret = bt_ctfser_write_float32(&stream->ctfser, val,
fc->base.base.alignment, BYTE_ORDER);
} else {
+ val = bt_field_real_double_precision_get_value(field);
ret = bt_ctfser_write_float64(&stream->ctfser, val,
fc->base.base.alignment, BYTE_ORDER);
}
return ret;
}
+static inline
+int write_option_field(struct fs_sink_stream *stream,
+ struct fs_sink_ctf_field_class_option *fc,
+ const bt_field *field)
+{
+ int ret;
+ const bt_field *content_field =
+ bt_field_option_borrow_field_const(field);
+
+ ret = bt_ctfser_write_unsigned_int(&stream->ctfser,
+ content_field ? 1 : 0, 8, 8, BYTE_ORDER);
+ if (G_UNLIKELY(ret)) {
+ goto end;
+ }
+
+ /*
+ * CTF 1.8 has no option field class type, so this component
+ * translates the option field class to a variant field class
+ * where the options are:
+ *
+ * * An empty structure field class (field occupies 0 bits).
+ * * The optional field class itself.
+ *
+ * If `content_field` is `NULL`, do not write anything (empty
+ * structure).
+ */
+ if (content_field) {
+ ret = write_field(stream, fc->content_fc, content_field);
+ }
+
+end:
+ return ret;
+}
+
static inline
int write_variant_field(struct fs_sink_stream *stream,
struct fs_sink_ctf_field_class_variant *fc,
const bt_field *field)
{
uint64_t opt_index =
- bt_field_variant_get_selected_option_field_index(field);
+ bt_field_variant_get_selected_option_index(field);
int ret;
if (fc->tag_is_before) {
int ret;
switch (fc->type) {
+ case FS_SINK_CTF_FIELD_CLASS_TYPE_BOOL:
+ ret = write_bool_field(stream, (void *) fc, field);
+ break;
+ case FS_SINK_CTF_FIELD_CLASS_TYPE_BIT_ARRAY:
+ ret = write_bit_array_field(stream, (void *) fc, field);
+ break;
case FS_SINK_CTF_FIELD_CLASS_TYPE_INT:
ret = write_int_field(stream, (void *) fc, field);
break;
case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE:
ret = write_sequence_field(stream, (void *) fc, field);
break;
+ case FS_SINK_CTF_FIELD_CLASS_TYPE_OPTION:
+ ret = write_option_field(stream, (void *) fc, field);
+ break;
case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT:
ret = write_variant_field(stream, (void *) fc, field);
break;
default:
- abort();
+ bt_common_abort();
}
return ret;
/* Time */
if (stream->sc->default_clock_class) {
- BT_ASSERT(cs);
+ BT_ASSERT_DBG(cs);
ret = bt_ctfser_write_byte_aligned_unsigned_int(&stream->ctfser,
bt_clock_snapshot_get_value(cs), 8, 64, BYTE_ORDER);
if (G_UNLIKELY(ret)) {
/* Common context */
if (stream->sc->event_common_context_fc) {
field = bt_event_borrow_common_context_field_const(event);
- BT_ASSERT(field);
+ BT_ASSERT_DBG(field);
ret = write_struct_field(stream,
(void *) stream->sc->event_common_context_fc,
field, true);
/* Specific context */
if (ec->spec_context_fc) {
field = bt_event_borrow_specific_context_field_const(event);
- BT_ASSERT(field);
+ BT_ASSERT_DBG(field);
ret = write_struct_field(stream, (void *) ec->spec_context_fc,
field, true);
if (G_UNLIKELY(ret)) {
/* Specific context */
if (ec->payload_fc) {
field = bt_event_borrow_payload_field_const(event);
- BT_ASSERT(field);
+ BT_ASSERT_DBG(field);
ret = write_struct_field(stream, (void *) ec->payload_fc,
field, true);
if (G_UNLIKELY(ret)) {