# CTF writer API
babeltracectfwriterincludedir = "$(includedir)/babeltrace/ctf-writer"
babeltracectfwriterinclude_HEADERS = \
- babeltrace/ctf-writer/clock-class.h \
babeltrace/ctf-writer/clock.h \
babeltrace/ctf-writer/event-fields.h \
babeltrace/ctf-writer/event.h \
babeltrace/ctf-writer/stream-class.h \
babeltrace/ctf-writer/stream.h \
babeltrace/ctf-writer/trace.h \
+ babeltrace/ctf-writer/utils.h \
+ babeltrace/ctf-writer/visitor.h \
babeltrace/ctf-writer/writer.h
# CTF IR API
babeltrace/plugin/python-plugin-provider-internal.h \
babeltrace/assert-internal.h \
babeltrace/values-internal.h \
- babeltrace/ctf-writer/fields-internal.h \
- babeltrace/ctf-writer/stream-class-internal.h \
+ babeltrace/ctf-writer/attributes-internal.h \
+ babeltrace/ctf-writer/clock-class-internal.h \
+ babeltrace/ctf-writer/clock-internal.h \
+ babeltrace/ctf-writer/event-class-internal.h \
babeltrace/ctf-writer/event-internal.h \
- babeltrace/ctf-writer/trace-internal.h \
+ babeltrace/ctf-writer/field-path-internal.h \
+ babeltrace/ctf-writer/fields-internal.h \
babeltrace/ctf-writer/field-types-internal.h \
+ babeltrace/ctf-writer/field-wrapper-internal.h \
+ babeltrace/ctf-writer/functor-internal.h \
+ babeltrace/ctf-writer/resolve-internal.h \
babeltrace/ctf-writer/serialize-internal.h \
- babeltrace/ctf-writer/writer-internal.h \
+ babeltrace/ctf-writer/stream-class-internal.h \
babeltrace/ctf-writer/stream-internal.h \
- babeltrace/ctf-writer/clock-internal.h \
- babeltrace/ctf-writer/functor-internal.h \
+ babeltrace/ctf-writer/trace-internal.h \
+ babeltrace/ctf-writer/utils-internal.h \
+ babeltrace/ctf-writer/validation-internal.h \
+ babeltrace/ctf-writer/visitor-internal.h \
+ babeltrace/ctf-writer/writer-internal.h \
babeltrace/mmap-align-internal.h \
babeltrace/align-internal.h \
babeltrace/logging-internal.h \
#include <babeltrace/ctf/events.h>
/* CTF writer API */
-#include <babeltrace/ctf-writer/clock-class.h>
#include <babeltrace/ctf-writer/clock.h>
#include <babeltrace/ctf-writer/event-fields.h>
#include <babeltrace/ctf-writer/event-types.h>
#include <babeltrace/ctf-writer/stream-class.h>
#include <babeltrace/ctf-writer/stream.h>
#include <babeltrace/ctf-writer/trace.h>
+#include <babeltrace/ctf-writer/utils.h>
+#include <babeltrace/ctf-writer/visitor.h>
#include <babeltrace/ctf-writer/writer.h>
/* CTF IR API */
/** @} */
-/* Pre-2.0 CTF writer compatibility */
-static inline
-int bt_ctf_validate_identifier(const char *identifier)
-{
- return bt_identifier_is_valid(identifier) ? 1 : 0;
-}
-
#ifdef __cplusplus
}
#endif
--- /dev/null
+#ifndef BABELTRACE_CTF_WRITER_ATTRIBUTES_H
+#define BABELTRACE_CTF_WRITER_ATTRIBUTES_H
+
+/*
+ * attributes.c
+ *
+ * Babeltrace - CTF writer: Attributes internal
+ *
+ * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
+ * Copyright (c) 2015 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:
+ *
+ * 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.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+
+BT_HIDDEN
+struct bt_value *bt_ctf_attributes_create(void);
+
+BT_HIDDEN
+void bt_ctf_attributes_destroy(struct bt_value *attr_obj);
+
+BT_HIDDEN
+int64_t bt_ctf_attributes_get_count(struct bt_value *attr_obj);
+
+BT_HIDDEN
+const char *bt_ctf_attributes_get_field_name(struct bt_value *attr_obj,
+ uint64_t index);
+
+BT_HIDDEN
+struct bt_value *bt_ctf_attributes_borrow_field_value(struct bt_value *attr_obj,
+ uint64_t index);
+
+BT_HIDDEN
+int bt_ctf_attributes_set_field_value(struct bt_value *attr_obj,
+ const char *name, struct bt_value *value_obj);
+
+BT_HIDDEN
+struct bt_value *bt_ctf_attributes_borrow_field_value_by_name(
+ struct bt_value *attr_obj, const char *name);
+
+BT_HIDDEN
+int bt_ctf_attributes_freeze(struct bt_value *attr_obj);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_CTF_WRITER_ATTRIBUTES_H */
--- /dev/null
+#ifndef BABELTRACE_CTF_WRITER_CLOCK_CLASS_INTERNAL_H
+#define BABELTRACE_CTF_WRITER_CLOCK_CLASS_INTERNAL_H
+
+/*
+ * BabelTrace - CTF writer: Clock class internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@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:
+ *
+ * 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.
+ */
+
+#include <babeltrace/object-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/compat/uuid-internal.h>
+#include <babeltrace/types.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <glib.h>
+
+struct bt_ctf_clock_class {
+ struct bt_object base;
+ GString *name;
+ GString *description;
+ uint64_t frequency;
+ uint64_t precision;
+ int64_t offset_s; /* Offset in seconds */
+ int64_t offset; /* Offset in ticks */
+ unsigned char uuid[BABELTRACE_UUID_LEN];
+ int uuid_set;
+ int absolute;
+
+ /*
+ * A clock's properties can't be modified once it is added to a stream
+ * class.
+ */
+ int frozen;
+};
+
+BT_HIDDEN
+void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class *clock_class);
+
+BT_HIDDEN
+bt_bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class *clock_class);
+
+BT_HIDDEN
+int bt_ctf_clock_class_compare(struct bt_ctf_clock_class *clock_class_a,
+ struct bt_ctf_clock_class *clock_class_b);
+
+BT_HIDDEN
+struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name,
+ uint64_t freq);
+BT_HIDDEN
+const char *bt_ctf_clock_class_get_name(
+ struct bt_ctf_clock_class *clock_class);
+BT_HIDDEN
+int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class,
+ const char *name);
+BT_HIDDEN
+const char *bt_ctf_clock_class_get_description(
+ struct bt_ctf_clock_class *clock_class);
+BT_HIDDEN
+int bt_ctf_clock_class_set_description(
+ struct bt_ctf_clock_class *clock_class,
+ const char *desc);
+BT_HIDDEN
+uint64_t bt_ctf_clock_class_get_frequency(
+ struct bt_ctf_clock_class *clock_class);
+BT_HIDDEN
+int bt_ctf_clock_class_set_frequency(
+ struct bt_ctf_clock_class *clock_class, uint64_t freq);
+BT_HIDDEN
+uint64_t bt_ctf_clock_class_get_precision(
+ struct bt_ctf_clock_class *clock_class);
+BT_HIDDEN
+int bt_ctf_clock_class_set_precision(
+ struct bt_ctf_clock_class *clock_class, uint64_t precision);
+BT_HIDDEN
+int bt_ctf_clock_class_get_offset_s(
+ struct bt_ctf_clock_class *clock_class, int64_t *seconds);
+BT_HIDDEN
+int bt_ctf_clock_class_set_offset_s(
+ struct bt_ctf_clock_class *clock_class, int64_t seconds);
+BT_HIDDEN
+int bt_ctf_clock_class_get_offset_cycles(
+ struct bt_ctf_clock_class *clock_class, int64_t *cycles);
+BT_HIDDEN
+int bt_ctf_clock_class_set_offset_cycles(
+ struct bt_ctf_clock_class *clock_class, int64_t cycles);
+BT_HIDDEN
+bt_bool bt_ctf_clock_class_is_absolute(
+ struct bt_ctf_clock_class *clock_class);
+BT_HIDDEN
+int bt_ctf_clock_class_set_is_absolute(
+ struct bt_ctf_clock_class *clock_class, bt_bool is_absolute);
+BT_HIDDEN
+const unsigned char *bt_ctf_clock_class_get_uuid(
+ struct bt_ctf_clock_class *clock_class);
+BT_HIDDEN
+int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
+ const unsigned char *uuid);
+
+#endif /* BABELTRACE_CTF_WRITER_CLOCK_CLASS_INTERNAL_H */
+++ /dev/null
-#ifndef BABELTRACE_CTF_WRITER_CLOCK_H
-#define BABELTRACE_CTF_WRITER_CLOCK_H
-
-/*
- * BabelTrace - CTF Writer: Clock
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@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:
- *
- * 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.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-#include <babeltrace/ref.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_ctf_clock;
-
-/*
- * bt_ctf_clock_create: create a clock.
- *
- * Allocate a new clock setting its reference count to 1.
- *
- * @param name Name of the clock (will be copied); can be set to NULL
- * for nameless clocks.
- *
- * Returns an allocated clock on success, NULL on error.
- */
-extern struct bt_ctf_clock *bt_ctf_clock_create(const char *name);
-
-/*
- * bt_ctf_clock_get_name: get a clock's name.
- *
- * Get the clock's name.
- *
- * @param clock Clock instance.
- *
- * Returns the clock's name, NULL on error.
- */
-extern const char *bt_ctf_clock_get_name(struct bt_ctf_clock *clock);
-
-/*
- * bt_ctf_clock_get_description: get a clock's description.
- *
- * Get the clock's description.
- *
- * @param clock Clock instance.
- *
- * Returns the clock's description, NULL if unset.
- */
-extern const char *bt_ctf_clock_get_description(struct bt_ctf_clock *clock);
-
-/*
- * bt_ctf_clock_set_description: set a clock's description.
- *
- * Set the clock's description. The description appears in the clock's TSDL
- * meta-data.
- *
- * @param clock Clock instance.
- * @param desc Description of the clock.
- *
- * Returns 0 on success, a negative value on error.
- */
-extern int bt_ctf_clock_set_description(struct bt_ctf_clock *clock,
- const char *desc);
-
-/*
- * bt_ctf_clock_get_frequency: get a clock's frequency.
- *
- * Get the clock's frequency (Hz).
- *
- * @param clock Clock instance.
- *
- * Returns the clock's frequency, -1ULL on error.
- */
-extern uint64_t bt_ctf_clock_get_frequency(struct bt_ctf_clock *clock);
-
-/*
- * bt_ctf_clock_set_frequency: set a clock's frequency.
- *
- * Set the clock's frequency (Hz).
- *
- * @param clock Clock instance.
- * @param freq Clock's frequency in Hz, defaults to 1 000 000 000 Hz (1ns).
- *
- * Returns 0 on success, a negative value on error.
- */
-extern int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock,
- uint64_t freq);
-
-/*
- * bt_ctf_clock_get_precision: get a clock's precision.
- *
- * Get the clock's precision (in clock ticks).
- *
- * @param clock Clock instance.
- *
- * Returns the clock's precision, -1ULL on error.
- */
-extern uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock);
-
-/*
- * bt_ctf_clock_set_precision: set a clock's precision.
- *
- * Set the clock's precision.
- *
- * @param clock Clock instance.
- * @param precision Clock's precision in clock ticks, defaults to 1.
- *
- * Returns 0 on success, a negative value on error.
- */
-extern int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock,
- uint64_t precision);
-
-/*
- * bt_ctf_clock_get_offset_s: get a clock's offset in seconds.
- *
- * Get the clock's offset in seconds from POSIX.1 Epoch, 1970-01-01.
- *
- * @param clock Clock instance.
- * @param offset_s Pointer to clock offset in seconds (output).
- *
- * Returns 0 on success, a negative value on error.
- */
-extern int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock,
- int64_t *offset_s);
-
-/*
- * bt_ctf_clock_set_offset_s: set a clock's offset in seconds.
- *
- * Set the clock's offset in seconds from POSIX.1 Epoch, 1970-01-01,
- * defaults to 0.
- *
- * @param clock Clock instance.
- * @param offset_s Clock's offset in seconds, defaults to 0.
- *
- * Returns 0 on success, a negative value on error.
- */
-extern int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock,
- int64_t offset_s);
-
-/*
- * bt_ctf_clock_get_offset: get a clock's offset in ticks.
- *
- * Get the clock's offset in ticks from Epoch + offset_t.
- *
- * @param clock Clock instance.
- * @param offset Clock offset in ticks from Epoch + offset_s (output).
- *
- * Returns 0 on success, a negative value on error.
- */
-extern int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock,
- int64_t *offset);
-
-/*
- * bt_ctf_clock_set_offset: set a clock's offset in ticks.
- *
- * Set the clock's offset in ticks from Epoch + offset_s.
- *
- * @param clock Clock instance.
- * @param offset Clock's offset in ticks from Epoch + offset_s, defaults to 0.
- *
- * Returns 0 on success, a negative value on error.
- */
-extern int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock,
- int64_t offset);
-
-/*
- * bt_ctf_clock_get_is_absolute: get a clock's absolute attribute.
- *
- * Get the clock's absolute attribute. A clock is absolute if the clock is a
- * global reference across the trace's other clocks.
- *
- * @param clock Clock instance.
- *
- * Returns the clock's absolute attribute, a negative value on error.
- */
-extern int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock);
-
-/*
- * bt_ctf_clock_set_is_absolute: set a clock's absolute attribute.
- *
- * Set the clock's absolute attribute. A clock is absolute if the clock is a
- * global reference across the trace's other clocks.
- *
- * @param clock Clock instance.
- * @param is_absolute Clock's absolute attribute, defaults to FALSE.
- *
- * Returns 0 on success, a negative value on error.
- */
-extern int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock,
- int is_absolute);
-
-/*
- * bt_ctf_clock_get_uuid: get a clock's UUID.
- *
- * Get the clock's UUID.
- *
- * @param clock Clock instance.
- *
- * Returns a pointer to the clock's UUID (16 byte array) on success,
- * NULL on error.
- */
-extern const unsigned char *bt_ctf_clock_get_uuid(struct bt_ctf_clock *clock);
-
-/*
- * bt_ctf_clock_set_uuid: set a clock's UUID.
- *
- * Set a clock's UUID.
- *
- * @param clock Clock instance.
- * @param uuid A 16-byte array containing a UUID.
- *
- * Returns 0 on success, a negative value on error.
- */
-extern int bt_ctf_clock_set_uuid(struct bt_ctf_clock *clock,
- const unsigned char *uuid);
-
-/*
- * bt_ctf_clock_set_time: set a clock's current time value.
- *
- * Set the current time in nanoseconds since the clock's origin (offset and
- * offset_s attributes). Defaults to 0.
- *
- * Returns 0 on success, a negative value on error.
- */
-extern int bt_ctf_clock_set_time(struct bt_ctf_clock *clock,
- int64_t time);
-
-/*
- * bt_ctf_clock_get and bt_ctf_clock_put: increment and decrement the
- * refcount of the clock
- *
- * You may also use bt_ctf_get() and bt_ctf_put() with clock objects.
- *
- * These functions ensure that the clock won't be destroyed when it
- * is in use. The same number of get and put (plus one extra put to
- * release the initial reference done at creation) has to be done to
- * destroy a clock.
- *
- * When the clock refcount is decremented to 0 by a bt_ctf_clock_put,
- * the clock is freed.
- *
- * @param clock Clock instance.
- */
-
-/* Pre-2.0 CTF writer compatibility */
-static inline
-void bt_ctf_clock_get(struct bt_ctf_clock *clock)
-{
- bt_get(clock);
-}
-
-/* Pre-2.0 CTF writer compatibility */
-static inline
-void bt_ctf_clock_put(struct bt_ctf_clock *clock)
-{
- bt_put(clock);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_WRITER_CLOCK_H */
*/
#include <babeltrace/ctf-writer/clock.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
+#include <babeltrace/ctf-writer/clock-class-internal.h>
+#include <babeltrace/ctf-writer/trace-internal.h>
#include <babeltrace/object-internal.h>
#include <babeltrace/babeltrace-internal.h>
#include <glib.h>
#include <babeltrace/compat/uuid-internal.h>
-struct bt_ctf_clock_class {
- struct bt_clock_class common;
-};
-
struct bt_ctf_clock {
struct bt_object base;
struct bt_ctf_clock_class *clock_class;
--- /dev/null
+#ifndef BABELTRACE_CTF_WRITER_EVENT_CLASS_INTERNAL_H
+#define BABELTRACE_CTF_WRITER_EVENT_CLASS_INTERNAL_H
+
+/*
+ * Babeltrace - CTF writer: Event class internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@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:
+ *
+ * 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.
+ */
+
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/ctf-writer/event.h>
+#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/ctf-writer/fields.h>
+#include <babeltrace/ctf-writer/stream-class.h>
+#include <babeltrace/ctf-writer/stream.h>
+#include <babeltrace/ctf-writer/trace-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/values.h>
+#include <glib.h>
+
+struct bt_ctf_event_class_common {
+ struct bt_object base;
+ struct bt_ctf_field_type_common *context_field_type;
+ struct bt_ctf_field_type_common *payload_field_type;
+ int frozen;
+
+ /*
+ * This flag indicates if the event class is valid. A valid
+ * event class is _always_ frozen. However, an event class
+ * may be frozen, but not valid yet. This is okay, as long as
+ * no events are created out of this event class.
+ */
+ int valid;
+
+ /* Attributes */
+ GString *name;
+ int64_t id;
+ int log_level;
+ GString *emf_uri;
+};
+
+BT_HIDDEN
+void bt_ctf_event_class_common_freeze(struct bt_ctf_event_class_common *event_class);
+
+BT_HIDDEN
+void bt_ctf_event_class_common_set_native_byte_order(
+ struct bt_ctf_event_class_common *event_class, int byte_order);
+
+static inline
+struct bt_ctf_stream_class_common *bt_ctf_event_class_common_borrow_stream_class(
+ struct bt_ctf_event_class_common *event_class)
+{
+ BT_ASSERT(event_class);
+ return (void *) bt_object_borrow_parent(&event_class->base);
+}
+
+typedef struct bt_ctf_field_type_common *(*bt_ctf_field_type_structure_create_func)();
+
+BT_HIDDEN
+int bt_ctf_event_class_common_initialize(struct bt_ctf_event_class_common *event_class,
+ const char *name, bt_object_release_func release_func,
+ bt_ctf_field_type_structure_create_func ft_struct_create_func);
+
+BT_HIDDEN
+void bt_ctf_event_class_common_finalize(struct bt_object *obj);
+
+BT_HIDDEN
+int bt_ctf_event_class_common_validate_single_clock_class(
+ struct bt_ctf_event_class_common *event_class,
+ struct bt_ctf_clock_class **expected_clock_class);
+
+static inline
+const char *bt_ctf_event_class_common_get_name(
+ struct bt_ctf_event_class_common *event_class)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ BT_ASSERT(event_class->name);
+ return event_class->name->str;
+}
+
+static inline
+int64_t bt_ctf_event_class_common_get_id(
+ struct bt_ctf_event_class_common *event_class)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ return event_class->id;
+}
+
+static inline
+int bt_ctf_event_class_common_set_id(
+ struct bt_ctf_event_class_common *event_class, uint64_t id_param)
+{
+ int ret = 0;
+ int64_t id = (int64_t) id_param;
+
+ if (!event_class) {
+ BT_LOGW_STR("Invalid parameter: event class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (event_class->frozen) {
+ BT_LOGW("Invalid parameter: event class is frozen: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ event_class,
+ bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class));
+ ret = -1;
+ goto end;
+ }
+
+ if (id < 0) {
+ BT_LOGW("Invalid parameter: invalid event class's ID: "
+ "addr=%p, name=\"%s\", id=%" PRIu64,
+ event_class,
+ bt_ctf_event_class_common_get_name(event_class),
+ id_param);
+ ret = -1;
+ goto end;
+ }
+
+ event_class->id = id;
+ BT_LOGV("Set event class's ID: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ event_class, bt_ctf_event_class_common_get_name(event_class), id);
+
+end:
+ return ret;
+}
+
+static inline
+int bt_ctf_event_class_common_get_log_level(
+ struct bt_ctf_event_class_common *event_class)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ return event_class->log_level;
+}
+
+static inline
+int bt_ctf_event_class_common_set_log_level(
+ struct bt_ctf_event_class_common *event_class, int log_level)
+{
+ int ret = 0;
+
+ if (!event_class) {
+ BT_LOGW_STR("Invalid parameter: event class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (event_class->frozen) {
+ BT_LOGW("Invalid parameter: event class is frozen: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ event_class,
+ bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class));
+ ret = -1;
+ goto end;
+ }
+
+ switch (log_level) {
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_ALERT:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_ERROR:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_WARNING:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_NOTICE:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE:
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG:
+ break;
+ default:
+ BT_LOGW("Invalid parameter: unknown event class log level: "
+ "addr=%p, name=\"%s\", id=%" PRId64 ", log-level=%d",
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class), log_level);
+ ret = -1;
+ goto end;
+ }
+
+ event_class->log_level = log_level;
+ BT_LOGV("Set event class's log level: "
+ "addr=%p, name=\"%s\", id=%" PRId64 ", log-level=%s",
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class),
+ bt_ctf_event_class_log_level_string(log_level));
+
+end:
+ return ret;
+}
+
+static inline
+const char *bt_ctf_event_class_common_get_emf_uri(
+ struct bt_ctf_event_class_common *event_class)
+{
+ const char *emf_uri = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+
+ if (event_class->emf_uri->len > 0) {
+ emf_uri = event_class->emf_uri->str;
+ }
+
+ return emf_uri;
+}
+
+static inline
+int bt_ctf_event_class_common_set_emf_uri(
+ struct bt_ctf_event_class_common *event_class,
+ const char *emf_uri)
+{
+ int ret = 0;
+
+ if (!event_class) {
+ BT_LOGW_STR("Invalid parameter: event class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (emf_uri && strlen(emf_uri) == 0) {
+ BT_LOGW_STR("Invalid parameter: EMF URI is empty.");
+ ret = -1;
+ goto end;
+ }
+
+ if (event_class->frozen) {
+ BT_LOGW("Invalid parameter: event class is frozen: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class));
+ ret = -1;
+ goto end;
+ }
+
+ if (emf_uri) {
+ g_string_assign(event_class->emf_uri, emf_uri);
+ BT_LOGV("Set event class's EMF URI: "
+ "addr=%p, name=\"%s\", id=%" PRId64 ", emf-uri=\"%s\"",
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class), emf_uri);
+ } else {
+ g_string_assign(event_class->emf_uri, "");
+ BT_LOGV("Reset event class's EMF URI: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class));
+ }
+
+end:
+ return ret;
+}
+
+static inline
+struct bt_ctf_field_type_common *bt_ctf_event_class_common_borrow_context_field_type(
+ struct bt_ctf_event_class_common *event_class)
+{
+ struct bt_ctf_field_type_common *context_ft = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+
+ if (!event_class->context_field_type) {
+ BT_LOGV("Event class has no context field type: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class));
+ goto end;
+ }
+
+ context_ft = event_class->context_field_type;
+
+end:
+ return context_ft;
+}
+
+static inline
+int bt_ctf_event_class_common_set_context_field_type(
+ struct bt_ctf_event_class_common *event_class,
+ struct bt_ctf_field_type_common *context_ft)
+{
+ int ret = 0;
+
+ if (!event_class) {
+ BT_LOGW_STR("Invalid parameter: event class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (event_class->frozen) {
+ BT_LOGW("Invalid parameter: event class is frozen: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class));
+ ret = -1;
+ goto end;
+ }
+
+ if (context_ft && bt_ctf_field_type_common_get_type_id(context_ft) !=
+ BT_CTF_FIELD_TYPE_ID_STRUCT) {
+ BT_LOGW("Invalid parameter: event class's context field type must be a structure: "
+ "addr=%p, name=\"%s\", id=%" PRId64 ", "
+ "context-ft-id=%s",
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class),
+ bt_ctf_field_type_id_string(
+ bt_ctf_field_type_common_get_type_id(context_ft)));
+ ret = -1;
+ goto end;
+ }
+
+ bt_put(event_class->context_field_type);
+ event_class->context_field_type = bt_get(context_ft);
+ BT_LOGV("Set event class's context field type: "
+ "event-class-addr=%p, event-class-name=\"%s\", "
+ "event-class-id=%" PRId64 ", context-ft-addr=%p",
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class), context_ft);
+
+end:
+ return ret;
+}
+
+static inline
+struct bt_ctf_field_type_common *bt_ctf_event_class_common_borrow_payload_field_type(
+ struct bt_ctf_event_class_common *event_class)
+{
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ return event_class->payload_field_type;
+}
+
+static inline
+int bt_ctf_event_class_common_set_payload_field_type(
+ struct bt_ctf_event_class_common *event_class,
+ struct bt_ctf_field_type_common *payload_ft)
+{
+ int ret = 0;
+
+ if (!event_class) {
+ BT_LOGW_STR("Invalid parameter: event class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (payload_ft && bt_ctf_field_type_common_get_type_id(payload_ft) !=
+ BT_CTF_FIELD_TYPE_ID_STRUCT) {
+ BT_LOGW("Invalid parameter: event class's payload field type must be a structure: "
+ "addr=%p, name=\"%s\", id=%" PRId64 ", "
+ "payload-ft-addr=%p, payload-ft-id=%s",
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class), payload_ft,
+ bt_ctf_field_type_id_string(
+ bt_ctf_field_type_common_get_type_id(payload_ft)));
+ ret = -1;
+ goto end;
+ }
+
+ bt_put(event_class->payload_field_type);
+ event_class->payload_field_type = bt_get(payload_ft);
+ BT_LOGV("Set event class's payload field type: "
+ "event-class-addr=%p, event-class-name=\"%s\", "
+ "event-class-id=%" PRId64 ", payload-ft-addr=%p",
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class), payload_ft);
+end:
+ return ret;
+}
+
+#endif /* BABELTRACE_CTF_WRITER_EVENT_CLASS_INTERNAL_H */
/* Pre-2.0 CTF writer compatibility */
static inline
-void bt_ctf_field_get(struct bt_field *field)
+void bt_ctf_field_get(struct bt_ctf_field *field)
{
bt_get(field);
}
/* Pre-2.0 CTF writer compatibility */
static inline
-void bt_ctf_field_put(struct bt_field *field)
+void bt_ctf_field_put(struct bt_ctf_field *field)
{
bt_put(field);
}
* http://www.efficios.com/ctf
*/
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/assert-pre-internal.h>
#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
+#include <babeltrace/ctf-writer/event-class-internal.h>
+#include <babeltrace/ctf-writer/event-internal.h>
#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/ctf-writer/field-wrapper-internal.h>
+#include <babeltrace/ctf-writer/fields-internal.h>
+#include <babeltrace/ctf-writer/fields.h>
+#include <babeltrace/ctf-writer/stream-class.h>
+#include <babeltrace/ctf-writer/stream-internal.h>
+#include <babeltrace/ctf-writer/stream.h>
+#include <babeltrace/ctf-writer/validation-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/values.h>
struct bt_ctf_stream_class;
struct bt_ctf_stream_pos;
struct metadata_context;
+struct bt_ctf_event_common {
+ struct bt_object base;
+ struct bt_ctf_event_class_common *class;
+ struct bt_ctf_field_wrapper *header_field;
+ struct bt_ctf_field_common *stream_event_context_field;
+ struct bt_ctf_field_common *context_field;
+ struct bt_ctf_field_common *payload_field;
+ int frozen;
+};
+
+BT_HIDDEN
+int _bt_ctf_event_common_validate(struct bt_ctf_event_common *event);
+
+BT_HIDDEN
+void _bt_ctf_event_common_set_is_frozen(struct bt_ctf_event_common *event,
+ bool is_frozen);
+
+#ifdef BT_DEV_MODE
+# define bt_ctf_event_common_validate _bt_ctf_event_common_validate
+# define bt_ctf_event_common_set_is_frozen _bt_ctf_event_common_set_is_frozen
+#else
+# define bt_ctf_event_common_validate(_event) 0
+# define bt_ctf_event_common_set_is_frozen(_event, _is_frozen)
+#endif
+
+#define BT_ASSERT_PRE_EVENT_COMMON_HOT(_event, _name) \
+ BT_ASSERT_PRE_HOT((_event), (_name), ": event-addr=%p", (_event))
+
+static inline
+struct bt_ctf_event_class_common *bt_ctf_event_common_borrow_class(
+ struct bt_ctf_event_common *event)
+{
+ BT_ASSERT(event);
+ return event->class;
+}
+
+typedef void *(*create_field_func)(void *);
+typedef void (*release_field_func)(void *);
+typedef void *(*create_header_field_func)(void *, void *);
+typedef void (*release_header_field_func)(void *, void *);
+
+BT_HIDDEN
+int bt_ctf_event_common_initialize(struct bt_ctf_event_common *event,
+ struct bt_ctf_event_class_common *event_class,
+ struct bt_ctf_clock_class *init_expected_clock_class,
+ bool is_shared_with_parent, bt_object_release_func release_func,
+ bt_ctf_validation_flag_copy_field_type_func field_type_copy_func,
+ bool must_be_in_trace,
+ int (*map_clock_classes_func)(struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_field_type_common *packet_context_field_type,
+ struct bt_ctf_field_type_common *event_header_field_type),
+ create_field_func create_field_func,
+ release_field_func release_field_func,
+ create_header_field_func create_header_field_func,
+ release_header_field_func release_header_field_func);
+
+static inline
+struct bt_ctf_field_common *bt_ctf_event_common_borrow_payload(
+ struct bt_ctf_event_common *event)
+{
+ struct bt_ctf_field_common *payload = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+
+ if (!event->payload_field) {
+ BT_LOGV("Event has no current payload field: addr=%p, "
+ "event-class-name=\"%s\", event-class-id=%" PRId64,
+ event, bt_ctf_event_class_common_get_name(event->class),
+ bt_ctf_event_class_common_get_id(event->class));
+ goto end;
+ }
+
+ payload = event->payload_field;
+
+end:
+ return payload;
+}
+
+static inline
+struct bt_ctf_field_common *bt_ctf_event_common_borrow_header(
+ struct bt_ctf_event_common *event)
+{
+ struct bt_ctf_field_common *header = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+
+ if (!event->header_field) {
+ BT_LOGV("Event has no current header field: addr=%p, "
+ "event-class-name=\"%s\", event-class-id=%" PRId64,
+ event, bt_ctf_event_class_common_get_name(event->class),
+ bt_ctf_event_class_common_get_id(event->class));
+ goto end;
+ }
+
+ header = event->header_field->field;
+
+end:
+ return header;
+}
+
+static inline
+struct bt_ctf_field_common *bt_ctf_event_common_borrow_context(
+ struct bt_ctf_event_common *event)
+{
+ struct bt_ctf_field_common *context = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+
+ if (!event->context_field) {
+ BT_LOGV("Event has no current context field: addr=%p, "
+ "event-class-name=\"%s\", event-class-id=%" PRId64,
+ event, bt_ctf_event_class_common_get_name(event->class),
+ bt_ctf_event_class_common_get_id(event->class));
+ goto end;
+ }
+
+ context = event->context_field;
+
+end:
+ return context;
+}
+
+static inline
+struct bt_ctf_field_common *bt_ctf_event_common_borrow_stream_event_context(
+ struct bt_ctf_event_common *event)
+{
+ struct bt_ctf_field_common *stream_event_context = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+
+ if (!event->stream_event_context_field) {
+ BT_LOGV("Event has no current stream event context field: addr=%p, "
+ "event-class-name=\"%s\", event-class-id=%" PRId64,
+ event, bt_ctf_event_class_common_get_name(event->class),
+ bt_ctf_event_class_common_get_id(event->class));
+ goto end;
+ }
+
+ stream_event_context = event->stream_event_context_field;
+
+end:
+ return stream_event_context;
+}
+
+static inline
+void bt_ctf_event_common_finalize(struct bt_object *obj,
+ void (*field_release_func)(void *),
+ void (*header_field_release_func)(void *, struct bt_ctf_event_common *))
+{
+ struct bt_ctf_event_common *event = (void *) obj;
+
+ BT_LOGD("Destroying event: addr=%p, "
+ "event-class-name=\"%s\", event-class-id=%" PRId64,
+ event,
+ event->class ? bt_ctf_event_class_common_get_name(event->class) : NULL,
+ event->class ? bt_ctf_event_class_common_get_id(event->class) : INT64_C(-1));
+
+ if (event->header_field) {
+ BT_LOGD_STR("Releasing event's header field.");
+ header_field_release_func(event->header_field, event);
+ }
+
+ if (event->stream_event_context_field) {
+ BT_LOGD_STR("Releasing event's stream event context field.");
+ field_release_func(event->stream_event_context_field);
+ }
+
+ if (event->context_field) {
+ BT_LOGD_STR("Releasing event's context field.");
+ field_release_func(event->context_field);
+ }
+
+ if (event->payload_field) {
+ BT_LOGD_STR("Releasing event's payload field.");
+ field_release_func(event->payload_field);
+ }
+
+ /*
+ * Leave this after calling header_field_release_func() because
+ * this function receives the event object and could need its
+ * class to perform some cleanup.
+ */
+ if (!event->base.parent) {
+ /*
+ * Event was keeping a reference to its class since it shared no
+ * common ancestor with it to guarantee they would both have the
+ * same lifetime.
+ */
+ bt_put(event->class);
+ }
+}
+
struct bt_ctf_event {
- struct bt_event_common common;
+ struct bt_ctf_event_common common;
};
struct bt_ctf_event_class {
- struct bt_event_class_common common;
+ struct bt_ctf_event_class_common common;
};
BT_HIDDEN
struct bt_ctf_stream_class *bt_ctf_event_class_borrow_stream_class(
struct bt_ctf_event_class *event_class)
{
- return BT_FROM_COMMON(bt_event_class_common_borrow_stream_class(
- BT_TO_COMMON(event_class)));
+ return BT_CTF_FROM_COMMON(bt_ctf_event_class_common_borrow_stream_class(
+ BT_CTF_TO_COMMON(event_class)));
}
#endif /* BABELTRACE_CTF_WRITER_EVENT_INTERNAL_H */
*/
#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/field-types.h>
+#include <babeltrace/ctf-writer/field-types.h>
#ifdef __cplusplus
extern "C" {
/* Pre-2.0 CTF writer compatibility */
static inline
-void bt_ctf_field_type_get(struct bt_field_type *type)
+void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
{
bt_get(type);
}
/* Pre-2.0 CTF writer compatibility */
static inline
-void bt_ctf_field_type_put(struct bt_field_type *type)
+void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
{
bt_put(type);
}
*/
#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event.h>
#ifdef __cplusplus
extern "C" {
enum bt_ctf_event_class_log_level {
/// Unknown, used for errors.
- BT_CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN = BT_EVENT_CLASS_LOG_LEVEL_UNKNOWN,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN = -1,
/// Unspecified log level.
- BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED = BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED = 255,
/// System is unusable.
- BT_CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY = BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY = 0,
/// Action must be taken immediately.
- BT_CTF_EVENT_CLASS_LOG_LEVEL_ALERT = BT_EVENT_CLASS_LOG_LEVEL_ALERT,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_ALERT = 1,
/// Critical conditions.
- BT_CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL = BT_EVENT_CLASS_LOG_LEVEL_CRITICAL,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL = 2,
/// Error conditions.
- BT_CTF_EVENT_CLASS_LOG_LEVEL_ERROR = BT_EVENT_CLASS_LOG_LEVEL_ERROR,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_ERROR = 3,
/// Warning conditions.
- BT_CTF_EVENT_CLASS_LOG_LEVEL_WARNING = BT_EVENT_CLASS_LOG_LEVEL_WARNING,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_WARNING = 4,
/// Normal, but significant, condition.
- BT_CTF_EVENT_CLASS_LOG_LEVEL_NOTICE = BT_EVENT_CLASS_LOG_LEVEL_NOTICE,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_NOTICE = 5,
/// Informational message.
- BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO = BT_EVENT_CLASS_LOG_LEVEL_INFO,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO = 6,
/// Debug information with system-level scope (set of programs).
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM = 7,
/// Debug information with program-level scope (set of processes).
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM = 8,
/// Debug information with process-level scope (set of modules).
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS = 9,
/// Debug information with module (executable/library) scope (set of units).
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE = 10,
/// Debug information with compilation unit scope (set of functions).
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT = 11,
/// Debug information with function-level scope.
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION = 12,
/// Debug information with line-level scope (default log level).
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE = 13,
/// Debug-level message.
- BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG = BT_EVENT_CLASS_LOG_LEVEL_DEBUG,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG = 14,
};
extern struct bt_ctf_event *bt_ctf_event_create(
--- /dev/null
+#ifndef BABELTRACE_CTF_WRITER_FIELD_PATH_INTERNAL
+#define BABELTRACE_CTF_WRITER_FIELD_PATH_INTERNAL
+
+/*
+ * BabelTrace - CTF writer: Field path
+ *
+ * Copyright 2016 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:
+ *
+ * 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.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <babeltrace/common-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/ctf-writer/field-types.h>
+#include <glib.h>
+
+struct bt_ctf_field_path {
+ struct bt_object base;
+ enum bt_ctf_scope root;
+
+ /*
+ * Array of integers (int) indicating the index in either
+ * structures, variants, arrays, or sequences that make up
+ * the path to a field type. -1 means the "current element
+ * of an array or sequence type".
+ */
+ GArray *indexes;
+};
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_path_create(void);
+
+BT_HIDDEN
+void bt_ctf_field_path_clear(struct bt_ctf_field_path *field_path);
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_path_copy(
+ struct bt_ctf_field_path *path);
+
+BT_HIDDEN enum bt_ctf_scope bt_ctf_field_path_get_root_scope(
+ const struct bt_ctf_field_path *field_path);
+
+BT_HIDDEN int64_t bt_ctf_field_path_get_index_count(
+ const struct bt_ctf_field_path *field_path);
+
+BT_HIDDEN int bt_ctf_field_path_get_index(
+ const struct bt_ctf_field_path *field_path, uint64_t index);
+
+#endif /* BABELTRACE_CTF_WRITER_FIELD_PATH_INTERNAL */
#include <stdint.h>
#include <stddef.h>
-/* For bt_bool */
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/ctf-writer/clock-class-internal.h>
#include <babeltrace/ctf-writer/field-types.h>
#include <babeltrace/ctf-writer/writer-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/types.h>
+
+#define BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(_ft, _type_id, _name) \
+ BT_ASSERT_PRE(((struct bt_ctf_field_type_common *) (_ft))->id == (_type_id), \
+ _name " has the wrong type ID: expected-type-id=%s, " \
+ "ft-addr=%p", bt_ctf_field_type_id_string(_type_id), (_ft))
+
+#define BT_ASSERT_PRE_CTF_FT_HOT(_ft, _name) \
+ BT_ASSERT_PRE_HOT((_ft), (_name), ": ft-addr=%p", (_ft))
+
+#define BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(_ft, _index) \
+ (&g_array_index(((struct bt_ctf_field_type_common_structure *) (_ft))->fields, \
+ struct bt_ctf_field_type_common_structure_field, (_index)))
+
+#define BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(_ft, _index) \
+ (&g_array_index(((struct bt_ctf_field_type_common_variant *) (_ft))->choices, \
+ struct bt_ctf_field_type_common_variant_choice, (_index)))
+
+struct bt_ctf_field_common;
+struct bt_ctf_field_type_common;
+
+typedef void (*bt_ctf_field_type_common_method_freeze)(
+ struct bt_ctf_field_type_common *);
+typedef int (*bt_ctf_field_type_common_method_validate)(
+ struct bt_ctf_field_type_common *);
+typedef void (*bt_ctf_field_type_common_method_set_byte_order)(
+ struct bt_ctf_field_type_common *, enum bt_ctf_byte_order);
+typedef struct bt_ctf_field_type_common *(*bt_ctf_field_type_common_method_copy)(
+ struct bt_ctf_field_type_common *);
+typedef int (*bt_ctf_field_type_common_method_compare)(
+ struct bt_ctf_field_type_common *,
+ struct bt_ctf_field_type_common *);
+
+struct bt_ctf_field_type_common_methods {
+ bt_ctf_field_type_common_method_freeze freeze;
+ bt_ctf_field_type_common_method_validate validate;
+ bt_ctf_field_type_common_method_set_byte_order set_byte_order;
+ bt_ctf_field_type_common_method_copy copy;
+ bt_ctf_field_type_common_method_compare compare;
+};
+
+struct bt_ctf_field_type_common {
+ struct bt_object base;
+ enum bt_ctf_field_type_id id;
+ unsigned int alignment;
+
+ /* Virtual table */
+ struct bt_ctf_field_type_common_methods *methods;
+
+ /*
+ * A type can't be modified once it is added to an event or after a
+ * a field has been instanciated from it.
+ */
+ int frozen;
+
+ /*
+ * This flag indicates if the field type is valid. A valid
+ * field type is _always_ frozen. All the nested field types of
+ * a valid field type are also valid (and thus frozen).
+ */
+ int valid;
+
+ /*
+ * Specialized data for either CTF IR or CTF writer APIs.
+ * Having this here ensures that:
+ *
+ * * The type-specific common data is always found at the same
+ * offset when the common API has a `struct
+ * bt_ctf_field_type_common *` so that you can cast it to `struct
+ * bt_ctf_field_type_common_integer *` for example and access the
+ * common integer field type fields.
+ *
+ * * The specific CTF IR and CTF writer APIs can access their
+ * specific field type fields in this union at an offset known
+ * at build time. This avoids a pointer to specific data so
+ * that all the fields, common or specific, of a CTF IR
+ * integer field type or of a CTF writer integer field type,
+ * for example, are contained within the same contiguous block
+ * of memory.
+ */
+ union {
+ struct {
+ } ir;
+ struct {
+ void *serialize_func;
+ } writer;
+ } spec;
+};
+
+struct bt_ctf_field_type_common_integer {
+ struct bt_ctf_field_type_common common;
+
+ /* Owned by this */
+ struct bt_ctf_clock_class *mapped_clock_class;
+
+ enum bt_ctf_byte_order user_byte_order;
+ bt_bool is_signed;
+ unsigned int size;
+ enum bt_ctf_integer_base base;
+ enum bt_ctf_string_encoding encoding;
+};
+
+struct bt_ctf_enumeration_mapping {
+ union {
+ uint64_t _unsigned;
+ int64_t _signed;
+ } range_start;
+ union {
+ uint64_t _unsigned;
+ int64_t _signed;
+ } range_end;
+ GQuark string;
+};
+
+struct bt_ctf_field_type_common_enumeration {
+ struct bt_ctf_field_type_common common;
+
+ /* Owned by this */
+ struct bt_ctf_field_type_common_integer *container_ft;
+
+ /* Array of `struct bt_ctf_enumeration_mapping *`, owned by this */
+ GPtrArray *entries;
+
+ /* Only set during validation */
+ bt_bool has_overlapping_ranges;
+};
+
+enum bt_ctf_field_type_enumeration_mapping_iterator_type {
+ CTF_ITERATOR_BY_NAME,
+ CTF_ITERATOR_BY_SIGNED_VALUE,
+ CTF_ITERATOR_BY_UNSIGNED_VALUE,
+};
+
+struct bt_ctf_field_type_enumeration_mapping_iterator {
+ struct bt_object base;
+
+ /* Owned by this */
+ struct bt_ctf_field_type_common_enumeration *enumeration_ft;
+
+ enum bt_ctf_field_type_enumeration_mapping_iterator_type type;
+ int index;
+ union {
+ GQuark name_quark;
+ int64_t signed_value;
+ uint64_t unsigned_value;
+ } u;
+};
+
+struct bt_ctf_field_type_common_floating_point {
+ struct bt_ctf_field_type_common common;
+ enum bt_ctf_byte_order user_byte_order;
+ unsigned int exp_dig;
+ unsigned int mant_dig;
+};
+
+struct bt_ctf_field_type_common_structure_field {
+ GQuark name;
+
+ /* Owned by this */
+ struct bt_ctf_field_type_common *type;
+};
+
+struct bt_ctf_field_type_common_structure {
+ struct bt_ctf_field_type_common common;
+ GHashTable *field_name_to_index;
+
+ /*
+ * Array of `struct bt_ctf_field_type_common_structure_field`,
+ * owned by this
+ */
+ GArray *fields;
+};
+
+struct bt_ctf_field_type_common_variant_choice_range {
+ union {
+ int64_t i;
+ uint64_t u;
+ } lower;
+ union {
+ int64_t i;
+ uint64_t u;
+ } upper;
+};
+
+struct bt_ctf_field_type_common_variant_choice {
+ GQuark name;
+
+ /* Owned by this */
+ struct bt_ctf_field_type_common *type;
+
+ /* Array of `struct bt_ctf_field_type_common_variant_choice_range` */
+ GArray *ranges;
+};
+
+struct bt_ctf_field_type_common_variant {
+ struct bt_ctf_field_type_common common;
+ GString *tag_name;
+ bool choices_up_to_date;
+
+ /* Owned by this */
+ struct bt_ctf_field_type_common_enumeration *tag_ft;
+
+ /* Owned by this */
+ struct bt_ctf_field_path *tag_field_path;
+
+ GHashTable *choice_name_to_index;
+
+ /*
+ * Array of `struct bt_ctf_field_type_common_variant_choice`,
+ * owned by this */
+ GArray *choices;
+};
+
+struct bt_ctf_field_type_common_array {
+ struct bt_ctf_field_type_common common;
+
+ /* Owned by this */
+ struct bt_ctf_field_type_common *element_ft;
+
+ unsigned int length;
+};
+
+struct bt_ctf_field_type_common_sequence {
+ struct bt_ctf_field_type_common common;
+
+ /* Owned by this */
+ struct bt_ctf_field_type_common *element_ft;
+
+ GString *length_field_name;
+
+ /* Owned by this */
+ struct bt_ctf_field_path *length_field_path;
+};
+
+struct bt_ctf_field_type_common_string {
+ struct bt_ctf_field_type_common common;
+ enum bt_ctf_string_encoding encoding;
+};
+
+typedef struct bt_ctf_field_common *(* bt_ctf_field_common_create_func)(
+ struct bt_ctf_field_type_common *);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_initialize(struct bt_ctf_field_type_common *ft,
+ bool init_bo, bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_integer_initialize(
+ struct bt_ctf_field_type_common *ft,
+ unsigned int size, bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_floating_point_initialize(
+ struct bt_ctf_field_type_common *ft,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_enumeration_initialize(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *container_ft,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_string_initialize(
+ struct bt_ctf_field_type_common *ft,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_structure_initialize(
+ struct bt_ctf_field_type_common *ft,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_array_initialize(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *element_ft,
+ unsigned int length, bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_sequence_initialize(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *element_ft,
+ const char *length_field_name,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_variant_initialize(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *tag_ft,
+ const char *tag_name,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_integer_destroy(struct bt_object *obj);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_floating_point_destroy(struct bt_object *obj);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_enumeration_destroy_recursive(struct bt_object *obj);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_string_destroy(struct bt_object *obj);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_structure_destroy_recursive(struct bt_object *obj);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_array_destroy_recursive(struct bt_object *obj);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_sequence_destroy_recursive(struct bt_object *obj);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_variant_destroy_recursive(struct bt_object *obj);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_validate(struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_enumeration_validate_recursive(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_sequence_validate_recursive(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_array_validate_recursive(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_structure_validate_recursive(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_validate_recursive(
+ struct bt_ctf_field_type_common *type);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_validate(struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_get_size(struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+bt_bool bt_ctf_field_type_common_integer_is_signed(struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_set_is_signed(struct bt_ctf_field_type_common *ft,
+ bt_bool is_signed);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_set_size(struct bt_ctf_field_type_common *ft,
+ unsigned int size);
+
+BT_HIDDEN
+enum bt_ctf_integer_base bt_ctf_field_type_common_integer_get_base(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_set_base(struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_integer_base base);
+
+BT_HIDDEN
+enum bt_ctf_string_encoding bt_ctf_field_type_common_integer_get_encoding(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_set_encoding(struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_string_encoding encoding);
+
+BT_HIDDEN
+struct bt_ctf_clock_class *bt_ctf_field_type_common_integer_borrow_mapped_clock_class(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_set_mapped_clock_class_no_check_frozen(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_clock_class *clock_class);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_set_mapped_clock_class(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_clock_class *clock_class);
+
+BT_HIDDEN
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_common_enumeration_find_mappings_by_name(
+ struct bt_ctf_field_type_common *ft, const char *name);
+
+BT_HIDDEN
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_common_enumeration_signed_find_mappings_by_value(
+ struct bt_ctf_field_type_common *ft, int64_t value);
+
+BT_HIDDEN
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_common_enumeration_unsigned_find_mappings_by_value(
+ struct bt_ctf_field_type_common *ft, uint64_t value);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_enumeration_signed_get_mapping_by_index(
+ struct bt_ctf_field_type_common *ft, uint64_t index,
+ const char **mapping_name, int64_t *range_begin,
+ int64_t *range_end);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_enumeration_unsigned_get_mapping_by_index(
+ struct bt_ctf_field_type_common *ft, uint64_t index,
+ const char **mapping_name, uint64_t *range_begin,
+ uint64_t *range_end);
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_enumeration_borrow_container_field_type(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_enumeration_signed_add_mapping(
+ struct bt_ctf_field_type_common *ft, const char *string,
+ int64_t range_start, int64_t range_end);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_enumeration_unsigned_add_mapping(
+ struct bt_ctf_field_type_common *ft, const char *string,
+ uint64_t range_start, uint64_t range_end);
+
+BT_HIDDEN
+int64_t bt_ctf_field_type_common_enumeration_get_mapping_count(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_floating_point_get_exponent_digits(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_floating_point_set_exponent_digits(
+ struct bt_ctf_field_type_common *ft,
+ unsigned int exponent_digits);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_floating_point_get_mantissa_digits(
+ struct bt_ctf_field_type_common *type);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_floating_point_set_mantissa_digits(
+ struct bt_ctf_field_type_common *ft, unsigned int mantissa_digits);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_structure_replace_field(
+ struct bt_ctf_field_type_common *ft,
+ const char *field_name,
+ struct bt_ctf_field_type_common *field_type);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_structure_add_field(struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *field_type,
+ const char *field_name);
+
+BT_HIDDEN
+int64_t bt_ctf_field_type_common_structure_get_field_count(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_structure_borrow_field_by_index(
+ struct bt_ctf_field_type_common *ft,
+ const char **field_name,
+ struct bt_ctf_field_type_common **field_type, uint64_t index);
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_structure_borrow_field_type_by_name(
+ struct bt_ctf_field_type_common *ft, const char *name);
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_variant_borrow_tag_field_type(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+const char *bt_ctf_field_type_common_variant_get_tag_name(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_set_tag_name(
+ struct bt_ctf_field_type_common *ft, const char *name);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_add_field(struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *field_type,
+ const char *field_name);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_update_choices(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_variant_borrow_field_type_by_name(
+ struct bt_ctf_field_type_common *ft,
+ const char *field_name);
+
+BT_HIDDEN
+int64_t bt_ctf_field_type_common_variant_get_field_count(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_borrow_field_by_index(
+ struct bt_ctf_field_type_common *ft,
+ const char **field_name,
+ struct bt_ctf_field_type_common **field_type, uint64_t index);
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_array_borrow_element_field_type(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_array_set_element_field_type(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *element_ft);
+
+BT_HIDDEN
+int64_t bt_ctf_field_type_common_array_get_length(struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_sequence_borrow_element_field_type(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_sequence_set_element_field_type(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *element_ft);
+
+BT_HIDDEN
+const char *bt_ctf_field_type_common_sequence_get_length_field_name(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+enum bt_ctf_string_encoding bt_ctf_field_type_common_string_get_encoding(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_string_set_encoding(struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_string_encoding encoding);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_get_alignment(struct bt_ctf_field_type_common *type);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_set_alignment(struct bt_ctf_field_type_common *ft,
+ unsigned int alignment);
+
+BT_HIDDEN
+enum bt_ctf_byte_order bt_ctf_field_type_common_get_byte_order(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_set_byte_order(struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_byte_order byte_order);
+
+BT_HIDDEN
+enum bt_ctf_field_type_id bt_ctf_field_type_common_get_type_id(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_freeze(struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_variant_borrow_field_type_signed(
+ struct bt_ctf_field_type_common_variant *var_ft,
+ int64_t tag_value);
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_variant_borrow_field_type_unsigned(
+ struct bt_ctf_field_type_common_variant *var_ft,
+ uint64_t tag_value);
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *bt_ctf_field_type_common_copy(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_structure_get_field_name_index(
+ struct bt_ctf_field_type_common *ft, const char *name);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_get_field_name_index(
+ struct bt_ctf_field_type_common *ft, const char *name);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_sequence_set_length_field_path(
+ struct bt_ctf_field_type_common *ft, struct bt_ctf_field_path *path);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_set_tag_field_path(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_path *path);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_set_tag_field_type(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *tag_ft);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_generic_freeze(struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_enumeration_freeze_recursive(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_structure_freeze_recursive(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_variant_freeze_recursive(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_array_freeze_recursive(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_sequence_freeze_recursive(
+ struct bt_ctf_field_type_common *type);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_integer_set_byte_order(
+ struct bt_ctf_field_type_common *ft, enum bt_ctf_byte_order byte_order);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_enumeration_set_byte_order_recursive(
+ struct bt_ctf_field_type_common *ft, enum bt_ctf_byte_order byte_order);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_floating_point_set_byte_order(
+ struct bt_ctf_field_type_common *ft, enum bt_ctf_byte_order byte_order);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_structure_set_byte_order_recursive(
+ struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_byte_order byte_order);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_variant_set_byte_order_recursive(
+ struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_byte_order byte_order);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_array_set_byte_order_recursive(
+ struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_byte_order byte_order);
+
+BT_HIDDEN
+void bt_ctf_field_type_common_sequence_set_byte_order_recursive(
+ struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_byte_order byte_order);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_compare(struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_floating_point_compare(
+ struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_enumeration_compare_recursive(
+ struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_string_compare(struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_structure_compare_recursive(
+ struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_compare_recursive(
+ struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_array_compare_recursive(
+ struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_sequence_compare_recursive(
+ struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_compare(struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b);
+
+BT_HIDDEN
+int64_t bt_ctf_field_type_common_get_field_count(struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *bt_ctf_field_type_common_borrow_field_at_index(
+ struct bt_ctf_field_type_common *ft, int index);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_get_field_index(struct bt_ctf_field_type_common *ft,
+ const char *name);
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_type_common_variant_borrow_tag_field_path(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_type_common_sequence_borrow_length_field_path(
+ struct bt_ctf_field_type_common *ft);
+
+BT_HIDDEN
+int bt_ctf_field_type_common_validate_single_clock_class(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_clock_class **expected_clock_class);
+
+BT_HIDDEN
+int64_t bt_ctf_field_type_common_variant_find_choice_index(
+ struct bt_ctf_field_type_common *ft, uint64_t uval,
+ bool is_signed);
BT_HIDDEN
int bt_ctf_field_type_serialize_recursive(struct bt_ctf_field_type *type,
#include <stddef.h>
#include <babeltrace/types.h>
-#include <babeltrace/ctf-ir/field-types.h>
#ifdef __cplusplus
extern "C" {
struct bt_ctf_field;
struct bt_ctf_field_type;
+enum bt_ctf_scope {
+ /// Unknown, used for errors.
+ BT_CTF_SCOPE_UNKNOWN = -1,
+
+ /// Trace packet header.
+ BT_CTF_SCOPE_TRACE_PACKET_HEADER = 1,
+
+ /// Stream packet context.
+ BT_CTF_SCOPE_STREAM_PACKET_CONTEXT = 2,
+
+ /// Stream event header.
+ BT_CTF_SCOPE_STREAM_EVENT_HEADER = 3,
+
+ /// Stream event context.
+ BT_CTF_SCOPE_STREAM_EVENT_CONTEXT = 4,
+
+ /// Event context.
+ BT_CTF_SCOPE_EVENT_CONTEXT = 5,
+
+ /// Event payload.
+ BT_CTF_SCOPE_EVENT_PAYLOAD = 6,
+
+ /// @cond DOCUMENT
+ BT_CTF_SCOPE_ENV = 0,
+ BT_CTF_SCOPE_EVENT_FIELDS = 6,
+ /// @endcond
+};
+
enum bt_ctf_field_type_id {
- BT_CTF_FIELD_TYPE_ID_UNKNOWN = BT_FIELD_TYPE_ID_UNKNOWN,
- BT_CTF_FIELD_TYPE_ID_INTEGER = BT_FIELD_TYPE_ID_INTEGER,
- BT_CTF_FIELD_TYPE_ID_FLOAT = BT_FIELD_TYPE_ID_FLOAT,
- BT_CTF_FIELD_TYPE_ID_ENUM = BT_FIELD_TYPE_ID_ENUM,
- BT_CTF_FIELD_TYPE_ID_STRING = BT_FIELD_TYPE_ID_STRING,
- BT_CTF_FIELD_TYPE_ID_STRUCT = BT_FIELD_TYPE_ID_STRUCT,
- BT_CTF_FIELD_TYPE_ID_ARRAY = BT_FIELD_TYPE_ID_ARRAY,
- BT_CTF_FIELD_TYPE_ID_SEQUENCE = BT_FIELD_TYPE_ID_SEQUENCE,
- BT_CTF_FIELD_TYPE_ID_VARIANT = BT_FIELD_TYPE_ID_VARIANT,
- BT_CTF_FIELD_TYPE_ID_NR = BT_FIELD_TYPE_ID_NR,
+ BT_CTF_FIELD_TYPE_ID_UNKNOWN = -1,
+ BT_CTF_FIELD_TYPE_ID_INTEGER = 0,
+ BT_CTF_FIELD_TYPE_ID_FLOAT = 1,
+ BT_CTF_FIELD_TYPE_ID_ENUM = 2,
+ BT_CTF_FIELD_TYPE_ID_STRING = 3,
+ BT_CTF_FIELD_TYPE_ID_STRUCT = 4,
+ BT_CTF_FIELD_TYPE_ID_ARRAY = 5,
+ BT_CTF_FIELD_TYPE_ID_SEQUENCE = 6,
+ BT_CTF_FIELD_TYPE_ID_VARIANT = 7,
+ BT_CTF_FIELD_TYPE_ID_NR,
};
extern enum bt_ctf_field_type_id bt_ctf_field_type_get_type_id(
struct bt_ctf_field_type *field_type);
enum bt_ctf_byte_order {
- BT_CTF_BYTE_ORDER_UNKNOWN = BT_BYTE_ORDER_UNKNOWN,
- BT_CTF_BYTE_ORDER_NATIVE = BT_BYTE_ORDER_NATIVE,
- BT_CTF_BYTE_ORDER_UNSPECIFIED = BT_BYTE_ORDER_UNSPECIFIED,
- BT_CTF_BYTE_ORDER_LITTLE_ENDIAN = BT_BYTE_ORDER_LITTLE_ENDIAN,
- BT_CTF_BYTE_ORDER_BIG_ENDIAN = BT_BYTE_ORDER_BIG_ENDIAN,
- BT_CTF_BYTE_ORDER_NETWORK = BT_BYTE_ORDER_NETWORK,
+ BT_CTF_BYTE_ORDER_UNKNOWN = -1,
+ BT_CTF_BYTE_ORDER_NATIVE = 0,
+ BT_CTF_BYTE_ORDER_UNSPECIFIED,
+ BT_CTF_BYTE_ORDER_LITTLE_ENDIAN,
+ BT_CTF_BYTE_ORDER_BIG_ENDIAN,
+ BT_CTF_BYTE_ORDER_NETWORK,
};
enum bt_ctf_string_encoding {
- BT_CTF_STRING_ENCODING_UNKNOWN = BT_STRING_ENCODING_UNKNOWN,
- BT_CTF_STRING_ENCODING_NONE = BT_STRING_ENCODING_NONE,
- BT_CTF_STRING_ENCODING_UTF8 = BT_STRING_ENCODING_UTF8,
- BT_CTF_STRING_ENCODING_ASCII = BT_STRING_ENCODING_ASCII,
+ BT_CTF_STRING_ENCODING_UNKNOWN = -1,
+ BT_CTF_STRING_ENCODING_NONE,
+ BT_CTF_STRING_ENCODING_UTF8,
+ BT_CTF_STRING_ENCODING_ASCII,
};
/* Pre-2.0 CTF writer compatibility */
--- /dev/null
+#ifndef BABELTRACE_CTF_WRITER_FIELD_WRAPPER_INTERNAL_H
+#define BABELTRACE_CTF_WRITER_FIELD_WRAPPER_INTERNAL_H
+
+/*
+ * Copyright 2018 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:
+ *
+ * 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.
+ */
+
+#include <babeltrace/ctf-writer/fields-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/object-internal.h>
+
+struct bt_ctf_field_wrapper {
+ struct bt_object base;
+
+ /* Owned by this */
+ struct bt_ctf_field_common *field;
+};
+
+BT_HIDDEN
+struct bt_ctf_field_wrapper *bt_ctf_field_wrapper_new(void *data);
+
+BT_HIDDEN
+void bt_ctf_field_wrapper_destroy(struct bt_ctf_field_wrapper *field);
+
+BT_HIDDEN
+struct bt_ctf_field_wrapper *bt_ctf_field_wrapper_create(
+ struct bt_object_pool *pool, struct bt_ctf_field_type *ft);
+
+#endif /* BABELTRACE_CTF_WRITER_FIELD_WRAPPER_INTERNAL_H */
#include <stdint.h>
#include <stddef.h>
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/babeltrace-internal.h>
#include <babeltrace/babeltrace.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
+#include <babeltrace/common-internal.h>
+#include <babeltrace/ctf-writer/field-types-internal.h>
#include <babeltrace/ctf-writer/fields.h>
#include <babeltrace/ctf-writer/serialize-internal.h>
+#include <babeltrace/ctf-writer/utils-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/types.h>
+#include <glib.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#define BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(_field, _type_id, _name) \
+ BT_ASSERT_PRE((_field)->type->id == ((int) (_type_id)), \
+ _name " has the wrong type ID: expected-type-id=%s, " \
+ "field-addr=%p", \
+ bt_ctf_field_type_id_string((int) (_type_id)), (_field))
+
+#define BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(_field, _name) \
+ BT_ASSERT_PRE(bt_ctf_field_common_is_set_recursive(_field), \
+ _name " is not set: field-addr=%p", (_field))
+
+#define BT_ASSERT_PRE_CTF_FIELD_COMMON_HOT(_field, _name) \
+ BT_ASSERT_PRE_HOT((_field), (_name), ": field-addr=%p", (_field))
+
+struct bt_ctf_field_common;
+
+typedef void (*bt_ctf_field_common_method_set_is_frozen)(struct bt_ctf_field_common *,
+ bool);
+typedef int (*bt_ctf_field_common_method_validate)(struct bt_ctf_field_common *);
+typedef struct bt_ctf_field_common *(*bt_ctf_field_common_method_copy)(
+ struct bt_ctf_field_common *);
+typedef bt_bool (*bt_ctf_field_common_method_is_set)(struct bt_ctf_field_common *);
+typedef void (*bt_ctf_field_common_method_reset)(struct bt_ctf_field_common *);
+
+struct bt_ctf_field_common_methods {
+ bt_ctf_field_common_method_set_is_frozen set_is_frozen;
+ bt_ctf_field_common_method_validate validate;
+ bt_ctf_field_common_method_copy copy;
+ bt_ctf_field_common_method_is_set is_set;
+ bt_ctf_field_common_method_reset reset;
+};
+
+struct bt_ctf_field_common {
+ struct bt_object base;
+ struct bt_ctf_field_type_common *type;
+ struct bt_ctf_field_common_methods *methods;
+ bool payload_set;
+ bool frozen;
+
+ /*
+ * Specialized data for either CTF IR or CTF writer APIs.
+ * See comment in `field-types-internal.h` for more details.
+ */
+ union {
+ struct {
+ } ir;
+ struct {
+ void *serialize_func;
+ } writer;
+ } spec;
+};
+
+struct bt_ctf_field_common_integer {
+ struct bt_ctf_field_common common;
+ union {
+ int64_t signd;
+ uint64_t unsignd;
+ } payload;
+};
+
+struct bt_ctf_field_common_floating_point {
+ struct bt_ctf_field_common common;
+ double payload;
+};
+
+struct bt_ctf_field_common_structure {
+ struct bt_ctf_field_common common;
+
+ /* Array of `struct bt_ctf_field_common *`, owned by this */
+ GPtrArray *fields;
+};
+
+struct bt_ctf_field_common_variant {
+ struct bt_ctf_field_common common;
+
+ union {
+ uint64_t u;
+ int64_t i;
+ } tag_value;
+
+ /* Weak: belongs to `choices` below */
+ struct bt_ctf_field_common *current_field;
+
+ /* Array of `struct bt_ctf_field_common *`, owned by this */
+ GPtrArray *fields;
+};
+
+struct bt_ctf_field_common_array {
+ struct bt_ctf_field_common common;
+
+ /* Array of `struct bt_ctf_field_common *`, owned by this */
+ GPtrArray *elements;
+};
+
+struct bt_ctf_field_common_sequence {
+ struct bt_ctf_field_common common;
+
+ /*
+ * This is the true sequence field's length: its value can be
+ * less than `elements->len` below because we never shrink the
+ * array of elements to avoid reallocation.
+ */
+ uint64_t length;
+
+ /* Array of `struct bt_ctf_field_common *`, owned by this */
+ GPtrArray *elements;
+};
+
+struct bt_ctf_field_common_string {
+ struct bt_ctf_field_common common;
+ GArray *buf;
+ size_t size;
+};
+
+BT_HIDDEN
+struct bt_ctf_field_common *bt_ctf_field_common_copy(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+int bt_ctf_field_common_structure_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods,
+ bt_ctf_field_common_create_func field_create_func,
+ GDestroyNotify field_release_func);
+
+BT_HIDDEN
+int bt_ctf_field_common_array_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods,
+ bt_ctf_field_common_create_func field_create_func,
+ GDestroyNotify field_destroy_func);
+
+BT_HIDDEN
+int bt_ctf_field_common_sequence_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods,
+ GDestroyNotify field_destroy_func);
+
+BT_HIDDEN
+int bt_ctf_field_common_variant_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods,
+ bt_ctf_field_common_create_func field_create_func,
+ GDestroyNotify field_release_func);
+
+BT_HIDDEN
+int bt_ctf_field_common_string_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods);
+
+BT_HIDDEN
+int bt_ctf_field_common_generic_validate(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+int bt_ctf_field_common_structure_validate_recursive(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+int bt_ctf_field_common_variant_validate_recursive(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+int bt_ctf_field_common_array_validate_recursive(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+int bt_ctf_field_common_sequence_validate_recursive(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+void bt_ctf_field_common_generic_reset(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+void bt_ctf_field_common_structure_reset_recursive(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+void bt_ctf_field_common_variant_reset_recursive(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+void bt_ctf_field_common_array_reset_recursive(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+void bt_ctf_field_common_sequence_reset_recursive(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+void bt_ctf_field_common_generic_set_is_frozen(struct bt_ctf_field_common *field,
+ bool is_frozen);
+
+BT_HIDDEN
+void bt_ctf_field_common_structure_set_is_frozen_recursive(
+ struct bt_ctf_field_common *field, bool is_frozen);
+
+BT_HIDDEN
+void bt_ctf_field_common_variant_set_is_frozen_recursive(
+ struct bt_ctf_field_common *field, bool is_frozen);
+
+BT_HIDDEN
+void bt_ctf_field_common_array_set_is_frozen_recursive(
+ struct bt_ctf_field_common *field, bool is_frozen);
+
+BT_HIDDEN
+void bt_ctf_field_common_sequence_set_is_frozen_recursive(
+ struct bt_ctf_field_common *field, bool is_frozen);
+
+BT_HIDDEN
+void _bt_ctf_field_common_set_is_frozen_recursive(struct bt_ctf_field_common *field,
+ bool is_frozen);
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_generic_is_set(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_structure_is_set_recursive(
+ struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_variant_is_set_recursive(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_array_is_set_recursive(struct bt_ctf_field_common *field);
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_sequence_is_set_recursive(struct bt_ctf_field_common *field);
+
+#ifdef BT_DEV_MODE
+# define bt_ctf_field_common_validate_recursive _bt_ctf_field_common_validate_recursive
+# define bt_ctf_field_common_set_is_frozen_recursive _bt_ctf_field_common_set_is_frozen_recursive
+# define bt_ctf_field_common_is_set_recursive _bt_ctf_field_common_is_set_recursive
+# define bt_ctf_field_common_reset_recursive _bt_ctf_field_common_reset_recursive
+# define bt_ctf_field_common_set _bt_ctf_field_common_set
+#else
+# define bt_ctf_field_common_validate_recursive(_field) (-1)
+# define bt_ctf_field_common_set_is_frozen_recursive(_field, _is_frozen)
+# define bt_ctf_field_common_is_set_recursive(_field) (BT_FALSE)
+# define bt_ctf_field_common_reset_recursive(_field)
+# define bt_ctf_field_common_set(_field, _val)
+#endif
+
+BT_ASSERT_FUNC
+static inline bool field_type_common_has_known_id(
+ struct bt_ctf_field_type_common *ft)
+{
+ return (int) ft->id > BT_CTF_FIELD_TYPE_ID_UNKNOWN ||
+ (int) ft->id < BT_CTF_FIELD_TYPE_ID_NR;
+}
+
+static inline
+int _bt_ctf_field_common_validate_recursive(struct bt_ctf_field_common *field)
+{
+ int ret = 0;
+
+ if (!field) {
+ BT_ASSERT_PRE_MSG("%s", "Invalid field: field is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ BT_ASSERT(field_type_common_has_known_id(field->type));
+
+ if (field->methods->validate) {
+ ret = field->methods->validate(field);
+ }
+
+end:
+ return ret;
+}
+
+static inline
+void _bt_ctf_field_common_reset_recursive(struct bt_ctf_field_common *field)
+{
+ BT_ASSERT(field);
+ BT_ASSERT(field->methods->reset);
+ field->methods->reset(field);
+}
+
+static inline
+void _bt_ctf_field_common_set(struct bt_ctf_field_common *field, bool value)
+{
+ BT_ASSERT(field);
+ field->payload_set = value;
+}
+
+static inline
+bt_bool _bt_ctf_field_common_is_set_recursive(struct bt_ctf_field_common *field)
+{
+ bt_bool is_set = BT_FALSE;
+
+ if (!field) {
+ goto end;
+ }
+
+ BT_ASSERT(field_type_common_has_known_id(field->type));
+ BT_ASSERT(field->methods->is_set);
+ is_set = field->methods->is_set(field);
+
+end:
+ return is_set;
+}
+
+static inline
+void bt_ctf_field_common_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *ft, bool is_shared,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods)
+{
+ BT_ASSERT(field);
+ BT_ASSERT(ft);
+ bt_object_init(&field->base, is_shared, release_func);
+ field->methods = methods;
+ field->type = bt_get(ft);
+}
+
+static inline
+struct bt_ctf_field_type_common *bt_ctf_field_common_borrow_type(
+ struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_type_common *ret = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ ret = field->type;
+ return ret;
+}
+
+static inline
+int64_t bt_ctf_field_common_sequence_get_length(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT_PRE_NON_NULL(field, "Sequence field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field, BT_CTF_FIELD_TYPE_ID_SEQUENCE,
+ "Field");
+ return (int64_t) sequence->length;
+}
+
+static inline
+int bt_ctf_field_common_sequence_set_length(struct bt_ctf_field_common *field,
+ uint64_t length, bt_ctf_field_common_create_func field_create_func)
+{
+ int ret = 0;
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT_PRE_NON_NULL(field, "Sequence field");
+ BT_ASSERT_PRE(((int64_t) length) >= 0,
+ "Invalid sequence length (too large): length=%" PRId64,
+ length);
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field, "Sequence field");
+
+ if (unlikely(length > sequence->elements->len)) {
+ /* Make more room */
+ struct bt_ctf_field_type_common_sequence *sequence_ft;
+ uint64_t cur_len = sequence->elements->len;
+ uint64_t i;
+
+ g_ptr_array_set_size(sequence->elements, length);
+ sequence_ft = BT_CTF_FROM_COMMON(sequence->common.type);
+
+ for (i = cur_len; i < sequence->elements->len; i++) {
+ struct bt_ctf_field_common *elem_field =
+ field_create_func(sequence_ft->element_ft);
+
+ if (!elem_field) {
+ ret = -1;
+ goto end;
+ }
+
+ BT_ASSERT(!sequence->elements->pdata[i]);
+ sequence->elements->pdata[i] = elem_field;
+ }
+ }
+
+ sequence->length = length;
+
+end:
+ return ret;
+}
+
+static inline
+struct bt_ctf_field_common *bt_ctf_field_common_structure_borrow_field_by_name(
+ struct bt_ctf_field_common *field, const char *name)
+{
+ struct bt_ctf_field_common *ret = NULL;
+ GQuark field_quark;
+ struct bt_ctf_field_type_common_structure *structure_ft;
+ struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
+ size_t index;
+ GHashTable *field_name_to_index;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Structure field");
+ BT_ASSERT_PRE_NON_NULL(name, "Field name");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
+ BT_CTF_FIELD_TYPE_ID_STRUCT, "Field");
+ structure_ft = BT_CTF_FROM_COMMON(field->type);
+ field_name_to_index = structure_ft->field_name_to_index;
+ field_quark = g_quark_from_string(name);
+ if (!g_hash_table_lookup_extended(field_name_to_index,
+ GUINT_TO_POINTER(field_quark),
+ NULL, (gpointer *) &index)) {
+ BT_LOGV("Invalid parameter: no such field in structure field's type: "
+ "struct-field-addr=%p, struct-ft-addr=%p, name=\"%s\"",
+ field, field->type, name);
+ goto error;
+ }
+
+ ret = structure->fields->pdata[index];
+ BT_ASSERT(ret);
+
+error:
+ return ret;
+}
+
+static inline
+struct bt_ctf_field_common *bt_ctf_field_common_structure_borrow_field_by_index(
+ struct bt_ctf_field_common *field, uint64_t index)
+{
+ struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT_PRE_NON_NULL(field, "Structure field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
+ BT_CTF_FIELD_TYPE_ID_STRUCT, "Field");
+ BT_ASSERT_PRE(index < structure->fields->len,
+ "Index is out of bound: struct-field-addr=%p, "
+ "index=%" PRIu64 ", count=%u", field, index,
+ structure->fields->len);
+ return structure->fields->pdata[index];
+}
+
+static inline
+struct bt_ctf_field_common *bt_ctf_field_common_array_borrow_field(
+ struct bt_ctf_field_common *field, uint64_t index)
+{
+ struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT_PRE_NON_NULL(field, "Array field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field, BT_CTF_FIELD_TYPE_ID_ARRAY,
+ "Field");
+ BT_ASSERT_PRE(index < array->elements->len,
+ "Index is out of bound: array-field-addr=%p, "
+ "index=%" PRIu64 ", count=%u", field,
+ index, array->elements->len);
+ return array->elements->pdata[(size_t) index];
+}
+
+static inline
+struct bt_ctf_field_common *bt_ctf_field_common_sequence_borrow_field(
+ struct bt_ctf_field_common *field, uint64_t index)
+{
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT_PRE_NON_NULL(field, "Sequence field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field, BT_CTF_FIELD_TYPE_ID_SEQUENCE,
+ "Field");
+ BT_ASSERT_PRE(index < sequence->length,
+ "Index is out of bound: seq-field-addr=%p, "
+ "index=%" PRIu64 ", count=%u", field, index,
+ sequence->elements->len);
+ return sequence->elements->pdata[(size_t) index];
+}
+
+static inline
+int bt_ctf_field_common_variant_set_tag(struct bt_ctf_field_common *variant_field,
+ uint64_t tag_uval, bool is_signed)
+{
+ int ret = 0;
+ int64_t choice_index;
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(variant_field);
+
+ BT_ASSERT_PRE_NON_NULL(variant_field, "Variant field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(variant_field,
+ BT_CTF_FIELD_TYPE_ID_VARIANT, "Field");
+
+ /* Find matching index in variant field's type */
+ choice_index = bt_ctf_field_type_common_variant_find_choice_index(
+ variant_field->type, tag_uval, is_signed);
+ if (choice_index < 0) {
+ ret = -1;
+ goto end;
+ }
+
+ /* Select corresponding field */
+ BT_ASSERT(choice_index < variant->fields->len);
+ variant->current_field = variant->fields->pdata[choice_index];
+ variant->tag_value.u = tag_uval;
+
+end:
+ return ret;
+}
+
+static inline
+struct bt_ctf_field_common *bt_ctf_field_common_variant_borrow_current_field(
+ struct bt_ctf_field_common *variant_field)
+{
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(variant_field);
+
+ BT_ASSERT_PRE_NON_NULL(variant_field, "Variant field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(variant_field,
+ BT_CTF_FIELD_TYPE_ID_VARIANT, "Field");
+ BT_ASSERT_PRE(variant->current_field,
+ "Variant field has no current field: field-addr=%p", variant_field);
+ return variant->current_field;
+}
+
+static inline
+int bt_ctf_field_common_variant_get_tag_signed(struct bt_ctf_field_common *variant_field,
+ int64_t *tag)
+{
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(variant_field);
+
+ BT_ASSERT_PRE_NON_NULL(variant_field, "Variant field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(variant_field,
+ BT_CTF_FIELD_TYPE_ID_VARIANT, "Field");
+ BT_ASSERT_PRE(variant->current_field,
+ "Variant field has no current field: field-addr=%p", variant_field);
+ *tag = variant->tag_value.i;
+ return 0;
+}
+
+static inline
+int bt_ctf_field_common_variant_get_tag_unsigned(struct bt_ctf_field_common *variant_field,
+ uint64_t *tag)
+{
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(variant_field);
+
+ BT_ASSERT_PRE_NON_NULL(variant_field, "Variant field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(variant_field,
+ BT_CTF_FIELD_TYPE_ID_VARIANT, "Field");
+ BT_ASSERT_PRE(variant->current_field,
+ "Variant field has no current field: field-addr=%p", variant_field);
+ *tag = variant->tag_value.u;
+ return 0;
+}
+
+static inline
+int bt_ctf_field_common_floating_point_get_value(struct bt_ctf_field_common *field,
+ double *value)
+{
+ struct bt_ctf_field_common_floating_point *floating_point =
+ BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT_PRE_NON_NULL(field, "Floating point number field");
+ BT_ASSERT_PRE_NON_NULL(value, "Value");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field, "Floating point number field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
+ BT_CTF_FIELD_TYPE_ID_FLOAT, "Field");
+ *value = floating_point->payload;
+ return 0;
+}
+
+static inline
+int bt_ctf_field_common_floating_point_set_value(struct bt_ctf_field_common *field,
+ double value)
+{
+ struct bt_ctf_field_common_floating_point *floating_point =
+ BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT_PRE_NON_NULL(field, "Floating point number field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field, "Floating point number field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
+ BT_CTF_FIELD_TYPE_ID_FLOAT, "Field");
+ floating_point->payload = value;
+ bt_ctf_field_common_set(field, true);
+ return 0;
+}
+
+static inline
+const char *bt_ctf_field_common_string_get_value(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_string *string = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT_PRE_NON_NULL(field, "String field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field, "String field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
+ BT_CTF_FIELD_TYPE_ID_STRING, "Field");
+ return (const char *) string->buf->data;
+}
+
+static inline
+int bt_ctf_field_common_string_clear(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_string *string_field = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT_PRE_NON_NULL(field, "String field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field, "String field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
+ BT_CTF_FIELD_TYPE_ID_STRING, "Field");
+ string_field->size = 0;
+ bt_ctf_field_common_set(field, true);
+ return 0;
+}
+
+static inline
+int bt_ctf_field_common_string_append_len(struct bt_ctf_field_common *field,
+ const char *value, unsigned int length)
+{
+ struct bt_ctf_field_common_string *string_field = BT_CTF_FROM_COMMON(field);
+ char *data;
+ size_t new_size;
+
+ BT_ASSERT_PRE_NON_NULL(field, "String field");
+ BT_ASSERT_PRE_NON_NULL(value, "Value");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field, "String field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
+ BT_CTF_FIELD_TYPE_ID_STRING, "Field");
+
+ /* Make sure no null bytes are appended */
+ BT_ASSERT_PRE(memchr(value, '\0', length) == NULL,
+ "String value to append contains a null character: "
+ "partial-value=\"%.32s\", length=%u", value, length);
+
+ new_size = string_field->size + length;
+
+ if (unlikely(new_size + 1 > string_field->buf->len)) {
+ g_array_set_size(string_field->buf, new_size + 1);
+ }
+
+ data = string_field->buf->data;
+ memcpy(data + string_field->size, value, length);
+ ((char *) string_field->buf->data)[new_size] = '\0';
+ string_field->size = new_size;
+ bt_ctf_field_common_set(field, true);
+ return 0;
+}
+
+static inline
+int bt_ctf_field_common_string_append(struct bt_ctf_field_common *field,
+ const char *value)
+{
+ BT_ASSERT_PRE_NON_NULL(value, "Value");
+ return bt_ctf_field_common_string_append_len(field, value,
+ strlen(value));
+}
+
+static inline
+int bt_ctf_field_common_string_set_value(struct bt_ctf_field_common *field,
+ const char *value)
+{
+ BT_ASSERT_PRE_NON_NULL(field, "String field");
+ BT_ASSERT_PRE_NON_NULL(value, "Value");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HOT(field, "String field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(field,
+ BT_CTF_FIELD_TYPE_ID_STRING, "Field");
+ bt_ctf_field_common_string_clear(field);
+ return bt_ctf_field_common_string_append_len(field,
+ value, strlen(value));
+}
+
+static inline
+void bt_ctf_field_common_finalize(struct bt_ctf_field_common *field)
+{
+ BT_ASSERT(field);
+ BT_LOGD_STR("Putting field's type.");
+ bt_put(field->type);
+}
+
+static inline
+void bt_ctf_field_common_integer_finalize(struct bt_ctf_field_common *field)
+{
+ BT_ASSERT(field);
+ BT_LOGD("Finalizing common integer field object: addr=%p", field);
+ bt_ctf_field_common_finalize(field);
+}
+
+static inline
+void bt_ctf_field_common_floating_point_finalize(struct bt_ctf_field_common *field)
+{
+ BT_ASSERT(field);
+ BT_LOGD("Finalizing common floating point number field object: addr=%p", field);
+ bt_ctf_field_common_finalize(field);
+}
+
+static inline
+void bt_ctf_field_common_structure_finalize_recursive(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+ BT_LOGD("Finalizing common structure field object: addr=%p", field);
+ bt_ctf_field_common_finalize(field);
+
+ if (structure->fields) {
+ g_ptr_array_free(structure->fields, TRUE);
+ }
+}
+
+static inline
+void bt_ctf_field_common_variant_finalize_recursive(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+ BT_LOGD("Finalizing common variant field object: addr=%p", field);
+ bt_ctf_field_common_finalize(field);
+
+ if (variant->fields) {
+ g_ptr_array_free(variant->fields, TRUE);
+ }
+}
+
+static inline
+void bt_ctf_field_common_array_finalize_recursive(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+ BT_LOGD("Finalizing common array field object: addr=%p", field);
+ bt_ctf_field_common_finalize(field);
+
+ if (array->elements) {
+ g_ptr_array_free(array->elements, TRUE);
+ }
+}
+
+static inline
+void bt_ctf_field_common_sequence_finalize_recursive(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+ BT_LOGD("Finalizing common sequence field object: addr=%p", field);
+ bt_ctf_field_common_finalize(field);
+
+ if (sequence->elements) {
+ g_ptr_array_free(sequence->elements, TRUE);
+ }
+}
+
+static inline
+void bt_ctf_field_common_string_finalize(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_string *string = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+ BT_LOGD("Finalizing common string field object: addr=%p", field);
+ bt_ctf_field_common_finalize(field);
+
+ if (string->buf) {
+ g_array_free(string->buf, TRUE);
+ }
+}
+
+BT_ASSERT_PRE_FUNC
+static inline bool value_is_in_range_signed(unsigned int size, int64_t value)
+{
+ bool ret = true;
+ int64_t min_value, max_value;
+
+ min_value = -(1ULL << (size - 1));
+ max_value = (1ULL << (size - 1)) - 1;
+ if (value < min_value || value > max_value) {
+ BT_LOGF("Value is out of bounds: value=%" PRId64 ", "
+ "min-value=%" PRId64 ", max-value=%" PRId64,
+ value, min_value, max_value);
+ ret = false;
+ }
+
+ return ret;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline bool value_is_in_range_unsigned(unsigned int size, uint64_t value)
+{
+ bool ret = true;
+ int64_t max_value;
+
+ max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
+ if (value > max_value) {
+ BT_LOGF("Value is out of bounds: value=%" PRIu64 ", "
+ "max-value=%" PRIu64,
+ value, max_value);
+ ret = false;
+ }
+
+ return ret;
+}
struct bt_ctf_field_enumeration {
- struct bt_field_common common;
- struct bt_field_common_integer *container;
+ struct bt_ctf_field_common common;
+ struct bt_ctf_field_common_integer *container;
};
struct bt_ctf_field_variant {
- struct bt_field_common_variant common;
+ struct bt_ctf_field_common_variant common;
struct bt_ctf_field_enumeration *tag;
};
static inline
bt_bool bt_ctf_field_is_set_recursive(struct bt_ctf_field *field)
{
- return bt_field_common_is_set_recursive((void *) field);
+ return bt_ctf_field_common_is_set_recursive((void *) field);
}
#endif /* BABELTRACE_CTF_WRITER_FIELDS_INTERNAL_H */
#include <stdint.h>
#include <stddef.h>
-/* For bt_bool */
-#include <babeltrace/ctf-writer/fields.h>
-
#ifdef __cplusplus
extern "C" {
#endif
--- /dev/null
+#ifndef BABELTRACE_CTF_WRITER_RESOLVE_INTERNAL_H
+#define BABELTRACE_CTF_WRITER_RESOLVE_INTERNAL_H
+
+/*
+ * Babeltrace - CTF writer: Type resolving internal
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Authors: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * 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:
+ *
+ * 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.
+ */
+
+#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <glib.h>
+
+enum bt_ctf_resolve_flag {
+ BT_CTF_RESOLVE_FLAG_PACKET_HEADER = 0x01,
+ BT_CTF_RESOLVE_FLAG_PACKET_CONTEXT = 0x02,
+ BT_CTF_RESOLVE_FLAG_EVENT_HEADER = 0x04,
+ BT_CTF_RESOLVE_FLAG_STREAM_EVENT_CTX = 0x08,
+ BT_CTF_RESOLVE_FLAG_EVENT_CONTEXT = 0x10,
+ BT_CTF_RESOLVE_FLAG_EVENT_PAYLOAD = 0x20,
+};
+
+/*
+ * Resolves CTF IR field types: recursively locates the tag and length
+ * field types of resp. variant and sequence field types.
+ *
+ * All `*_type` parameters may be resolved, and may as well serve as
+ * resolving targets.
+ *
+ * Resolving is performed based on the flags in `flags`.
+ *
+ * It is expected that, amongst all the provided types, no common
+ * references to sequence variant field types exist. In other words,
+ * this function does not copy field types.
+ *
+ * All parameters are owned by the caller.
+ */
+BT_HIDDEN
+int bt_ctf_resolve_types(struct bt_value *environment,
+ struct bt_ctf_field_type_common *packet_header_type,
+ struct bt_ctf_field_type_common *packet_context_type,
+ struct bt_ctf_field_type_common *event_header_type,
+ struct bt_ctf_field_type_common *stream_event_ctx_type,
+ struct bt_ctf_field_type_common *event_context_type,
+ struct bt_ctf_field_type_common *event_payload_type,
+ enum bt_ctf_resolve_flag flags);
+
+#endif /* BABELTRACE_CTF_WRITER_RESOLVE_INTERNAL_H */
#include <babeltrace/common-internal.h>
#include <babeltrace/mmap-align-internal.h>
#include <babeltrace/types.h>
-#include <babeltrace/ctf-writer/fields.h>
#include <babeltrace/ctf-writer/field-types.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
+#include <babeltrace/ctf-writer/fields-internal.h>
+#include <babeltrace/ctf-writer/fields.h>
#include <babeltrace/assert-internal.h>
#define PACKET_LEN_INCREMENT (bt_common_get_page_size() * 8 * CHAR_BIT)
};
BT_HIDDEN
-int bt_ctf_field_integer_write(struct bt_field_common *field,
+int bt_ctf_field_integer_write(struct bt_ctf_field_common *field,
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order);
BT_HIDDEN
-int bt_ctf_field_floating_point_write(struct bt_field_common *field,
+int bt_ctf_field_floating_point_write(struct bt_ctf_field_common *field,
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order);
* http://www.efficios.com/ctf
*/
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/common-internal.h>
#include <babeltrace/ctf-writer/clock-internal.h>
+#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/ctf-writer/stream-class-internal.h>
+#include <babeltrace/ctf-writer/utils-internal.h>
+#include <babeltrace/ctf-writer/validation-internal.h>
+#include <babeltrace/ctf-writer/visitor.h>
+#include <babeltrace/object-internal.h>
+#include <inttypes.h>
+
+struct bt_ctf_stream_class_common {
+ struct bt_object base;
+ GString *name;
+
+ /* Array of pointers to event class addresses */
+ GPtrArray *event_classes;
+
+ /* event class id (int64_t) to event class address */
+ GHashTable *event_classes_ht;
+ int id_set;
+ int64_t id;
+ int64_t next_event_id;
+ struct bt_ctf_field_type_common *packet_context_field_type;
+ struct bt_ctf_field_type_common *event_header_field_type;
+ struct bt_ctf_field_type_common *event_context_field_type;
+ int frozen;
+ int byte_order;
+
+ /*
+ * This flag indicates if the stream class is valid. A valid
+ * stream class is _always_ frozen.
+ */
+ int valid;
+
+ /*
+ * Unique clock class mapped to any field type within this
+ * stream class, including all the stream class's event class
+ * field types. This is only set if the stream class is frozen.
+ *
+ * If the stream class is frozen and this is still NULL, it is
+ * still possible that it becomes non-NULL because
+ * bt_ctf_stream_class_add_event_class() can add an event class
+ * containing a field type mapped to some clock class. In this
+ * case, this is the mapped clock class, and at this point, both
+ * the new event class and the stream class are frozen, so the
+ * next added event classes are expected to contain field types
+ * which only map to this specific clock class.
+ *
+ * If this is a CTF writer stream class, then this is the
+ * backing clock class of the `clock` member above.
+ */
+ struct bt_ctf_clock_class *clock_class;
+};
+
+struct bt_ctf_event_class_common;
+
+BT_HIDDEN
+int bt_ctf_stream_class_common_initialize(struct bt_ctf_stream_class_common *stream_class,
+ const char *name, bt_object_release_func release_func);
+
+BT_HIDDEN
+void bt_ctf_stream_class_common_finalize(struct bt_ctf_stream_class_common *stream_class);
+
+BT_HIDDEN
+void bt_ctf_stream_class_common_freeze(struct bt_ctf_stream_class_common *stream_class);
+
+static inline
+const char *bt_ctf_stream_class_common_get_name(
+ struct bt_ctf_stream_class_common *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return stream_class->name->len > 0 ? stream_class->name->str : NULL;
+}
+
+static inline
+int64_t bt_ctf_stream_class_common_get_id(
+ struct bt_ctf_stream_class_common *stream_class)
+{
+ int64_t ret;
+
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+
+ if (!stream_class->id_set) {
+ BT_LOGV("Stream class's ID is not set: addr=%p, name=\"%s\"",
+ stream_class,
+ bt_ctf_stream_class_common_get_name(stream_class));
+ ret = (int64_t) -1;
+ goto end;
+ }
+
+ ret = stream_class->id;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_stream_class_common_set_byte_order(
+ struct bt_ctf_stream_class_common *stream_class, int byte_order);
+
+BT_HIDDEN
+int bt_ctf_stream_class_common_validate_single_clock_class(
+ struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_clock_class **expected_clock_class);
+
+BT_HIDDEN
+int bt_ctf_stream_class_common_add_event_class(
+ struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_event_class_common *event_class,
+ bt_ctf_validation_flag_copy_field_type_func copy_field_type_func);
+
+BT_HIDDEN
+int bt_ctf_stream_class_common_visit(struct bt_ctf_stream_class_common *stream_class,
+ bt_ctf_visitor visitor, void *data);
+
+BT_HIDDEN
+int bt_ctf_stream_class_visit(struct bt_ctf_stream_class *stream_class,
+ bt_ctf_visitor visitor, void *data);
+
+static inline
+struct bt_ctf_trace_common *bt_ctf_stream_class_common_borrow_trace(
+ struct bt_ctf_stream_class_common *stream_class)
+{
+ BT_ASSERT(stream_class);
+ return (void *) bt_object_borrow_parent(&stream_class->base);
+}
+
+static inline
+int bt_ctf_stream_class_common_set_name(struct bt_ctf_stream_class_common *stream_class,
+ const char *name)
+{
+ int ret = 0;
+
+ if (!stream_class) {
+ BT_LOGW_STR("Invalid parameter: stream class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (stream_class->frozen) {
+ BT_LOGW("Invalid parameter: stream class is frozen: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ stream_class,
+ bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+ ret = -1;
+ goto end;
+ }
+
+ if (!name) {
+ g_string_assign(stream_class->name, "");
+ } else {
+ if (strlen(name) == 0) {
+ BT_LOGW("Invalid parameter: name is empty.");
+ ret = -1;
+ goto end;
+ }
+
+ g_string_assign(stream_class->name, name);
+ }
+
+ BT_LOGV("Set stream class's name: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+end:
+ return ret;
+}
+
+static inline
+void _bt_ctf_stream_class_common_set_id(
+ struct bt_ctf_stream_class_common *stream_class, int64_t id)
+{
+ BT_ASSERT(stream_class);
+ stream_class->id = id;
+ stream_class->id_set = 1;
+ BT_LOGV("Set stream class's ID (internal): "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+}
+
+static inline
+int bt_ctf_stream_class_common_set_id_no_check(
+ struct bt_ctf_stream_class_common *stream_class, int64_t id)
+{
+ _bt_ctf_stream_class_common_set_id(stream_class, id);
+ return 0;
+}
+
+static inline
+int bt_ctf_stream_class_common_set_id(struct bt_ctf_stream_class_common *stream_class,
+ uint64_t id_param)
+{
+ int ret = 0;
+ int64_t id = (int64_t) id_param;
+
+ if (!stream_class) {
+ BT_LOGW_STR("Invalid parameter: stream class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (stream_class->frozen) {
+ BT_LOGW("Invalid parameter: stream class is frozen: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ stream_class,
+ bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+ ret = -1;
+ goto end;
+ }
+
+ if (id < 0) {
+ BT_LOGW("Invalid parameter: invalid stream class's ID: "
+ "stream-class-addr=%p, stream-class-name=\"%s\", "
+ "stream-class-id=%" PRId64 ", id=%" PRIu64,
+ stream_class,
+ bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class),
+ id_param);
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_stream_class_common_set_id_no_check(stream_class, id);
+ if (ret == 0) {
+ BT_LOGV("Set stream class's ID: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ stream_class,
+ bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+ }
+end:
+ return ret;
+}
+
+static inline
+int64_t bt_ctf_stream_class_common_get_event_class_count(
+ struct bt_ctf_stream_class_common *stream_class)
+{
+ int64_t ret;
+
+ if (!stream_class) {
+ BT_LOGW_STR("Invalid parameter: stream class is NULL.");
+ ret = (int64_t) -1;
+ goto end;
+ }
+
+ ret = (int64_t) stream_class->event_classes->len;
+end:
+ return ret;
+}
+
+static inline
+struct bt_ctf_event_class_common *bt_ctf_stream_class_common_borrow_event_class_by_index(
+ struct bt_ctf_stream_class_common *stream_class, uint64_t index)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE(index < stream_class->event_classes->len,
+ "Index is out of bounds: index=%" PRIu64 ", "
+ "count=%u",
+ index, stream_class->event_classes->len);
+ return g_ptr_array_index(stream_class->event_classes, index);
+}
+
+static inline
+struct bt_ctf_event_class_common *bt_ctf_stream_class_common_borrow_event_class_by_id(
+ struct bt_ctf_stream_class_common *stream_class, uint64_t id)
+{
+ int64_t id_key = (int64_t) id;
+
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ BT_ASSERT_PRE(id_key >= 0,
+ "Invalid event class ID: %" PRIu64, id);
+ return g_hash_table_lookup(stream_class->event_classes_ht,
+ &id_key);
+}
+
+static inline
+struct bt_ctf_field_type_common *
+bt_ctf_stream_class_common_borrow_packet_context_field_type(
+ struct bt_ctf_stream_class_common *stream_class)
+{
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+ return stream_class->packet_context_field_type;
+}
+
+static inline
+int bt_ctf_stream_class_common_set_packet_context_field_type(
+ struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_field_type_common *packet_context_type)
+{
+ int ret = 0;
+
+ if (!stream_class) {
+ BT_LOGW_STR("Invalid parameter: stream class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (stream_class->frozen) {
+ BT_LOGW("Invalid parameter: stream class is frozen: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+ ret = -1;
+ goto end;
+ }
+
+ if (packet_context_type &&
+ bt_ctf_field_type_common_get_type_id(packet_context_type) !=
+ BT_CTF_FIELD_TYPE_ID_STRUCT) {
+ /* A packet context must be a structure. */
+ BT_LOGW("Invalid parameter: stream class's packet context field type must be a structure: "
+ "addr=%p, name=\"%s\", id=%" PRId64 ", "
+ "packet-context-ft-addr=%p, packet-context-ft-id=%s",
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class),
+ packet_context_type,
+ bt_ctf_field_type_id_string(
+ bt_ctf_field_type_common_get_type_id(packet_context_type)));
+ ret = -1;
+ goto end;
+ }
+
+ bt_put(stream_class->packet_context_field_type);
+ bt_get(packet_context_type);
+ stream_class->packet_context_field_type = packet_context_type;
+ BT_LOGV("Set stream class's packet context field type: "
+ "addr=%p, name=\"%s\", id=%" PRId64 ", "
+ "packet-context-ft-addr=%p",
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class),
+ packet_context_type);
+
+end:
+ return ret;
+}
+
+static inline
+struct bt_ctf_field_type_common *
+bt_ctf_stream_class_common_borrow_event_header_field_type(
+ struct bt_ctf_stream_class_common *stream_class)
+{
+ struct bt_ctf_field_type_common *ret = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+
+ if (!stream_class->event_header_field_type) {
+ BT_LOGV("Stream class has no event header field type: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ stream_class,
+ bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+ goto end;
+ }
+
+ ret = stream_class->event_header_field_type;
+
+end:
+ return ret;
+}
+
+static inline
+int bt_ctf_stream_class_common_set_event_header_field_type(
+ struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_field_type_common *event_header_type)
+{
+ int ret = 0;
+
+ if (!stream_class) {
+ BT_LOGW_STR("Invalid parameter: stream class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (stream_class->frozen) {
+ BT_LOGW("Invalid parameter: stream class is frozen: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ stream_class,
+ bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+ ret = -1;
+ goto end;
+ }
+
+ if (event_header_type &&
+ bt_ctf_field_type_common_get_type_id(event_header_type) !=
+ BT_CTF_FIELD_TYPE_ID_STRUCT) {
+ /* An event header must be a structure. */
+ BT_LOGW("Invalid parameter: stream class's event header field type must be a structure: "
+ "addr=%p, name=\"%s\", id=%" PRId64 ", "
+ "event-header-ft-addr=%p, event-header-ft-id=%s",
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class),
+ event_header_type,
+ bt_ctf_field_type_id_string(
+ bt_ctf_field_type_common_get_type_id(event_header_type)));
+ ret = -1;
+ goto end;
+ }
+
+ bt_put(stream_class->event_header_field_type);
+ stream_class->event_header_field_type = bt_get(event_header_type);
+ BT_LOGV("Set stream class's event header field type: "
+ "addr=%p, name=\"%s\", id=%" PRId64 ", "
+ "event-header-ft-addr=%p",
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class),
+ event_header_type);
+end:
+ return ret;
+}
+
+static inline
+struct bt_ctf_field_type_common *
+bt_ctf_stream_class_common_borrow_event_context_field_type(
+ struct bt_ctf_stream_class_common *stream_class)
+{
+ struct bt_ctf_field_type_common *ret = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+
+ if (!stream_class->event_context_field_type) {
+ goto end;
+ }
+
+ ret = stream_class->event_context_field_type;
+
+end:
+ return ret;
+}
+
+static inline
+int bt_ctf_stream_class_common_set_event_context_field_type(
+ struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_field_type_common *event_context_type)
+{
+ int ret = 0;
+
+ if (!stream_class) {
+ BT_LOGW_STR("Invalid parameter: stream class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (stream_class->frozen) {
+ BT_LOGW("Invalid parameter: stream class is frozen: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+ ret = -1;
+ goto end;
+ }
+
+ if (event_context_type &&
+ bt_ctf_field_type_common_get_type_id(event_context_type) !=
+ BT_CTF_FIELD_TYPE_ID_STRUCT) {
+ /* A packet context must be a structure. */
+ BT_LOGW("Invalid parameter: stream class's event context field type must be a structure: "
+ "addr=%p, name=\"%s\", id=%" PRId64 ", "
+ "event-context-ft-addr=%p, event-context-ft-id=%s",
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class),
+ event_context_type,
+ bt_ctf_field_type_id_string(
+ bt_ctf_field_type_common_get_type_id(event_context_type)));
+ ret = -1;
+ goto end;
+ }
+
+ bt_put(stream_class->event_context_field_type);
+ stream_class->event_context_field_type = bt_get(event_context_type);
+ BT_LOGV("Set stream class's event context field type: "
+ "addr=%p, name=\"%s\", id=%" PRId64 ", "
+ "event-context-ft-addr=%p",
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class),
+ event_context_type);
+end:
+ return ret;
+}
struct bt_ctf_stream_class {
- struct bt_stream_class_common common;
+ struct bt_ctf_stream_class_common common;
struct bt_ctf_clock *clock;
int64_t next_stream_id;
};
*/
#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/stream-class.h>
#ifdef __cplusplus
extern "C" {
* http://www.efficios.com/ctf
*/
+#include <babeltrace/assert-internal.h>
#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-writer/serialize-internal.h>
+#include <babeltrace/babeltrace-internal.h>
#include <babeltrace/babeltrace.h>
+#include <babeltrace/ctf-writer/serialize-internal.h>
+#include <babeltrace/ctf-writer/stream-internal.h>
+#include <babeltrace/ctf-writer/stream.h>
+#include <babeltrace/ctf-writer/utils-internal.h>
+#include <babeltrace/object-internal.h>
#include <stdint.h>
+struct bt_ctf_stream_common;
+
+struct bt_ctf_stream_common {
+ struct bt_object base;
+ int64_t id;
+ struct bt_ctf_stream_class_common *stream_class;
+ GString *name;
+};
+
+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_object_release_func release_func);
+
+BT_HIDDEN
+void bt_ctf_stream_common_finalize(struct bt_ctf_stream_common *stream);
+
+static inline
+struct bt_ctf_stream_class_common *bt_ctf_stream_common_borrow_class(
+ struct bt_ctf_stream_common *stream)
+{
+ BT_ASSERT(stream);
+ return stream->stream_class;
+}
+
+static inline
+const char *bt_ctf_stream_common_get_name(struct bt_ctf_stream_common *stream)
+{
+ BT_ASSERT_PRE_NON_NULL(stream, "Stream");
+ return stream->name ? stream->name->str : NULL;
+}
+
+static inline
+int64_t bt_ctf_stream_common_get_id(struct bt_ctf_stream_common *stream)
+{
+ int64_t ret;
+
+ BT_ASSERT_PRE_NON_NULL(stream, "Stream");
+ ret = stream->id;
+ if (ret < 0) {
+ BT_LOGV("Stream's ID is not set: addr=%p, name=\"%s\"",
+ stream, bt_ctf_stream_common_get_name(stream));
+ }
+
+ return ret;
+}
+
struct bt_ctf_stream {
- struct bt_stream_common common;
+ struct bt_ctf_stream_common common;
struct bt_ctf_field *packet_header;
struct bt_ctf_field *packet_context;
};
BT_HIDDEN
-int bt_stream_set_fd(struct bt_stream *stream, int fd);
+int bt_ctf_stream_set_fd(struct bt_ctf_stream *stream, int fd);
BT_HIDDEN
struct bt_ctf_stream *bt_ctf_stream_create_with_id(
* http://www.efficios.com/ctf
*/
-#include <babeltrace/ctf-ir/trace-internal.h>
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/compat/uuid-internal.h>
+#include <babeltrace/ctf-writer/attributes-internal.h>
+#include <babeltrace/ctf-writer/clock-class-internal.h>
+#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/ctf-writer/fields.h>
+#include <babeltrace/ctf-writer/stream-class-internal.h>
+#include <babeltrace/ctf-writer/trace.h>
+#include <babeltrace/ctf-writer/validation-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/types.h>
+#include <babeltrace/values.h>
+#include <glib.h>
+#include <sys/types.h>
+
+struct bt_ctf_trace_common {
+ struct bt_object base;
+ GString *name;
+ int frozen;
+ unsigned char uuid[BABELTRACE_UUID_LEN];
+ bt_bool uuid_set;
+ enum bt_ctf_byte_order native_byte_order;
+ struct bt_value *environment;
+ GPtrArray *clock_classes; /* Array of pointers to bt_ctf_clock_class */
+ GPtrArray *stream_classes; /* Array of ptrs to bt_ctf_stream_class_common */
+ GPtrArray *streams; /* Array of ptrs to bt_ctf_stream_common */
+ struct bt_ctf_field_type_common *packet_header_field_type;
+ int64_t next_stream_id;
+
+ /*
+ * This flag indicates if the trace is valid. A valid
+ * trace is _always_ frozen.
+ */
+ int valid;
+};
+
+BT_HIDDEN
+bt_bool bt_ctf_trace_common_has_clock_class(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_clock_class *clock_class);
+
+BT_HIDDEN
+int bt_ctf_trace_common_initialize(struct bt_ctf_trace_common *trace,
+ bt_object_release_func release_func);
+
+BT_HIDDEN
+void bt_ctf_trace_common_finalize(struct bt_ctf_trace_common *trace);
+
+static inline
+const char *bt_ctf_trace_common_get_name(struct bt_ctf_trace_common *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return trace->name ? trace->name->str : NULL;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_name(struct bt_ctf_trace_common *trace, const char *name);
+
+static inline
+const unsigned char *bt_ctf_trace_common_get_uuid(struct bt_ctf_trace_common *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return trace->uuid_set ? trace->uuid : NULL;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_uuid(struct bt_ctf_trace_common *trace, const unsigned char *uuid);
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_environment_field(struct bt_ctf_trace_common *trace,
+ const char *name, struct bt_value *value);
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_environment_field_string(struct bt_ctf_trace_common *trace,
+ const char *name, const char *value);
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_environment_field_integer(struct bt_ctf_trace_common *trace,
+ const char *name, int64_t value);
+
+static inline
+int64_t bt_ctf_trace_common_get_environment_field_count(
+ struct bt_ctf_trace_common *trace)
+{
+ int64_t ret;
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ ret = bt_ctf_attributes_get_count(trace->environment);
+ BT_ASSERT(ret >= 0);
+ return ret;
+}
+
+static inline
+const char *
+bt_ctf_trace_common_get_environment_field_name_by_index(
+ struct bt_ctf_trace_common *trace, uint64_t index)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return bt_ctf_attributes_get_field_name(trace->environment, index);
+}
+
+static inline
+struct bt_value *bt_ctf_trace_common_borrow_environment_field_value_by_index(
+ struct bt_ctf_trace_common *trace, uint64_t index)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return bt_ctf_attributes_borrow_field_value(trace->environment, index);
+}
+
+static inline
+struct bt_value *bt_ctf_trace_common_borrow_environment_field_value_by_name(
+ struct bt_ctf_trace_common *trace, const char *name)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ return bt_ctf_attributes_borrow_field_value_by_name(trace->environment,
+ name);
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_add_clock_class(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_clock_class *clock_class);
+
+static inline
+int64_t bt_ctf_trace_common_get_clock_class_count(struct bt_ctf_trace_common *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return trace->clock_classes->len;
+}
+
+static inline
+struct bt_ctf_clock_class *bt_ctf_trace_common_borrow_clock_class_by_index(
+ struct bt_ctf_trace_common *trace, uint64_t index)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE(index < trace->clock_classes->len,
+ "Index is out of bounds: index=%" PRIu64 ", "
+ "count=%u",
+ index, trace->clock_classes->len);
+ return g_ptr_array_index(trace->clock_classes, index);
+}
+
+static inline
+int64_t bt_ctf_trace_common_get_stream_count(struct bt_ctf_trace_common *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return (int64_t) trace->streams->len;
+}
+
+static inline
+struct bt_ctf_stream_common *bt_ctf_trace_common_borrow_stream_by_index(
+ struct bt_ctf_trace_common *trace,
+ uint64_t index)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE(index < trace->streams->len,
+ "Index is out of bounds: index=%" PRIu64 ", "
+ "count=%u",
+ index, trace->streams->len);
+ return g_ptr_array_index(trace->streams, index);
+}
+
+static inline
+int64_t bt_ctf_trace_common_get_stream_class_count(struct bt_ctf_trace_common *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return (int64_t) trace->stream_classes->len;
+}
+
+static inline
+struct bt_ctf_stream_class_common *bt_ctf_trace_common_borrow_stream_class_by_index(
+ struct bt_ctf_trace_common *trace, uint64_t index)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE(index < trace->stream_classes->len,
+ "Index is out of bounds: index=%" PRIu64 ", "
+ "count=%u",
+ index, trace->stream_classes->len);
+ return g_ptr_array_index(trace->stream_classes, index);
+}
+
+static inline
+struct bt_ctf_stream_class_common *bt_ctf_trace_common_borrow_stream_class_by_id(
+ struct bt_ctf_trace_common *trace, uint64_t id_param)
+{
+ int i;
+ struct bt_ctf_stream_class_common *stream_class = NULL;
+ int64_t id = (int64_t) id_param;
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE(id >= 0,
+ "Invalid stream class ID: %" PRIu64, id_param);
+
+ for (i = 0; i < trace->stream_classes->len; i++) {
+ struct bt_ctf_stream_class_common *stream_class_candidate;
+
+ stream_class_candidate =
+ g_ptr_array_index(trace->stream_classes, i);
+
+ if (bt_ctf_stream_class_common_get_id(stream_class_candidate) ==
+ (int64_t) id) {
+ stream_class = stream_class_candidate;
+ goto end;
+ }
+ }
+
+end:
+ return stream_class;
+}
+
+static inline
+struct bt_ctf_clock_class *bt_ctf_trace_common_borrow_clock_class_by_name(
+ struct bt_ctf_trace_common *trace, const char *name)
+{
+ size_t i;
+ struct bt_ctf_clock_class *clock_class = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+
+ for (i = 0; i < trace->clock_classes->len; i++) {
+ struct bt_ctf_clock_class *cur_clk =
+ g_ptr_array_index(trace->clock_classes, i);
+ const char *cur_clk_name = bt_ctf_clock_class_get_name(cur_clk);
+
+ if (!cur_clk_name) {
+ goto end;
+ }
+
+ if (!strcmp(cur_clk_name, name)) {
+ clock_class = cur_clk;
+ goto end;
+ }
+ }
+
+end:
+ return clock_class;
+}
+
+static inline
+enum bt_ctf_byte_order bt_ctf_trace_common_get_native_byte_order(
+ struct bt_ctf_trace_common *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return trace->native_byte_order;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_native_byte_order(struct bt_ctf_trace_common *trace,
+ enum bt_ctf_byte_order byte_order, bool allow_unspecified);
+
+static inline
+struct bt_ctf_field_type_common *bt_ctf_trace_common_borrow_packet_header_field_type(
+ struct bt_ctf_trace_common *trace)
+{
+ BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+ return trace->packet_header_field_type;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_packet_header_field_type(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_field_type_common *packet_header_field_type);
+
+static inline
+void bt_ctf_trace_common_freeze(struct bt_ctf_trace_common *trace)
+{
+ int i;
+
+ if (trace->frozen) {
+ return;
+ }
+
+ BT_LOGD("Freezing trace: addr=%p, name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace));
+ BT_LOGD_STR("Freezing packet header field type.");
+ bt_ctf_field_type_common_freeze(trace->packet_header_field_type);
+ BT_LOGD_STR("Freezing environment attributes.");
+ bt_ctf_attributes_freeze(trace->environment);
+
+ if (trace->clock_classes->len > 0) {
+ BT_LOGD_STR("Freezing clock classes.");
+ }
+
+ for (i = 0; i < trace->clock_classes->len; i++) {
+ struct bt_ctf_clock_class *clock_class =
+ g_ptr_array_index(trace->clock_classes, i);
+
+ bt_ctf_clock_class_freeze(clock_class);
+ }
+
+ trace->frozen = 1;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_add_stream_class(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_stream_class_common *stream_class,
+ bt_ctf_validation_flag_copy_field_type_func copy_field_type_func,
+ struct bt_ctf_clock_class *init_expected_clock_class,
+ int (*map_clock_classes_func)(struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_field_type_common *packet_context_field_type,
+ struct bt_ctf_field_type_common *event_header_field_type),
+ bool check_ts_begin_end_mapped);
struct bt_ctf_trace {
- struct bt_trace_common common;
+ struct bt_ctf_trace_common common;
};
/*
BT_HIDDEN
struct bt_ctf_trace *bt_ctf_trace_create(void);
+BT_HIDDEN
+int64_t bt_ctf_trace_get_clock_class_count(
+ struct bt_ctf_trace *trace);
+
+BT_HIDDEN
+struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_index(
+ struct bt_ctf_trace *trace, uint64_t index);
+
+BT_HIDDEN
+struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_name(
+ struct bt_ctf_trace *trace, const char *name);
+
+BT_HIDDEN
+int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace,
+ struct bt_ctf_clock_class *clock_class);
+
#endif /* BABELTRACE_CTF_WRITER_TRACE_INTERNAL_H */
struct bt_ctf_trace;
struct bt_ctf_stream_class;
struct bt_ctf_stream;
-struct bt_ctf_clock_class;
extern enum bt_ctf_byte_order bt_ctf_trace_get_native_byte_order(
struct bt_ctf_trace *trace);
extern int bt_ctf_trace_set_packet_header_field_type(struct bt_ctf_trace *trace,
struct bt_ctf_field_type *packet_header_type);
-extern int64_t bt_ctf_trace_get_clock_class_count(
- struct bt_ctf_trace *trace);
-
-extern struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_index(
- struct bt_ctf_trace *trace, uint64_t index);
-
-extern struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_name(
- struct bt_ctf_trace *trace, const char *name);
-
-extern int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace,
- struct bt_ctf_clock_class *clock_class);
-
extern int64_t bt_ctf_trace_get_stream_class_count(
struct bt_ctf_trace *trace);
--- /dev/null
+#ifndef BABELTRACE_CTF_WRITER_UTILS_INTERNAL_H
+#define BABELTRACE_CTF_WRITER_UTILS_INTERNAL_H
+
+/*
+ * Babeltrace - Internal CTF writer utilities
+ *
+ * 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:
+ *
+ * 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.
+ */
+
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/ctf-writer/field-path-internal.h>
+#include <babeltrace/ctf-writer/event.h>
+#include <stdint.h>
+
+#define BT_CTF_TO_COMMON(_obj) (&(_obj)->common)
+#define BT_CTF_FROM_COMMON(_obj) ((void *) _obj)
+
+struct bt_ctf_search_query {
+ gpointer value;
+ int found;
+};
+
+BT_HIDDEN
+const char *bt_ctf_get_byte_order_string(enum bt_ctf_byte_order byte_order);
+
+static inline
+const char *bt_ctf_field_type_id_string(enum bt_ctf_field_type_id type_id)
+{
+ switch (type_id) {
+ case BT_CTF_FIELD_TYPE_ID_UNKNOWN:
+ return "BT_CTF_FIELD_TYPE_ID_UNKNOWN";
+ case BT_CTF_FIELD_TYPE_ID_INTEGER:
+ return "BT_CTF_FIELD_TYPE_ID_INTEGER";
+ case BT_CTF_FIELD_TYPE_ID_FLOAT:
+ return "BT_CTF_FIELD_TYPE_ID_FLOAT";
+ case BT_CTF_FIELD_TYPE_ID_ENUM:
+ return "BT_CTF_FIELD_TYPE_ID_ENUM";
+ case BT_CTF_FIELD_TYPE_ID_STRING:
+ return "BT_CTF_FIELD_TYPE_ID_STRING";
+ case BT_CTF_FIELD_TYPE_ID_STRUCT:
+ return "BT_CTF_FIELD_TYPE_ID_STRUCT";
+ case BT_CTF_FIELD_TYPE_ID_ARRAY:
+ return "BT_CTF_FIELD_TYPE_ID_ARRAY";
+ case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ return "BT_CTF_FIELD_TYPE_ID_SEQUENCE";
+ case BT_CTF_FIELD_TYPE_ID_VARIANT:
+ return "BT_CTF_FIELD_TYPE_ID_VARIANT";
+ default:
+ return "(unknown)";
+ }
+};
+
+static inline
+const char *bt_ctf_byte_order_string(enum bt_ctf_byte_order bo)
+{
+ switch (bo) {
+ case BT_CTF_BYTE_ORDER_UNKNOWN:
+ return "BT_CTF_BYTE_ORDER_UNKNOWN";
+ case BT_CTF_BYTE_ORDER_UNSPECIFIED:
+ return "BT_CTF_BYTE_ORDER_UNSPECIFIED";
+ case BT_CTF_BYTE_ORDER_NATIVE:
+ return "BT_CTF_BYTE_ORDER_NATIVE";
+ case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
+ return "BT_CTF_BYTE_ORDER_LITTLE_ENDIAN";
+ case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
+ return "BT_CTF_BYTE_ORDER_BIG_ENDIAN";
+ case BT_CTF_BYTE_ORDER_NETWORK:
+ return "BT_CTF_BYTE_ORDER_NETWORK";
+ default:
+ return "(unknown)";
+ }
+};
+
+static inline
+const char *bt_ctf_string_encoding_string(enum bt_ctf_string_encoding encoding)
+{
+ switch (encoding) {
+ case BT_CTF_STRING_ENCODING_UNKNOWN:
+ return "BT_CTF_STRING_ENCODING_UNKNOWN";
+ case BT_CTF_STRING_ENCODING_NONE:
+ return "BT_CTF_STRING_ENCODING_NONE";
+ case BT_CTF_STRING_ENCODING_UTF8:
+ return "BT_CTF_STRING_ENCODING_UTF8";
+ case BT_CTF_STRING_ENCODING_ASCII:
+ return "BT_CTF_STRING_ENCODING_ASCII";
+ default:
+ return "(unknown)";
+ }
+};
+
+static inline
+const char *bt_ctf_integer_base_string(enum bt_ctf_integer_base base)
+{
+ switch (base) {
+ case BT_CTF_INTEGER_BASE_UNKNOWN:
+ return "BT_CTF_INTEGER_BASE_UNKNOWN";
+ case BT_CTF_INTEGER_BASE_UNSPECIFIED:
+ return "BT_CTF_INTEGER_BASE_UNSPECIFIED";
+ case BT_CTF_INTEGER_BASE_BINARY:
+ return "BT_CTF_INTEGER_BASE_BINARY";
+ case BT_CTF_INTEGER_BASE_OCTAL:
+ return "BT_CTF_INTEGER_BASE_OCTAL";
+ case BT_CTF_INTEGER_BASE_DECIMAL:
+ return "BT_CTF_INTEGER_BASE_DECIMAL";
+ case BT_CTF_INTEGER_BASE_HEXADECIMAL:
+ return "BT_CTF_INTEGER_BASE_HEXADECIMAL";
+ default:
+ return "(unknown)";
+ }
+}
+
+static inline
+const char *bt_ctf_scope_string(enum bt_ctf_scope scope)
+{
+ switch (scope) {
+ case BT_CTF_SCOPE_UNKNOWN:
+ return "BT_CTF_SCOPE_UNKNOWN";
+ case BT_CTF_SCOPE_TRACE_PACKET_HEADER:
+ return "BT_CTF_SCOPE_TRACE_PACKET_HEADER";
+ case BT_CTF_SCOPE_STREAM_PACKET_CONTEXT:
+ return "BT_CTF_SCOPE_STREAM_PACKET_CONTEXT";
+ case BT_CTF_SCOPE_STREAM_EVENT_HEADER:
+ return "BT_CTF_SCOPE_STREAM_EVENT_HEADER";
+ case BT_CTF_SCOPE_STREAM_EVENT_CONTEXT:
+ return "BT_CTF_SCOPE_STREAM_EVENT_CONTEXT";
+ case BT_CTF_SCOPE_EVENT_CONTEXT:
+ return "BT_CTF_SCOPE_EVENT_CONTEXT";
+ case BT_CTF_SCOPE_EVENT_PAYLOAD:
+ return "BT_CTF_SCOPE_EVENT_PAYLOAD";
+ case BT_CTF_SCOPE_ENV:
+ return "BT_CTF_SCOPE_ENV";
+ default:
+ return "(unknown)";
+ }
+}
+
+static inline
+const char *bt_ctf_event_class_log_level_string(
+ enum bt_ctf_event_class_log_level level)
+{
+ switch (level) {
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_ALERT:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_ALERT";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_ERROR:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_ERROR";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_WARNING:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_WARNING";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_NOTICE:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_NOTICE";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE";
+ case BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG:
+ return "BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG";
+ default:
+ return "(unknown)";
+ }
+};
+
+static inline
+GString *bt_ctf_field_path_string(struct bt_ctf_field_path *path)
+{
+ GString *str = g_string_new(NULL);
+ size_t i;
+
+ BT_ASSERT(path);
+
+ if (!str) {
+ goto end;
+ }
+
+ g_string_append_printf(str, "[%s", bt_common_scope_string(
+ bt_ctf_field_path_get_root_scope(path)));
+
+ for (i = 0; i < bt_ctf_field_path_get_index_count(path); i++) {
+ int index = bt_ctf_field_path_get_index(path, i);
+
+ g_string_append_printf(str, ", %d", index);
+ }
+
+ g_string_append(str, "]");
+
+end:
+ return str;
+}
+
+#endif /* BABELTRACE_CTF_WRITER_UTILS_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_CTF_WRITER_UTILS_H
+#define BABELTRACE_CTF_WRITER_UTILS_H
+
+/*
+ * BabelTrace - CTF writer: Utilities
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@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:
+ *
+ * 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.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+/* For bt_bool */
+#include <babeltrace/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern bt_bool bt_ctf_identifier_is_valid(const char *identifier);
+
+static inline
+int bt_ctf_validate_identifier(const char *identifier)
+{
+ return bt_ctf_identifier_is_valid(identifier) ? 1 : 0;
+}
+
+#endif /* BABELTRACE_CTF_WRITER_UTILS_H */
--- /dev/null
+#ifndef BABELTRACE_CTF_WRITER_VALIDATION_INTERNAL_H
+#define BABELTRACE_CTF_WRITER_VALIDATION_INTERNAL_H
+
+/*
+ * Babeltrace - CTF writer: Validation of trace, stream class, and event class
+ *
+ * Copyright 2016 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:
+ *
+ * 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.
+ */
+
+#include <babeltrace/values.h>
+#include <babeltrace/babeltrace-internal.h>
+
+struct bt_ctf_trace_common;
+struct bt_ctf_stream_class_common;
+struct bt_ctf_event_class_common;
+struct bt_ctf_field_type_common;
+
+typedef struct bt_ctf_field_type_common *(*bt_ctf_validation_flag_copy_field_type_func)(
+ struct bt_ctf_field_type_common *);
+
+enum bt_ctf_validation_flag {
+ BT_CTF_VALIDATION_FLAG_TRACE = 1,
+ BT_CTF_VALIDATION_FLAG_STREAM = 2,
+ BT_CTF_VALIDATION_FLAG_EVENT = 4,
+};
+
+/*
+ * Validation output structure.
+ *
+ * This is where the results of the validation function go. The field
+ * types are the validated ones which should replace the original field
+ * types of a trace, a stream class, and an event class.
+ *
+ * `valid_flags` contains the results of the validation.
+ */
+struct bt_ctf_validation_output {
+ struct bt_ctf_field_type_common *packet_header_type;
+ struct bt_ctf_field_type_common *packet_context_type;
+ struct bt_ctf_field_type_common *event_header_type;
+ struct bt_ctf_field_type_common *stream_event_ctx_type;
+ struct bt_ctf_field_type_common *event_context_type;
+ struct bt_ctf_field_type_common *event_payload_type;
+ enum bt_ctf_validation_flag valid_flags;
+};
+
+/*
+ * This function resolves and validates the field types of an event
+ * class, a stream class, and a trace. Copies are created if needed
+ * and the resulting field types to use are placed in the `output`
+ * validation structure, which also contains the results of the
+ * validation. Copies can replace the original field types of a trace,
+ * a stream class, and an event class using
+ * bt_ctf_validation_replace_types().
+ *
+ * The current known validity of the field types of the trace,
+ * stream class, and event class must be indicated with the
+ * `trace_valid`, `stream_class_valid`, and `event_class_valid`
+ * parameters. If a class is valid, its field types are not copied,
+ * validated, or resolved during this call.
+ *
+ * The validation flags `validate_flags` indicate which classes should
+ * have their field types validated.
+ *
+ * All parameters are owned by the caller.
+ */
+BT_HIDDEN
+int bt_ctf_validate_class_types(struct bt_value *environment,
+ struct bt_ctf_field_type_common *packet_header_type,
+ struct bt_ctf_field_type_common *packet_context_type,
+ struct bt_ctf_field_type_common *event_header_type,
+ struct bt_ctf_field_type_common *stream_event_ctx_type,
+ struct bt_ctf_field_type_common *event_context_type,
+ struct bt_ctf_field_type_common *event_payload_type,
+ int trace_valid, int stream_class_valid, int event_class_valid,
+ struct bt_ctf_validation_output *output,
+ enum bt_ctf_validation_flag validate_flags,
+ bt_ctf_validation_flag_copy_field_type_func copy_field_type_func);
+
+/*
+ * This function replaces the actual field types of a trace, a stream
+ * class, and an event class with the appropriate field types contained
+ * in a validation output structure.
+ *
+ * The replace flags `replace_flags` indicate which classes should have
+ * their field types replaced.
+ *
+ * Note that the field types that are not used in the validation output
+ * structure are still owned by it at the end of this call.
+ * bt_ctf_validation_output_put_types() should be called to clean the
+ * structure.
+ *
+ * All parameters are owned by the caller.
+ */
+BT_HIDDEN
+void bt_ctf_validation_replace_types(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_event_class_common *event_class,
+ struct bt_ctf_validation_output *output,
+ enum bt_ctf_validation_flag replace_flags);
+
+/*
+ * This function puts all the field types contained in a given
+ * validation output structure.
+ *
+ * `output` is owned by the caller and is not freed here.
+ */
+BT_HIDDEN
+void bt_ctf_validation_output_put_types(
+ struct bt_ctf_validation_output *output);
+
+#endif /* BABELTRACE_CTF_WRITER_VALIDATION_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_CTF_WRITER_VISITOR_INTERNAL_H
+#define BABELTRACE_CTF_WRITER_VISITOR_INTERNAL_H
+
+/*
+ * BabelTrace - CTF writer: Visitor internal
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@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:
+ *
+ * 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.
+ */
+
+#include <babeltrace/ctf-writer/visitor.h>
+#include <babeltrace/babeltrace-internal.h>
+
+typedef void *(*bt_ctf_child_accessor)(void *object, int index);
+typedef int64_t (*bt_ctf_child_count_accessor)(void *object);
+typedef int (*bt_ctf_child_visitor)(void *object, bt_ctf_visitor visitor,
+ void *data);
+
+struct bt_ctf_visitor_object {
+ enum bt_ctf_visitor_object_type type;
+ void *object;
+};
+
+BT_HIDDEN
+int visitor_helper(struct bt_ctf_visitor_object *root,
+ bt_ctf_child_count_accessor child_counter,
+ bt_ctf_child_accessor child_accessor,
+ bt_ctf_child_visitor child_visitor,
+ bt_ctf_visitor visitor,
+ void *data);
+
+#endif /* BABELTRACE_CTF_WRITER_VISITOR_INTERNAL_H */
--- /dev/null
+#ifndef BABELTRACE_CTF_WRITER_VISITOR_H
+#define BABELTRACE_CTF_WRITER_VISITOR_H
+
+/*
+ * BabelTrace - CTF writer: Visitor
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@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:
+ *
+ * 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.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+@defgroup ctfirvisitor CTF IR visitor
+@ingroup ctfir
+@brief CTF IR visitor.
+
+@code
+#include <babeltrace/ctf-ir/visitor.h>
+@endcode
+
+A CTF IR <strong><em>visitor</em></strong> is a function that you
+can use to visit the hierarchy of a
+\link ctfirtraceclass CTF IR trace class\endlink with
+bt_ctf_trace_visit() or of a
+\link ctfirstreamclass CTF IR stream class\endlink with
+bt_ctf_stream_class_visit().
+
+The traversal of the object's hierarchy is always done in a
+pre-order fashion.
+
+@sa ctfirstreamclass
+@sa ctfirtraceclass
+
+@file
+@brief CTF IR visitor types and functions.
+@sa ctfirvisitor
+
+@addtogroup ctfirvisitor
+@{
+*/
+
+/**
+@struct bt_object
+@brief A CTF IR object wrapper.
+
+This structure wraps both a CTF IR object and its type
+(see #bt_object_type). It is used in the visiting function.
+
+You can use the bt_object_get_type() and
+bt_object_get_object() accessors to get the type and wrapped
+CTF IR object of a CTF IR object wrapper.
+
+A CTF IR object wrapper has <strong>no reference count</strong>: do \em
+not use bt_put() or bt_get() on it.
+
+@sa ctfirvisitor
+*/
+struct bt_ctf_visitor_object;
+
+/**
+@brief CTF IR object wrapper type.
+*/
+enum bt_ctf_visitor_object_type {
+ /// Unknown (used for errors).
+ BT_CTF_VISITOR_OBJECT_TYPE_UNKNOWN = -1,
+
+ /// \ref ctfirtraceclass.
+ BT_CTF_VISITOR_OBJECT_TYPE_TRACE = 0,
+
+ /// \ref ctfirstreamclass.
+ BT_CTF_VISITOR_OBJECT_TYPE_STREAM_CLASS = 1,
+
+ /// \ref ctfirstream.
+ BT_CTF_VISITOR_OBJECT_TYPE_STREAM = 2,
+
+ /// \ref ctfireventclass.
+ BT_CTF_VISITOR_OBJECT_TYPE_EVENT_CLASS = 3,
+
+ /// \ref ctfirevent.
+ BT_CTF_VISITOR_OBJECT_TYPE_EVENT = 4,
+
+ /// Number of entries in this enumeration.
+ BT_CTF_VISITOR_OBJECT_TYPE_NR,
+};
+
+/**
+@brief Visting function type.
+
+A function of this type is called by bt_ctf_trace_visit() or
+bt_ctf_stream_class_visit() when visiting the CTF IR object wrapper
+\p object.
+
+\p object has <strong>no reference count</strong>: do \em not use
+bt_put() or bt_get() on it.
+
+@param[in] object Currently visited CTF IR object wrapper.
+@param[in] data User data.
+@returns 0 on success, or a negative value on error.
+
+@prenotnull{object}
+
+@sa bt_ctf_trace_visit(): Accepts a visitor to visit a trace class.
+@sa bt_ctf_stream_class_visit(): Accepts a visitor to visit a stream
+ class.
+*/
+typedef int (*bt_ctf_visitor)(struct bt_ctf_visitor_object *object,
+ void *data);
+
+/**
+@brief Returns the type of the CTF IR object wrapped by the CTF IR
+ object wrapper \p object.
+
+@param[in] object Object wrapper of which to get the type.
+@returns Type of \p object.
+
+@prenotnull{object}
+
+@sa bt_ctf_visitor_object_get_object(): Returns the object wrapped by a given
+ CTF IR object wrapper.
+*/
+enum bt_ctf_visitor_object_type bt_ctf_visitor_object_get_type(
+ struct bt_ctf_visitor_object *object);
+
+/**
+@brief Returns the CTF IR object wrapped by the CTF IR object
+ wrapper \p object.
+
+The reference count of \p object is \em not incremented by this
+function. On success, you must call bt_get() on the return value to
+have your own reference.
+
+@param[in] object Object wrapper of which to get the wrapped
+ CTF IR object.
+@returns CTF IR object wrapped by \p object.
+
+@prenotnull{object}
+@post The reference count of the returned object is not modified.
+
+@sa bt_ctf_visitor_object_get_type(): Returns the type of a given
+ CTF IR object wrapper.
+*/
+void *bt_ctf_visitor_object_get_object(struct bt_ctf_visitor_object *object);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_CTF_WRITER_VISITOR_H */
#include <glib.h>
#include <dirent.h>
#include <sys/types.h>
-#include <babeltrace/ctf-ir/trace.h>
+#include <babeltrace/ctf-writer/trace.h>
#include <babeltrace/object-internal.h>
struct metadata_context {
struct bt_ctf_field_type *get_field_type(enum field_type_alias alias);
BT_HIDDEN
-const char *get_byte_order_string(enum bt_byte_order byte_order);
+const char *bt_ctf_get_byte_order_string(enum bt_ctf_byte_order byte_order);
BT_HIDDEN
void bt_ctf_writer_freeze(struct bt_ctf_writer *writer);
* 3. Optional: `+` to print extended fields. This depends on the
* provided format specifier.
*
- * 4. Objet category: `w` for CTF writer objects, `_` for common
- * objects, or nothing for default objects (includes CTF IR).
+ * 4. Objet category: `_` for common objects, or nothing for default
+ * objects (includes CTF IR).
*
* 5. Format specifier (see below).
*
* `o`:
* Object pool. The parameter type is `struct bt_object_pool *`.
*
- * CTF writer category:
- * `F`:
- * CTF writer field type. The parameter type is `struct bt_field_type *`.
- *
- * `f`:
- * CTF writer field. The parameter type is `struct bt_field *`.
- *
- * `E`:
- * CTF writer event class. The parameter type is
- * `struct bt_event_class *`.
- *
- * `e`:
- * CTF writer event. The parameter type is `struct bt_event *`.
- *
- * `S`:
- * CTF writer stream class. The parameter type is
- * `struct bt_stream_class *`.
- *
- * `s`:
- * CTF writer stream. The parameter type is `struct bt_stream *`.
- *
- * `t`:
- * CTF writer trace. The parameter type is `struct bt_trace *`.
- *
- * `w`:
- * CTF writer. The parameter type is `struct bt_ctf_writer *`.
- *
* Common category:
* `F`:
* Common field type. The parameter type is `struct bt_field_type *`.
* %!f
* %![my-event-]+e
* %!_t
- * %![ctf-writer-ec-]wE
* %!+_F
*
* The string `, ` is printed between individual fields, but not after
noinst_LTLIBRARIES = libctf-writer.la
libctf_writer_la_SOURCES = \
+ attributes.c \
clock.c \
- event-class.c \
+ clock-class.c \
event.c \
- field-types.c \
+ event-class.c \
+ field-path.c \
fields.c \
+ field-types.c \
+ field-wrapper.c \
functor.c \
+ resolve.c \
serialize.c \
- stream-class.c \
stream.c \
+ stream-class.c \
trace.c \
+ utils.c \
+ validation.c \
+ visitor.c \
writer.c
libctf_writer_la_LIBADD = $(UUID_LIBS)
--- /dev/null
+/*
+ * attributes.c
+ *
+ * Babeltrace CTF writer - Attributes
+ *
+ * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
+ * Copyright (c) 2015 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:
+ *
+ * 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.
+ */
+
+#define BT_LOG_TAG "CTF-WRITER-ATTRS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/compat/string-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/values-internal.h>
+#include <babeltrace/values.h>
+#include <inttypes.h>
+
+#define BT_CTF_ATTR_NAME_INDEX 0
+#define BT_CTF_ATTR_VALUE_INDEX 1
+
+BT_HIDDEN
+struct bt_value *bt_ctf_attributes_create(void)
+{
+ struct bt_value *attr_obj;
+
+ /*
+ * Attributes: array value object of array value objects, each one
+ * containing two entries: a string value object (attributes
+ * field name), and a value object (attributes field value).
+ *
+ * Example (JSON representation):
+ *
+ * [
+ * ["hostname", "eeppdesk"],
+ * ["sysname", "Linux"],
+ * ["tracer_major", 2],
+ * ["tracer_minor", 5]
+ * ]
+ */
+ BT_LOGD_STR("Creating attributes object.");
+ attr_obj = bt_value_array_create();
+ if (!attr_obj) {
+ BT_LOGE_STR("Failed to create array value.");
+ } else {
+ BT_LOGD("Created attributes object: addr=%p",
+ attr_obj);
+ }
+
+ return attr_obj;
+}
+
+BT_HIDDEN
+void bt_ctf_attributes_destroy(struct bt_value *attr_obj)
+{
+ BT_LOGD("Destroying attributes object: addr=%p", attr_obj);
+ bt_put(attr_obj);
+}
+
+BT_HIDDEN
+int64_t bt_ctf_attributes_get_count(struct bt_value *attr_obj)
+{
+ return bt_value_array_size(attr_obj);
+}
+
+BT_HIDDEN
+const char *bt_ctf_attributes_get_field_name(struct bt_value *attr_obj,
+ uint64_t index)
+{
+ int rc;
+ const char *ret = NULL;
+ struct bt_value *attr_field_obj = NULL;
+ struct bt_value *attr_field_name_obj = NULL;
+
+ if (!attr_obj) {
+ BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
+ goto end;
+ }
+
+ if (index >= bt_value_array_size(attr_obj)) {
+ BT_LOGW("Invalid parameter: index is out of bounds: "
+ "index=%" PRIu64 ", count=%" PRId64,
+ index, bt_value_array_size(attr_obj));
+ goto end;
+ }
+
+ attr_field_obj = bt_value_array_borrow(attr_obj, index);
+ if (!attr_field_obj) {
+ BT_LOGE("Cannot get attributes object's array value's element by index: "
+ "value-addr=%p, index=%" PRIu64, attr_obj, index);
+ goto end;
+ }
+
+ attr_field_name_obj = bt_value_array_borrow(attr_field_obj,
+ BT_CTF_ATTR_NAME_INDEX);
+ if (!attr_field_name_obj) {
+ BT_LOGE("Cannot get attribute array value's element by index: "
+ "value-addr=%p, index=%" PRIu64, attr_field_obj,
+ (uint64_t) BT_CTF_ATTR_NAME_INDEX);
+ goto end;
+ }
+
+ rc = bt_value_string_get(attr_field_name_obj, &ret);
+ if (rc) {
+ BT_LOGE("Cannot get raw value from string value: value-addr=%p",
+ attr_field_name_obj);
+ ret = NULL;
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+struct bt_value *bt_ctf_attributes_borrow_field_value(struct bt_value *attr_obj,
+ uint64_t index)
+{
+ struct bt_value *value_obj = NULL;
+ struct bt_value *attr_field_obj = NULL;
+
+ if (!attr_obj) {
+ BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
+ goto end;
+ }
+
+ if (index >= bt_value_array_size(attr_obj)) {
+ BT_LOGW("Invalid parameter: index is out of bounds: "
+ "index=%" PRIu64 ", count=%" PRId64,
+ index, bt_value_array_size(attr_obj));
+ goto end;
+ }
+
+ attr_field_obj = bt_value_array_borrow(attr_obj, index);
+ if (!attr_field_obj) {
+ BT_LOGE("Cannot get attributes object's array value's element by index: "
+ "value-addr=%p, index=%" PRIu64, attr_obj, index);
+ goto end;
+ }
+
+ value_obj = bt_value_array_borrow(attr_field_obj,
+ BT_CTF_ATTR_VALUE_INDEX);
+ if (!value_obj) {
+ BT_LOGE("Cannot get attribute array value's element by index: "
+ "value-addr=%p, index=%" PRIu64, attr_field_obj,
+ (uint64_t) BT_CTF_ATTR_VALUE_INDEX);
+ }
+
+end:
+ return value_obj;
+}
+
+static
+struct bt_value *bt_ctf_attributes_borrow_field_by_name(
+ struct bt_value *attr_obj, const char *name)
+{
+ uint64_t i;
+ int64_t attr_size;
+ struct bt_value *value_obj = NULL;
+ struct bt_value *attr_field_name_obj = NULL;
+
+ attr_size = bt_value_array_size(attr_obj);
+ if (attr_size < 0) {
+ BT_LOGE("Cannot get array value's size: value-addr=%p",
+ attr_obj);
+ goto error;
+ }
+
+ for (i = 0; i < attr_size; ++i) {
+ int ret;
+ const char *field_name;
+
+ value_obj = bt_value_array_borrow(attr_obj, i);
+ if (!value_obj) {
+ BT_LOGE("Cannot get attributes object's array value's element by index: "
+ "value-addr=%p, index=%" PRIu64, attr_obj, i);
+ goto error;
+ }
+
+ attr_field_name_obj = bt_value_array_borrow(value_obj,
+ BT_CTF_ATTR_NAME_INDEX);
+ if (!attr_field_name_obj) {
+ BT_LOGE("Cannot get attribute array value's element by index: "
+ "value-addr=%p, index=%" PRIu64,
+ value_obj, (int64_t) BT_CTF_ATTR_NAME_INDEX);
+ goto error;
+ }
+
+ ret = bt_value_string_get(attr_field_name_obj, &field_name);
+ if (ret) {
+ BT_LOGE("Cannot get raw value from string value: value-addr=%p",
+ attr_field_name_obj);
+ goto error;
+ }
+
+ if (!strcmp(field_name, name)) {
+ break;
+ }
+
+ value_obj = NULL;
+ }
+
+ return value_obj;
+
+error:
+ value_obj = NULL;
+ return value_obj;
+}
+
+BT_HIDDEN
+int bt_ctf_attributes_set_field_value(struct bt_value *attr_obj,
+ const char *name, struct bt_value *value_obj)
+{
+ int ret = 0;
+ struct bt_value *attr_field_obj = NULL;
+
+ if (!attr_obj || !name || !value_obj) {
+ BT_LOGW("Invalid parameter: attributes object, name, or value object is NULL: "
+ "attr-value-addr=%p, name-addr=%p, value-addr=%p",
+ attr_obj, name, value_obj);
+ ret = -1;
+ goto end;
+ }
+
+ attr_field_obj = bt_ctf_attributes_borrow_field_by_name(attr_obj, name);
+ if (attr_field_obj) {
+ ret = bt_value_array_set(attr_field_obj,
+ BT_CTF_ATTR_VALUE_INDEX, value_obj);
+ attr_field_obj = NULL;
+ goto end;
+ }
+
+ attr_field_obj = bt_value_array_create();
+ if (!attr_field_obj) {
+ BT_LOGE_STR("Failed to create empty array value.");
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_value_array_append_string(attr_field_obj, name);
+ ret |= bt_value_array_append(attr_field_obj, value_obj);
+ if (ret) {
+ BT_LOGE("Cannot append elements to array value: addr=%p",
+ attr_field_obj);
+ goto end;
+ }
+
+ ret = bt_value_array_append(attr_obj, attr_field_obj);
+ if (ret) {
+ BT_LOGE("Cannot append element to array value: "
+ "array-value-addr=%p, element-value-addr=%p",
+ attr_obj, attr_field_obj);
+ }
+
+end:
+ bt_put(attr_field_obj);
+ return ret;
+}
+
+BT_HIDDEN
+struct bt_value *bt_ctf_attributes_borrow_field_value_by_name(
+ struct bt_value *attr_obj, const char *name)
+{
+ struct bt_value *value_obj = NULL;
+ struct bt_value *attr_field_obj = NULL;
+
+ if (!attr_obj || !name) {
+ BT_LOGW("Invalid parameter: attributes object or name is NULL: "
+ "value-addr=%p, name-addr=%p", attr_obj, name);
+ goto end;
+ }
+
+ attr_field_obj = bt_ctf_attributes_borrow_field_by_name(attr_obj, name);
+ if (!attr_field_obj) {
+ BT_LOGD("Cannot find attributes object's field by name: "
+ "value-addr=%p, name=\"%s\"", attr_obj, name);
+ goto end;
+ }
+
+ value_obj = bt_value_array_borrow(attr_field_obj,
+ BT_CTF_ATTR_VALUE_INDEX);
+ if (!value_obj) {
+ BT_LOGE("Cannot get attribute array value's element by index: "
+ "value-addr=%p, index=%" PRIu64, attr_field_obj,
+ (uint64_t) BT_CTF_ATTR_VALUE_INDEX);
+ }
+
+end:
+ return value_obj;
+}
+
+BT_HIDDEN
+int bt_ctf_attributes_freeze(struct bt_value *attr_obj)
+{
+ uint64_t i;
+ int64_t count;
+ int ret = 0;
+
+ if (!attr_obj) {
+ BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ BT_LOGD("Freezing attributes object: value-addr=%p", attr_obj);
+ count = bt_value_array_size(attr_obj);
+ BT_ASSERT(count >= 0);
+
+ /*
+ * We do not freeze the array value object itself here, since
+ * internal stuff could need to modify/add attributes. Each
+ * attribute is frozen one by one.
+ */
+ for (i = 0; i < count; ++i) {
+ struct bt_value *obj = NULL;
+
+ obj = bt_ctf_attributes_borrow_field_value(attr_obj, i);
+ if (!obj) {
+ BT_LOGE("Cannot get attributes object's field value by index: "
+ "value-addr=%p, index=%" PRIu64,
+ attr_obj, i);
+ ret = -1;
+ goto end;
+ }
+
+ bt_value_freeze(obj);
+ }
+
+end:
+ return ret;
+}
--- /dev/null
+/*
+ * clock-class.c
+ *
+ * Babeltrace CTF writer - Clock class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@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:
+ *
+ * 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.
+ */
+
+#define BT_LOG_TAG "CTF-WRITER-CLOCK-CLASS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/compat/uuid-internal.h>
+#include <babeltrace/ctf-writer/clock-class-internal.h>
+#include <babeltrace/ctf-writer/utils.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/types.h>
+#include <babeltrace/compat/string-internal.h>
+#include <inttypes.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/assert-internal.h>
+
+static
+void bt_ctf_clock_class_destroy(struct bt_object *obj);
+
+BT_HIDDEN
+bt_bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class *clock_class)
+{
+ return clock_class && clock_class->name;
+}
+
+BT_HIDDEN
+int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class,
+ const char *name)
+{
+ int ret = 0;
+
+ if (!clock_class) {
+ BT_LOGW_STR("Invalid parameter: clock class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (clock_class->frozen) {
+ BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ ret = -1;
+ goto end;
+ }
+
+ if (!bt_ctf_identifier_is_valid(name)) {
+ BT_LOGW("Clock class's name is not a valid CTF identifier: "
+ "addr=%p, name=\"%s\"",
+ clock_class, name);
+ ret = -1;
+ goto end;
+ }
+
+ if (clock_class->name) {
+ g_string_assign(clock_class->name, name);
+ } else {
+ clock_class->name = g_string_new(name);
+ if (!clock_class->name) {
+ BT_LOGE_STR("Failed to allocate a GString.");
+ ret = -1;
+ goto end;
+ }
+ }
+
+ BT_LOGV("Set clock class's name: addr=%p, name=\"%s\"",
+ clock_class, name);
+
+end:
+ return ret;
+}
+
+static
+bool validate_freq(struct bt_ctf_clock_class *clock_class,
+ const char *name, uint64_t freq)
+{
+ bool is_valid = true;
+
+ if (freq == -1ULL || freq == 0) {
+ BT_LOGW("Invalid parameter: frequency is invalid: "
+ "addr=%p, name=\"%s\", freq=%" PRIu64,
+ clock_class, name, freq);
+ is_valid = false;
+ goto end;
+ }
+
+end:
+ return is_valid;
+}
+
+BT_HIDDEN
+struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name,
+ uint64_t freq)
+{
+ int ret;
+ struct bt_ctf_clock_class *clock_class = NULL;
+
+ BT_LOGD("Creating default clock class object: name=\"%s\"",
+ name);
+
+ if (!validate_freq(NULL, name, freq)) {
+ /* validate_freq() logs errors */
+ goto error;
+ }
+
+ clock_class = g_new0(struct bt_ctf_clock_class, 1);
+ if (!clock_class) {
+ BT_LOGE_STR("Failed to allocate one clock class.");
+ goto error;
+ }
+
+ clock_class->precision = 1;
+ clock_class->frequency = freq;
+ bt_object_init_shared(&clock_class->base, bt_ctf_clock_class_destroy);
+
+ if (name) {
+ ret = bt_ctf_clock_class_set_name(clock_class, name);
+ if (ret) {
+ /* bt_ctf_clock_class_set_name() logs errors */
+ goto error;
+ }
+ }
+
+ BT_LOGD("Created clock class object: addr=%p, name=\"%s\"",
+ clock_class, name);
+ return clock_class;
+error:
+ BT_PUT(clock_class);
+ return clock_class;
+}
+
+BT_HIDDEN
+const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class *clock_class)
+{
+ const char *ret = NULL;
+
+ if (!clock_class) {
+ BT_LOGW_STR("Invalid parameter: clock class is NULL.");
+ goto end;
+ }
+
+ if (clock_class->name) {
+ ret = clock_class->name->str;
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+const char *bt_ctf_clock_class_get_description(
+ struct bt_ctf_clock_class *clock_class)
+{
+ const char *ret = NULL;
+
+ if (!clock_class) {
+ BT_LOGW_STR("Invalid parameter: clock class is NULL.");
+ goto end;
+ }
+
+ if (clock_class->description) {
+ ret = clock_class->description->str;
+ }
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class *clock_class,
+ const char *desc)
+{
+ int ret = 0;
+
+ if (!clock_class || !desc) {
+ BT_LOGW("Invalid parameter: clock class or description is NULL: "
+ "clock-class-addr=%p, name=\"%s\", desc-addr=%p",
+ clock_class, bt_ctf_clock_class_get_name(clock_class),
+ desc);
+ ret = -1;
+ goto end;
+ }
+
+ if (clock_class->frozen) {
+ BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ ret = -1;
+ goto end;
+ }
+
+ clock_class->description = g_string_new(desc);
+ ret = clock_class->description ? 0 : -1;
+ BT_LOGV("Set clock class's description: addr=%p, "
+ "name=\"%s\", desc=\"%s\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class), desc);
+end:
+ return ret;
+}
+
+BT_HIDDEN
+uint64_t bt_ctf_clock_class_get_frequency(
+ struct bt_ctf_clock_class *clock_class)
+{
+ uint64_t ret = -1ULL;
+
+ if (!clock_class) {
+ BT_LOGW_STR("Invalid parameter: clock class is NULL.");
+ goto end;
+ }
+
+ ret = clock_class->frequency;
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class *clock_class,
+ uint64_t freq)
+{
+ int ret = 0;
+
+ if (!clock_class) {
+ BT_LOGW("Invalid parameter: clock class is NULL or frequency is invalid: "
+ "addr=%p, name=\"%s\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ ret = -1;
+ goto end;
+ }
+
+ if (!validate_freq(clock_class, bt_ctf_clock_class_get_name(clock_class),
+ freq)) {
+ /* validate_freq() logs errors */
+ goto end;
+ }
+
+ if (clock_class->frozen) {
+ BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ ret = -1;
+ goto end;
+ }
+
+ clock_class->frequency = freq;
+ BT_LOGV("Set clock class's frequency: addr=%p, name=\"%s\", freq=%" PRIu64,
+ clock_class, bt_ctf_clock_class_get_name(clock_class), freq);
+end:
+ return ret;
+}
+
+BT_HIDDEN
+uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class *clock_class)
+{
+ uint64_t ret = -1ULL;
+
+ if (!clock_class) {
+ BT_LOGW_STR("Invalid parameter: clock class is NULL.");
+ goto end;
+ }
+
+ ret = clock_class->precision;
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class *clock_class,
+ uint64_t precision)
+{
+ int ret = 0;
+
+ if (!clock_class || precision == -1ULL) {
+ BT_LOGW("Invalid parameter: clock class is NULL or precision is invalid: "
+ "addr=%p, name=\"%s\", precision=%" PRIu64,
+ clock_class, bt_ctf_clock_class_get_name(clock_class),
+ precision);
+ ret = -1;
+ goto end;
+ }
+
+ if (clock_class->frozen) {
+ BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ ret = -1;
+ goto end;
+ }
+
+ clock_class->precision = precision;
+ BT_LOGV("Set clock class's precision: addr=%p, name=\"%s\", precision=%" PRIu64,
+ clock_class, bt_ctf_clock_class_get_name(clock_class),
+ precision);
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class *clock_class,
+ int64_t *offset_s)
+{
+ int ret = 0;
+
+ if (!clock_class || !offset_s) {
+ BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
+ "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
+ clock_class, bt_ctf_clock_class_get_name(clock_class),
+ offset_s);
+ ret = -1;
+ goto end;
+ }
+
+ *offset_s = clock_class->offset_s;
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class *clock_class,
+ int64_t offset_s)
+{
+ int ret = 0;
+
+ if (!clock_class) {
+ BT_LOGW_STR("Invalid parameter: clock class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (clock_class->frozen) {
+ BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ ret = -1;
+ goto end;
+ }
+
+ clock_class->offset_s = offset_s;
+ BT_LOGV("Set clock class's offset (seconds): "
+ "addr=%p, name=\"%s\", offset-s=%" PRId64,
+ clock_class, bt_ctf_clock_class_get_name(clock_class),
+ offset_s);
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class *clock_class,
+ int64_t *offset)
+{
+ int ret = 0;
+
+ if (!clock_class || !offset) {
+ BT_LOGW("Invalid parameter: clock class or offset pointer is NULL: "
+ "clock-class-addr=%p, name=\"%s\", offset-addr=%p",
+ clock_class, bt_ctf_clock_class_get_name(clock_class),
+ offset);
+ ret = -1;
+ goto end;
+ }
+
+ *offset = clock_class->offset;
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class *clock_class,
+ int64_t offset)
+{
+ int ret = 0;
+
+ if (!clock_class) {
+ BT_LOGW_STR("Invalid parameter: clock class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (clock_class->frozen) {
+ BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ ret = -1;
+ goto end;
+ }
+
+ clock_class->offset = offset;
+ BT_LOGV("Set clock class's offset (cycles): addr=%p, name=\"%s\", offset-cycles=%" PRId64,
+ clock_class, bt_ctf_clock_class_get_name(clock_class), offset);
+end:
+ return ret;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_clock_class_is_absolute(struct bt_ctf_clock_class *clock_class)
+{
+ int ret = -1;
+
+ if (!clock_class) {
+ BT_LOGW_STR("Invalid parameter: clock class is NULL.");
+ goto end;
+ }
+
+ ret = clock_class->absolute;
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class *clock_class,
+ bt_bool is_absolute)
+{
+ int ret = 0;
+
+ if (!clock_class) {
+ BT_LOGW_STR("Invalid parameter: clock class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (clock_class->frozen) {
+ BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ ret = -1;
+ goto end;
+ }
+
+ clock_class->absolute = !!is_absolute;
+ BT_LOGV("Set clock class's absolute flag: addr=%p, name=\"%s\", is-absolute=%d",
+ clock_class, bt_ctf_clock_class_get_name(clock_class),
+ is_absolute);
+end:
+ return ret;
+}
+
+BT_HIDDEN
+const unsigned char *bt_ctf_clock_class_get_uuid(
+ struct bt_ctf_clock_class *clock_class)
+{
+ const unsigned char *ret;
+
+ if (!clock_class) {
+ BT_LOGW_STR("Invalid parameter: clock class is NULL.");
+ ret = NULL;
+ goto end;
+ }
+
+ if (!clock_class->uuid_set) {
+ BT_LOGV("Clock class's UUID is not set: addr=%p, name=\"%s\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ ret = NULL;
+ goto end;
+ }
+
+ ret = clock_class->uuid;
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
+ const unsigned char *uuid)
+{
+ int ret = 0;
+
+ if (!clock_class || !uuid) {
+ BT_LOGW("Invalid parameter: clock class or UUID is NULL: "
+ "clock-class-addr=%p, name=\"%s\", uuid-addr=%p",
+ clock_class, bt_ctf_clock_class_get_name(clock_class),
+ uuid);
+ ret = -1;
+ goto end;
+ }
+
+ if (clock_class->frozen) {
+ BT_LOGW("Invalid parameter: clock class is frozen: addr=%p, name=\"%s\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ ret = -1;
+ goto end;
+ }
+
+ memcpy(clock_class->uuid, uuid, BABELTRACE_UUID_LEN);
+ clock_class->uuid_set = 1;
+ BT_LOGV("Set clock class's UUID: addr=%p, name=\"%s\", "
+ "uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class),
+ (unsigned int) uuid[0],
+ (unsigned int) uuid[1],
+ (unsigned int) uuid[2],
+ (unsigned int) uuid[3],
+ (unsigned int) uuid[4],
+ (unsigned int) uuid[5],
+ (unsigned int) uuid[6],
+ (unsigned int) uuid[7],
+ (unsigned int) uuid[8],
+ (unsigned int) uuid[9],
+ (unsigned int) uuid[10],
+ (unsigned int) uuid[11],
+ (unsigned int) uuid[12],
+ (unsigned int) uuid[13],
+ (unsigned int) uuid[14],
+ (unsigned int) uuid[15]);
+end:
+ return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class *clock_class)
+{
+ if (!clock_class || clock_class->frozen) {
+ return;
+ }
+
+ BT_LOGD("Freezing clock class: addr=%p, name=\"%s\"",
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ clock_class->frozen = 1;
+}
+
+static
+void bt_ctf_clock_class_destroy(struct bt_object *obj)
+{
+ struct bt_ctf_clock_class *clock_class;
+
+ clock_class = container_of(obj, struct bt_ctf_clock_class, base);
+ BT_LOGD("Destroying clock class: addr=%p, name=\"%s\"",
+ obj, bt_ctf_clock_class_get_name(clock_class));
+
+ if (clock_class->name) {
+ g_string_free(clock_class->name, TRUE);
+ }
+
+ if (clock_class->description) {
+ g_string_free(clock_class->description, TRUE);
+ }
+
+ g_free(clock_class);
+}
+
+BT_HIDDEN
+int bt_ctf_clock_class_compare(struct bt_ctf_clock_class *clock_class_a,
+ struct bt_ctf_clock_class *clock_class_b)
+{
+ int ret = 1;
+ BT_ASSERT(clock_class_a);
+ BT_ASSERT(clock_class_b);
+
+ /* Name */
+ if (strcmp(clock_class_a->name->str, clock_class_b->name->str) != 0) {
+ BT_LOGV("Clock classes differ: different names: "
+ "cc-a-name=\"%s\", cc-b-name=\"%s\"",
+ clock_class_a->name->str,
+ clock_class_b->name->str);
+ goto end;
+ }
+
+ /* Description */
+ if (clock_class_a->description) {
+ if (!clock_class_b->description) {
+ BT_LOGV_STR("Clock classes differ: clock class A has a "
+ "description, but clock class B does not.");
+ goto end;
+ }
+
+ if (strcmp(clock_class_a->name->str, clock_class_b->name->str)
+ != 0) {
+ BT_LOGV("Clock classes differ: different descriptions: "
+ "cc-a-descr=\"%s\", cc-b-descr=\"%s\"",
+ clock_class_a->description->str,
+ clock_class_b->description->str);
+ goto end;
+ }
+ } else {
+ if (clock_class_b->description) {
+ BT_LOGV_STR("Clock classes differ: clock class A has "
+ "no description, but clock class B has one.");
+ goto end;
+ }
+ }
+
+ /* Frequency */
+ if (clock_class_a->frequency != clock_class_b->frequency) {
+ BT_LOGV("Clock classes differ: different frequencies: "
+ "cc-a-freq=%" PRIu64 ", cc-b-freq=%" PRIu64,
+ clock_class_a->frequency,
+ clock_class_b->frequency);
+ goto end;
+ }
+
+ /* Precision */
+ if (clock_class_a->precision != clock_class_b->precision) {
+ BT_LOGV("Clock classes differ: different precisions: "
+ "cc-a-freq=%" PRIu64 ", cc-b-freq=%" PRIu64,
+ clock_class_a->precision,
+ clock_class_b->precision);
+ goto end;
+ }
+
+ /* Offset (seconds) */
+ if (clock_class_a->offset_s != clock_class_b->offset_s) {
+ BT_LOGV("Clock classes differ: different offsets (seconds): "
+ "cc-a-offset-s=%" PRId64 ", cc-b-offset-s=%" PRId64,
+ clock_class_a->offset_s,
+ clock_class_b->offset_s);
+ goto end;
+ }
+
+ /* Offset (cycles) */
+ if (clock_class_a->offset != clock_class_b->offset) {
+ BT_LOGV("Clock classes differ: different offsets (cycles): "
+ "cc-a-offset-s=%" PRId64 ", cc-b-offset-s=%" PRId64,
+ clock_class_a->offset,
+ clock_class_b->offset);
+ goto end;
+ }
+
+ /* UUIDs */
+ if (clock_class_a->uuid_set) {
+ if (!clock_class_b->uuid_set) {
+ BT_LOGV_STR("Clock classes differ: clock class A has a "
+ "UUID, but clock class B does not.");
+ goto end;
+ }
+
+ if (memcmp(clock_class_a->uuid, clock_class_b->uuid,
+ BABELTRACE_UUID_LEN) != 0) {
+ BT_LOGV("Clock classes differ: different UUIDs: "
+ "cc-a-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\", "
+ "cc-b-uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
+ (unsigned int) clock_class_a->uuid[0],
+ (unsigned int) clock_class_a->uuid[1],
+ (unsigned int) clock_class_a->uuid[2],
+ (unsigned int) clock_class_a->uuid[3],
+ (unsigned int) clock_class_a->uuid[4],
+ (unsigned int) clock_class_a->uuid[5],
+ (unsigned int) clock_class_a->uuid[6],
+ (unsigned int) clock_class_a->uuid[7],
+ (unsigned int) clock_class_a->uuid[8],
+ (unsigned int) clock_class_a->uuid[9],
+ (unsigned int) clock_class_a->uuid[10],
+ (unsigned int) clock_class_a->uuid[11],
+ (unsigned int) clock_class_a->uuid[12],
+ (unsigned int) clock_class_a->uuid[13],
+ (unsigned int) clock_class_a->uuid[14],
+ (unsigned int) clock_class_a->uuid[15],
+ (unsigned int) clock_class_b->uuid[0],
+ (unsigned int) clock_class_b->uuid[1],
+ (unsigned int) clock_class_b->uuid[2],
+ (unsigned int) clock_class_b->uuid[3],
+ (unsigned int) clock_class_b->uuid[4],
+ (unsigned int) clock_class_b->uuid[5],
+ (unsigned int) clock_class_b->uuid[6],
+ (unsigned int) clock_class_b->uuid[7],
+ (unsigned int) clock_class_b->uuid[8],
+ (unsigned int) clock_class_b->uuid[9],
+ (unsigned int) clock_class_b->uuid[10],
+ (unsigned int) clock_class_b->uuid[11],
+ (unsigned int) clock_class_b->uuid[12],
+ (unsigned int) clock_class_b->uuid[13],
+ (unsigned int) clock_class_b->uuid[14],
+ (unsigned int) clock_class_b->uuid[15]);
+ goto end;
+ }
+ } else {
+ if (clock_class_b->uuid_set) {
+ BT_LOGV_STR("Clock classes differ: clock class A has "
+ "no UUID, but clock class B has one.");
+ goto end;
+ }
+ }
+
+ /* Absolute */
+ if (!!clock_class_a->absolute != !!clock_class_b->absolute) {
+ BT_LOGV("Clock classes differ: one is absolute, the other "
+ "is not: cc-a-is-absolute=%d, cc-b-is-absolute=%d",
+ !!clock_class_a->absolute,
+ !!clock_class_b->absolute);
+ goto end;
+ }
+
+ /* Equal */
+ ret = 0;
+
+end:
+ return ret;
+}
/*
* clock.c
*
- * Babeltrace CTF IR - Clock
+ * Babeltrace CTF writer - Clock
*
* Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
* Copyright 2017 Philippe Proulx <pproulx@efficios.com>
#define BT_LOG_TAG "CTF-WRITER-CLOCK"
#include <babeltrace/lib-logging-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/compat/uuid-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/ctf-writer/clock-class-internal.h>
#include <babeltrace/ctf-writer/clock-internal.h>
+#include <babeltrace/ctf-writer/utils.h>
#include <babeltrace/ctf-writer/writer-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/compat/uuid-internal.h>
-#include <babeltrace/ref.h>
#include <babeltrace/object-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/assert-internal.h>
+#include <babeltrace/ref.h>
#include <inttypes.h>
static
clock->value = 0;
/* Pre-2.0.0 backward compatibility: default frequency is 1 GHz */
- clock->clock_class = (void *) bt_clock_class_create(name, 1000000000);
+ clock->clock_class = (void *) bt_ctf_clock_class_create(name, 1000000000);
if (!clock->clock_class) {
goto error;
}
goto error;
}
- ret = bt_clock_class_set_uuid(BT_TO_COMMON(clock->clock_class),
- cc_uuid);
+ ret = bt_ctf_clock_class_set_uuid(clock->clock_class, cc_uuid);
BT_ASSERT(ret == 0);
return clock;
const char *bt_ctf_clock_get_name(struct bt_ctf_clock *clock)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_get_name(BT_TO_COMMON(clock->clock_class));
+ return bt_ctf_clock_class_get_name(clock->clock_class);
}
const char *bt_ctf_clock_get_description(struct bt_ctf_clock *clock)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_get_description(BT_TO_COMMON(clock->clock_class));
+ return bt_ctf_clock_class_get_description(clock->clock_class);
}
int bt_ctf_clock_set_description(struct bt_ctf_clock *clock, const char *desc)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_set_description(BT_TO_COMMON(clock->clock_class),
+ return bt_ctf_clock_class_set_description(clock->clock_class,
desc);
}
uint64_t bt_ctf_clock_get_frequency(struct bt_ctf_clock *clock)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_get_frequency(BT_TO_COMMON(clock->clock_class));
+ return bt_ctf_clock_class_get_frequency(clock->clock_class);
}
int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock, uint64_t freq)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_set_frequency(BT_TO_COMMON(clock->clock_class),
+ return bt_ctf_clock_class_set_frequency(clock->clock_class,
freq);
}
uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_get_precision(BT_TO_COMMON(clock->clock_class));
+ return bt_ctf_clock_class_get_precision(clock->clock_class);
}
int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock, uint64_t precision)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_set_precision(BT_TO_COMMON(clock->clock_class),
+ return bt_ctf_clock_class_set_precision(clock->clock_class,
precision);
}
int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock, int64_t *offset_s)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_get_offset_s(BT_TO_COMMON(clock->clock_class),
+ return bt_ctf_clock_class_get_offset_s(clock->clock_class,
offset_s);
}
int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, int64_t offset_s)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_set_offset_s(BT_TO_COMMON(clock->clock_class),
+ return bt_ctf_clock_class_set_offset_s(clock->clock_class,
offset_s);
}
int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock, int64_t *offset)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_get_offset_cycles(BT_TO_COMMON(clock->clock_class),
+ return bt_ctf_clock_class_get_offset_cycles(clock->clock_class,
offset);
}
int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, int64_t offset)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_set_offset_cycles(BT_TO_COMMON(clock->clock_class),
+ return bt_ctf_clock_class_set_offset_cycles(clock->clock_class,
offset);
}
int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_is_absolute(BT_TO_COMMON(clock->clock_class));
+ return bt_ctf_clock_class_is_absolute(clock->clock_class);
}
int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock, int is_absolute)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_set_is_absolute(BT_TO_COMMON(clock->clock_class),
+ return bt_ctf_clock_class_set_is_absolute(clock->clock_class,
is_absolute);
}
const unsigned char *bt_ctf_clock_get_uuid(struct bt_ctf_clock *clock)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_get_uuid(BT_TO_COMMON(clock->clock_class));
+ return bt_ctf_clock_class_get_uuid(clock->clock_class);
}
int bt_ctf_clock_set_uuid(struct bt_ctf_clock *clock, const unsigned char *uuid)
{
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- return bt_clock_class_set_uuid(BT_TO_COMMON(clock->clock_class), uuid);
+ return bt_ctf_clock_class_set_uuid(clock->clock_class, uuid);
}
int bt_ctf_clock_set_time(struct bt_ctf_clock *clock, int64_t time)
{
int64_t value;
- struct bt_clock_class *cc;
+ struct bt_ctf_clock_class *cc;
BT_ASSERT_PRE_NON_NULL(clock, "CTF writer clock");
- cc = BT_TO_COMMON(clock->clock_class);
+ cc = clock->clock_class;
/* Common case where cycles are actually nanoseconds */
if (cc->frequency == 1000000000) {
struct bt_ctf_clock *clock;
clock = container_of(obj, struct bt_ctf_clock, base);
- bt_put(BT_TO_COMMON(clock->clock_class));
+ bt_put(clock->clock_class);
g_free(clock);
}
BT_LOGD("Serializing clock class's metadata: clock-class-addr=%p, "
"name=\"%s\", metadata-context-addr=%p", clock_class,
- bt_clock_class_get_name(BT_TO_COMMON(clock_class)),
+ bt_ctf_clock_class_get_name(clock_class),
context);
if (!clock_class || !context) {
BT_LOGW("Invalid parameter: clock class or metadata context is NULL: "
"clock-class-addr=%p, name=\"%s\", metadata-context-addr=%p",
clock_class,
- bt_clock_class_get_name(BT_TO_COMMON(clock_class)),
+ bt_ctf_clock_class_get_name(clock_class),
context);
return;
}
- uuid = clock_class->common.uuid;
+ uuid = clock_class->uuid;
g_string_append(context->string, "clock {\n");
g_string_append_printf(context->string, "\tname = %s;\n",
- clock_class->common.name->str);
+ clock_class->name->str);
- if (clock_class->common.uuid_set) {
+ if (clock_class->uuid_set) {
g_string_append_printf(context->string,
"\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
uuid[0], uuid[1], uuid[2], uuid[3],
uuid[12], uuid[13], uuid[14], uuid[15]);
}
- if (clock_class->common.description) {
+ if (clock_class->description) {
g_string_append_printf(context->string, "\tdescription = \"%s\";\n",
- clock_class->common.description->str);
+ clock_class->description->str);
}
g_string_append_printf(context->string, "\tfreq = %" PRIu64 ";\n",
- clock_class->common.frequency);
+ clock_class->frequency);
g_string_append_printf(context->string, "\tprecision = %" PRIu64 ";\n",
- clock_class->common.precision);
+ clock_class->precision);
g_string_append_printf(context->string, "\toffset_s = %" PRIu64 ";\n",
- clock_class->common.offset_s);
+ clock_class->offset_s);
g_string_append_printf(context->string, "\toffset = %" PRIu64 ";\n",
- clock_class->common.offset);
+ clock_class->offset);
g_string_append_printf(context->string, "\tabsolute = %s;\n",
- clock_class->common.absolute ? "true" : "false");
+ clock_class->absolute ? "true" : "false");
g_string_append(context->string, "};\n\n");
}
-
-struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name,
- uint64_t freq)
-{
- return BT_FROM_COMMON(bt_clock_class_create(name, freq));
-}
-
-const char *bt_ctf_clock_class_get_name(
- struct bt_ctf_clock_class *clock_class)
-{
- return bt_clock_class_get_name(BT_TO_COMMON(clock_class));
-}
-
-int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class,
- const char *name)
-{
- return bt_clock_class_set_name(BT_TO_COMMON(clock_class), name);
-}
-
-const char *bt_ctf_clock_class_get_description(
- struct bt_ctf_clock_class *clock_class)
-{
- return bt_clock_class_get_description(BT_TO_COMMON(clock_class));
-}
-
-int bt_ctf_clock_class_set_description(
- struct bt_ctf_clock_class *clock_class,
- const char *desc)
-{
- return bt_clock_class_set_description(BT_TO_COMMON(clock_class), desc);
-}
-
-uint64_t bt_ctf_clock_class_get_frequency(
- struct bt_ctf_clock_class *clock_class)
-{
- return bt_clock_class_get_frequency(BT_TO_COMMON(clock_class));
-}
-
-int bt_ctf_clock_class_set_frequency(
- struct bt_ctf_clock_class *clock_class, uint64_t freq)
-{
- return bt_clock_class_set_frequency(BT_TO_COMMON(clock_class), freq);
-}
-
-uint64_t bt_ctf_clock_class_get_precision(
- struct bt_ctf_clock_class *clock_class)
-{
- return bt_clock_class_get_precision(BT_TO_COMMON(clock_class));
-}
-
-int bt_ctf_clock_class_set_precision(
- struct bt_ctf_clock_class *clock_class, uint64_t precision)
-{
- return bt_clock_class_set_precision(BT_TO_COMMON(clock_class),
- precision);
-}
-
-int bt_ctf_clock_class_get_offset_s(
- struct bt_ctf_clock_class *clock_class, int64_t *seconds)
-{
- return bt_clock_class_get_offset_s(BT_TO_COMMON(clock_class), seconds);
-}
-
-int bt_ctf_clock_class_set_offset_s(
- struct bt_ctf_clock_class *clock_class, int64_t seconds)
-{
- return bt_clock_class_set_offset_s(BT_TO_COMMON(clock_class), seconds);
-}
-
-int bt_ctf_clock_class_get_offset_cycles(
- struct bt_ctf_clock_class *clock_class, int64_t *cycles)
-{
- return bt_clock_class_get_offset_cycles(BT_TO_COMMON(clock_class),
- cycles);
-}
-
-int bt_ctf_clock_class_set_offset_cycles(
- struct bt_ctf_clock_class *clock_class, int64_t cycles)
-{
- return bt_clock_class_set_offset_cycles(BT_TO_COMMON(clock_class),
- cycles);
-}
-
-bt_bool bt_ctf_clock_class_is_absolute(
- struct bt_ctf_clock_class *clock_class)
-{
- return bt_clock_class_is_absolute(BT_TO_COMMON(clock_class));
-}
-
-int bt_ctf_clock_class_set_is_absolute(
- struct bt_ctf_clock_class *clock_class, bt_bool is_absolute)
-{
- return bt_clock_class_set_is_absolute(BT_TO_COMMON(clock_class),
- is_absolute);
-}
-
-const unsigned char *bt_ctf_clock_class_get_uuid(
- struct bt_ctf_clock_class *clock_class)
-{
- return bt_clock_class_get_uuid(BT_TO_COMMON(clock_class));
-}
-
-int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
- const unsigned char *uuid)
-{
- return bt_clock_class_set_uuid(BT_TO_COMMON(clock_class), uuid);
-}
#define BT_LOG_TAG "CTF-WRITER-EVENT-CLASS"
#include <babeltrace/lib-logging-internal.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ctf-writer/event.h>
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/ctf-writer/attributes-internal.h>
+#include <babeltrace/ctf-writer/event-class-internal.h>
#include <babeltrace/ctf-writer/event-internal.h>
-#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/ctf-writer/event.h>
#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/ctf-writer/fields-internal.h>
+#include <babeltrace/ctf-writer/stream-class-internal.h>
+#include <babeltrace/ctf-writer/stream-class.h>
+#include <babeltrace/ctf-writer/trace-internal.h>
+#include <babeltrace/ctf-writer/utils-internal.h>
+#include <babeltrace/ctf-writer/utils.h>
+#include <babeltrace/ctf-writer/validation-internal.h>
#include <babeltrace/ctf-writer/writer-internal.h>
+#include <babeltrace/endian-internal.h>
#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/assert-pre-internal.h>
-#include <inttypes.h>
+#include <babeltrace/types.h>
+#include <babeltrace/values-internal.h>
#include <glib.h>
+#include <inttypes.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+BT_HIDDEN
+void bt_ctf_event_class_common_finalize(struct bt_object *obj)
+{
+ struct bt_ctf_event_class_common *event_class;
+
+ event_class = container_of(obj, struct bt_ctf_event_class_common, base);
+ BT_LOGD("Finalizing common event class: addr=%p, name=\"%s\", id=%" PRId64,
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class));
+
+ if (event_class->name) {
+ g_string_free(event_class->name, TRUE);
+ }
+
+ if (event_class->emf_uri) {
+ g_string_free(event_class->emf_uri, TRUE);
+ }
+
+ BT_LOGD_STR("Putting context field type.");
+ bt_put(event_class->context_field_type);
+ BT_LOGD_STR("Putting payload field type.");
+ bt_put(event_class->payload_field_type);
+}
+
+BT_HIDDEN
+int bt_ctf_event_class_common_initialize(struct bt_ctf_event_class_common *event_class,
+ const char *name, bt_object_release_func release_func,
+ bt_ctf_field_type_structure_create_func ft_struct_create_func)
+{
+ int ret = 0;
+
+ BT_LOGD("Initializing common event class object: name=\"%s\"",
+ name);
+ bt_object_init_shared_with_parent(&event_class->base, release_func);
+ event_class->payload_field_type = ft_struct_create_func();
+ if (!event_class->payload_field_type) {
+ BT_LOGE_STR("Cannot create event class's initial payload field type object.");
+ goto error;
+ }
+
+ event_class->id = -1;
+ event_class->name = g_string_new(name);
+ if (!event_class->name) {
+ BT_LOGE_STR("Failed to allocate a GString.");
+ goto error;
+ }
+
+ event_class->emf_uri = g_string_new(NULL);
+ if (!event_class->emf_uri) {
+ BT_LOGE_STR("Failed to allocate a GString.");
+ goto error;
+ }
+
+ event_class->log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED;
+ BT_LOGD("Initialized common event class object: addr=%p, name=\"%s\"",
+ event_class, bt_ctf_event_class_common_get_name(event_class));
+ return ret;
+
+error:
+ ret = -1;
+ return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_event_class_common_freeze(struct bt_ctf_event_class_common *event_class)
+{
+ BT_ASSERT(event_class);
+
+ if (event_class->frozen) {
+ return;
+ }
+
+ BT_LOGD("Freezing event class: addr=%p, name=\"%s\", id=%" PRId64,
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class));
+ event_class->frozen = 1;
+ BT_LOGD_STR("Freezing event class's context field type.");
+ bt_ctf_field_type_common_freeze(event_class->context_field_type);
+ BT_LOGD_STR("Freezing event class's payload field type.");
+ bt_ctf_field_type_common_freeze(event_class->payload_field_type);
+}
+
+BT_HIDDEN
+int bt_ctf_event_class_common_validate_single_clock_class(
+ struct bt_ctf_event_class_common *event_class,
+ struct bt_ctf_clock_class **expected_clock_class)
+{
+ int ret = 0;
+
+ BT_ASSERT(event_class);
+ BT_ASSERT(expected_clock_class);
+ ret = bt_ctf_field_type_common_validate_single_clock_class(
+ event_class->context_field_type,
+ expected_clock_class);
+ if (ret) {
+ BT_LOGW("Event class's context field type "
+ "is not recursively mapped to the "
+ "expected clock class: "
+ "event-class-addr=%p, "
+ "event-class-name=\"%s\", "
+ "event-class-id=%" PRId64 ", "
+ "ft-addr=%p",
+ event_class,
+ bt_ctf_event_class_common_get_name(event_class),
+ event_class->id,
+ event_class->context_field_type);
+ goto end;
+ }
+
+ ret = bt_ctf_field_type_common_validate_single_clock_class(
+ event_class->payload_field_type,
+ expected_clock_class);
+ if (ret) {
+ BT_LOGW("Event class's payload field type "
+ "is not recursively mapped to the "
+ "expected clock class: "
+ "event-class-addr=%p, "
+ "event-class-name=\"%s\", "
+ "event-class-id=%" PRId64 ", "
+ "ft-addr=%p",
+ event_class,
+ bt_ctf_event_class_common_get_name(event_class),
+ event_class->id,
+ event_class->payload_field_type);
+ goto end;
+ }
+
+end:
+ return ret;
+}
static
void bt_ctf_event_class_destroy(struct bt_object *obj)
{
- bt_event_class_common_finalize(obj);
+ bt_ctf_event_class_common_finalize(obj);
g_free(obj);
}
goto error;
}
- ret = bt_event_class_common_initialize(BT_TO_COMMON(ctf_event_class),
+ ret = bt_ctf_event_class_common_initialize(BT_CTF_TO_COMMON(ctf_event_class),
name, bt_ctf_event_class_destroy,
- (bt_field_type_structure_create_func)
+ (bt_ctf_field_type_structure_create_func)
bt_ctf_field_type_structure_create);
if (ret) {
goto error;
const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
{
- return bt_event_class_common_get_name(BT_TO_COMMON(event_class));
+ return bt_ctf_event_class_common_get_name(BT_CTF_TO_COMMON(event_class));
}
int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
{
- return bt_event_class_common_get_id(BT_TO_COMMON(event_class));
+ return bt_ctf_event_class_common_get_id(BT_CTF_TO_COMMON(event_class));
}
int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
uint64_t id)
{
- return bt_event_class_common_set_id(BT_TO_COMMON(event_class), id);
+ return bt_ctf_event_class_common_set_id(BT_CTF_TO_COMMON(event_class), id);
}
enum bt_ctf_event_class_log_level bt_ctf_event_class_get_log_level(
struct bt_ctf_event_class *event_class)
{
- return bt_event_class_common_get_log_level(BT_TO_COMMON(event_class));
+ return bt_ctf_event_class_common_get_log_level(BT_CTF_TO_COMMON(event_class));
}
int bt_ctf_event_class_set_log_level(struct bt_ctf_event_class *event_class,
enum bt_ctf_event_class_log_level log_level)
{
- return bt_event_class_common_set_log_level(BT_TO_COMMON(event_class),
+ return bt_ctf_event_class_common_set_log_level(BT_CTF_TO_COMMON(event_class),
log_level);
}
const char *bt_ctf_event_class_get_emf_uri(
struct bt_ctf_event_class *event_class)
{
- return bt_event_class_common_get_emf_uri(BT_TO_COMMON(event_class));
+ return bt_ctf_event_class_common_get_emf_uri(BT_CTF_TO_COMMON(event_class));
}
int bt_ctf_event_class_set_emf_uri(struct bt_ctf_event_class *event_class,
const char *emf_uri)
{
- return bt_event_class_common_set_emf_uri(BT_TO_COMMON(event_class),
+ return bt_ctf_event_class_common_set_emf_uri(BT_CTF_TO_COMMON(event_class),
emf_uri);
}
struct bt_ctf_event_class *event_class)
{
BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
- return bt_get(bt_event_class_common_borrow_stream_class(
- BT_TO_COMMON(event_class)));
+ return bt_get(bt_ctf_event_class_common_borrow_stream_class(
+ BT_CTF_TO_COMMON(event_class)));
}
struct bt_ctf_field_type *bt_ctf_event_class_get_payload_field_type(
struct bt_ctf_event_class *event_class)
{
- return bt_get(bt_event_class_common_borrow_payload_field_type(
- BT_TO_COMMON(event_class)));
+ return bt_get(bt_ctf_event_class_common_borrow_payload_field_type(
+ BT_CTF_TO_COMMON(event_class)));
}
int bt_ctf_event_class_set_payload_field_type(
struct bt_ctf_event_class *event_class,
struct bt_ctf_field_type *field_type)
{
- return bt_event_class_common_set_payload_field_type(
- BT_TO_COMMON(event_class), (void *) field_type);
+ return bt_ctf_event_class_common_set_payload_field_type(
+ BT_CTF_TO_COMMON(event_class), (void *) field_type);
}
struct bt_ctf_field_type *bt_ctf_event_class_get_context_field_type(
struct bt_ctf_event_class *event_class)
{
- return bt_get(bt_event_class_common_borrow_context_field_type(
- BT_TO_COMMON(event_class)));
+ return bt_get(bt_ctf_event_class_common_borrow_context_field_type(
+ BT_CTF_TO_COMMON(event_class)));
}
int bt_ctf_event_class_set_context_field_type(
struct bt_ctf_event_class *event_class,
struct bt_ctf_field_type *field_type)
{
- return bt_event_class_common_set_context_field_type(
- BT_TO_COMMON(event_class), (void *) field_type);
+ return bt_ctf_event_class_common_set_context_field_type(
+ BT_CTF_TO_COMMON(event_class), (void *) field_type);
}
int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class,
goto end;
}
- if (!bt_identifier_is_valid(name)) {
+ if (!bt_ctf_identifier_is_valid(name)) {
BT_LOGW("Invalid parameter: event class's payload field type's field name is not a valid CTF identifier: "
"addr=%p, name=\"%s\", id=%" PRId64 ", field-name=\"%s\"",
event_class, bt_ctf_event_class_get_name(event_class),
goto end;
}
- BT_ASSERT(bt_field_type_common_get_type_id(
+ BT_ASSERT(bt_ctf_field_type_common_get_type_id(
event_class->common.payload_field_type) ==
- BT_FIELD_TYPE_ID_STRUCT);
+ BT_CTF_FIELD_TYPE_ID_STRUCT);
ret = bt_ctf_field_type_structure_add_field(
(void *) event_class->common.payload_field_type,
(void *) type, name);
goto end;
}
- BT_ASSERT(bt_field_type_common_get_type_id(
+ BT_ASSERT(bt_ctf_field_type_common_get_type_id(
event_class->common.payload_field_type) ==
- BT_FIELD_TYPE_ID_STRUCT);
- ret = bt_field_type_common_structure_get_field_count(
+ BT_CTF_FIELD_TYPE_ID_STRUCT);
+ ret = bt_ctf_field_type_common_structure_get_field_count(
event_class->common.payload_field_type);
end:
return ret;
goto end;
}
- BT_ASSERT(bt_field_type_common_get_type_id(
+ BT_ASSERT(bt_ctf_field_type_common_get_type_id(
event_class->common.payload_field_type) ==
- BT_FIELD_TYPE_ID_STRUCT);
+ BT_CTF_FIELD_TYPE_ID_STRUCT);
ret = bt_ctf_field_type_structure_get_field_by_index(
(void *) event_class->common.payload_field_type,
field_name, (void *) field_type, index);
return ret;
}
-struct bt_field_type *
+struct bt_ctf_field_type *
bt_ctf_event_class_get_payload_type_field_type_by_name(
struct bt_ctf_event_class *event_class, const char *name)
{
GQuark name_quark;
- struct bt_field_type *field_type = NULL;
+ struct bt_ctf_field_type *field_type = NULL;
if (!event_class || !name) {
BT_LOGW("Invalid parameter: event class or name is NULL: "
goto end;
}
- BT_ASSERT(bt_field_type_common_get_type_id(
+ BT_ASSERT(bt_ctf_field_type_common_get_type_id(
event_class->common.payload_field_type) ==
- BT_FIELD_TYPE_ID_STRUCT);
+ BT_CTF_FIELD_TYPE_ID_STRUCT);
name_quark = g_quark_try_string(name);
if (!name_quark) {
BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
g_string_append_printf(context->string, "\tid = %" PRId64 ";\n",
event_class->common.id);
g_string_append_printf(context->string, "\tstream_id = %" PRId64 ";\n",
- bt_stream_class_common_get_id(
- bt_event_class_common_borrow_stream_class(
- BT_TO_COMMON(event_class))));
+ bt_ctf_stream_class_common_get_id(
+ bt_ctf_event_class_common_borrow_stream_class(
+ BT_CTF_TO_COMMON(event_class))));
if (event_class->common.log_level !=
- BT_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED) {
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED) {
g_string_append_printf(context->string, "\tloglevel = %d;\n",
(int) event_class->common.log_level);
}
}
BT_ASSERT(event_class->common.payload_field_type->id ==
- BT_FIELD_TYPE_ID_STRUCT);
+ BT_CTF_FIELD_TYPE_ID_STRUCT);
name_quark = g_quark_try_string(name);
if (!name_quark) {
BT_LOGE("Cannot get GQuark: string=\"%s\"", name);
* from the structure already does.
*/
field_type = bt_get(
- bt_field_type_common_structure_borrow_field_type_by_name(
+ bt_ctf_field_type_common_structure_borrow_field_type_by_name(
event_class->common.payload_field_type, name));
end:
#define BT_LOG_TAG "CTF-WRITER-EVENT"
#include <babeltrace/lib-logging-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/ctf-writer/attributes-internal.h>
+#include <babeltrace/ctf-writer/clock-class-internal.h>
#include <babeltrace/ctf-writer/clock-internal.h>
+#include <babeltrace/ctf-writer/event-class-internal.h>
#include <babeltrace/ctf-writer/event-internal.h>
#include <babeltrace/ctf-writer/event.h>
-#include <babeltrace/ctf-writer/fields-internal.h>
#include <babeltrace/ctf-writer/field-types-internal.h>
#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/ctf-writer/fields-internal.h>
#include <babeltrace/ctf-writer/fields.h>
#include <babeltrace/ctf-writer/stream-class-internal.h>
#include <babeltrace/ctf-writer/stream-class.h>
+#include <babeltrace/ctf-writer/stream-internal.h>
#include <babeltrace/ctf-writer/trace-internal.h>
#include <babeltrace/ctf-writer/trace.h>
+#include <babeltrace/ctf-writer/utils.h>
+#include <babeltrace/ctf-writer/validation-internal.h>
#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/assert-pre-internal.h>
#include <inttypes.h>
static
-void bt_ctf_event_destroy(struct bt_object *obj);
+int bt_ctf_event_common_validate_types_for_create(
+ struct bt_ctf_event_class_common *event_class,
+ struct bt_ctf_validation_output *validation_output,
+ bt_ctf_validation_flag_copy_field_type_func copy_field_type_func)
+{
+ int ret;
+ enum bt_ctf_validation_flag validation_flags =
+ BT_CTF_VALIDATION_FLAG_STREAM |
+ BT_CTF_VALIDATION_FLAG_EVENT;
+ struct bt_ctf_trace_common *trace = NULL;
+ struct bt_ctf_stream_class_common *stream_class = NULL;
+ struct bt_ctf_field_type_common *packet_header_type = NULL;
+ struct bt_ctf_field_type_common *packet_context_type = NULL;
+ struct bt_ctf_field_type_common *event_header_type = NULL;
+ struct bt_ctf_field_type_common *stream_event_ctx_type = NULL;
+ struct bt_ctf_field_type_common *event_context_type = NULL;
+ struct bt_ctf_field_type_common *event_payload_type = NULL;
+ int trace_valid = 0;
+ struct bt_value *environment = NULL;
+
+ stream_class = bt_ctf_event_class_common_borrow_stream_class(event_class);
+ BT_ASSERT(stream_class);
+ trace = bt_ctf_stream_class_common_borrow_trace(stream_class);
+ if (trace) {
+ BT_LOGD_STR("Event class is part of a trace.");
+ packet_header_type =
+ bt_ctf_trace_common_borrow_packet_header_field_type(trace);
+ trace_valid = trace->valid;
+ BT_ASSERT(trace_valid);
+ environment = trace->environment;
+ }
+
+ packet_context_type =
+ bt_ctf_stream_class_common_borrow_packet_context_field_type(
+ stream_class);
+ event_header_type =
+ bt_ctf_stream_class_common_borrow_event_header_field_type(
+ stream_class);
+ stream_event_ctx_type =
+ bt_ctf_stream_class_common_borrow_event_context_field_type(
+ stream_class);
+ event_context_type =
+ bt_ctf_event_class_common_borrow_context_field_type(event_class);
+ event_payload_type =
+ bt_ctf_event_class_common_borrow_payload_field_type(event_class);
+ ret = bt_ctf_validate_class_types(environment, packet_header_type,
+ packet_context_type, event_header_type, stream_event_ctx_type,
+ event_context_type, event_payload_type, trace_valid,
+ stream_class->valid, event_class->valid,
+ validation_output, validation_flags, copy_field_type_func);
+ if (ret) {
+ /*
+ * This means something went wrong during the validation
+ * process, not that the objects are invalid.
+ */
+ BT_LOGE("Failed to validate event and parents: ret=%d", ret);
+ goto error;
+ }
+
+ if ((validation_output->valid_flags & validation_flags) !=
+ validation_flags) {
+ /* Invalid trace/stream class/event class */
+ BT_LOGW("Invalid trace, stream class, or event class: "
+ "valid-flags=0x%x", validation_output->valid_flags);
+ goto error;
+ }
+
+ goto end;
+
+error:
+ bt_ctf_validation_output_put_types(validation_output);
+ ret = -1;
+
+end:
+ return ret;
+}
static
-int map_clock_classes_func(struct bt_stream_class_common *stream_class,
- struct bt_field_type_common *packet_context_type,
- struct bt_field_type_common *event_header_type)
+int bt_ctf_event_common_create_fields(
+ struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_validation_output *validation_output,
+ create_field_func create_field_func,
+ release_field_func release_field_func,
+ create_header_field_func create_header_field_func,
+ release_header_field_func release_header_field_func,
+ struct bt_ctf_field_wrapper **header_field,
+ struct bt_ctf_field_common **stream_event_context_field,
+ struct bt_ctf_field_common **context_field,
+ struct bt_ctf_field_common **payload_field)
+{
+ int ret = 0;
+
+ if (validation_output->event_header_type) {
+ BT_LOGD("Creating initial event header field: ft-addr=%p",
+ validation_output->event_header_type);
+ *header_field =
+ create_header_field_func(stream_class,
+ validation_output->event_header_type);
+ if (!*header_field) {
+ BT_LOGE_STR("Cannot create initial event header field object.");
+ goto error;
+ }
+ }
+
+ if (validation_output->stream_event_ctx_type) {
+ BT_LOGD("Creating initial stream event context field: ft-addr=%p",
+ validation_output->stream_event_ctx_type);
+ *stream_event_context_field = create_field_func(
+ validation_output->stream_event_ctx_type);
+ if (!*stream_event_context_field) {
+ BT_LOGE_STR("Cannot create initial stream event context field object.");
+ goto error;
+ }
+ }
+
+ if (validation_output->event_context_type) {
+ BT_LOGD("Creating initial event context field: ft-addr=%p",
+ validation_output->event_context_type);
+ *context_field = create_field_func(
+ validation_output->event_context_type);
+ if (!*context_field) {
+ BT_LOGE_STR("Cannot create initial event context field object.");
+ goto error;
+ }
+ }
+
+ if (validation_output->event_payload_type) {
+ BT_LOGD("Creating initial event payload field: ft-addr=%p",
+ validation_output->event_payload_type);
+ *payload_field = create_field_func(
+ validation_output->event_payload_type);
+ if (!*payload_field) {
+ BT_LOGE_STR("Cannot create initial event payload field object.");
+ goto error;
+ }
+ }
+
+ goto end;
+
+error:
+ if (*header_field) {
+ release_header_field_func(*header_field, stream_class);
+ }
+
+ if (*stream_event_context_field) {
+ release_field_func(*stream_event_context_field);
+ }
+
+ if (*context_field) {
+ release_field_func(*context_field);
+ }
+
+ if (*payload_field) {
+ release_field_func(*payload_field);
+ }
+
+ ret = -1;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int _bt_ctf_event_common_validate(struct bt_ctf_event_common *event)
+{
+ int ret = 0;
+ struct bt_ctf_stream_class_common *stream_class;
+
+ BT_ASSERT(event);
+ if (event->header_field) {
+ ret = bt_ctf_field_common_validate_recursive(
+ event->header_field->field);
+ if (ret) {
+ BT_ASSERT_PRE_MSG("Invalid event's header field: "
+ "event-addr=%p, field-addr=%p",
+ event, event->header_field->field);
+ goto end;
+ }
+ }
+
+ stream_class = bt_ctf_event_class_common_borrow_stream_class(event->class);
+
+ /*
+ * We should not have been able to create the event without associating
+ * the event class to a stream class.
+ */
+ BT_ASSERT(stream_class);
+
+ if (stream_class->event_context_field_type) {
+ ret = bt_ctf_field_common_validate_recursive(
+ event->stream_event_context_field);
+ if (ret) {
+ BT_ASSERT_PRE_MSG("Invalid event's stream event context field: "
+ "event-addr=%p, field-addr=%p",
+ event, event->stream_event_context_field);
+ goto end;
+ }
+ }
+
+ if (event->class->context_field_type) {
+ ret = bt_ctf_field_common_validate_recursive(event->context_field);
+ if (ret) {
+ BT_ASSERT_PRE_MSG("Invalid event's payload field: "
+ "event-addr=%p, field-addr=%p",
+ event, event->context_field);
+ goto end;
+ }
+ }
+
+ ret = bt_ctf_field_common_validate_recursive(event->payload_field);
+ if (ret) {
+ BT_ASSERT_PRE_MSG("Invalid event's payload field: "
+ "event-addr=%p, field-addr=%p",
+ event, event->payload_field);
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+void _bt_ctf_event_common_set_is_frozen(struct bt_ctf_event_common *event,
+ bool is_frozen)
+{
+ BT_ASSERT(event);
+ BT_LOGD("Freezing event: addr=%p, "
+ "event-class-name=\"%s\", event-class-id=%" PRId64,
+ event, bt_ctf_event_class_common_get_name(event->class),
+ bt_ctf_event_class_common_get_id(event->class));
+
+ if (event->header_field) {
+ BT_LOGD_STR("Freezing event's header field.");
+ bt_ctf_field_common_set_is_frozen_recursive(
+ event->header_field->field, is_frozen);
+ }
+
+ if (event->stream_event_context_field) {
+ BT_LOGD_STR("Freezing event's stream event context field.");
+ bt_ctf_field_common_set_is_frozen_recursive(
+ event->stream_event_context_field, is_frozen);
+ }
+
+ if (event->context_field) {
+ BT_LOGD_STR("Freezing event's context field.");
+ bt_ctf_field_common_set_is_frozen_recursive(event->context_field,
+ is_frozen);
+ }
+
+ if (event->payload_field) {
+ BT_LOGD_STR("Freezing event's payload field.");
+ bt_ctf_field_common_set_is_frozen_recursive(event->payload_field,
+ is_frozen);
+ }
+
+ event->frozen = is_frozen;
+}
+
+BT_HIDDEN
+int bt_ctf_event_common_initialize(struct bt_ctf_event_common *event,
+ struct bt_ctf_event_class_common *event_class,
+ struct bt_ctf_clock_class *init_expected_clock_class,
+ bool is_shared_with_parent, bt_object_release_func release_func,
+ bt_ctf_validation_flag_copy_field_type_func field_type_copy_func,
+ bool must_be_in_trace,
+ int (*map_clock_classes_func)(struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_field_type_common *packet_context_field_type,
+ struct bt_ctf_field_type_common *event_header_field_type),
+ create_field_func create_field_func,
+ release_field_func release_field_func,
+ create_header_field_func create_header_field_func,
+ release_header_field_func release_header_field_func)
+{
+ int ret;
+ struct bt_ctf_trace_common *trace = NULL;
+ struct bt_ctf_stream_class_common *stream_class = NULL;
+ struct bt_ctf_field_wrapper *event_header = NULL;
+ struct bt_ctf_field_common *stream_event_context = NULL;
+ struct bt_ctf_field_common *event_context = NULL;
+ struct bt_ctf_field_common *event_payload = NULL;
+ struct bt_ctf_validation_output validation_output = { 0 };
+ struct bt_ctf_clock_class *expected_clock_class =
+ init_expected_clock_class ? bt_get(init_expected_clock_class) :
+ NULL;
+
+ BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+ BT_LOGD("Initializing common event object: event-class-addr=%p, "
+ "event-class-name=\"%s\", event-class-id=%" PRId64,
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class));
+
+ stream_class = bt_ctf_event_class_common_borrow_stream_class(event_class);
+ BT_ASSERT_PRE(stream_class,
+ "Event class is not part of a stream class: event-class-addr=%p",
+ event_class);
+
+ /* The event class was frozen when added to its stream class */
+ BT_ASSERT(event_class->frozen);
+ trace = bt_ctf_stream_class_common_borrow_trace(stream_class);
+
+ if (must_be_in_trace) {
+ BT_ASSERT_PRE(trace,
+ "Event class's stream class is not part of a trace: "
+ "ec-addr=%p, sc-addr=%p", event_class, stream_class);
+ }
+
+ /*
+ * This must be called before anything that can fail because on
+ * failure, the caller releases the reference to `event` to
+ * destroy it.
+ */
+ if (is_shared_with_parent) {
+ bt_object_init_shared_with_parent(&event->base, release_func);
+ } else {
+ bt_object_init_unique(&event->base);
+ }
+
+ if (!stream_class->frozen) {
+ /*
+ * Because this function freezes the stream class,
+ * validate that this stream class contains at most a
+ * single clock class so that we set its expected clock
+ * class for future checks.
+ */
+ ret = bt_ctf_stream_class_common_validate_single_clock_class(
+ stream_class, &expected_clock_class);
+ if (ret) {
+ BT_LOGW("Event class's stream class or one of its event "
+ "classes contains a field type which is not "
+ "recursively mapped to the expected "
+ "clock class: "
+ "stream-class-addr=%p, "
+ "stream-class-id=%" PRId64 ", "
+ "stream-class-name=\"%s\", "
+ "expected-clock-class-addr=%p, "
+ "expected-clock-class-name=\"%s\"",
+ stream_class,
+ bt_ctf_stream_class_common_get_id(stream_class),
+ bt_ctf_stream_class_common_get_name(stream_class),
+ expected_clock_class,
+ expected_clock_class ?
+ bt_ctf_clock_class_get_name(expected_clock_class) :
+ NULL);
+ goto error;
+ }
+ }
+
+ /* Validate the trace, the stream class, and the event class */
+ ret = bt_ctf_event_common_validate_types_for_create(
+ event_class, &validation_output, field_type_copy_func);
+ if (ret) {
+ /* bt_ctf_event_common_validate_types_for_create() logs errors */
+ goto error;
+ }
+
+ if (map_clock_classes_func) {
+ /*
+ * Safe to automatically map selected fields to the
+ * stream's clock's class here because the stream class
+ * is about to be frozen.
+ */
+ if (map_clock_classes_func(stream_class,
+ validation_output.packet_context_type,
+ validation_output.event_header_type)) {
+ BT_LOGW_STR("Cannot automatically map selected stream class's "
+ "field types to stream class's clock's class.");
+ goto error;
+ }
+ }
+
+ /*
+ * event does not share a common ancestor with the event class; it has
+ * to guarantee its existence by holding a reference. This reference
+ * shall be released once the event is associated to a stream since,
+ * from that point, the event and its class will share the same
+ * lifetime.
+ */
+ event->class = bt_get(event_class);
+
+ ret = bt_ctf_event_common_create_fields(stream_class,
+ &validation_output,
+ create_field_func, release_field_func,
+ create_header_field_func, release_header_field_func,
+ &event_header, &stream_event_context, &event_context,
+ &event_payload);
+ if (ret) {
+ /* bt_ctf_event_common_create_fields() logs errors */
+ goto error;
+ }
+
+ /*
+ * At this point all the fields are created, potentially from
+ * validated copies of field types, so that the field types and
+ * fields can be replaced in the trace, stream class,
+ * event class, and created event.
+ */
+ bt_ctf_validation_replace_types(trace, stream_class, event_class,
+ &validation_output,
+ BT_CTF_VALIDATION_FLAG_STREAM | BT_CTF_VALIDATION_FLAG_EVENT);
+ event->header_field = event_header;
+ event_header = NULL;
+ event->stream_event_context_field = stream_event_context;
+ stream_event_context = NULL;
+ event->context_field = event_context;
+ event_context = NULL;
+ event->payload_field = event_payload;
+ event_payload = NULL;
+
+ /*
+ * Put what was not moved in bt_ctf_validation_replace_types().
+ */
+ bt_ctf_validation_output_put_types(&validation_output);
+
+ /*
+ * Freeze the stream class since the event header must not be changed
+ * anymore.
+ */
+ bt_ctf_stream_class_common_freeze(stream_class);
+
+ /*
+ * It is safe to set the stream class's unique clock class
+ * now because the stream class is frozen.
+ */
+ if (expected_clock_class) {
+ BT_MOVE(stream_class->clock_class, expected_clock_class);
+ }
+
+ /*
+ * Mark stream class, and event class as valid since
+ * they're all frozen now.
+ */
+ stream_class->valid = 1;
+ event_class->valid = 1;
+
+ /* Put stuff we borrowed from the event class */
+ BT_LOGD("Initialized event object: addr=%p, event-class-name=\"%s\", "
+ "event-class-id=%" PRId64,
+ event, bt_ctf_event_class_common_get_name(event->class),
+ bt_ctf_event_class_common_get_id(event->class));
+ goto end;
+
+error:
+ bt_ctf_validation_output_put_types(&validation_output);
+ bt_put(expected_clock_class);
+
+ if (event_header) {
+ release_header_field_func(event_header, stream_class);
+ }
+
+ if (stream_event_context) {
+ release_field_func(stream_event_context);
+ }
+
+ if (event_context) {
+ release_field_func(event_context);
+ }
+
+ if (event_payload) {
+ release_field_func(event_payload);
+ }
+
+ ret = -1;
+
+end:
+ return ret;
+}
+
+int map_clock_classes_func(struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_field_type_common *packet_context_type,
+ struct bt_ctf_field_type_common *event_header_type)
{
int ret = bt_ctf_stream_class_map_clock_class(
- BT_FROM_COMMON(stream_class),
- BT_FROM_COMMON(packet_context_type),
- BT_FROM_COMMON(event_header_type));
+ BT_CTF_FROM_COMMON(stream_class),
+ BT_CTF_FROM_COMMON(packet_context_type),
+ BT_CTF_FROM_COMMON(event_header_type));
if (ret) {
BT_LOGW_STR("Cannot automatically map selected stream class's field types to stream class's clock's class.");
}
static
-void destroy_event_header_field(struct bt_field_wrapper *field_wrapper)
+void destroy_event_header_field(struct bt_ctf_field_wrapper *field_wrapper)
{
BT_ASSERT(field_wrapper);
bt_put(field_wrapper->field);
- bt_field_wrapper_destroy(field_wrapper);
+ bt_ctf_field_wrapper_destroy(field_wrapper);
}
static
-struct bt_field_wrapper *create_event_header_field(
- struct bt_stream_class *stream_class,
- struct bt_field_type_common *ft)
+struct bt_ctf_field_wrapper *create_event_header_field(
+ struct bt_ctf_stream_class *stream_class,
+ struct bt_ctf_field_type_common *ft)
{
- struct bt_field_wrapper *field_wrapper = NULL;
+ struct bt_ctf_field_wrapper *field_wrapper = NULL;
struct bt_ctf_field *field = bt_ctf_field_create((void *) ft);
if (!field) {
goto error;
}
- field_wrapper = bt_field_wrapper_new(NULL);
+ field_wrapper = bt_ctf_field_wrapper_new(NULL);
if (!field_wrapper) {
goto error;
}
return field_wrapper;
}
+static
+void release_event_header_field(struct bt_ctf_field_wrapper *field_wrapper,
+ struct bt_ctf_event_common *event_common)
+{
+ BT_ASSERT(field_wrapper);
+ BT_PUT(field_wrapper->field);
+ bt_ctf_field_wrapper_destroy(field_wrapper);
+}
+
+static
+void bt_ctf_event_destroy(struct bt_object *obj)
+{
+ bt_ctf_event_common_finalize(obj, (void *) bt_put,
+ (void *) release_event_header_field);
+ g_free(obj);
+}
+
struct bt_ctf_event *bt_ctf_event_create(struct bt_ctf_event_class *event_class)
{
int ret;
struct bt_ctf_event *event = NULL;
- struct bt_clock_class *expected_clock_class = NULL;
+ struct bt_ctf_clock_class *expected_clock_class = NULL;
event = g_new0(struct bt_ctf_event, 1);
if (!event) {
if (event_class) {
struct bt_ctf_stream_class *stream_class =
- BT_FROM_COMMON(bt_event_class_common_borrow_stream_class(
- BT_TO_COMMON(event_class)));
+ BT_CTF_FROM_COMMON(bt_ctf_event_class_common_borrow_stream_class(
+ BT_CTF_TO_COMMON(event_class)));
if (stream_class && stream_class->clock) {
- expected_clock_class = BT_TO_COMMON(
- stream_class->clock->clock_class);
+ expected_clock_class = stream_class->clock->clock_class;
}
}
- ret = bt_event_common_initialize(BT_TO_COMMON(event),
- BT_TO_COMMON(event_class), expected_clock_class,
+ ret = bt_ctf_event_common_initialize(BT_CTF_TO_COMMON(event),
+ BT_CTF_TO_COMMON(event_class), expected_clock_class,
true, bt_ctf_event_destroy,
- (bt_validation_flag_copy_field_type_func)
+ (bt_ctf_validation_flag_copy_field_type_func)
bt_ctf_field_type_copy,
false, map_clock_classes_func,
(create_field_func) bt_ctf_field_create,
(create_header_field_func) create_event_header_field,
(release_header_field_func) destroy_event_header_field);
if (ret) {
- /* bt_event_common_initialize() logs errors */
+ /* bt_ctf_event_common_initialize() logs errors */
goto error;
}
struct bt_ctf_event_class *bt_ctf_event_get_class(struct bt_ctf_event *event)
{
BT_ASSERT_PRE_NON_NULL(event, "Event");
- return bt_get(bt_event_common_borrow_class(BT_TO_COMMON(event)));
+ return bt_get(bt_ctf_event_common_borrow_class(BT_CTF_TO_COMMON(event)));
}
BT_HIDDEN
{
BT_ASSERT(event);
return (struct bt_ctf_stream *)
- bt_object_borrow_parent(&BT_TO_COMMON(event)->base);
+ bt_object_borrow_parent(&BT_CTF_TO_COMMON(event)->base);
}
struct bt_ctf_stream *bt_ctf_event_get_stream(struct bt_ctf_event *event)
{
BT_ASSERT_PRE_NON_NULL(event, "Event");
BT_ASSERT_PRE_NON_NULL(field, "Payload field");
- BT_ASSERT_PRE_EVENT_COMMON_HOT(BT_TO_COMMON(event), "Event");
+ BT_ASSERT_PRE_EVENT_COMMON_HOT(BT_CTF_TO_COMMON(event), "Event");
return bt_ctf_field_structure_set_field_by_name(
(void *) event->common.payload_field, name, field);
}
if (name) {
field = bt_ctf_field_structure_get_field_by_name(
- BT_FROM_COMMON(event->common.payload_field), name);
+ BT_CTF_FROM_COMMON(event->common.payload_field), name);
} else {
- field = BT_FROM_COMMON(event->common.payload_field);
+ field = BT_CTF_FROM_COMMON(event->common.payload_field);
bt_get(field);
}
struct bt_ctf_field *bt_ctf_event_get_payload_field(
struct bt_ctf_event *event)
{
- return bt_get(bt_event_common_borrow_payload(BT_TO_COMMON(event)));
+ return bt_get(bt_ctf_event_common_borrow_payload(BT_CTF_TO_COMMON(event)));
}
struct bt_ctf_field *bt_ctf_event_get_header(struct bt_ctf_event *event)
{
- return bt_get(bt_event_common_borrow_header(BT_TO_COMMON(event)));
+ return bt_get(bt_ctf_event_common_borrow_header(BT_CTF_TO_COMMON(event)));
}
struct bt_ctf_field *bt_ctf_event_get_context(struct bt_ctf_event *event)
{
- return bt_get(bt_event_common_borrow_context(BT_TO_COMMON(event)));
+ return bt_get(bt_ctf_event_common_borrow_context(BT_CTF_TO_COMMON(event)));
}
struct bt_ctf_field *bt_ctf_event_get_stream_event_context(
struct bt_ctf_event *event)
{
- return bt_get(bt_event_common_borrow_stream_event_context(
- BT_TO_COMMON(event)));
-}
-
-static
-void release_event_header_field(struct bt_field_wrapper *field_wrapper,
- struct bt_event_common *event_common)
-{
- BT_ASSERT(field_wrapper);
- BT_PUT(field_wrapper->field);
- bt_field_wrapper_destroy(field_wrapper);
-}
-
-static
-void bt_ctf_event_destroy(struct bt_object *obj)
-{
- bt_event_common_finalize(obj, (void *) bt_put,
- (void *) release_event_header_field);
- g_free(obj);
+ return bt_get(bt_ctf_event_common_borrow_stream_event_context(
+ BT_CTF_TO_COMMON(event)));
}
BT_HIDDEN
"event-addr=%p, event-class-name=\"%s\", "
"event-class-id=%" PRId64,
event,
- bt_event_class_common_get_name(event->common.class),
- bt_event_class_common_get_id(event->common.class));
+ bt_ctf_event_class_common_get_name(event->common.class),
+ bt_ctf_event_class_common_get_id(event->common.class));
goto end;
}
}
"event-addr=%p, event-class-name=\"%s\", "
"event-class-id=%" PRId64,
event,
- bt_event_class_common_get_name(event->common.class),
- bt_event_class_common_get_id(event->common.class));
+ bt_ctf_event_class_common_get_name(event->common.class),
+ bt_ctf_event_class_common_get_id(event->common.class));
goto end;
}
}
BT_HIDDEN
void _bt_ctf_event_freeze(struct bt_ctf_event *event)
{
- _bt_event_common_set_is_frozen(BT_TO_COMMON(event), true);
+ _bt_ctf_event_common_set_is_frozen(BT_CTF_TO_COMMON(event), true);
}
int bt_ctf_event_set_header(struct bt_ctf_event *event,
struct bt_ctf_field *header)
{
BT_ASSERT_PRE_NON_NULL(event, "Event");
- BT_ASSERT_PRE_EVENT_COMMON_HOT(BT_TO_COMMON(event), "Event");
+ BT_ASSERT_PRE_EVENT_COMMON_HOT(BT_CTF_TO_COMMON(event), "Event");
/*
* Ensure the provided header's type matches the one registered to the
* stream class.
*/
if (header) {
- BT_ASSERT_PRE(bt_field_type_common_compare(
- ((struct bt_field_common *) header)->type,
- bt_event_class_common_borrow_stream_class(event->common.class)->event_header_field_type) == 0,
+ BT_ASSERT_PRE(bt_ctf_field_type_common_compare(
+ ((struct bt_ctf_field_common *) header)->type,
+ bt_ctf_event_class_common_borrow_stream_class(event->common.class)->event_header_field_type) == 0,
"Header field's type is different from the "
- "expected field type: %![event-]+we, %![ft-]+wF, "
- "%![expected-ft-]+wF",
- event, ((struct bt_field_common *) header)->type,
- bt_event_class_common_borrow_stream_class(event->common.class)->event_header_field_type);
+ "expected field type: event-addr=%p, ft-addr=%p, "
+ "expected-ft-addr=%p",
+ event, ((struct bt_ctf_field_common *) header)->type,
+ bt_ctf_event_class_common_borrow_stream_class(event->common.class)->event_header_field_type);
} else {
- BT_ASSERT_PRE(!bt_event_class_common_borrow_stream_class(event->common.class)->event_header_field_type,
+ BT_ASSERT_PRE(!bt_ctf_event_class_common_borrow_stream_class(event->common.class)->event_header_field_type,
"Setting no event header field, "
"but event header field type is not NULL: ",
- "%![event-]+we, %![header-ft-]+wF",
+ "event-addr=%p, header-ft-addr=%p",
event,
- bt_event_class_common_borrow_stream_class(event->common.class)->event_header_field_type);
+ bt_ctf_event_class_common_borrow_stream_class(event->common.class)->event_header_field_type);
}
bt_put(event->common.header_field->field);
BT_LOGV("Set event's header field: event-addr=%p, "
"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
"header-field-addr=%p",
- event, bt_event_class_common_get_name(event->common.class),
- bt_event_class_common_get_id(event->common.class), header);
+ event, bt_ctf_event_class_common_get_name(event->common.class),
+ bt_ctf_event_class_common_get_id(event->common.class), header);
return 0;
}
struct bt_ctf_field *payload)
{
BT_ASSERT_PRE_NON_NULL(event, "Event");
- BT_ASSERT_PRE_EVENT_COMMON_HOT(BT_TO_COMMON(event), "Event");
+ BT_ASSERT_PRE_EVENT_COMMON_HOT(BT_CTF_TO_COMMON(event), "Event");
if (payload) {
- BT_ASSERT_PRE(bt_field_type_common_compare(
- ((struct bt_field_common *) payload)->type,
+ BT_ASSERT_PRE(bt_ctf_field_type_common_compare(
+ ((struct bt_ctf_field_common *) payload)->type,
event->common.class->payload_field_type) == 0,
"Payload field's type is different from the "
- "expected field type: %![event-]+we, %![ft-]+wF, "
- "%![expected-ft-]+wF",
+ "expected field type: event-addr=%p, ft-addr=%p, "
+ "expected-ft-addr=%p",
event,
- ((struct bt_field_common *) payload)->type,
+ ((struct bt_ctf_field_common *) payload)->type,
event->common.class->payload_field_type);
} else {
BT_ASSERT_PRE(!event->common.class->payload_field_type,
"Setting no event payload field, "
"but event payload field type is not NULL: ",
- "%![event-]+we, %![payload-ft-]+wF",
+ "event-addr=%p, payload-ft-addr=%p",
event, event->common.class->payload_field_type);
}
BT_LOGV("Set event's payload field: event-addr=%p, "
"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
"payload-field-addr=%p",
- event, bt_event_class_common_get_name(event->common.class),
- bt_event_class_common_get_id(event->common.class), payload);
+ event, bt_ctf_event_class_common_get_name(event->common.class),
+ bt_ctf_event_class_common_get_id(event->common.class), payload);
return 0;
}
struct bt_ctf_field *context)
{
BT_ASSERT_PRE_NON_NULL(event, "Event");
- BT_ASSERT_PRE_EVENT_COMMON_HOT(BT_TO_COMMON(event), "Event");
+ BT_ASSERT_PRE_EVENT_COMMON_HOT(BT_CTF_TO_COMMON(event), "Event");
if (context) {
- BT_ASSERT_PRE(bt_field_type_common_compare(
- ((struct bt_field_common *) context)->type,
+ BT_ASSERT_PRE(bt_ctf_field_type_common_compare(
+ ((struct bt_ctf_field_common *) context)->type,
event->common.class->context_field_type) == 0,
"Context field's type is different from the "
- "expected field type: %![event-]+we, %![ft-]+wF, "
- "%![expected-ft-]+wF",
- event, ((struct bt_field_common *) context)->type,
+ "expected field type: event-addr=%p, ft-addr=%p, "
+ "expected-ft-addr=%p",
+ event, ((struct bt_ctf_field_common *) context)->type,
event->common.class->context_field_type);
} else {
BT_ASSERT_PRE(!event->common.class->context_field_type,
"Setting no event context field, "
"but event context field type is not NULL: ",
- "%![event-]+we, %![context-ft-]+wF",
+ "event-addr=%p, context-ft-addr=%p",
event, event->common.class->context_field_type);
}
BT_LOGV("Set event's context field: event-addr=%p, "
"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
"context-field-addr=%p",
- event, bt_event_class_common_get_name(event->common.class),
- bt_event_class_common_get_id(event->common.class), context);
+ event, bt_ctf_event_class_common_get_name(event->common.class),
+ bt_ctf_event_class_common_get_id(event->common.class), context);
return 0;
}
struct bt_ctf_field *stream_event_context)
{
BT_ASSERT_PRE_NON_NULL(event, "Event");
- BT_ASSERT_PRE_EVENT_COMMON_HOT(BT_TO_COMMON(event), "Event");
+ BT_ASSERT_PRE_EVENT_COMMON_HOT(BT_CTF_TO_COMMON(event), "Event");
if (stream_event_context) {
- BT_ASSERT_PRE(bt_field_type_common_compare(
- ((struct bt_field_common *) stream_event_context)->type,
- bt_event_class_common_borrow_stream_class(event->common.class)->event_context_field_type) == 0,
+ BT_ASSERT_PRE(bt_ctf_field_type_common_compare(
+ ((struct bt_ctf_field_common *) stream_event_context)->type,
+ bt_ctf_event_class_common_borrow_stream_class(event->common.class)->event_context_field_type) == 0,
"Stream event context field's type is different from the "
- "expected field type: %![event-]+we, %![ft-]+wF, "
- "%![expected-ft-]+wF",
+ "expected field type: event-addr=%p, ft-addr=%p, "
+ "expected-ft-addr=%p",
event,
- ((struct bt_field_common *) stream_event_context)->type,
- bt_event_class_common_borrow_stream_class(event->common.class)->event_context_field_type);
+ ((struct bt_ctf_field_common *) stream_event_context)->type,
+ bt_ctf_event_class_common_borrow_stream_class(event->common.class)->event_context_field_type);
} else {
- BT_ASSERT_PRE(!bt_event_class_common_borrow_stream_class(event->common.class)->event_context_field_type,
+ BT_ASSERT_PRE(!bt_ctf_event_class_common_borrow_stream_class(event->common.class)->event_context_field_type,
"Setting no stream event context field, "
"but stream event context field type is not NULL: ",
- "%![event-]+we, %![context-ft-]+wF",
+ "event-addr=%p, context-ft-addr=%p",
event,
- bt_event_class_common_borrow_stream_class(event->common.class)->event_context_field_type);
+ bt_ctf_event_class_common_borrow_stream_class(event->common.class)->event_context_field_type);
}
bt_put(event->common.stream_event_context_field);
BT_LOGV("Set event's stream event context field: event-addr=%p, "
"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
"stream-event-context-field-addr=%p",
- event, bt_event_class_common_get_name(event->common.class),
- bt_event_class_common_get_id(event->common.class),
+ event, bt_ctf_event_class_common_get_name(event->common.class),
+ bt_ctf_event_class_common_get_id(event->common.class),
stream_event_context);
return 0;
}
--- /dev/null
+/*
+ * field-path.c
+ *
+ * Babeltrace CTF writer - Field path
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2016 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:
+ *
+ * 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.
+ */
+
+#define BT_LOG_TAG "CTF-WRITER-FIELD-PATH"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/ctf-writer/field-path-internal.h>
+#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/ctf-writer/field-types.h>
+#include <glib.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdint.h>
+
+static
+void field_path_destroy(struct bt_object *obj)
+{
+ struct bt_ctf_field_path *field_path = (struct bt_ctf_field_path *) obj;
+
+ BT_LOGD("Destroying field path: addr=%p", obj);
+
+ if (!field_path) {
+ return;
+ }
+
+ if (field_path->indexes) {
+ g_array_free(field_path->indexes, TRUE);
+ }
+ g_free(field_path);
+}
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_path_create(void)
+{
+ struct bt_ctf_field_path *field_path = NULL;
+
+ BT_LOGD_STR("Creating empty field path object.");
+
+ field_path = g_new0(struct bt_ctf_field_path, 1);
+ if (!field_path) {
+ BT_LOGE_STR("Failed to allocate one field path.");
+ goto error;
+ }
+
+ bt_object_init_shared(&field_path->base, field_path_destroy);
+ field_path->root = BT_CTF_SCOPE_UNKNOWN;
+ field_path->indexes = g_array_new(TRUE, FALSE, sizeof(int));
+ if (!field_path->indexes) {
+ BT_LOGE_STR("Failed to allocate a GArray.");
+ goto error;
+ }
+
+ BT_LOGD("Created empty field path object: addr=%p", field_path);
+ return field_path;
+
+error:
+ BT_PUT(field_path);
+ return NULL;
+}
+
+BT_HIDDEN
+void bt_ctf_field_path_clear(struct bt_ctf_field_path *field_path)
+{
+ if (field_path->indexes->len > 0) {
+ g_array_remove_range(field_path->indexes, 0,
+ field_path->indexes->len);
+ }
+}
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_path_copy(
+ struct bt_ctf_field_path *path)
+{
+ struct bt_ctf_field_path *new_path;
+
+ BT_ASSERT(path);
+ BT_LOGD("Copying field path: addr=%p, index-count=%u",
+ path, path->indexes->len);
+ new_path = bt_ctf_field_path_create();
+ if (!new_path) {
+ BT_LOGE_STR("Cannot create empty field path.");
+ goto end;
+ }
+
+ new_path->root = path->root;
+ g_array_insert_vals(new_path->indexes, 0,
+ path->indexes->data, path->indexes->len);
+ BT_LOGD("Copied field path: original-addr=%p, copy-addr=%p",
+ path, new_path);
+end:
+ return new_path;
+}
+
+enum bt_ctf_scope bt_ctf_field_path_get_root_scope(
+ const struct bt_ctf_field_path *field_path)
+{
+ enum bt_ctf_scope scope = BT_CTF_SCOPE_UNKNOWN;
+
+ if (!field_path) {
+ BT_LOGW_STR("Invalid parameter: field path is NULL.");
+ goto end;
+ }
+
+ scope = field_path->root;
+
+end:
+ return scope;
+}
+
+int64_t bt_ctf_field_path_get_index_count(
+ const struct bt_ctf_field_path *field_path)
+{
+ int64_t count = (int64_t) -1;
+
+ if (!field_path) {
+ BT_LOGW_STR("Invalid parameter: field path is NULL.");
+ goto end;
+ }
+
+ count = (int64_t) field_path->indexes->len;
+
+end:
+ return count;
+}
+
+int bt_ctf_field_path_get_index(const struct bt_ctf_field_path *field_path,
+ uint64_t index)
+{
+ int ret = INT_MIN;
+
+ if (!field_path) {
+ BT_LOGW_STR("Invalid parameter: field path is NULL.");
+ goto end;
+ }
+
+ if (index >= field_path->indexes->len) {
+ BT_LOGW("Invalid parameter: index is out of bounds: "
+ "addr=%p, index=%" PRIu64 ", count=%u",
+ field_path, index, field_path->indexes->len);
+ goto end;
+ }
+
+ ret = g_array_index(field_path->indexes, int, index);
+
+end:
+ return ret;
+}
#include <babeltrace/lib-logging-internal.h>
#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/ctf-writer/clock-class-internal.h>
+#include <babeltrace/ctf-writer/clock-internal.h>
+#include <babeltrace/ctf-writer/field-path-internal.h>
#include <babeltrace/ctf-writer/field-types-internal.h>
-#include <babeltrace/ctf-writer/fields.h>
+#include <babeltrace/ctf-writer/field-types.h>
#include <babeltrace/ctf-writer/fields-internal.h>
-#include <babeltrace/ctf-writer/clock-internal.h>
+#include <babeltrace/ctf-writer/fields.h>
+#include <babeltrace/ctf-writer/utils-internal.h>
+#include <babeltrace/ctf-writer/utils.h>
+#include <babeltrace/endian-internal.h>
#include <babeltrace/object-internal.h>
#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/endian-internal.h>
-#include <babeltrace/assert-internal.h>
#include <float.h>
#include <inttypes.h>
#include <stdlib.h>
+static
+void destroy_enumeration_mapping(struct bt_ctf_enumeration_mapping *mapping)
+{
+ g_free(mapping);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_initialize(struct bt_ctf_field_type_common *ft,
+ bool init_bo, bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods)
+{
+ BT_ASSERT(ft && (ft->id > BT_CTF_FIELD_TYPE_ID_UNKNOWN) &&
+ (ft->id < BT_CTF_FIELD_TYPE_ID_NR));
+
+ bt_object_init_shared(&ft->base, release_func);
+ ft->methods = methods;
+
+ if (init_bo) {
+ int ret;
+ const enum bt_ctf_byte_order bo = BT_CTF_BYTE_ORDER_NATIVE;
+
+ BT_LOGD("Setting initial field type's byte order: bo=%s",
+ bt_ctf_byte_order_string(bo));
+ ret = bt_ctf_field_type_common_set_byte_order(ft, bo);
+ BT_ASSERT(ret == 0);
+ }
+
+ ft->alignment = 1;
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_integer_initialize(
+ struct bt_ctf_field_type_common *ft,
+ unsigned int size, bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods)
+{
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT(size > 0);
+ BT_LOGD("Initializing common integer field type object: size=%u",
+ size);
+ ft->id = BT_CTF_FIELD_TYPE_ID_INTEGER;
+ int_ft->size = size;
+ int_ft->base = BT_CTF_INTEGER_BASE_DECIMAL;
+ int_ft->encoding = BT_CTF_STRING_ENCODING_NONE;
+ bt_ctf_field_type_common_initialize(ft, true, release_func, methods);
+ BT_LOGD("Initialized common integer field type object: addr=%p, size=%u",
+ ft, size);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_floating_point_initialize(
+ struct bt_ctf_field_type_common *ft,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods)
+{
+ struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_LOGD_STR("Initializing common floating point number field type object.");
+ ft->id = BT_CTF_FIELD_TYPE_ID_FLOAT;
+ flt_ft->exp_dig = sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
+ flt_ft->mant_dig = FLT_MANT_DIG;
+ bt_ctf_field_type_common_initialize(ft, true, release_func, methods);
+ BT_LOGD("Initialized common floating point number field type object: addr=%p, "
+ "exp-size=%u, mant-size=%u", ft, flt_ft->exp_dig,
+ flt_ft->mant_dig);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_enumeration_initialize(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *container_ft,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods)
+{
+ struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT(container_ft);
+ BT_LOGD("Initializing common enumeration field type object: int-ft-addr=%p",
+ container_ft);
+ ft->id = BT_CTF_FIELD_TYPE_ID_ENUM;
+ enum_ft->container_ft = bt_get(container_ft);
+ enum_ft->entries = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) destroy_enumeration_mapping);
+ bt_ctf_field_type_common_initialize(ft, false, release_func, methods);
+ BT_LOGD("Initialized common enumeration field type object: addr=%p, "
+ "int-ft-addr=%p, int-ft-size=%u", ft, container_ft,
+ bt_ctf_field_type_common_integer_get_size(container_ft));
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_string_initialize(
+ struct bt_ctf_field_type_common *ft,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods)
+{
+ struct bt_ctf_field_type_common_string *string_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_LOGD_STR("Initializing common string field type object.");
+ ft->id = BT_CTF_FIELD_TYPE_ID_STRING;
+ bt_ctf_field_type_common_initialize(ft, true, release_func, methods);
+ string_ft->encoding = BT_CTF_STRING_ENCODING_UTF8;
+ ft->alignment = CHAR_BIT;
+ BT_LOGD("Initialized common string field type object: addr=%p", ft);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_structure_initialize(
+ struct bt_ctf_field_type_common *ft,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods)
+{
+ struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_LOGD_STR("Initializing common structure field type object.");
+ ft->id = BT_CTF_FIELD_TYPE_ID_STRUCT;
+ struct_ft->fields = g_array_new(FALSE, TRUE,
+ sizeof(struct bt_ctf_field_type_common_structure_field));
+ struct_ft->field_name_to_index = g_hash_table_new(NULL, NULL);
+ bt_ctf_field_type_common_initialize(ft, true, release_func, methods);
+ BT_LOGD("Initialized common structure field type object: addr=%p", ft);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_array_initialize(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *element_ft,
+ unsigned int length, bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods)
+{
+ struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT(element_ft);
+ BT_LOGD("Initializing common array field type object: element-ft-addr=%p, "
+ "length=%u", element_ft, length);
+ ft->id = BT_CTF_FIELD_TYPE_ID_ARRAY;
+ array_ft->element_ft = bt_get(element_ft);
+ array_ft->length = length;
+ bt_ctf_field_type_common_initialize(ft, false, release_func, methods);
+ BT_LOGD("Initialized common array field type object: addr=%p, "
+ "element-ft-addr=%p, length=%u", ft, element_ft, length);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_sequence_initialize(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *element_ft,
+ const char *length_field_name,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods)
+{
+ struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT(element_ft);
+ BT_ASSERT(length_field_name);
+ BT_ASSERT(bt_ctf_identifier_is_valid(length_field_name));
+ BT_LOGD("Initializing common sequence field type object: element-ft-addr=%p, "
+ "length-field-name=\"%s\"", element_ft, length_field_name);
+ ft->id = BT_CTF_FIELD_TYPE_ID_SEQUENCE;
+ seq_ft->element_ft = bt_get(element_ft);
+ seq_ft->length_field_name = g_string_new(length_field_name);
+ bt_ctf_field_type_common_initialize(ft, false, release_func, methods);
+ BT_LOGD("Initialized common sequence field type object: addr=%p, "
+ "element-ft-addr=%p, length-field-name=\"%s\"",
+ ft, element_ft, length_field_name);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_variant_initialize(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *tag_ft,
+ const char *tag_name,
+ bt_object_release_func release_func,
+ struct bt_ctf_field_type_common_methods *methods)
+{
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT(!tag_name || bt_ctf_identifier_is_valid(tag_name));
+ BT_LOGD("Initializing common variant field type object: "
+ "tag-ft-addr=%p, tag-field-name=\"%s\"",
+ tag_ft, tag_name);
+ ft->id = BT_CTF_FIELD_TYPE_ID_VARIANT;
+ var_ft->tag_name = g_string_new(tag_name);
+ var_ft->choice_name_to_index = g_hash_table_new(NULL, NULL);
+ var_ft->choices = g_array_new(FALSE, TRUE,
+ sizeof(struct bt_ctf_field_type_common_variant_choice));
+
+ if (tag_ft) {
+ var_ft->tag_ft = bt_get(tag_ft);
+ }
+
+ bt_ctf_field_type_common_initialize(ft, true, release_func, methods);
+ /* A variant's alignment is undefined */
+ ft->alignment = 0;
+ BT_LOGD("Initialized common variant field type object: addr=%p, "
+ "tag-ft-addr=%p, tag-field-name=\"%s\"",
+ ft, tag_ft, tag_name);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_integer_destroy(struct bt_object *obj)
+{
+ struct bt_ctf_field_type_common_integer *ft = (void *) obj;
+
+ if (!ft) {
+ return;
+ }
+
+ BT_LOGD("Destroying integer field type object: addr=%p", ft);
+ BT_LOGD_STR("Putting mapped clock class.");
+ bt_put(ft->mapped_clock_class);
+ g_free(ft);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_floating_point_destroy(struct bt_object *obj)
+{
+ struct bt_ctf_field_type_common_floating_point *ft = (void *) obj;
+
+ if (!ft) {
+ return;
+ }
+
+ BT_LOGD("Destroying floating point number field type object: addr=%p", ft);
+ g_free(ft);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_enumeration_destroy_recursive(struct bt_object *obj)
+{
+ struct bt_ctf_field_type_common_enumeration *ft = (void *) obj;
+
+ if (!ft) {
+ return;
+ }
+
+ BT_LOGD("Destroying enumeration field type object: addr=%p", ft);
+ g_ptr_array_free(ft->entries, TRUE);
+ BT_LOGD_STR("Putting container field type.");
+ bt_put(ft->container_ft);
+ g_free(ft);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_string_destroy(struct bt_object *obj)
+{
+ struct bt_ctf_field_type_common_string *ft = (void *) obj;
+
+ if (!ft) {
+ return;
+ }
+
+ BT_LOGD("Destroying string field type object: addr=%p", ft);
+ g_free(ft);
+}
+
+static
+void bt_ctf_field_type_common_structure_field_finalize(
+ struct bt_ctf_field_type_common_structure_field *field)
+{
+ if (!field) {
+ return;
+ }
+
+ BT_LOGD("Finalizing structure field type's field: "
+ "addr=%p, field-ft-addr=%p, field-name=\"%s\"",
+ field, field->type, g_quark_to_string(field->name));
+ BT_LOGD_STR("Putting field type.");
+ bt_put(field->type);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_structure_destroy_recursive(struct bt_object *obj)
+{
+ struct bt_ctf_field_type_common_structure *ft = (void *) obj;
+ uint64_t i;
+
+ if (!ft) {
+ return;
+ }
+
+ BT_LOGD("Destroying structure field type object: addr=%p", ft);
+
+ if (ft->fields) {
+ for (i = 0; i < ft->fields->len; i++) {
+ bt_ctf_field_type_common_structure_field_finalize(
+ BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
+ ft, i));
+ }
+
+ g_array_free(ft->fields, TRUE);
+ }
+
+ if (ft->field_name_to_index) {
+ g_hash_table_destroy(ft->field_name_to_index);
+ }
+
+ g_free(ft);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_array_destroy_recursive(struct bt_object *obj)
+{
+ struct bt_ctf_field_type_common_array *ft = (void *) obj;
+
+ if (!ft) {
+ return;
+ }
+
+ BT_LOGD("Destroying array field type object: addr=%p", ft);
+ BT_LOGD_STR("Putting element field type.");
+ bt_put(ft->element_ft);
+ g_free(ft);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_sequence_destroy_recursive(struct bt_object *obj)
+{
+ struct bt_ctf_field_type_common_sequence *ft = (void *) obj;
+
+ if (!ft) {
+ return;
+ }
+
+ BT_LOGD("Destroying sequence field type object: addr=%p", ft);
+ BT_LOGD_STR("Putting element field type.");
+ bt_put(ft->element_ft);
+ g_string_free(ft->length_field_name, TRUE);
+ BT_LOGD_STR("Putting length field path.");
+ bt_put(ft->length_field_path);
+ g_free(ft);
+}
+
+static
+void bt_ctf_field_type_common_variant_choice_finalize(
+ struct bt_ctf_field_type_common_variant_choice *choice)
+{
+ if (!choice) {
+ return;
+ }
+
+ BT_LOGD("Finalizing variant field type's choice: "
+ "addr=%p, field-ft-addr=%p, field-name=\"%s\"",
+ choice, choice->type, g_quark_to_string(choice->name));
+ BT_LOGD_STR("Putting field type.");
+ bt_put(choice->type);
+
+ if (choice->ranges) {
+ g_array_free(choice->ranges, TRUE);
+ }
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_variant_destroy_recursive(struct bt_object *obj)
+{
+ struct bt_ctf_field_type_common_variant *ft = (void *) obj;
+ uint64_t i;
+
+ if (!ft) {
+ return;
+ }
+
+ BT_LOGD("Destroying variant field type object: addr=%p", ft);
+
+ if (ft->choices) {
+ for (i = 0; i < ft->choices->len; i++) {
+ bt_ctf_field_type_common_variant_choice_finalize(
+ BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
+ ft, i));
+ }
+
+ g_array_free(ft->choices, TRUE);
+ }
+
+ if (ft->choice_name_to_index) {
+ g_hash_table_destroy(ft->choice_name_to_index);
+ }
+
+ if (ft->tag_name) {
+ g_string_free(ft->tag_name, TRUE);
+ }
+
+ BT_LOGD_STR("Putting tag field type.");
+ bt_put(ft->tag_ft);
+ BT_LOGD_STR("Putting tag field path.");
+ bt_put(ft->tag_field_path);
+ g_free(ft);
+}
+
+struct range_overlap_query {
+ union {
+ uint64_t _unsigned;
+ int64_t _signed;
+ } range_start;
+
+ union {
+ uint64_t _unsigned;
+ int64_t _signed;
+ } range_end;
+ int overlaps;
+ GQuark mapping_name;
+};
+
+static
+void check_ranges_overlap(gpointer element, gpointer query)
+{
+ struct bt_ctf_enumeration_mapping *mapping = element;
+ struct range_overlap_query *overlap_query = query;
+
+ if (mapping->range_start._signed <= overlap_query->range_end._signed
+ && overlap_query->range_start._signed <=
+ mapping->range_end._signed) {
+ overlap_query->overlaps = 1;
+ overlap_query->mapping_name = mapping->string;
+ }
+
+ overlap_query->overlaps |=
+ mapping->string == overlap_query->mapping_name;
+
+ if (overlap_query->overlaps) {
+ BT_LOGV("Overlapping enumeration field type mappings: "
+ "mapping-name=\"%s\", "
+ "mapping-a-range-start=%" PRId64 ", "
+ "mapping-a-range-end=%" PRId64 ", "
+ "mapping-b-range-start=%" PRId64 ", "
+ "mapping-b-range-end=%" PRId64,
+ g_quark_to_string(mapping->string),
+ mapping->range_start._signed,
+ mapping->range_end._signed,
+ overlap_query->range_start._signed,
+ overlap_query->range_end._signed);
+ }
+}
+
+static
+void check_ranges_overlap_unsigned(gpointer element, gpointer query)
+{
+ struct bt_ctf_enumeration_mapping *mapping = element;
+ struct range_overlap_query *overlap_query = query;
+
+ if (mapping->range_start._unsigned <= overlap_query->range_end._unsigned
+ && overlap_query->range_start._unsigned <=
+ mapping->range_end._unsigned) {
+ overlap_query->overlaps = 1;
+ overlap_query->mapping_name = mapping->string;
+ }
+
+ overlap_query->overlaps |=
+ mapping->string == overlap_query->mapping_name;
+
+ if (overlap_query->overlaps) {
+ BT_LOGW("Overlapping enumeration field type mappings: "
+ "mapping-name=\"%s\", "
+ "mapping-a-range-start=%" PRIu64 ", "
+ "mapping-a-range-end=%" PRIu64 ", "
+ "mapping-b-range-start=%" PRIu64 ", "
+ "mapping-b-range-end=%" PRIu64,
+ g_quark_to_string(mapping->string),
+ mapping->range_start._unsigned,
+ mapping->range_end._unsigned,
+ overlap_query->range_start._unsigned,
+ overlap_query->range_end._unsigned);
+ }
+}
+
+static
+gint compare_enumeration_mappings_signed(struct bt_ctf_enumeration_mapping **a,
+ struct bt_ctf_enumeration_mapping **b)
+{
+ return ((*a)->range_start._signed < (*b)->range_start._signed) ? -1 : 1;
+}
+
+static
+gint compare_enumeration_mappings_unsigned(struct bt_ctf_enumeration_mapping **a,
+ struct bt_ctf_enumeration_mapping **b)
+{
+ return ((*a)->range_start._unsigned < (*b)->range_start._unsigned) ? -1 : 1;
+}
+
+static
+int add_structure_variant_member(GArray *members,
+ GHashTable *field_name_to_index,
+ struct bt_ctf_field_type_common *field_type, const char *field_name,
+ bool is_variant)
+{
+ int ret = 0;
+ GQuark name_quark = g_quark_from_string(field_name);
+ struct bt_ctf_field_type_common **member_ft;
+ GQuark *member_name;
+
+ /* Make sure structure does not contain a field of the same name */
+ if (g_hash_table_lookup_extended(field_name_to_index,
+ GUINT_TO_POINTER(name_quark), NULL, NULL)) {
+ BT_LOGW("Structure or variant field type already contains a field type with this name: "
+ "field-name=\"%s\"", field_name);
+ ret = -1;
+ goto end;
+ }
+
+ g_array_set_size(members, members->len + 1);
+
+ if (is_variant) {
+ struct bt_ctf_field_type_common_variant_choice *choice =
+ &g_array_index(members,
+ struct bt_ctf_field_type_common_variant_choice,
+ members->len - 1);
+
+ member_ft = &choice->type;
+ member_name = &choice->name;
+ BT_ASSERT(!choice->ranges);
+ choice->ranges = g_array_new(FALSE, TRUE,
+ sizeof(struct bt_ctf_field_type_common_variant_choice_range));
+ BT_ASSERT(choice->ranges);
+ } else {
+ struct bt_ctf_field_type_common_structure_field *field =
+ &g_array_index(members,
+ struct bt_ctf_field_type_common_structure_field,
+ members->len - 1);
+
+ member_ft = &field->type;
+ member_name = &field->name;
+ }
+
+ *member_name = name_quark;
+ *member_ft = bt_get(field_type);
+ g_hash_table_insert(field_name_to_index,
+ GUINT_TO_POINTER(name_quark),
+ GUINT_TO_POINTER(members->len - 1));
+ BT_LOGV("Added structure/variant field type member: member-ft-addr=%p, "
+ "member-name=\"%s\"", field_type, field_name);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_validate(struct bt_ctf_field_type_common *ft)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (int_ft->mapped_clock_class && int_ft->is_signed) {
+ BT_LOGW("Invalid integer field type: cannot be signed and have a mapped clock class: "
+ "ft-addr=%p, clock-class-addr=%p, clock-class-name=\"%s\"",
+ ft, int_ft->mapped_clock_class,
+ bt_ctf_clock_class_get_name(int_ft->mapped_clock_class));
+ ret = -1;
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
+static
+void bt_ctf_field_type_enum_iter_destroy(struct bt_object *obj)
+{
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter =
+ container_of(obj,
+ struct bt_ctf_field_type_enumeration_mapping_iterator,
+ base);
+
+ BT_LOGD("Destroying enumeration field type mapping iterator: addr=%p",
+ obj);
+ BT_LOGD_STR("Putting parent enumeration field type.");
+ bt_put(iter->enumeration_ft);
+ g_free(iter);
+}
+
+static
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_common_enumeration_find_mappings_type(
+ struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_field_type_enumeration_mapping_iterator_type iterator_type)
+{
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_ENUM,
+ "Field type");
+ iter = g_new0(struct bt_ctf_field_type_enumeration_mapping_iterator, 1);
+ if (!iter) {
+ BT_LOGE_STR("Failed to allocate one enumeration field type mapping.");
+ goto end;
+ }
+
+ bt_object_init_shared(&iter->base, bt_ctf_field_type_enum_iter_destroy);
+ iter->enumeration_ft = bt_get(ft);
+ iter->index = -1;
+ iter->type = iterator_type;
+
+end:
+ return iter;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_common_enumeration_find_mappings_by_name(
+ struct bt_ctf_field_type_common *ft, const char *name)
+{
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
+
+ iter = bt_ctf_field_type_common_enumeration_find_mappings_type(
+ ft, CTF_ITERATOR_BY_NAME);
+ if (!iter) {
+ BT_LOGW("Cannot create enumeration field type mapping iterator: "
+ "ft-addr=%p, mapping-name=\"%s\"", ft, name);
+ goto error;
+ }
+
+ iter->u.name_quark = g_quark_try_string(name);
+ if (!iter->u.name_quark) {
+ /*
+ * No results are possible, set the iterator's position at the
+ * end.
+ */
+ iter->index = iter->enumeration_ft->entries->len;
+ }
+
+ return iter;
+
+error:
+ bt_put(iter);
+ return NULL;
+}
+
+static
+struct bt_ctf_enumeration_mapping *bt_ctf_field_type_common_enumeration_get_mapping_by_index(
+ struct bt_ctf_field_type_common *ft, uint64_t index)
+{
+ struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
+ struct bt_ctf_enumeration_mapping *mapping = NULL;
+
+ if (index >= enum_ft->entries->len) {
+ BT_LOGW("Invalid parameter: index is out of bounds: "
+ "addr=%p, index=%" PRIu64 ", count=%u",
+ ft, index, enum_ft->entries->len);
+ goto end;
+ }
+
+ mapping = g_ptr_array_index(enum_ft->entries, index);
+
+end:
+ return mapping;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_enumeration_mapping_iterator_next(
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter)
+{
+ struct bt_ctf_field_type_common_enumeration *enum_ft = iter->enumeration_ft;
+ int i, ret = 0, len;
+
+ BT_ASSERT_PRE_NON_NULL(iter, "Enumeration field type mapping iterator");
+ len = enum_ft->entries->len;
+ for (i = iter->index + 1; i < len; i++) {
+ struct bt_ctf_enumeration_mapping *mapping =
+ bt_ctf_field_type_common_enumeration_get_mapping_by_index(
+ BT_CTF_TO_COMMON(enum_ft), i);
+
+ switch (iter->type) {
+ case CTF_ITERATOR_BY_NAME:
+ if (mapping->string == iter->u.name_quark) {
+ iter->index = i;
+ goto end;
+ }
+ break;
+ case CTF_ITERATOR_BY_SIGNED_VALUE:
+ {
+ int64_t value = iter->u.signed_value;
+
+ if (value >= mapping->range_start._signed &&
+ value <= mapping->range_end._signed) {
+ iter->index = i;
+ goto end;
+ }
+ break;
+ }
+ case CTF_ITERATOR_BY_UNSIGNED_VALUE:
+ {
+ uint64_t value = iter->u.unsigned_value;
+
+ if (value >= mapping->range_start._unsigned &&
+ value <= mapping->range_end._unsigned) {
+ iter->index = i;
+ goto end;
+ }
+ break;
+ }
+ default:
+ BT_LOGF("Invalid enumeration field type mapping iterator type: "
+ "type=%d", iter->type);
+ abort();
+ }
+ }
+
+ ret = -1;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_common_enumeration_signed_find_mappings_by_value(
+ struct bt_ctf_field_type_common *ft, int64_t value)
+{
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
+
+ iter = bt_ctf_field_type_common_enumeration_find_mappings_type(
+ ft, CTF_ITERATOR_BY_SIGNED_VALUE);
+ if (!iter) {
+ BT_LOGW("Cannot create enumeration field type mapping iterator: "
+ "ft-addr=%p, value=%" PRId64, ft, value);
+ goto error;
+ }
+
+ if (bt_ctf_field_type_common_integer_is_signed(
+ BT_CTF_TO_COMMON(iter->enumeration_ft->container_ft)) != 1) {
+ BT_LOGW("Invalid parameter: enumeration field type is unsigned: "
+ "enum-ft-addr=%p, int-ft-addr=%p",
+ ft, iter->enumeration_ft->container_ft);
+ goto error;
+ }
+
+ iter->u.signed_value = value;
+ return iter;
+
+error:
+ bt_put(iter);
+ return NULL;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_common_enumeration_unsigned_find_mappings_by_value(
+ struct bt_ctf_field_type_common *ft, uint64_t value)
+{
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
+
+ iter = bt_ctf_field_type_common_enumeration_find_mappings_type(
+ ft, CTF_ITERATOR_BY_UNSIGNED_VALUE);
+ if (!iter) {
+ BT_LOGW("Cannot create enumeration field type mapping iterator: "
+ "ft-addr=%p, value=%" PRIu64, ft, value);
+ goto error;
+ }
+
+ if (bt_ctf_field_type_common_integer_is_signed(
+ BT_CTF_TO_COMMON(iter->enumeration_ft->container_ft)) != 0) {
+ BT_LOGW("Invalid parameter: enumeration field type is signed: "
+ "enum-ft-addr=%p, int-ft-addr=%p",
+ ft, iter->enumeration_ft->container_ft);
+ goto error;
+ }
+
+ iter->u.unsigned_value = value;
+ return iter;
+
+error:
+ bt_put(iter);
+ return NULL;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_enumeration_mapping_iterator_signed_get(
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
+ const char **mapping_name, int64_t *range_begin,
+ int64_t *range_end)
+{
+ BT_ASSERT_PRE_NON_NULL(iter, "Enumeration field type mapping iterator");
+ BT_ASSERT_PRE(iter->index != -1,
+ "Invalid enumeration field type mapping iterator access: "
+ "addr=%p, position=-1", iter);
+ return bt_ctf_field_type_common_enumeration_signed_get_mapping_by_index(
+ (void *) iter->enumeration_ft, iter->index,
+ mapping_name, range_begin, range_end);
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_enumeration_mapping_iterator_unsigned_get(
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
+ const char **mapping_name, uint64_t *range_begin,
+ uint64_t *range_end)
+{
+ BT_ASSERT_PRE_NON_NULL(iter, "Enumeration field type mapping iterator");
+ BT_ASSERT_PRE(iter->index != -1,
+ "Invalid enumeration field type mapping iterator access: "
+ "addr=%p, position=-1", iter);
+ return bt_ctf_field_type_common_enumeration_unsigned_get_mapping_by_index(
+ (void *) iter->enumeration_ft, iter->index,
+ mapping_name, range_begin, range_end);
+}
+
+/*
+ * Note: This algorithm is O(n^2) vs number of enumeration mappings.
+ * Only used when freezing an enumeration.
+ */
+static
+void bt_ctf_field_type_common_enumeration_set_range_overlap(
+ struct bt_ctf_field_type_common_enumeration *ft)
+{
+ int64_t i, j, len;
+ int is_signed;
+
+ BT_LOGV("Setting enumeration field type's overlap flag: addr=%p",
+ ft);
+ len = ft->entries->len;
+ is_signed = bt_ctf_field_type_common_integer_is_signed(
+ BT_CTF_TO_COMMON(ft->container_ft));
+
+ for (i = 0; i < len; i++) {
+ for (j = i + 1; j < len; j++) {
+ struct bt_ctf_enumeration_mapping *mapping[2];
+
+ mapping[0] = bt_ctf_field_type_common_enumeration_get_mapping_by_index(
+ BT_CTF_TO_COMMON(ft), i);
+ mapping[1] = bt_ctf_field_type_common_enumeration_get_mapping_by_index(
+ BT_CTF_TO_COMMON(ft), j);
+ if (is_signed) {
+ if (mapping[0]->range_start._signed
+ <= mapping[1]->range_end._signed
+ && mapping[0]->range_end._signed
+ >= mapping[1]->range_start._signed) {
+ ft->has_overlapping_ranges = BT_TRUE;
+ goto end;
+ }
+ } else {
+ if (mapping[0]->range_start._unsigned
+ <= mapping[1]->range_end._unsigned
+ && mapping[0]->range_end._unsigned
+ >= mapping[1]->range_start._unsigned) {
+ ft->has_overlapping_ranges = BT_TRUE;
+ goto end;
+ }
+ }
+ }
+ }
+
+end:
+ if (ft->has_overlapping_ranges) {
+ BT_LOGV_STR("Enumeration field type has overlapping ranges.");
+ } else {
+ BT_LOGV_STR("Enumeration field type has no overlapping ranges.");
+ }
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_enumeration_validate_recursive(
+ struct bt_ctf_field_type_common *ft)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
+
+ ret = bt_ctf_field_type_common_integer_validate(
+ BT_CTF_TO_COMMON(enum_ft->container_ft));
+ if (ret) {
+ BT_LOGW("Invalid enumeration field type: container type is invalid: "
+ "enum-ft-addr=%p, int-ft-addr=%p",
+ ft, enum_ft->container_ft);
+ goto end;
+ }
+
+ /* Ensure enum has entries */
+ if (enum_ft->entries->len == 0) {
+ BT_LOGW("Invalid enumeration field type: no entries: "
+ "addr=%p", ft);
+ ret = -1;
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_sequence_validate_recursive(
+ struct bt_ctf_field_type_common *ft)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
+
+ /* Length field name should be set at this point */
+ if (seq_ft->length_field_name->len == 0) {
+ BT_LOGW("Invalid sequence field type: no length field name: "
+ "addr=%p", ft);
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_field_type_common_validate(seq_ft->element_ft);
+ if (ret) {
+ BT_LOGW("Invalid sequence field type: invalid element field type: "
+ "seq-ft-addr=%p, element-ft-add=%p",
+ ft, seq_ft->element_ft);
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_array_validate_recursive(
+ struct bt_ctf_field_type_common *ft)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
+
+ ret = bt_ctf_field_type_common_validate(array_ft->element_ft);
+ if (ret) {
+ BT_LOGW("Invalid array field type: invalid element field type: "
+ "array-ft-addr=%p, element-ft-add=%p",
+ ft, array_ft->element_ft);
+ }
+
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_structure_validate_recursive(
+ struct bt_ctf_field_type_common *ft)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common *child_ft = NULL;
+ int64_t field_count =
+ bt_ctf_field_type_common_structure_get_field_count(ft);
+ int64_t i;
+
+ BT_ASSERT(field_count >= 0);
+
+ for (i = 0; i < field_count; ++i) {
+ const char *field_name;
+
+ ret = bt_ctf_field_type_common_structure_borrow_field_by_index(ft,
+ &field_name, &child_ft, i);
+ BT_ASSERT(ret == 0);
+ ret = bt_ctf_field_type_common_validate(child_ft);
+ if (ret) {
+ BT_LOGW("Invalid structure field type: "
+ "a contained field type is invalid: "
+ "struct-ft-addr=%p, field-ft-addr=%p, "
+ "field-name=\"%s\", field-index=%" PRId64,
+ ft, child_ft, field_name, i);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
+static
+bt_bool bt_ctf_field_type_common_enumeration_has_overlapping_ranges(
+ struct bt_ctf_field_type_common_enumeration *enum_ft)
+{
+ if (!enum_ft->common.frozen) {
+ bt_ctf_field_type_common_enumeration_set_range_overlap(enum_ft);
+ }
+
+ return enum_ft->has_overlapping_ranges;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_validate_recursive(
+ struct bt_ctf_field_type_common *ft)
+{
+ int ret = 0;
+ int64_t field_count;
+ struct bt_ctf_field_type_common *child_ft = NULL;
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+ int64_t i;
+
+ if (var_ft->tag_name->len == 0) {
+ BT_LOGW("Invalid variant field type: no tag field name: "
+ "addr=%p", ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (!var_ft->tag_ft) {
+ BT_LOGW("Invalid variant field type: no tag field type: "
+ "addr=%p, tag-field-name=\"%s\"", var_ft,
+ var_ft->tag_name->str);
+ ret = -1;
+ goto end;
+ }
+
+ if (bt_ctf_field_type_common_enumeration_has_overlapping_ranges(var_ft->tag_ft)) {
+ BT_LOGW("Invalid variant field type: enumeration tag field type has overlapping ranges: "
+ "variant-ft-addr=%p, tag-field-name=\"%s\", "
+ "enum-ft-addr=%p", ft, var_ft->tag_name->str,
+ var_ft->tag_ft);
+ ret = -1;
+ goto end;
+ }
+
+ /*
+ * It is valid to have a variant field type which does not have
+ * the fields corresponding to each label in the associated
+ * enumeration.
+ *
+ * It is also valid to have variant field type fields which
+ * cannot be selected because the variant field type tag has no
+ * mapping named as such. This scenario, while not ideal, cannot
+ * cause any error.
+ *
+ * If a non-existing field happens to be selected by an
+ * enumeration while reading a variant field, an error will be
+ * generated at that point (while reading the stream).
+ */
+ field_count = bt_ctf_field_type_common_variant_get_field_count(ft);
+ if (field_count < 0) {
+ BT_LOGW("Invalid variant field type: no fields: "
+ "addr=%p, tag-field-name=\"%s\"",
+ ft, var_ft->tag_name->str);
+ ret = -1;
+ goto end;
+ }
+
+ for (i = 0; i < field_count; ++i) {
+ const char *field_name;
+
+ ret = bt_ctf_field_type_common_variant_borrow_field_by_index(ft,
+ &field_name, &child_ft, i);
+ BT_ASSERT(ret == 0);
+ ret = bt_ctf_field_type_common_validate(child_ft);
+ if (ret) {
+ BT_LOGW("Invalid variant field type: "
+ "a contained field type is invalid: "
+ "variant-ft-addr=%p, tag-field-name=\"%s\", "
+ "field-ft-addr=%p, field-name=\"%s\", "
+ "field-index=%" PRId64,
+ ft, var_ft->tag_name->str, child_ft,
+ field_name, i);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
+/*
+ * This function validates a given field type without considering
+ * where this field type is located. It only validates the properties
+ * of the given field type and the properties of its children if
+ * applicable.
+ */
+BT_HIDDEN
+int bt_ctf_field_type_common_validate(struct bt_ctf_field_type_common *ft)
+{
+ int ret = 0;
+
+ BT_ASSERT(ft);
+
+ if (ft->valid) {
+ /* Already marked as valid */
+ goto end;
+ }
+
+ if (ft->methods->validate) {
+ ret = ft->methods->validate(ft);
+ }
+
+ if (ret == 0 && ft->frozen) {
+ /* Field type is valid */
+ BT_LOGV("Marking field type as valid: addr=%p", ft);
+ ft->valid = 1;
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_get_size(struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_INTEGER,
+ "Field type");
+ return (int) int_ft->size;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_field_type_common_integer_is_signed(struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_INTEGER,
+ "Field type");
+ return int_ft->is_signed;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_set_is_signed(struct bt_ctf_field_type_common *ft,
+ bt_bool is_signed)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid parameter: field type is not an integer field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ int_ft->is_signed = !!is_signed;
+ BT_LOGV("Set integer field type's signedness: addr=%p, is-signed=%d",
+ ft, is_signed);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_set_size(struct bt_ctf_field_type_common *ft,
+ unsigned int size)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid parameter: field type is not an integer field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ if (size == 0 || size > 64) {
+ BT_LOGW("Invalid parameter: size must be between 1 and 64: "
+ "addr=%p, size=%u", ft, size);
+ ret = -1;
+ goto end;
+ }
+
+ int_ft->size = size;
+ BT_LOGV("Set integer field type's size: addr=%p, size=%u",
+ ft, size);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+enum bt_ctf_integer_base bt_ctf_field_type_common_integer_get_base(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_INTEGER,
+ "Field type");
+ return int_ft->base;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_set_base(struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_integer_base base)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid parameter: field type is not an integer field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ switch (base) {
+ case BT_CTF_INTEGER_BASE_UNSPECIFIED:
+ case BT_CTF_INTEGER_BASE_BINARY:
+ case BT_CTF_INTEGER_BASE_OCTAL:
+ case BT_CTF_INTEGER_BASE_DECIMAL:
+ case BT_CTF_INTEGER_BASE_HEXADECIMAL:
+ {
+ int_ft->base = base;
+ break;
+ }
+ default:
+ BT_LOGW("Invalid parameter: unknown integer field type base: "
+ "addr=%p, base=%d", ft, base);
+ ret = -1;
+ }
+
+ BT_LOGV("Set integer field type's base: addr=%p, base=%s",
+ ft, bt_ctf_integer_base_string(base));
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+enum bt_ctf_string_encoding bt_ctf_field_type_common_integer_get_encoding(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_INTEGER,
+ "Field type");
+ return int_ft->encoding;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_set_encoding(struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_string_encoding encoding)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid parameter: field type is not an integer field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ if (encoding != BT_CTF_STRING_ENCODING_UTF8 &&
+ encoding != BT_CTF_STRING_ENCODING_ASCII &&
+ encoding != BT_CTF_STRING_ENCODING_NONE) {
+ BT_LOGW("Invalid parameter: unknown string encoding: "
+ "addr=%p, encoding=%d", ft, encoding);
+ ret = -1;
+ goto end;
+ }
+
+ int_ft->encoding = encoding;
+ BT_LOGV("Set integer field type's encoding: addr=%p, encoding=%s",
+ ft, bt_ctf_string_encoding_string(encoding));
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+struct bt_ctf_clock_class *bt_ctf_field_type_common_integer_borrow_mapped_clock_class(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_INTEGER,
+ "Field type");
+ return int_ft->mapped_clock_class;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_set_mapped_clock_class_no_check_frozen(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_clock_class *clock_class)
+{
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+ int ret = 0;
+
+ if (!clock_class) {
+ BT_LOGW_STR("Invalid parameter: clock class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid parameter: field type is not an integer field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ goto end;
+ }
+
+ if (!bt_ctf_clock_class_is_valid(clock_class)) {
+ BT_LOGW("Invalid parameter: clock class is invalid: ft-addr=%p"
+ "clock-class-addr=%p, clock-class-name=\"%s\"",
+ ft, clock_class,
+ bt_ctf_clock_class_get_name(clock_class));
+ ret = -1;
+ goto end;
+ }
+
+ bt_put(int_ft->mapped_clock_class);
+ int_ft->mapped_clock_class = bt_get(clock_class);
+ BT_LOGV("Set integer field type's mapped clock class: ft-addr=%p, "
+ "clock-class-addr=%p, clock-class-name=\"%s\"",
+ ft, clock_class, bt_ctf_clock_class_get_name(clock_class));
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_set_mapped_clock_class(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_clock_class *clock_class)
+{
+ int ret = 0;
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_field_type_common_integer_set_mapped_clock_class_no_check_frozen(
+ ft, clock_class);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_enumeration_signed_get_mapping_by_index(
+ struct bt_ctf_field_type_common *ft, uint64_t index,
+ const char **mapping_name, int64_t *range_begin,
+ int64_t *range_end)
+{
+ int ret = 0;
+ struct bt_ctf_enumeration_mapping *mapping;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft,
+ BT_CTF_FIELD_TYPE_ID_ENUM, "Field type");
+ mapping = bt_ctf_field_type_common_enumeration_get_mapping_by_index(ft,
+ index);
+ if (!mapping) {
+ /* bt_ctf_field_type_common_enumeration_get_mapping_by_index() logs errors */
+ ret = -1;
+ goto end;
+ }
+
+ if (mapping_name) {
+ *mapping_name = g_quark_to_string(mapping->string);
+ BT_ASSERT(*mapping_name);
+ }
+
+ if (range_begin) {
+ *range_begin = mapping->range_start._signed;
+ }
+
+ if (range_end) {
+ *range_end = mapping->range_end._signed;
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_enumeration_unsigned_get_mapping_by_index(
+ struct bt_ctf_field_type_common *ft, uint64_t index,
+ const char **mapping_name, uint64_t *range_begin,
+ uint64_t *range_end)
+{
+ int ret = 0;
+ struct bt_ctf_enumeration_mapping *mapping;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_ENUM, "Field type");
+ mapping = bt_ctf_field_type_common_enumeration_get_mapping_by_index(
+ ft, index);
+ if (!mapping) {
+ /* bt_ctf_field_type_common_enumeration_get_mapping_by_index() reports any error */
+ ret = -1;
+ goto end;
+ }
+
+ if (mapping_name) {
+ *mapping_name = g_quark_to_string(mapping->string);
+ BT_ASSERT(*mapping_name);
+ }
+
+ if (range_begin) {
+ *range_begin = mapping->range_start._unsigned;
+ }
+
+ if (range_end) {
+ *range_end = mapping->range_end._unsigned;
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_enumeration_borrow_container_field_type(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_ENUM, "Field type");
+ return BT_CTF_TO_COMMON(enum_ft->container_ft);
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_enumeration_signed_add_mapping(
+ struct bt_ctf_field_type_common *ft, const char *string,
+ int64_t range_start, int64_t range_end)
+{
+ int ret = 0;
+ GQuark mapping_name;
+ struct bt_ctf_enumeration_mapping *mapping;
+ struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
+ char *escaped_string;
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!string) {
+ BT_LOGW_STR("Invalid parameter: string is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_ENUM) {
+ BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ if (range_end < range_start) {
+ BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
+ "addr=%p, range-start=%" PRId64 ", range-end=%" PRId64,
+ ft, range_start, range_end);
+ ret = -1;
+ goto end;
+ }
+
+ if (strlen(string) == 0) {
+ BT_LOGW("Invalid parameter: mapping name is an empty string: "
+ "enum-ft-addr=%p, mapping-name-addr=%p", ft,
+ string);
+ ret = -1;
+ goto end;
+ }
+
+ escaped_string = g_strescape(string, NULL);
+ if (!escaped_string) {
+ BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
+ "mapping-name-addr=%p, mapping-name=\"%s\"",
+ ft, string, string);
+ ret = -1;
+ goto end;
+ }
+
+ mapping = g_new(struct bt_ctf_enumeration_mapping, 1);
+ if (!mapping) {
+ BT_LOGE_STR("Failed to allocate one enumeration mapping.");
+ ret = -1;
+ goto error_free;
+ }
+ mapping_name = g_quark_from_string(escaped_string);
+ *mapping = (struct bt_ctf_enumeration_mapping) {
+ .range_start._signed = range_start,
+ .range_end._signed = range_end,
+ .string = mapping_name,
+ };
+ g_ptr_array_add(enum_ft->entries, mapping);
+ g_ptr_array_sort(enum_ft->entries,
+ (GCompareFunc) compare_enumeration_mappings_signed);
+ BT_LOGV("Added mapping to signed enumeration field type: addr=%p, "
+ "name=\"%s\", range-start=%" PRId64 ", "
+ "range-end=%" PRId64,
+ ft, string, range_start, range_end);
+
+error_free:
+ free(escaped_string);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_enumeration_unsigned_add_mapping(
+ struct bt_ctf_field_type_common *ft, const char *string,
+ uint64_t range_start, uint64_t range_end)
+{
+ int ret = 0;
+ GQuark mapping_name;
+ struct bt_ctf_enumeration_mapping *mapping;
+ struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
+ char *escaped_string;
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!string) {
+ BT_LOGW_STR("Invalid parameter: string is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_ENUM) {
+ BT_LOGW("Invalid parameter: field type is not an enumeration field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ if (range_end < range_start) {
+ BT_LOGW("Invalid parameter: range's end is lesser than range's start: "
+ "addr=%p, range-start=%" PRIu64 ", range-end=%" PRIu64,
+ ft, range_start, range_end);
+ ret = -1;
+ goto end;
+ }
+
+ if (strlen(string) == 0) {
+ BT_LOGW("Invalid parameter: mapping name is an empty string: "
+ "enum-ft-addr=%p, mapping-name-addr=%p", ft,
+ string);
+ ret = -1;
+ goto end;
+ }
+
+ escaped_string = g_strescape(string, NULL);
+ if (!escaped_string) {
+ BT_LOGE("Cannot escape mapping name: enum-ft-addr=%p, "
+ "mapping-name-addr=%p, mapping-name=\"%s\"",
+ ft, string, string);
+ ret = -1;
+ goto end;
+ }
+
+ mapping = g_new(struct bt_ctf_enumeration_mapping, 1);
+ if (!mapping) {
+ BT_LOGE_STR("Failed to allocate one enumeration mapping.");
+ ret = -1;
+ goto error_free;
+ }
+ mapping_name = g_quark_from_string(escaped_string);
+ *mapping = (struct bt_ctf_enumeration_mapping) {
+ .range_start._unsigned = range_start,
+ .range_end._unsigned = range_end,
+ .string = mapping_name,
+ };
+ g_ptr_array_add(enum_ft->entries, mapping);
+ g_ptr_array_sort(enum_ft->entries,
+ (GCompareFunc) compare_enumeration_mappings_unsigned);
+ BT_LOGV("Added mapping to unsigned enumeration field type: addr=%p, "
+ "name=\"%s\", range-start=%" PRIu64 ", "
+ "range-end=%" PRIu64,
+ ft, string, range_start, range_end);
+
+error_free:
+ free(escaped_string);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int64_t bt_ctf_field_type_common_enumeration_get_mapping_count(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_ENUM, "Field type");
+ return (int64_t) enum_ft->entries->len;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_floating_point_get_exponent_digits(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_FLOAT,
+ "Field type");
+ return (int) flt_ft->exp_dig;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_floating_point_set_exponent_digits(
+ struct bt_ctf_field_type_common *ft,
+ unsigned int exponent_digits)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_FLOAT) {
+ BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
+ (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
+ (exponent_digits !=
+ sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
+ BT_LOGW("Invalid parameter: invalid exponent size: "
+ "addr=%p, exp-size=%u", ft, exponent_digits);
+ ret = -1;
+ goto end;
+ }
+
+ flt_ft->exp_dig = exponent_digits;
+ BT_LOGV("Set floating point number field type's exponent size: addr=%p, "
+ "exp-size=%u", ft, exponent_digits);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_floating_point_get_mantissa_digits(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_FLOAT,
+ "Field type");
+ return (int) flt_ft->mant_dig;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_floating_point_set_mantissa_digits(
+ struct bt_ctf_field_type_common *ft, unsigned int mantissa_digits)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_FLOAT) {
+ BT_LOGW("Invalid parameter: field type is not a floating point number field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ if ((mantissa_digits != FLT_MANT_DIG) &&
+ (mantissa_digits != DBL_MANT_DIG) &&
+ (mantissa_digits != LDBL_MANT_DIG)) {
+ BT_LOGW("Invalid parameter: invalid mantissa size: "
+ "addr=%p, mant-size=%u", ft, mantissa_digits);
+ ret = -1;
+ goto end;
+ }
+
+ flt_ft->mant_dig = mantissa_digits;
+ BT_LOGV("Set floating point number field type's mantissa size: addr=%p, "
+ "mant-size=%u", ft, mantissa_digits);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_structure_replace_field(
+ struct bt_ctf_field_type_common *ft,
+ const char *field_name,
+ struct bt_ctf_field_type_common *field_type)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
+ GQuark name_quark;
+ uint64_t i;
+
+ BT_ASSERT(ft);
+ BT_ASSERT(field_name);
+ BT_ASSERT(field_type);
+ BT_ASSERT(ft->id == BT_CTF_FIELD_TYPE_ID_STRUCT);
+ name_quark = g_quark_from_string(field_name);
+
+ for (i = 0; i < struct_ft->fields->len; i++) {
+ struct bt_ctf_field_type_common_structure_field *field =
+ BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(ft, i);
+
+ if (field->name == name_quark) {
+ bt_put(field->type);
+ field->type = bt_get(field_type);
+ }
+ }
+
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_structure_add_field(struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *field_type,
+ const char *field_name)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
+
+ /*
+ * TODO: check that `field_type` does not contain `type`,
+ * recursively.
+ */
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!field_name) {
+ BT_LOGW_STR("Invalid parameter: field name is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_STRUCT) {
+ BT_LOGW("Invalid parameter: field type is not a structure field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ if (ft == field_type) {
+ BT_LOGW("Invalid parameter: structure field type and field type to add are the same: "
+ "addr=%p", ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (add_structure_variant_member(struct_ft->fields,
+ struct_ft->field_name_to_index, field_type, field_name,
+ false)) {
+ BT_LOGW("Cannot add field to structure field type: "
+ "struct-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
+ ft, field_type, field_name);
+ ret = -1;
+ goto end;
+ }
+
+ BT_LOGV("Added structure field type field: struct-ft-addr=%p, "
+ "field-ft-addr=%p, field-name=\"%s\"", ft,
+ field_type, field_name);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int64_t bt_ctf_field_type_common_structure_get_field_count(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_STRUCT,
+ "Field type");
+ return (int64_t) struct_ft->fields->len;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_structure_borrow_field_by_index(
+ struct bt_ctf_field_type_common *ft,
+ const char **field_name,
+ struct bt_ctf_field_type_common **field_type, uint64_t index)
+{
+ struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
+ struct bt_ctf_field_type_common_structure_field *field;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_STRUCT,
+ "Field type");
+ BT_ASSERT_PRE(index < struct_ft->fields->len,
+ "Index is out of bounds: index=%" PRIu64 ", "
+ "count=%u, ft-addr=%p",
+ index, struct_ft->fields->len, ft);
+ field = BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(struct_ft, index);
+
+ if (field_type) {
+ *field_type = field->type;
+ }
+
+ if (field_name) {
+ *field_name = g_quark_to_string(field->name);
+ BT_ASSERT(*field_name);
+ }
+
+ return 0;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_structure_borrow_field_type_by_name(
+ struct bt_ctf_field_type_common *ft, const char *name)
+{
+ size_t index;
+ GQuark name_quark;
+ struct bt_ctf_field_type_common_structure_field *field;
+ struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
+ struct bt_ctf_field_type_common *field_type = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_STRUCT,
+ "Field type");
+ name_quark = g_quark_try_string(name);
+ if (!name_quark) {
+ BT_LOGV("No such structure field type field name: "
+ "ft-addr=%p, field-name=\"%s\"",
+ ft, name);
+ goto end;
+ }
+
+ if (!g_hash_table_lookup_extended(struct_ft->field_name_to_index,
+ GUINT_TO_POINTER(name_quark), NULL, (gpointer *) &index)) {
+ BT_LOGV("No such structure field type field name: "
+ "ft-addr=%p, field-name=\"%s\"",
+ ft, name);
+ goto end;
+ }
+
+ field = BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(ft, index);
+ field_type = field->type;
+
+end:
+ return field_type;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_variant_borrow_tag_field_type(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+ struct bt_ctf_field_type_common *tag_ft = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
+ "Field type");
+
+ if (!var_ft->tag_ft) {
+ BT_LOGV("Variant field type has no tag field type: "
+ "addr=%p", ft);
+ goto end;
+ }
+
+ tag_ft = BT_CTF_TO_COMMON(var_ft->tag_ft);
+
+end:
+ return tag_ft;
+}
+
+BT_HIDDEN
+const char *bt_ctf_field_type_common_variant_get_tag_name(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+ const char *tag_name = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
+ "Field type");
+
+ if (var_ft->tag_name->len == 0) {
+ BT_LOGV("Variant field type has no tag field name: "
+ "addr=%p", ft);
+ goto end;
+ }
+
+ tag_name = var_ft->tag_name->str;
+
+end:
+ return tag_name;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_set_tag_name(
+ struct bt_ctf_field_type_common *ft, const char *name)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
+ BT_LOGW("Invalid parameter: field type is not a variant field type: "
+ "addr=%p, ft-id=%s", ft, bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ if (!bt_ctf_identifier_is_valid(name)) {
+ BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
+ "variant-ft-addr=%p, tag-field-name=\"%s\"",
+ ft, name);
+ ret = -1;
+ goto end;
+ }
+
+ g_string_assign(var_ft->tag_name, name);
+ BT_LOGV("Set variant field type's tag field name: addr=%p, "
+ "tag-field-name=\"%s\"", ft, name);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_add_field(struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *field_type,
+ const char *field_name)
+{
+ size_t i;
+ int ret = 0;
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+ GQuark field_name_quark = g_quark_from_string(field_name);
+
+ /*
+ * TODO: check that `field_type` does not contain `type`,
+ * recursively.
+ */
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
+ BT_LOGW("Invalid parameter: field type is not a variant field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ if (ft == field_type) {
+ BT_LOGW("Invalid parameter: variant field type and field type to add are the same: "
+ "addr=%p", ft);
+ ret = -1;
+ goto end;
+ }
+
+ /* The user has explicitly provided a tag; validate against it. */
+ if (var_ft->tag_ft) {
+ int name_found = 0;
+
+ /* Make sure this name is present in the enum tag */
+ for (i = 0; i < var_ft->tag_ft->entries->len; i++) {
+ struct bt_ctf_enumeration_mapping *mapping =
+ g_ptr_array_index(var_ft->tag_ft->entries, i);
+
+ if (mapping->string == field_name_quark) {
+ name_found = 1;
+ break;
+ }
+ }
+
+ if (!name_found) {
+ /* Validation failed */
+ BT_LOGW("Invalid parameter: field name does not name a tag field type's mapping: "
+ "variant-ft-addr=%p, tag-ft-addr=%p, "
+ "tag-field-name=\"%s\""
+ "field-ft-addr=%p, field-name=\"%s\"",
+ ft, var_ft->tag_ft, var_ft->tag_name->str,
+ field_type, field_name);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ if (add_structure_variant_member(var_ft->choices,
+ var_ft->choice_name_to_index, field_type,
+ field_name, true)) {
+ BT_LOGW("Cannot add field to variant field type: "
+ "variant-ft-addr=%p, field-ft-addr=%p, field-name=\"%s\"",
+ ft, field_type, field_name);
+ ret = -1;
+ goto end;
+ }
+
+ BT_LOGV("Added variant field type field: variant-ft-addr=%p, "
+ "field-ft-addr=%p, field-name=\"%s\"", ft,
+ field_type, field_name);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_variant_borrow_field_type_by_name(
+ struct bt_ctf_field_type_common *ft,
+ const char *field_name)
+{
+ size_t index;
+ GQuark name_quark;
+ struct bt_ctf_field_type_common_variant_choice *choice;
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+ struct bt_ctf_field_type_common *field_type = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_NON_NULL(field_name, "Name");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
+ "Field type");
+ name_quark = g_quark_try_string(field_name);
+ if (!name_quark) {
+ BT_LOGV("No such variant field type field name: "
+ "ft-addr=%p, field-name=\"%s\"",
+ ft, field_name);
+ goto end;
+ }
+
+ if (!g_hash_table_lookup_extended(var_ft->choice_name_to_index,
+ GUINT_TO_POINTER(name_quark), NULL, (gpointer *) &index)) {
+ BT_LOGV("No such variant field type field name: "
+ "ft-addr=%p, field-name=\"%s\"",
+ ft, field_name);
+ goto end;
+ }
+
+ choice = BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft, index);
+ field_type = choice->type;
+
+end:
+ return field_type;
+}
+
+BT_HIDDEN
+int64_t bt_ctf_field_type_common_variant_get_field_count(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Variant field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
+ "Field type");
+ return (int64_t) var_ft->choices->len;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_borrow_field_by_index(
+ struct bt_ctf_field_type_common *ft,
+ const char **field_name,
+ struct bt_ctf_field_type_common **field_type, uint64_t index)
+{
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+ struct bt_ctf_field_type_common_variant_choice *choice;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
+ "Field type");
+ BT_ASSERT_PRE(index < var_ft->choices->len,
+ "Index is out of bounds: index=%" PRIu64 ", "
+ "count=%u, ft-addr=%p",
+ index, var_ft->choices->len, ft);
+ choice = BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft, index);
+
+ if (field_type) {
+ *field_type = choice->type;
+ }
+
+ if (field_name) {
+ *field_name = g_quark_to_string(choice->name);
+ BT_ASSERT(*field_name);
+ }
+
+ return 0;
+}
+
+BT_HIDDEN
+int64_t bt_ctf_field_type_common_variant_find_choice_index(
+ struct bt_ctf_field_type_common *ft, uint64_t uval,
+ bool is_signed)
+{
+ int64_t ret;
+ uint64_t i;
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT(ft);
+ BT_ASSERT(ft->id == BT_CTF_FIELD_TYPE_ID_VARIANT);
+
+ if (bt_ctf_field_type_common_variant_update_choices(ft)) {
+ ret = INT64_C(-1);
+ goto end;
+ }
+
+ for (i = 0; i < var_ft->choices->len; i++) {
+ uint64_t range_i;
+ struct bt_ctf_field_type_common_variant_choice *choice =
+ BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
+ var_ft, i);
+
+ for (range_i = 0; range_i < choice->ranges->len; range_i++) {
+ struct bt_ctf_field_type_common_variant_choice_range *range =
+ &g_array_index(
+ choice->ranges,
+ struct bt_ctf_field_type_common_variant_choice_range,
+ range_i);
+
+ if (is_signed) {
+ int64_t tag_ival = (int64_t) uval;
+
+ if (tag_ival >= range->lower.i &&
+ tag_ival <= range->upper.i) {
+ goto found;
+ }
+ } else {
+ if (uval >= range->lower.u &&
+ uval <= range->upper.u) {
+ goto found;
+ }
+ }
+ }
+ }
+
+ /* Range not found */
+ ret = INT64_C(-1);
+ goto end;
+
+found:
+ ret = (int64_t) i;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_array_borrow_element_field_type(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_ARRAY,
+ "Field type");
+ BT_ASSERT(array_ft && array_ft->element_ft);
+ return array_ft->element_ft;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_array_set_element_field_type(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *element_ft)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: array field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!element_ft) {
+ BT_LOGW_STR("Invalid parameter: element field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_ARRAY) {
+ BT_LOGW("Invalid parameter: field type is not an array field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ if (array_ft->element_ft) {
+ BT_PUT(array_ft->element_ft);
+ }
+
+ array_ft->element_ft = bt_get(element_ft);
+ BT_LOGV("Set array field type's element field type: array-ft-addr=%p, "
+ "element-ft-addr=%p", ft, element_ft);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int64_t bt_ctf_field_type_common_array_get_length(struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_ARRAY,
+ "Field type");
+ return (int64_t) array_ft->length;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *bt_ctf_field_type_common_sequence_borrow_element_field_type(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_SEQUENCE,
+ "Field type");
+ return seq_ft->element_ft;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_sequence_set_element_field_type(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *element_ft)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: sequence field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!element_ft) {
+ BT_LOGW_STR("Invalid parameter: element field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
+ BT_LOGW("Invalid parameter: field type is not a sequence field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ if (seq_ft->element_ft) {
+ BT_PUT(seq_ft->element_ft);
+ }
+
+ seq_ft->element_ft = element_ft;
+ bt_get(seq_ft->element_ft);
+ BT_LOGV("Set sequence field type's element field type: sequence-ft-addr=%p, "
+ "element-ft-addr=%p", ft, element_ft);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+const char *bt_ctf_field_type_common_sequence_get_length_field_name(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_SEQUENCE,
+ "Field type");
+ return seq_ft->length_field_name ?
+ seq_ft->length_field_name->str : NULL;
+}
+
+BT_HIDDEN
+enum bt_ctf_string_encoding bt_ctf_field_type_common_string_get_encoding(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_string *string_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_STRING,
+ "Field type");
+ return string_ft->encoding;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_string_set_encoding(struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_string_encoding encoding)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_string *string_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_STRING) {
+ BT_LOGW("Invalid parameter: field type is not a string field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ if (encoding != BT_CTF_STRING_ENCODING_UTF8 &&
+ encoding != BT_CTF_STRING_ENCODING_ASCII) {
+ BT_LOGW("Invalid parameter: unknown string encoding: "
+ "addr=%p, encoding=%d", ft, encoding);
+ ret = -1;
+ goto end;
+ }
+
+ string_ft->encoding = encoding;
+ BT_LOGV("Set string field type's encoding: addr=%p, encoding=%s",
+ ft, bt_ctf_string_encoding_string(encoding));
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_get_alignment(struct bt_ctf_field_type_common *ft)
+{
+ int ret;
+ enum bt_ctf_field_type_id type_id;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+
+ if (ft->frozen) {
+ ret = (int) ft->alignment;
+ goto end;
+ }
+
+ type_id = bt_ctf_field_type_common_get_type_id(ft);
+ switch (type_id) {
+ case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ {
+ struct bt_ctf_field_type_common *element_ft =
+ bt_ctf_field_type_common_sequence_borrow_element_field_type(ft);
+
+ BT_ASSERT(element_ft);
+ ret = bt_ctf_field_type_common_get_alignment(element_ft);
+ break;
+ }
+ case BT_CTF_FIELD_TYPE_ID_ARRAY:
+ {
+ struct bt_ctf_field_type_common *element_ft =
+ bt_ctf_field_type_common_array_borrow_element_field_type(ft);
+
+ BT_ASSERT(element_ft);
+ ret = bt_ctf_field_type_common_get_alignment(element_ft);
+ break;
+ }
+ case BT_CTF_FIELD_TYPE_ID_STRUCT:
+ {
+ int64_t i, element_count;
+
+ element_count = bt_ctf_field_type_common_structure_get_field_count(
+ ft);
+ BT_ASSERT(element_count >= 0);
+
+ for (i = 0; i < element_count; i++) {
+ struct bt_ctf_field_type_common *field = NULL;
+ int field_alignment;
+
+ ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
+ ft, NULL, &field, i);
+ BT_ASSERT(ret == 0);
+ BT_ASSERT(field);
+ field_alignment = bt_ctf_field_type_common_get_alignment(
+ field);
+ if (field_alignment < 0) {
+ ret = field_alignment;
+ goto end;
+ }
+
+ ft->alignment = MAX(field_alignment, ft->alignment);
+ }
+ ret = (int) ft->alignment;
+ break;
+ }
+ case BT_CTF_FIELD_TYPE_ID_UNKNOWN:
+ BT_LOGW("Invalid parameter: unknown field type ID: "
+ "addr=%p, ft-id=%d", ft, type_id);
+ ret = -1;
+ break;
+ default:
+ ret = (int) ft->alignment;
+ break;
+ }
+
+end:
+ return ret;
+}
+
+static inline
+int is_power_of_two(unsigned int value)
+{
+ return ((value & (value - 1)) == 0) && value > 0;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_set_alignment(struct bt_ctf_field_type_common *ft,
+ unsigned int alignment)
+{
+ int ret = 0;
+ enum bt_ctf_field_type_id type_id;
+
+ /* Alignment must be a power of two */
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (!is_power_of_two(alignment)) {
+ BT_LOGW("Invalid parameter: alignment is not a power of two: "
+ "addr=%p, align=%u", ft, alignment);
+ ret = -1;
+ goto end;
+ }
+
+ type_id = bt_ctf_field_type_common_get_type_id(ft);
+ if (type_id == BT_CTF_FIELD_TYPE_ID_UNKNOWN) {
+ BT_LOGW("Invalid parameter: unknown field type ID: "
+ "addr=%p, ft-id=%d", ft, type_id);
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id == BT_CTF_FIELD_TYPE_ID_STRING && alignment != CHAR_BIT) {
+ BT_LOGW("Invalid parameter: alignment must be %u for a string field type: "
+ "addr=%p, align=%u", CHAR_BIT, ft, alignment);
+ ret = -1;
+ goto end;
+ }
+
+ if (type_id == BT_CTF_FIELD_TYPE_ID_VARIANT ||
+ type_id == BT_CTF_FIELD_TYPE_ID_SEQUENCE ||
+ type_id == BT_CTF_FIELD_TYPE_ID_ARRAY) {
+ /* Setting an alignment on these types makes no sense */
+ BT_LOGW("Invalid parameter: cannot set the alignment of this field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ ft->alignment = alignment;
+ ret = 0;
+ BT_LOGV("Set field type's alignment: addr=%p, align=%u",
+ ft, alignment);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+enum bt_ctf_byte_order bt_ctf_field_type_common_get_byte_order(
+ struct bt_ctf_field_type_common *ft)
+{
+ enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+
+ switch (ft->id) {
+ case BT_CTF_FIELD_TYPE_ID_INTEGER:
+ {
+ struct bt_ctf_field_type_common_integer *integer =
+ BT_CTF_FROM_COMMON(ft);
+
+ ret = integer->user_byte_order;
+ break;
+ }
+ case BT_CTF_FIELD_TYPE_ID_ENUM:
+ {
+ struct bt_ctf_field_type_common_enumeration *enum_ft =
+ BT_CTF_FROM_COMMON(ft);
+
+ ret = bt_ctf_field_type_common_get_byte_order(
+ BT_CTF_TO_COMMON(enum_ft->container_ft));
+ break;
+ }
+ case BT_CTF_FIELD_TYPE_ID_FLOAT:
+ {
+ struct bt_ctf_field_type_common_floating_point *floating_point =
+ BT_CTF_FROM_COMMON(ft);
+ ret = floating_point->user_byte_order;
+ break;
+ }
+ default:
+ BT_LOGW("Invalid parameter: cannot get the byte order of this field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ goto end;
+ }
+
+ BT_ASSERT(ret == BT_CTF_BYTE_ORDER_NATIVE ||
+ ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
+ ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
+ ret == BT_CTF_BYTE_ORDER_NETWORK);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_set_byte_order(struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_byte_order byte_order)
+{
+ int ret = 0;
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->frozen) {
+ BT_LOGW("Invalid parameter: field type is frozen: addr=%p",
+ ft);
+ ret = -1;
+ goto end;
+ }
+
+ if (byte_order != BT_CTF_BYTE_ORDER_NATIVE &&
+ byte_order != BT_CTF_BYTE_ORDER_LITTLE_ENDIAN &&
+ byte_order != BT_CTF_BYTE_ORDER_BIG_ENDIAN &&
+ byte_order != BT_CTF_BYTE_ORDER_NETWORK) {
+ BT_LOGW("Invalid parameter: invalid byte order: "
+ "addr=%p, bo=%s", ft,
+ bt_ctf_byte_order_string(byte_order));
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->methods->set_byte_order) {
+ ft->methods->set_byte_order(ft, byte_order);
+ }
+
+ BT_LOGV("Set field type's byte order: addr=%p, bo=%s",
+ ft, bt_ctf_byte_order_string(byte_order));
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+enum bt_ctf_field_type_id bt_ctf_field_type_common_get_type_id(
+ struct bt_ctf_field_type_common *ft)
+{
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ return ft->id;
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_freeze(struct bt_ctf_field_type_common *ft)
+{
+ if (!ft || ft->frozen) {
+ return;
+ }
+
+ BT_ASSERT(ft->methods->freeze);
+ ft->methods->freeze(ft);
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_variant_borrow_field_type_signed(
+ struct bt_ctf_field_type_common_variant *var_ft,
+ int64_t tag_value)
+{
+ struct bt_ctf_field_type_common *field_type = NULL;
+ GQuark field_name_quark;
+ gpointer index;
+ struct bt_ctf_field_type_common_variant_choice *choice;
+ struct range_overlap_query query = {
+ .range_start._signed = tag_value,
+ .range_end._signed = tag_value,
+ .mapping_name = 0,
+ .overlaps = 0,
+ };
+
+ g_ptr_array_foreach(var_ft->tag_ft->entries, check_ranges_overlap,
+ &query);
+ if (!query.overlaps) {
+ goto end;
+ }
+
+ field_name_quark = query.mapping_name;
+ if (!g_hash_table_lookup_extended(var_ft->choice_name_to_index,
+ GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
+ goto end;
+ }
+
+ choice = BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft,
+ (size_t) index);
+ field_type = choice->type;
+
+end:
+ return field_type;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *
+bt_ctf_field_type_common_variant_borrow_field_type_unsigned(
+ struct bt_ctf_field_type_common_variant *var_ft,
+ uint64_t tag_value)
+{
+ struct bt_ctf_field_type_common *field_type = NULL;
+ GQuark field_name_quark;
+ gpointer index;
+ struct bt_ctf_field_type_common_variant_choice *choice;
+ struct range_overlap_query query = {
+ .range_start._unsigned = tag_value,
+ .range_end._unsigned = tag_value,
+ .mapping_name = 0,
+ .overlaps = 0,
+ };
+
+ g_ptr_array_foreach(var_ft->tag_ft->entries,
+ check_ranges_overlap_unsigned, &query);
+ if (!query.overlaps) {
+ goto end;
+ }
+
+ field_name_quark = query.mapping_name;
+ if (!g_hash_table_lookup_extended(var_ft->choice_name_to_index,
+ GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
+ goto end;
+ }
+
+ choice = BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft,
+ (size_t) index);
+ field_type = choice->type;
+
+end:
+ return field_type;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *bt_ctf_field_type_common_copy(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common *ft_copy = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT(ft->methods->copy);
+ ft_copy = ft->methods->copy(ft);
+ if (!ft_copy) {
+ BT_LOGE_STR("Cannot copy field type.");
+ goto end;
+ }
+
+ ft_copy->alignment = ft->alignment;
+
+end:
+ return ft_copy;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_structure_get_field_name_index(
+ struct bt_ctf_field_type_common *ft, const char *name)
+{
+ int ret;
+ size_t index;
+ GQuark name_quark;
+ struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_STRUCT,
+ "Field type");
+
+ name_quark = g_quark_try_string(name);
+ if (!name_quark) {
+ BT_LOGV("No such structure field type field name: "
+ "ft-addr=%p, field-name=\"%s\"",
+ ft, name);
+ ret = -1;
+ goto end;
+ }
+
+ if (!g_hash_table_lookup_extended(struct_ft->field_name_to_index,
+ GUINT_TO_POINTER(name_quark),
+ NULL, (gpointer *) &index)) {
+ BT_LOGV("No such structure field type field name: "
+ "ft-addr=%p, field-name=\"%s\"",
+ ft, name);
+ ret = -1;
+ goto end;
+ }
+
+ ret = (int) index;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_get_field_name_index(
+ struct bt_ctf_field_type_common *ft, const char *name)
+{
+ int ret;
+ size_t index;
+ GQuark name_quark;
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
+ "Field type");
+ name_quark = g_quark_try_string(name);
+ if (!name_quark) {
+ BT_LOGV("No such variant field type field name: "
+ "ft-addr=%p, field-name=\"%s\"",
+ ft, name);
+ ret = -1;
+ goto end;
+ }
+
+ if (!g_hash_table_lookup_extended(var_ft->choice_name_to_index,
+ GUINT_TO_POINTER(name_quark),
+ NULL, (gpointer *) &index)) {
+ BT_LOGV("No such variant field type field name: "
+ "ft-addr=%p, field-name=\"%s\"",
+ ft, name);
+ ret = -1;
+ goto end;
+ }
+
+ ret = (int) index;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_sequence_set_length_field_path(
+ struct bt_ctf_field_type_common *ft, struct bt_ctf_field_path *path)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
+ BT_LOGW("Invalid parameter: field type is not a sequence field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ bt_get(path);
+ BT_MOVE(seq_ft->length_field_path, path);
+ BT_LOGV("Set sequence field type's length field path: ft-addr=%p, "
+ "field-path-addr=%p", ft, path);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_set_tag_field_path(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_path *path)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
+ BT_LOGW("Invalid parameter: field type is not a variant field type: "
+ "addr=%p, ft-id=%s", ft,
+ bt_ctf_field_type_id_string(ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ bt_get(path);
+ BT_MOVE(var_ft->tag_field_path, path);
+ BT_LOGV("Set variant field type's tag field path: ft-addr=%p, "
+ "field-path-addr=%p", ft, path);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_set_tag_field_type(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_field_type_common *tag_ft)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+
+ if (!ft) {
+ BT_LOGW_STR("Invalid parameter: variant field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!tag_ft) {
+ BT_LOGW_STR("Invalid parameter: tag field type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (tag_ft->id != BT_CTF_FIELD_TYPE_ID_ENUM) {
+ BT_LOGW("Invalid parameter: tag field type is not an enumeration field type: "
+ "addr=%p, ft-id=%s", tag_ft,
+ bt_ctf_field_type_id_string(tag_ft->id));
+ ret = -1;
+ goto end;
+ }
+
+ bt_put(var_ft->tag_ft);
+ var_ft->tag_ft = bt_get(tag_ft);
+ BT_LOGV("Set variant field type's tag field type: variant-ft-addr=%p, "
+ "tag-ft-addr=%p", ft, tag_ft);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_generic_freeze(struct bt_ctf_field_type_common *ft)
+{
+ ft->frozen = 1;
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_enumeration_freeze_recursive(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_LOGD("Freezing enumeration field type object: addr=%p", ft);
+ bt_ctf_field_type_common_enumeration_set_range_overlap(enum_ft);
+ bt_ctf_field_type_common_generic_freeze(ft);
+ BT_LOGD("Freezing enumeration field type object's container field type: int-ft-addr=%p",
+ enum_ft->container_ft);
+ bt_ctf_field_type_common_freeze(BT_CTF_TO_COMMON(enum_ft->container_ft));
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_structure_freeze_recursive(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
+ uint64_t i;
+
+ /* Cache the alignment */
+ BT_LOGD("Freezing structure field type object: addr=%p", ft);
+ ft->alignment = bt_ctf_field_type_common_get_alignment(ft);
+ bt_ctf_field_type_common_generic_freeze(ft);
+
+ for (i = 0; i < struct_ft->fields->len; i++) {
+ struct bt_ctf_field_type_common_structure_field *field =
+ BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(ft, i);
+
+ BT_LOGD("Freezing structure field type field: "
+ "ft-addr=%p, name=\"%s\"",
+ field->type, g_quark_to_string(field->name));
+ bt_ctf_field_type_common_freeze(field->type);
+ }
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_update_choices(struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+ uint64_t i;
+ int ret = 0;
+ bool is_signed;
+
+ if (ft->frozen && var_ft->choices_up_to_date) {
+ goto end;
+ }
+
+ BT_ASSERT(var_ft->tag_ft);
+ is_signed = !!var_ft->tag_ft->container_ft->is_signed;
+
+ for (i = 0; i < var_ft->choices->len; i++) {
+ struct bt_ctf_field_type_common_variant_choice *choice =
+ BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft, i);
+ const char *choice_name = g_quark_to_string(choice->name);
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter =
+ bt_ctf_field_type_common_enumeration_find_mappings_by_name(
+ BT_CTF_TO_COMMON(var_ft->tag_ft), choice_name);
+
+ if (!iter) {
+ ret = -1;
+ goto end;
+ }
+
+ BT_ASSERT(choice->ranges);
+ g_array_set_size(choice->ranges, 0);
+
+ while (bt_ctf_field_type_enumeration_mapping_iterator_next(iter) == 0) {
+ struct bt_ctf_field_type_common_variant_choice_range range;
+
+ if (is_signed) {
+ ret = bt_ctf_field_type_enumeration_mapping_iterator_signed_get(
+ iter, NULL,
+ &range.lower.i, &range.upper.i);
+ } else {
+ ret = bt_ctf_field_type_enumeration_mapping_iterator_unsigned_get(
+ iter, NULL,
+ &range.lower.u, &range.upper.u);
+ }
+
+ BT_ASSERT(ret == 0);
+ g_array_append_val(choice->ranges, range);
+ }
+
+ bt_put(iter);
+ }
+
+ var_ft->choices_up_to_date = true;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_variant_freeze_recursive(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+ uint64_t i;
+
+ BT_LOGD("Freezing variant field type object: addr=%p", ft);
+ bt_ctf_field_type_common_generic_freeze(ft);
+
+ for (i = 0; i < var_ft->choices->len; i++) {
+ struct bt_ctf_field_type_common_variant_choice *choice =
+ BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(ft, i);
+
+ BT_LOGD("Freezing variant field type member: "
+ "ft-addr=%p, name=\"%s\"",
+ choice->type, g_quark_to_string(choice->name));
+ bt_ctf_field_type_common_freeze(choice->type);
+ }
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_array_freeze_recursive(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
+
+ /* Cache the alignment */
+ BT_LOGD("Freezing array field type object: addr=%p", ft);
+ ft->alignment = bt_ctf_field_type_common_get_alignment(ft);
+ bt_ctf_field_type_common_generic_freeze(ft);
+ BT_LOGD("Freezing array field type object's element field type: element-ft-addr=%p",
+ array_ft->element_ft);
+ bt_ctf_field_type_common_freeze(array_ft->element_ft);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_sequence_freeze_recursive(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
+
+ /* Cache the alignment */
+ BT_LOGD("Freezing sequence field type object: addr=%p", ft);
+ ft->alignment = bt_ctf_field_type_common_get_alignment(ft);
+ bt_ctf_field_type_common_generic_freeze(ft);
+ BT_LOGD("Freezing sequence field type object's element field type: element-ft-addr=%p",
+ seq_ft->element_ft);
+ bt_ctf_field_type_common_freeze(seq_ft->element_ft);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_integer_set_byte_order(
+ struct bt_ctf_field_type_common *ft, enum bt_ctf_byte_order byte_order)
+{
+ struct bt_ctf_field_type_common_integer *int_ft = BT_CTF_FROM_COMMON(ft);
+
+ int_ft->user_byte_order = byte_order;
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_enumeration_set_byte_order_recursive(
+ struct bt_ctf_field_type_common *ft, enum bt_ctf_byte_order byte_order)
+{
+ struct bt_ctf_field_type_common_enumeration *enum_ft = BT_CTF_FROM_COMMON(ft);
+
+ bt_ctf_field_type_common_set_byte_order(BT_CTF_TO_COMMON(enum_ft->container_ft),
+ byte_order);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_floating_point_set_byte_order(
+ struct bt_ctf_field_type_common *ft, enum bt_ctf_byte_order byte_order)
+{
+ struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
+
+ flt_ft->user_byte_order = byte_order;
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_structure_set_byte_order_recursive(
+ struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_byte_order byte_order)
+{
+ int i;
+ struct bt_ctf_field_type_common_structure *struct_ft = BT_CTF_FROM_COMMON(ft);
+
+ for (i = 0; i < struct_ft->fields->len; i++) {
+ struct bt_ctf_field_type_common_structure_field *field =
+ BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
+ struct_ft, i);
+ struct bt_ctf_field_type_common *field_type = field->type;
+
+ bt_ctf_field_type_common_set_byte_order(field_type, byte_order);
+ }
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_variant_set_byte_order_recursive(
+ struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_byte_order byte_order)
+{
+ int i;
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+
+ for (i = 0; i < var_ft->choices->len; i++) {
+ struct bt_ctf_field_type_common_variant_choice *choice =
+ BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
+ var_ft, i);
+ struct bt_ctf_field_type_common *field_type = choice->type;
+
+ bt_ctf_field_type_common_set_byte_order(field_type, byte_order);
+ }
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_array_set_byte_order_recursive(
+ struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_byte_order byte_order)
+{
+ struct bt_ctf_field_type_common_array *array_ft = BT_CTF_FROM_COMMON(ft);
+
+ bt_ctf_field_type_common_set_byte_order(array_ft->element_ft, byte_order);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_common_sequence_set_byte_order_recursive(
+ struct bt_ctf_field_type_common *ft,
+ enum bt_ctf_byte_order byte_order)
+{
+ struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
+
+ bt_ctf_field_type_common_set_byte_order(seq_ft->element_ft, byte_order);
+}
+
+
+BT_HIDDEN
+int bt_ctf_field_type_common_integer_compare(struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b)
+{
+ int ret = 1;
+ struct bt_ctf_field_type_common_integer *int_ft_a = BT_CTF_FROM_COMMON(ft_a);
+ struct bt_ctf_field_type_common_integer *int_ft_b = BT_CTF_FROM_COMMON(ft_b);
+
+ /* Length */
+ if (int_ft_a->size != int_ft_b->size) {
+ BT_LOGV("Integer field types differ: different sizes: "
+ "ft-a-size=%u, ft-b-size=%u",
+ int_ft_a->size, int_ft_b->size);
+ goto end;
+ }
+
+ /* Byte order */
+ if (int_ft_a->user_byte_order != int_ft_b->user_byte_order) {
+ BT_LOGV("Integer field types differ: different byte orders: "
+ "ft-a-bo=%s, ft-b-bo=%s",
+ bt_ctf_byte_order_string(int_ft_a->user_byte_order),
+ bt_ctf_byte_order_string(int_ft_b->user_byte_order));
+ goto end;
+ }
+
+ /* Signedness */
+ if (int_ft_a->is_signed != int_ft_b->is_signed) {
+ BT_LOGV("Integer field types differ: different signedness: "
+ "ft-a-is-signed=%d, ft-b-is-signed=%d",
+ int_ft_a->is_signed,
+ int_ft_b->is_signed);
+ goto end;
+ }
+
+ /* Base */
+ if (int_ft_a->base != int_ft_b->base) {
+ BT_LOGV("Integer field types differ: different bases: "
+ "ft-a-base=%s, ft-b-base=%s",
+ bt_ctf_integer_base_string(int_ft_a->base),
+ bt_ctf_integer_base_string(int_ft_b->base));
+ goto end;
+ }
+
+ /* Encoding */
+ if (int_ft_a->encoding != int_ft_b->encoding) {
+ BT_LOGV("Integer field types differ: different encodings: "
+ "ft-a-encoding=%s, ft-b-encoding=%s",
+ bt_ctf_string_encoding_string(int_ft_a->encoding),
+ bt_ctf_string_encoding_string(int_ft_b->encoding));
+ goto end;
+ }
+
+ /* Mapped clock class */
+ if (int_ft_a->mapped_clock_class) {
+ if (!int_ft_b->mapped_clock_class) {
+ BT_LOGV_STR("Integer field types differ: field type A "
+ "has a mapped clock class, but field type B "
+ "does not.");
+ goto end;
+ }
+
+ if (bt_ctf_clock_class_compare(int_ft_a->mapped_clock_class,
+ int_ft_b->mapped_clock_class) != 0) {
+ BT_LOGV_STR("Integer field types differ: different "
+ "mapped clock classes.");
+ }
+ } else {
+ if (int_ft_b->mapped_clock_class) {
+ BT_LOGV_STR("Integer field types differ: field type A "
+ "has no description, but field type B has one.");
+ goto end;
+ }
+ }
+
+ /* Equal */
+ ret = 0;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_floating_point_compare(
+ struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b)
+{
+ int ret = 1;
+ struct bt_ctf_field_type_common_floating_point *flt_ft_a =
+ BT_CTF_FROM_COMMON(ft_a);
+ struct bt_ctf_field_type_common_floating_point *flt_ft_b =
+ BT_CTF_FROM_COMMON(ft_b);
+
+ /* Byte order */
+ if (flt_ft_a->user_byte_order != flt_ft_b->user_byte_order) {
+ BT_LOGV("Floating point number field types differ: different byte orders: "
+ "ft-a-bo=%s, ft-b-bo=%s",
+ bt_ctf_byte_order_string(flt_ft_a->user_byte_order),
+ bt_ctf_byte_order_string(flt_ft_b->user_byte_order));
+ goto end;
+ }
+
+ /* Exponent length */
+ if (flt_ft_a->exp_dig != flt_ft_b->exp_dig) {
+ BT_LOGV("Floating point number field types differ: different exponent sizes: "
+ "ft-a-exp-size=%u, ft-b-exp-size=%u",
+ flt_ft_a->exp_dig, flt_ft_b->exp_dig);
+ goto end;
+ }
+
+ /* Mantissa length */
+ if (flt_ft_a->mant_dig != flt_ft_b->mant_dig) {
+ BT_LOGV("Floating point number field types differ: different mantissa sizes: "
+ "ft-a-mant-size=%u, ft-b-mant-size=%u",
+ flt_ft_a->mant_dig, flt_ft_b->mant_dig);
+ goto end;
+ }
+
+ /* Equal */
+ ret = 0;
+
+end:
+ return ret;
+}
+
+static
+int compare_enumeration_mappings(struct bt_ctf_enumeration_mapping *mapping_a,
+ struct bt_ctf_enumeration_mapping *mapping_b)
+{
+ int ret = 1;
+
+ /* Label */
+ if (mapping_a->string != mapping_b->string) {
+ BT_LOGV("Enumeration field type mappings differ: different names: "
+ "mapping-a-name=\"%s\", mapping-b-name=\"%s\"",
+ g_quark_to_string(mapping_a->string),
+ g_quark_to_string(mapping_b->string));
+ goto end;
+ }
+
+ /* Range start */
+ if (mapping_a->range_start._unsigned !=
+ mapping_b->range_start._unsigned) {
+ BT_LOGV("Enumeration field type mappings differ: different starts of range: "
+ "mapping-a-range-start-unsigned=%" PRIu64 ", "
+ "mapping-b-range-start-unsigned=%" PRIu64,
+ mapping_a->range_start._unsigned,
+ mapping_b->range_start._unsigned);
+ goto end;
+ }
+
+ /* Range end */
+ if (mapping_a->range_end._unsigned !=
+ mapping_b->range_end._unsigned) {
+ BT_LOGV("Enumeration field type mappings differ: different ends of range: "
+ "mapping-a-range-end-unsigned=%" PRIu64 ", "
+ "mapping-b-range-end-unsigned=%" PRIu64,
+ mapping_a->range_end._unsigned,
+ mapping_b->range_end._unsigned);
+ goto end;
+ }
+
+ /* Equal */
+ ret = 0;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_enumeration_compare_recursive(
+ struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b)
+{
+ int ret = 1;
+ int i;
+ struct bt_ctf_field_type_common_enumeration *enum_ft_a =
+ BT_CTF_FROM_COMMON(ft_a);
+ struct bt_ctf_field_type_common_enumeration *enum_ft_b =
+ BT_CTF_FROM_COMMON(ft_b);
+
+ /* Container field type */
+ ret = bt_ctf_field_type_common_compare(
+ BT_CTF_TO_COMMON(enum_ft_a->container_ft),
+ BT_CTF_TO_COMMON(enum_ft_b->container_ft));
+ if (ret) {
+ BT_LOGV("Enumeration field types differ: different container field types: "
+ "ft-a-container-ft-addr=%p, ft-b-container-ft-addr=%p",
+ enum_ft_a->container_ft, enum_ft_b->container_ft);
+ goto end;
+ }
+
+ ret = 1;
+
+ /* Entries */
+ if (enum_ft_a->entries->len != enum_ft_b->entries->len) {
+ goto end;
+ }
+
+ for (i = 0; i < enum_ft_a->entries->len; ++i) {
+ struct bt_ctf_enumeration_mapping *mapping_a =
+ g_ptr_array_index(enum_ft_a->entries, i);
+ struct bt_ctf_enumeration_mapping *mapping_b =
+ g_ptr_array_index(enum_ft_b->entries, i);
+
+ if (compare_enumeration_mappings(mapping_a, mapping_b)) {
+ BT_LOGV("Enumeration field types differ: different mappings: "
+ "ft-a-mapping-addr=%p, ft-b-mapping-addr=%p, "
+ "ft-a-mapping-name=\"%s\", ft-b-mapping-name=\"%s\"",
+ mapping_a, mapping_b,
+ g_quark_to_string(mapping_a->string),
+ g_quark_to_string(mapping_b->string));
+ goto end;
+ }
+ }
+
+ /* Equal */
+ ret = 0;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_string_compare(struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b)
+{
+ int ret = 1;
+ struct bt_ctf_field_type_common_string *string_ft_a = BT_CTF_FROM_COMMON(ft_a);
+ struct bt_ctf_field_type_common_string *string_ft_b = BT_CTF_FROM_COMMON(ft_b);
+
+ /* Encoding */
+ if (string_ft_a->encoding != string_ft_b->encoding) {
+ BT_LOGV("String field types differ: different encodings: "
+ "ft-a-encoding=%s, ft-b-encoding=%s",
+ bt_ctf_string_encoding_string(string_ft_a->encoding),
+ bt_ctf_string_encoding_string(string_ft_b->encoding));
+ goto end;
+ }
+
+ /* Equal */
+ ret = 0;
+
+end:
+ return ret;
+}
+
+static
+int compare_structure_variant_members(
+ struct bt_ctf_field_type_common *member_a_ft,
+ struct bt_ctf_field_type_common *member_b_ft,
+ GQuark member_a_name, GQuark member_b_name)
+{
+ int ret = 1;
+
+ /* Label */
+ if (member_a_name != member_b_name) {
+ BT_LOGV("Structure/variant field type fields differ: different names: "
+ "field-a-name=%s, field-b-name=%s",
+ g_quark_to_string(member_a_name),
+ g_quark_to_string(member_b_name));
+ goto end;
+ }
+
+ /* Type */
+ ret = bt_ctf_field_type_common_compare(member_a_ft, member_b_ft);
+ if (ret == 1) {
+ BT_LOGV("Structure/variant field type fields differ: different field types: "
+ "field-name=\"%s\", field-a-ft-addr=%p, field-b-ft-addr=%p",
+ g_quark_to_string(member_a_name),
+ member_a_ft, member_b_ft);
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_structure_compare_recursive(
+ struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b)
+{
+ int ret = 1;
+ int i;
+ struct bt_ctf_field_type_common_structure *struct_ft_a =
+ BT_CTF_FROM_COMMON(ft_a);
+ struct bt_ctf_field_type_common_structure *struct_ft_b =
+ BT_CTF_FROM_COMMON(ft_b);
+
+ /* Alignment */
+ if (bt_ctf_field_type_common_get_alignment(ft_a) !=
+ bt_ctf_field_type_common_get_alignment(ft_b)) {
+ BT_LOGV("Structure field types differ: different alignments: "
+ "ft-a-align=%u, ft-b-align=%u",
+ bt_ctf_field_type_common_get_alignment(ft_a),
+ bt_ctf_field_type_common_get_alignment(ft_b));
+ goto end;
+ }
+
+ /* Fields */
+ if (struct_ft_a->fields->len != struct_ft_b->fields->len) {
+ BT_LOGV("Structure field types differ: different field counts: "
+ "ft-a-field-count=%u, ft-b-field-count=%u",
+ struct_ft_a->fields->len, struct_ft_b->fields->len);
+ goto end;
+ }
+
+ for (i = 0; i < struct_ft_a->fields->len; ++i) {
+ struct bt_ctf_field_type_common_structure_field *field_a =
+ BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
+ struct_ft_a, i);
+ struct bt_ctf_field_type_common_structure_field *field_b =
+ BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
+ struct_ft_b, i);
+
+ ret = compare_structure_variant_members(field_a->type,
+ field_b->type, field_a->name, field_b->name);
+ if (ret) {
+ /* compare_structure_variant_members() logs what differs */
+ BT_LOGV_STR("Structure field types differ: different fields.");
+ goto end;
+ }
+ }
+
+ /* Equal */
+ ret = 0;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_variant_compare_recursive(
+ struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b)
+{
+ int ret = 1;
+ int i;
+ struct bt_ctf_field_type_common_variant *var_ft_a = BT_CTF_FROM_COMMON(ft_a);
+ struct bt_ctf_field_type_common_variant *var_ft_b = BT_CTF_FROM_COMMON(ft_b);
+
+ /* Tag name */
+ if (strcmp(var_ft_a->tag_name->str, var_ft_b->tag_name->str)) {
+ BT_LOGV("Variant field types differ: different tag field names: "
+ "ft-a-tag-field-name=\"%s\", ft-b-tag-field-name=\"%s\"",
+ var_ft_a->tag_name->str, var_ft_b->tag_name->str);
+ goto end;
+ }
+
+ /* Tag type */
+ ret = bt_ctf_field_type_common_compare(BT_CTF_TO_COMMON(var_ft_a->tag_ft),
+ BT_CTF_TO_COMMON(var_ft_b->tag_ft));
+ if (ret) {
+ BT_LOGV("Variant field types differ: different tag field types: "
+ "ft-a-tag-ft-addr=%p, ft-b-tag-ft-addr=%p",
+ var_ft_a->tag_ft, var_ft_b->tag_ft);
+ goto end;
+ }
+
+ ret = 1;
+
+ /* Fields */
+ if (var_ft_a->choices->len != var_ft_b->choices->len) {
+ BT_LOGV("Variant field types differ: different field counts: "
+ "ft-a-field-count=%u, ft-b-field-count=%u",
+ var_ft_a->choices->len, var_ft_b->choices->len);
+ goto end;
+ }
+
+ for (i = 0; i < var_ft_a->choices->len; ++i) {
+ struct bt_ctf_field_type_common_variant_choice *choice_a =
+ BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
+ var_ft_a, i);
+ struct bt_ctf_field_type_common_variant_choice *choice_b =
+ BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
+ var_ft_b, i);
+
+ ret = compare_structure_variant_members(choice_a->type,
+ choice_b->type, choice_a->name, choice_b->name);
+ if (ret) {
+ /* compare_structure_variant_members() logs what differs */
+ BT_LOGV_STR("Variant field types differ: different fields.");
+ goto end;
+ }
+ }
+
+ /* Equal */
+ ret = 0;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_array_compare_recursive(
+ struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b)
+{
+ int ret = 1;
+ struct bt_ctf_field_type_common_array *array_ft_a = BT_CTF_FROM_COMMON(ft_a);
+ struct bt_ctf_field_type_common_array *array_ft_b = BT_CTF_FROM_COMMON(ft_b);
+
+ /* Length */
+ if (array_ft_a->length != array_ft_b->length) {
+ BT_LOGV("Structure field types differ: different lengths: "
+ "ft-a-length=%u, ft-b-length=%u",
+ array_ft_a->length, array_ft_b->length);
+ goto end;
+ }
+
+ /* Element type */
+ ret = bt_ctf_field_type_common_compare(array_ft_a->element_ft,
+ array_ft_b->element_ft);
+ if (ret == 1) {
+ BT_LOGV("Array field types differ: different element field types: "
+ "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
+ array_ft_a->element_ft, array_ft_b->element_ft);
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_sequence_compare_recursive(
+ struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b)
+{
+ int ret = -1;
+ struct bt_ctf_field_type_common_sequence *seq_ft_a = BT_CTF_FROM_COMMON(ft_a);
+ struct bt_ctf_field_type_common_sequence *seq_ft_b = BT_CTF_FROM_COMMON(ft_b);
+
+ /* Length name */
+ if (strcmp(seq_ft_a->length_field_name->str,
+ seq_ft_b->length_field_name->str)) {
+ BT_LOGV("Sequence field types differ: different length field names: "
+ "ft-a-length-field-name=\"%s\", "
+ "ft-b-length-field-name=\"%s\"",
+ seq_ft_a->length_field_name->str,
+ seq_ft_b->length_field_name->str);
+ goto end;
+ }
+
+ /* Element type */
+ ret = bt_ctf_field_type_common_compare(seq_ft_a->element_ft,
+ seq_ft_b->element_ft);
+ if (ret == 1) {
+ BT_LOGV("Sequence field types differ: different element field types: "
+ "ft-a-element-ft-addr=%p, ft-b-element-ft-addr=%p",
+ seq_ft_a->element_ft, seq_ft_b->element_ft);
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_compare(struct bt_ctf_field_type_common *ft_a,
+ struct bt_ctf_field_type_common *ft_b)
+{
+ int ret = 1;
+
+ BT_ASSERT_PRE_NON_NULL(ft_a, "Field type A");
+ BT_ASSERT_PRE_NON_NULL(ft_b, "Field type B");
+
+ if (ft_a == ft_b) {
+ /* Same reference: equal (even if both are NULL) */
+ ret = 0;
+ goto end;
+ }
+
+ if (!ft_a) {
+ BT_LOGW_STR("Invalid parameter: field type A is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!ft_b) {
+ BT_LOGW_STR("Invalid parameter: field type B is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (ft_a->id != ft_b->id) {
+ /* Different type IDs */
+ BT_LOGV("Field types differ: different IDs: "
+ "ft-a-addr=%p, ft-b-addr=%p, "
+ "ft-a-id=%s, ft-b-id=%s",
+ ft_a, ft_b,
+ bt_ctf_field_type_id_string(ft_a->id),
+ bt_ctf_field_type_id_string(ft_b->id));
+ goto end;
+ }
+
+ if (ft_a->id == BT_CTF_FIELD_TYPE_ID_UNKNOWN) {
+ /* Both have unknown type IDs */
+ BT_LOGW_STR("Invalid parameter: field type IDs are unknown.");
+ goto end;
+ }
+
+ BT_ASSERT(ft_a->methods->compare);
+ ret = ft_a->methods->compare(ft_a, ft_b);
+ if (ret == 1) {
+ BT_LOGV("Field types differ: ft-a-addr=%p, ft-b-addr=%p",
+ ft_a, ft_b);
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int64_t bt_ctf_field_type_common_get_field_count(struct bt_ctf_field_type_common *ft)
+{
+ int64_t field_count = -1;
+
+ switch (ft->id) {
+ case BT_CTF_FIELD_TYPE_ID_STRUCT:
+ field_count =
+ bt_ctf_field_type_common_structure_get_field_count(ft);
+ break;
+ case BT_CTF_FIELD_TYPE_ID_VARIANT:
+ field_count =
+ bt_ctf_field_type_common_variant_get_field_count(ft);
+ break;
+ case BT_CTF_FIELD_TYPE_ID_ARRAY:
+ case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ /*
+ * Array and sequence types always contain a single member
+ * (the element type).
+ */
+ field_count = 1;
+ break;
+ default:
+ break;
+ }
+
+ return field_count;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type_common *bt_ctf_field_type_common_borrow_field_at_index(
+ struct bt_ctf_field_type_common *ft, int index)
+{
+ struct bt_ctf_field_type_common *field_type = NULL;
+
+ switch (ft->id) {
+ case BT_CTF_FIELD_TYPE_ID_STRUCT:
+ {
+ int ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
+ ft, NULL, &field_type, index);
+ if (ret) {
+ field_type = NULL;
+ goto end;
+ }
+ break;
+ }
+ case BT_CTF_FIELD_TYPE_ID_VARIANT:
+ {
+ int ret = bt_ctf_field_type_common_variant_borrow_field_by_index(
+ ft, NULL, &field_type, index);
+ if (ret) {
+ field_type = NULL;
+ goto end;
+ }
+ break;
+ }
+ case BT_CTF_FIELD_TYPE_ID_ARRAY:
+ field_type =
+ bt_ctf_field_type_common_array_borrow_element_field_type(ft);
+ break;
+ case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ field_type =
+ bt_ctf_field_type_common_sequence_borrow_element_field_type(ft);
+ break;
+ default:
+ break;
+ }
+
+end:
+ return field_type;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_get_field_index(struct bt_ctf_field_type_common *ft,
+ const char *name)
+{
+ int field_index = -1;
+
+ switch (ft->id) {
+ case BT_CTF_FIELD_TYPE_ID_STRUCT:
+ field_index = bt_ctf_field_type_common_structure_get_field_name_index(
+ ft, name);
+ break;
+ case BT_CTF_FIELD_TYPE_ID_VARIANT:
+ field_index = bt_ctf_field_type_common_variant_get_field_name_index(
+ ft, name);
+ break;
+ default:
+ break;
+ }
+
+ return field_index;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_type_common_variant_borrow_tag_field_path(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_variant *var_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
+ "Field type");
+ return var_ft->tag_field_path;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_type_common_sequence_borrow_length_field_path(
+ struct bt_ctf_field_type_common *ft)
+{
+ struct bt_ctf_field_type_common_sequence *seq_ft = BT_CTF_FROM_COMMON(ft);
+
+ BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_SEQUENCE,
+ "Field type");
+ return seq_ft->length_field_path;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_common_validate_single_clock_class(
+ struct bt_ctf_field_type_common *ft,
+ struct bt_ctf_clock_class **expected_clock_class)
+{
+ int ret = 0;
+
+ if (!ft) {
+ goto end;
+ }
+
+ BT_ASSERT(expected_clock_class);
+
+ switch (ft->id) {
+ case BT_CTF_FIELD_TYPE_ID_INTEGER:
+ {
+ struct bt_ctf_clock_class *mapped_clock_class =
+ bt_ctf_field_type_common_integer_borrow_mapped_clock_class(ft);
+
+ if (!mapped_clock_class) {
+ goto end;
+ }
+
+ if (!*expected_clock_class) {
+ /* Move reference to output parameter */
+ *expected_clock_class = bt_get(mapped_clock_class);
+ mapped_clock_class = NULL;
+ BT_LOGV("Setting expected clock class: "
+ "expected-clock-class-addr=%p",
+ *expected_clock_class);
+ } else {
+ if (mapped_clock_class != *expected_clock_class) {
+ BT_LOGW("Integer field type is not mapped to "
+ "the expected clock class: "
+ "mapped-clock-class-addr=%p, "
+ "mapped-clock-class-name=\"%s\", "
+ "expected-clock-class-addr=%p, "
+ "expected-clock-class-name=\"%s\"",
+ mapped_clock_class,
+ bt_ctf_clock_class_get_name(mapped_clock_class),
+ *expected_clock_class,
+ bt_ctf_clock_class_get_name(*expected_clock_class));
+ bt_put(mapped_clock_class);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ break;
+ }
+ case BT_CTF_FIELD_TYPE_ID_ENUM:
+ case BT_CTF_FIELD_TYPE_ID_ARRAY:
+ case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ {
+ struct bt_ctf_field_type_common *sub_ft = NULL;
+
+ switch (ft->id) {
+ case BT_CTF_FIELD_TYPE_ID_ENUM:
+ sub_ft = bt_ctf_field_type_common_enumeration_borrow_container_field_type(
+ ft);
+ break;
+ case BT_CTF_FIELD_TYPE_ID_ARRAY:
+ sub_ft = bt_ctf_field_type_common_array_borrow_element_field_type(
+ ft);
+ break;
+ case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ sub_ft = bt_ctf_field_type_common_sequence_borrow_element_field_type(
+ ft);
+ break;
+ default:
+ BT_LOGF("Unexpected field type ID: id=%d", ft->id);
+ abort();
+ }
+
+ BT_ASSERT(sub_ft);
+ ret = bt_ctf_field_type_common_validate_single_clock_class(sub_ft,
+ expected_clock_class);
+ break;
+ }
+ case BT_CTF_FIELD_TYPE_ID_STRUCT:
+ {
+ uint64_t i;
+ int64_t count = bt_ctf_field_type_common_structure_get_field_count(
+ ft);
+
+ for (i = 0; i < count; i++) {
+ const char *name;
+ struct bt_ctf_field_type_common *member_type;
+
+ ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
+ ft, &name, &member_type, i);
+ BT_ASSERT(ret == 0);
+ ret = bt_ctf_field_type_common_validate_single_clock_class(
+ member_type, expected_clock_class);
+ if (ret) {
+ BT_LOGW("Structure field type's field's type "
+ "is not recursively mapped to the "
+ "expected clock class: "
+ "field-ft-addr=%p, field-name=\"%s\"",
+ member_type, name);
+ goto end;
+ }
+ }
+ break;
+ }
+ case BT_CTF_FIELD_TYPE_ID_VARIANT:
+ {
+ uint64_t i;
+ int64_t count = bt_ctf_field_type_common_variant_get_field_count(
+ ft);
+
+ for (i = 0; i < count; i++) {
+ const char *name;
+ struct bt_ctf_field_type_common *member_type;
+
+ ret = bt_ctf_field_type_common_variant_borrow_field_by_index(
+ ft, &name, &member_type, i);
+ BT_ASSERT(ret == 0);
+ ret = bt_ctf_field_type_common_validate_single_clock_class(
+ member_type, expected_clock_class);
+ if (ret) {
+ BT_LOGW("Variant field type's field's type "
+ "is not recursively mapped to the "
+ "expected clock class: "
+ "field-ft-addr=%p, field-name=\"%s\"",
+ member_type, name);
+ goto end;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+end:
+ return ret;
+}
+
static
struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
struct bt_ctf_field_type *ft);
struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
struct bt_ctf_field_type *type);
-static struct bt_field_type_common_methods bt_ctf_field_type_integer_methods = {
- .freeze = bt_field_type_common_generic_freeze,
- .validate = bt_field_type_common_integer_validate,
- .set_byte_order = bt_field_type_common_integer_set_byte_order,
- .copy = (bt_field_type_common_method_copy)
+static struct bt_ctf_field_type_common_methods bt_ctf_field_type_integer_methods = {
+ .freeze = bt_ctf_field_type_common_generic_freeze,
+ .validate = bt_ctf_field_type_common_integer_validate,
+ .set_byte_order = bt_ctf_field_type_common_integer_set_byte_order,
+ .copy = (bt_ctf_field_type_common_method_copy)
bt_ctf_field_type_integer_copy,
- .compare = bt_field_type_common_integer_compare,
+ .compare = bt_ctf_field_type_common_integer_compare,
};
-static struct bt_field_type_common_methods bt_ctf_field_type_floating_point_methods = {
- .freeze = bt_field_type_common_generic_freeze,
+static struct bt_ctf_field_type_common_methods bt_ctf_field_type_floating_point_methods = {
+ .freeze = bt_ctf_field_type_common_generic_freeze,
.validate = NULL,
- .set_byte_order = bt_field_type_common_floating_point_set_byte_order,
- .copy = (bt_field_type_common_method_copy)
+ .set_byte_order = bt_ctf_field_type_common_floating_point_set_byte_order,
+ .copy = (bt_ctf_field_type_common_method_copy)
bt_ctf_field_type_floating_point_copy,
- .compare = bt_field_type_common_floating_point_compare,
+ .compare = bt_ctf_field_type_common_floating_point_compare,
};
-static struct bt_field_type_common_methods bt_ctf_field_type_enumeration_methods = {
- .freeze = bt_field_type_common_enumeration_freeze_recursive,
- .validate = bt_field_type_common_enumeration_validate_recursive,
- .set_byte_order = bt_field_type_common_enumeration_set_byte_order_recursive,
- .copy = (bt_field_type_common_method_copy)
+static struct bt_ctf_field_type_common_methods bt_ctf_field_type_enumeration_methods = {
+ .freeze = bt_ctf_field_type_common_enumeration_freeze_recursive,
+ .validate = bt_ctf_field_type_common_enumeration_validate_recursive,
+ .set_byte_order = bt_ctf_field_type_common_enumeration_set_byte_order_recursive,
+ .copy = (bt_ctf_field_type_common_method_copy)
bt_ctf_field_type_enumeration_copy_recursive,
- .compare = bt_field_type_common_enumeration_compare_recursive,
+ .compare = bt_ctf_field_type_common_enumeration_compare_recursive,
};
-static struct bt_field_type_common_methods bt_ctf_field_type_string_methods = {
- .freeze = bt_field_type_common_generic_freeze,
+static struct bt_ctf_field_type_common_methods bt_ctf_field_type_string_methods = {
+ .freeze = bt_ctf_field_type_common_generic_freeze,
.validate = NULL,
.set_byte_order = NULL,
- .copy = (bt_field_type_common_method_copy)
+ .copy = (bt_ctf_field_type_common_method_copy)
bt_ctf_field_type_string_copy,
- .compare = bt_field_type_common_string_compare,
+ .compare = bt_ctf_field_type_common_string_compare,
};
-static struct bt_field_type_common_methods bt_ctf_field_type_array_methods = {
- .freeze = bt_field_type_common_array_freeze_recursive,
- .validate = bt_field_type_common_array_validate_recursive,
- .set_byte_order = bt_field_type_common_array_set_byte_order_recursive,
- .copy = (bt_field_type_common_method_copy)
+static struct bt_ctf_field_type_common_methods bt_ctf_field_type_array_methods = {
+ .freeze = bt_ctf_field_type_common_array_freeze_recursive,
+ .validate = bt_ctf_field_type_common_array_validate_recursive,
+ .set_byte_order = bt_ctf_field_type_common_array_set_byte_order_recursive,
+ .copy = (bt_ctf_field_type_common_method_copy)
bt_ctf_field_type_array_copy_recursive,
- .compare = bt_field_type_common_array_compare_recursive,
+ .compare = bt_ctf_field_type_common_array_compare_recursive,
};
-static struct bt_field_type_common_methods bt_ctf_field_type_sequence_methods = {
- .freeze = bt_field_type_common_sequence_freeze_recursive,
- .validate = bt_field_type_common_sequence_validate_recursive,
- .set_byte_order = bt_field_type_common_sequence_set_byte_order_recursive,
- .copy = (bt_field_type_common_method_copy)
+static struct bt_ctf_field_type_common_methods bt_ctf_field_type_sequence_methods = {
+ .freeze = bt_ctf_field_type_common_sequence_freeze_recursive,
+ .validate = bt_ctf_field_type_common_sequence_validate_recursive,
+ .set_byte_order = bt_ctf_field_type_common_sequence_set_byte_order_recursive,
+ .copy = (bt_ctf_field_type_common_method_copy)
bt_ctf_field_type_sequence_copy_recursive,
- .compare = bt_field_type_common_sequence_compare_recursive,
+ .compare = bt_ctf_field_type_common_sequence_compare_recursive,
};
-static struct bt_field_type_common_methods bt_ctf_field_type_structure_methods = {
- .freeze = bt_field_type_common_structure_freeze_recursive,
- .validate = bt_field_type_common_structure_validate_recursive,
- .set_byte_order = bt_field_type_common_structure_set_byte_order_recursive,
- .copy = (bt_field_type_common_method_copy)
+static struct bt_ctf_field_type_common_methods bt_ctf_field_type_structure_methods = {
+ .freeze = bt_ctf_field_type_common_structure_freeze_recursive,
+ .validate = bt_ctf_field_type_common_structure_validate_recursive,
+ .set_byte_order = bt_ctf_field_type_common_structure_set_byte_order_recursive,
+ .copy = (bt_ctf_field_type_common_method_copy)
bt_ctf_field_type_structure_copy_recursive,
- .compare = bt_field_type_common_structure_compare_recursive,
+ .compare = bt_ctf_field_type_common_structure_compare_recursive,
};
-static struct bt_field_type_common_methods bt_ctf_field_type_variant_methods = {
- .freeze = bt_field_type_common_variant_freeze_recursive,
- .validate = bt_field_type_common_variant_validate_recursive,
- .set_byte_order = bt_field_type_common_variant_set_byte_order_recursive,
- .copy = (bt_field_type_common_method_copy)
+static struct bt_ctf_field_type_common_methods bt_ctf_field_type_variant_methods = {
+ .freeze = bt_ctf_field_type_common_variant_freeze_recursive,
+ .validate = bt_ctf_field_type_common_variant_validate_recursive,
+ .set_byte_order = bt_ctf_field_type_common_variant_set_byte_order_recursive,
+ .copy = (bt_ctf_field_type_common_method_copy)
bt_ctf_field_type_variant_copy_recursive,
- .compare = bt_field_type_common_variant_compare_recursive,
+ .compare = bt_ctf_field_type_common_variant_compare_recursive,
};
-typedef int (*bt_ctf_field_type_serialize_func)(struct bt_field_type_common *,
+typedef int (*bt_ctf_field_type_serialize_func)(struct bt_ctf_field_type_common *,
struct metadata_context *);
BT_HIDDEN
struct metadata_context *context)
{
int ret;
- struct bt_field_type_common *type_common = (void *) type;
+ struct bt_ctf_field_type_common *type_common = (void *) type;
bt_ctf_field_type_serialize_func serialize_func;
BT_ASSERT(type);
BT_ASSERT(context);
/* Make sure field type is valid before serializing it */
- ret = bt_field_type_common_validate((void *) type);
+ ret = bt_ctf_field_type_common_validate((void *) type);
if (ret) {
BT_LOGW("Cannot serialize field type's metadata: field type is invalid: "
"addr=%p", type);
}
static
-const char *get_encoding_string(enum bt_string_encoding encoding)
+const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
{
const char *encoding_string;
switch (encoding) {
- case BT_STRING_ENCODING_NONE:
+ case BT_CTF_STRING_ENCODING_NONE:
encoding_string = "none";
break;
- case BT_STRING_ENCODING_ASCII:
+ case BT_CTF_STRING_ENCODING_ASCII:
encoding_string = "ASCII";
break;
- case BT_STRING_ENCODING_UTF8:
+ case BT_CTF_STRING_ENCODING_UTF8:
encoding_string = "UTF8";
break;
default:
}
static
-const char *get_integer_base_string(enum bt_integer_base base)
+const char *get_integer_base_string(enum bt_ctf_integer_base base)
{
const char *base_string;
switch (base) {
- case BT_INTEGER_BASE_DECIMAL:
- case BT_INTEGER_BASE_UNSPECIFIED:
+ case BT_CTF_INTEGER_BASE_DECIMAL:
+ case BT_CTF_INTEGER_BASE_UNSPECIFIED:
base_string = "decimal";
break;
- case BT_INTEGER_BASE_HEXADECIMAL:
+ case BT_CTF_INTEGER_BASE_HEXADECIMAL:
base_string = "hexadecimal";
break;
- case BT_INTEGER_BASE_OCTAL:
+ case BT_CTF_INTEGER_BASE_OCTAL:
base_string = "octal";
break;
- case BT_INTEGER_BASE_BINARY:
+ case BT_CTF_INTEGER_BASE_BINARY:
base_string = "binary";
break;
default:
{
g_string_append_c(context->string, ' ');
- if (!bt_identifier_is_valid(name) || *name == '_') {
+ if (!bt_ctf_identifier_is_valid(name) || *name == '_') {
g_string_append_c(context->string, '_');
}
}
static
-int bt_ctf_field_type_integer_serialize(struct bt_field_type_common *type,
+int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type_common *type,
struct metadata_context *context)
{
- struct bt_field_type_common_integer *integer = BT_FROM_COMMON(type);
+ struct bt_ctf_field_type_common_integer *integer = BT_CTF_FROM_COMMON(type);
int ret = 0;
BT_LOGD("Serializing CTF writer integer field type's metadata: "
(integer->is_signed ? "true" : "false"),
get_encoding_string(integer->encoding),
get_integer_base_string(integer->base),
- get_byte_order_string(integer->user_byte_order));
+ bt_ctf_get_byte_order_string(integer->user_byte_order));
if (integer->mapped_clock_class) {
- const char *clock_name = bt_clock_class_get_name(
+ const char *clock_name = bt_ctf_clock_class_get_name(
integer->mapped_clock_class);
BT_ASSERT(clock_name);
static
int bt_ctf_field_type_enumeration_serialize_recursive(
- struct bt_field_type_common *type,
+ struct bt_ctf_field_type_common *type,
struct metadata_context *context)
{
size_t entry;
int ret;
- struct bt_field_type_common_enumeration *enumeration =
- BT_FROM_COMMON(type);
- struct bt_field_type_common *container_type;
+ struct bt_ctf_field_type_common_enumeration *enumeration =
+ BT_CTF_FROM_COMMON(type);
+ struct bt_ctf_field_type_common *container_type;
int container_signed;
BT_LOGD("Serializing CTF writer enumeration field type's metadata: "
"ft-addr=%p, metadata-context-addr=%p", type, context);
container_type =
- bt_field_type_common_enumeration_borrow_container_field_type(type);
+ bt_ctf_field_type_common_enumeration_borrow_container_field_type(type);
BT_ASSERT(container_type);
- container_signed = bt_field_type_common_integer_is_signed(
+ container_signed = bt_ctf_field_type_common_integer_is_signed(
container_type);
BT_ASSERT(container_signed >= 0);
g_string_append(context->string, "enum : ");
g_string_append(context->string, " { ");
for (entry = 0; entry < enumeration->entries->len; entry++) {
- struct enumeration_mapping *mapping =
+ struct bt_ctf_enumeration_mapping *mapping =
enumeration->entries->pdata[entry];
const char *label = g_quark_to_string(mapping->string);
g_string_append(context->string, "\"");
- if (!bt_identifier_is_valid(label) || label[0] == '_') {
+ if (!bt_ctf_identifier_is_valid(label) || label[0] == '_') {
g_string_append(context->string, "_");
}
}
static
-int bt_ctf_field_type_floating_point_serialize(struct bt_field_type_common *type,
+int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type_common *type,
struct metadata_context *context)
{
- struct bt_field_type_common_floating_point *floating_point =
- BT_FROM_COMMON(type);
+ struct bt_ctf_field_type_common_floating_point *floating_point =
+ BT_CTF_FROM_COMMON(type);
BT_LOGD("Serializing CTF writer floating point number field type's metadata: "
"ft-addr=%p, metadata-context-addr=%p", type, context);
"floating_point { exp_dig = %u; mant_dig = %u; byte_order = %s; align = %u; }",
floating_point->exp_dig,
floating_point->mant_dig,
- get_byte_order_string(floating_point->user_byte_order),
+ bt_ctf_get_byte_order_string(floating_point->user_byte_order),
type->alignment);
return 0;
}
static
int bt_ctf_field_type_structure_serialize_recursive(
- struct bt_field_type_common *type,
+ struct bt_ctf_field_type_common *type,
struct metadata_context *context)
{
size_t i;
unsigned int indent;
int ret = 0;
- struct bt_field_type_common_structure *structure = BT_FROM_COMMON(type);
+ struct bt_ctf_field_type_common_structure *structure = BT_CTF_FROM_COMMON(type);
GString *structure_field_name = context->field_name;
BT_LOGD("Serializing CTF writer structure field type's metadata: "
g_string_append(context->string, "struct {\n");
for (i = 0; i < structure->fields->len; i++) {
- struct bt_field_type_common_structure_field *field =
- BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
+ struct bt_ctf_field_type_common_structure_field *field =
+ BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
structure, i);
BT_LOGD("Serializing CTF writer structure field type's field metadata: "
static
int bt_ctf_field_type_variant_serialize_recursive(
- struct bt_field_type_common *type,
+ struct bt_ctf_field_type_common *type,
struct metadata_context *context)
{
size_t i;
unsigned int indent;
int ret = 0;
- struct bt_field_type_common_variant *variant = BT_FROM_COMMON(type);
+ struct bt_ctf_field_type_common_variant *variant = BT_CTF_FROM_COMMON(type);
GString *variant_field_name = context->field_name;
BT_LOGD("Serializing CTF writer variant field type's metadata: "
context->current_indentation_level++;
for (i = 0; i < variant->choices->len; i++) {
- struct bt_field_type_common_variant_choice *field =
- BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
+ struct bt_ctf_field_type_common_variant_choice *field =
+ BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
variant, i);
BT_LOGD("Serializing CTF writer variant field type's field metadata: "
static
int bt_ctf_field_type_array_serialize_recursive(
- struct bt_field_type_common *type,
+ struct bt_ctf_field_type_common *type,
struct metadata_context *context)
{
int ret = 0;
- struct bt_field_type_common_array *array = BT_FROM_COMMON(type);
+ struct bt_ctf_field_type_common_array *array = BT_CTF_FROM_COMMON(type);
BT_LOGD("Serializing CTF writer array field type's metadata: "
"ft-addr=%p, metadata-context-addr=%p", type, context);
static
int bt_ctf_field_type_sequence_serialize_recursive(
- struct bt_field_type_common *type,
+ struct bt_ctf_field_type_common *type,
struct metadata_context *context)
{
int ret = 0;
- struct bt_field_type_common_sequence *sequence = BT_FROM_COMMON(type);
+ struct bt_ctf_field_type_common_sequence *sequence = BT_CTF_FROM_COMMON(type);
BT_LOGD("Serializing CTF writer sequence field type's metadata: "
"ft-addr=%p, metadata-context-addr=%p", type, context);
}
static
-int bt_ctf_field_type_string_serialize(struct bt_field_type_common *type,
+int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type_common *type,
struct metadata_context *context)
{
- struct bt_field_type_common_string *string = BT_FROM_COMMON(type);
+ struct bt_ctf_field_type_common_string *string = BT_CTF_FROM_COMMON(type);
BT_LOGD("Serializing CTF writer string field type's metadata: "
"ft-addr=%p, metadata-context-addr=%p", type, context);
struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
{
- struct bt_field_type_common_integer *integer = NULL;
+ struct bt_ctf_field_type_common_integer *integer = NULL;
BT_LOGD("Creating CTF writer integer field type object: size=%u", size);
goto error;
}
- integer = g_new0(struct bt_field_type_common_integer, 1);
+ integer = g_new0(struct bt_ctf_field_type_common_integer, 1);
if (!integer) {
BT_LOGE_STR("Failed to allocate one integer field type.");
goto error;
}
- bt_field_type_common_integer_initialize(BT_TO_COMMON(integer),
- size, bt_field_type_common_integer_destroy,
+ bt_ctf_field_type_common_integer_initialize(BT_CTF_TO_COMMON(integer),
+ size, bt_ctf_field_type_common_integer_destroy,
&bt_ctf_field_type_integer_methods);
integer->common.spec.writer.serialize_func =
bt_ctf_field_type_integer_serialize;
int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *ft)
{
- return bt_field_type_common_integer_get_size((void *) ft);
+ return bt_ctf_field_type_common_integer_get_size((void *) ft);
}
bt_bool bt_ctf_field_type_integer_is_signed(struct bt_ctf_field_type *ft)
{
- return bt_field_type_common_integer_is_signed((void *) ft);
+ return bt_ctf_field_type_common_integer_is_signed((void *) ft);
}
int bt_ctf_field_type_integer_set_is_signed(struct bt_ctf_field_type *ft,
bt_bool is_signed)
{
- return bt_field_type_common_integer_set_is_signed((void *) ft,
+ return bt_ctf_field_type_common_integer_set_is_signed((void *) ft,
is_signed);
}
int bt_ctf_field_type_integer_set_size(struct bt_ctf_field_type *ft,
unsigned int size)
{
- return bt_field_type_common_integer_set_size((void *) ft, size);
+ return bt_ctf_field_type_common_integer_set_size((void *) ft, size);
}
enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
struct bt_ctf_field_type *ft)
{
- return (int) bt_field_type_common_integer_get_base((void *) ft);
+ return (int) bt_ctf_field_type_common_integer_get_base((void *) ft);
}
int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *ft,
enum bt_ctf_integer_base base)
{
- return bt_field_type_common_integer_set_base((void *) ft,
+ return bt_ctf_field_type_common_integer_set_base((void *) ft,
(int) base);
}
enum bt_ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
struct bt_ctf_field_type *ft)
{
- return (int) bt_field_type_common_integer_get_encoding((void *) ft);
+ return (int) bt_ctf_field_type_common_integer_get_encoding((void *) ft);
}
int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *ft,
enum bt_ctf_string_encoding encoding)
{
- return bt_field_type_common_integer_set_encoding((void *) ft,
+ return bt_ctf_field_type_common_integer_set_encoding((void *) ft,
(int) encoding);
}
struct bt_ctf_clock_class *bt_ctf_field_type_integer_get_mapped_clock_class(
struct bt_ctf_field_type *ft)
{
- return bt_get(bt_field_type_common_integer_borrow_mapped_clock_class(
+ return bt_get(bt_ctf_field_type_common_integer_borrow_mapped_clock_class(
(void *) ft));
}
struct bt_ctf_field_type *ft,
struct bt_ctf_clock_class *clock_class)
{
- return bt_field_type_common_integer_set_mapped_clock_class((void *) ft,
- BT_TO_COMMON(clock_class));
+ return bt_ctf_field_type_common_integer_set_mapped_clock_class((void *) ft,
+ clock_class);
}
int bt_ctf_field_type_enumeration_signed_get_mapping_by_index(
const char **mapping_name, int64_t *range_begin,
int64_t *range_end)
{
- return bt_field_type_common_enumeration_signed_get_mapping_by_index(
+ return bt_ctf_field_type_common_enumeration_signed_get_mapping_by_index(
(void *) ft, index, mapping_name, range_begin, range_end);
}
const char **mapping_name, uint64_t *range_begin,
uint64_t *range_end)
{
- return bt_field_type_common_enumeration_unsigned_get_mapping_by_index(
+ return bt_ctf_field_type_common_enumeration_unsigned_get_mapping_by_index(
(void *) ft, index, mapping_name, range_begin, range_end);
}
struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
struct bt_ctf_field_type *container_ft)
{
- struct bt_field_type_common_enumeration *enumeration = NULL;
- struct bt_field_type_common *int_ft = (void *) container_ft;
+ struct bt_ctf_field_type_common_enumeration *enumeration = NULL;
+ struct bt_ctf_field_type_common *int_ft = (void *) container_ft;
BT_LOGD("Creating CTF writer enumeration field type object: int-ft-addr=%p",
container_ft);
goto error;
}
- if (int_ft->id != BT_FIELD_TYPE_ID_INTEGER) {
+ if (int_ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
BT_LOGW("Invalid parameter: container field type is not an integer field type: "
"container-ft-addr=%p, container-ft-id=%s",
- container_ft, bt_common_field_type_id_string(int_ft->id));
+ container_ft, bt_ctf_field_type_id_string(int_ft->id));
goto error;
}
- enumeration = g_new0(struct bt_field_type_common_enumeration, 1);
+ enumeration = g_new0(struct bt_ctf_field_type_common_enumeration, 1);
if (!enumeration) {
BT_LOGE_STR("Failed to allocate one enumeration field type.");
goto error;
}
- bt_field_type_common_enumeration_initialize(BT_TO_COMMON(enumeration),
- int_ft, bt_field_type_common_enumeration_destroy_recursive,
+ bt_ctf_field_type_common_enumeration_initialize(BT_CTF_TO_COMMON(enumeration),
+ int_ft, bt_ctf_field_type_common_enumeration_destroy_recursive,
&bt_ctf_field_type_enumeration_methods);
enumeration->common.spec.writer.serialize_func =
bt_ctf_field_type_enumeration_serialize_recursive;
struct bt_ctf_field_type *ft)
{
return bt_get(
- bt_field_type_common_enumeration_borrow_container_field_type(
+ bt_ctf_field_type_common_enumeration_borrow_container_field_type(
(void *) ft));
}
struct bt_ctf_field_type *ft, const char *string,
int64_t range_start, int64_t range_end)
{
- return bt_field_type_common_enumeration_signed_add_mapping(
+ return bt_ctf_field_type_common_enumeration_signed_add_mapping(
(void *) ft, string, range_start, range_end);
}
struct bt_ctf_field_type *ft, const char *string,
uint64_t range_start, uint64_t range_end)
{
- return bt_field_type_common_enumeration_unsigned_add_mapping(
+ return bt_ctf_field_type_common_enumeration_unsigned_add_mapping(
(void *) ft, string, range_start, range_end);
}
int64_t bt_ctf_field_type_enumeration_get_mapping_count(
struct bt_ctf_field_type *ft)
{
- return bt_field_type_common_enumeration_get_mapping_count((void *) ft);
+ return bt_ctf_field_type_common_enumeration_get_mapping_count((void *) ft);
}
struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
{
- struct bt_field_type_common_floating_point *floating_point =
- g_new0(struct bt_field_type_common_floating_point, 1);
+ struct bt_ctf_field_type_common_floating_point *floating_point =
+ g_new0(struct bt_ctf_field_type_common_floating_point, 1);
BT_LOGD_STR("Creating CTF writer floating point number field type object.");
goto end;
}
- bt_field_type_common_floating_point_initialize(
- BT_TO_COMMON(floating_point),
- bt_field_type_common_floating_point_destroy,
+ bt_ctf_field_type_common_floating_point_initialize(
+ BT_CTF_TO_COMMON(floating_point),
+ bt_ctf_field_type_common_floating_point_destroy,
&bt_ctf_field_type_floating_point_methods);
floating_point->common.spec.writer.serialize_func =
bt_ctf_field_type_floating_point_serialize;
int bt_ctf_field_type_floating_point_get_exponent_digits(
struct bt_ctf_field_type *ft)
{
- return bt_field_type_common_floating_point_get_exponent_digits(
+ return bt_ctf_field_type_common_floating_point_get_exponent_digits(
(void *) ft);
}
int bt_ctf_field_type_floating_point_set_exponent_digits(
struct bt_ctf_field_type *ft, unsigned int exponent_digits)
{
- return bt_field_type_common_floating_point_set_exponent_digits(
+ return bt_ctf_field_type_common_floating_point_set_exponent_digits(
(void *) ft, exponent_digits);
}
int bt_ctf_field_type_floating_point_get_mantissa_digits(
struct bt_ctf_field_type *ft)
{
- return bt_field_type_common_floating_point_get_mantissa_digits(
+ return bt_ctf_field_type_common_floating_point_get_mantissa_digits(
(void *) ft);
}
int bt_ctf_field_type_floating_point_set_mantissa_digits(
struct bt_ctf_field_type *ft, unsigned int mantissa_digits)
{
- return bt_field_type_common_floating_point_set_mantissa_digits(
+ return bt_ctf_field_type_common_floating_point_set_mantissa_digits(
(void *) ft, mantissa_digits);
}
struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
{
- struct bt_field_type_common_structure *structure =
- g_new0(struct bt_field_type_common_structure, 1);
+ struct bt_ctf_field_type_common_structure *structure =
+ g_new0(struct bt_ctf_field_type_common_structure, 1);
BT_LOGD_STR("Creating CTF writer structure field type object.");
goto error;
}
- bt_field_type_common_structure_initialize(BT_TO_COMMON(structure),
- bt_field_type_common_structure_destroy_recursive,
+ bt_ctf_field_type_common_structure_initialize(BT_CTF_TO_COMMON(structure),
+ bt_ctf_field_type_common_structure_destroy_recursive,
&bt_ctf_field_type_structure_methods);
structure->common.spec.writer.serialize_func =
bt_ctf_field_type_structure_serialize_recursive;
struct bt_ctf_field_type *field_type,
const char *field_name)
{
- return bt_field_type_common_structure_add_field((void *) ft,
+ return bt_ctf_field_type_common_structure_add_field((void *) ft,
(void *) field_type, field_name);
}
int64_t bt_ctf_field_type_structure_get_field_count(struct bt_ctf_field_type *ft)
{
- return bt_field_type_common_structure_get_field_count((void *) ft);
+ return bt_ctf_field_type_common_structure_get_field_count((void *) ft);
}
int bt_ctf_field_type_structure_get_field_by_index(
const char **field_name,
struct bt_ctf_field_type **field_type, uint64_t index)
{
- int ret = bt_field_type_common_structure_borrow_field_by_index(
+ int ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
(void *) ft, field_name, (void *) field_type, index);
if (ret == 0 && field_type) {
struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
struct bt_ctf_field_type *ft, const char *name)
{
- return bt_get(bt_field_type_common_structure_borrow_field_type_by_name(
+ return bt_get(bt_ctf_field_type_common_structure_borrow_field_type_by_name(
(void *) ft, name));
}
struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
struct bt_ctf_field_type *tag_ft, const char *tag_name)
{
- struct bt_field_type_common_variant *var_ft = NULL;
+ struct bt_ctf_field_type_common_variant *var_ft = NULL;
BT_LOGD("Creating CTF writer variant field type object: "
"tag-ft-addr=%p, tag-field-name=\"%s\"",
tag_ft, tag_name);
- if (tag_name && !bt_identifier_is_valid(tag_name)) {
+ if (tag_name && !bt_ctf_identifier_is_valid(tag_name)) {
BT_LOGW("Invalid parameter: tag field name is not a valid CTF identifier: "
"tag-ft-addr=%p, tag-field-name=\"%s\"",
tag_ft, tag_name);
goto error;
}
- var_ft = g_new0(struct bt_field_type_common_variant, 1);
+ var_ft = g_new0(struct bt_ctf_field_type_common_variant, 1);
if (!var_ft) {
BT_LOGE_STR("Failed to allocate one variant field type.");
goto error;
}
- bt_field_type_common_variant_initialize(BT_TO_COMMON(var_ft),
+ bt_ctf_field_type_common_variant_initialize(BT_CTF_TO_COMMON(var_ft),
(void *) tag_ft, tag_name,
- bt_field_type_common_variant_destroy_recursive,
+ bt_ctf_field_type_common_variant_destroy_recursive,
&bt_ctf_field_type_variant_methods);
var_ft->common.spec.writer.serialize_func =
bt_ctf_field_type_variant_serialize_recursive;
struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_field_type(
struct bt_ctf_field_type *ft)
{
- return bt_get(bt_field_type_common_variant_borrow_tag_field_type(
+ return bt_get(bt_ctf_field_type_common_variant_borrow_tag_field_type(
(void *) ft));
}
const char *bt_ctf_field_type_variant_get_tag_name(struct bt_ctf_field_type *ft)
{
- return bt_field_type_common_variant_get_tag_name((void *) ft);
+ return bt_ctf_field_type_common_variant_get_tag_name((void *) ft);
}
int bt_ctf_field_type_variant_set_tag_name(
struct bt_ctf_field_type *ft, const char *name)
{
- return bt_field_type_common_variant_set_tag_name((void *) ft, name);
+ return bt_ctf_field_type_common_variant_set_tag_name((void *) ft, name);
}
int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *ft,
struct bt_ctf_field_type *field_type,
const char *field_name)
{
- return bt_field_type_common_variant_add_field((void *) ft,
+ return bt_ctf_field_type_common_variant_add_field((void *) ft,
(void *) field_type, field_name);
}
struct bt_ctf_field_type *ft,
const char *field_name)
{
- return bt_get(bt_field_type_common_variant_borrow_field_type_by_name(
+ return bt_get(bt_ctf_field_type_common_variant_borrow_field_type_by_name(
(void *) ft, field_name));
}
int ret;
int64_t choice_index;
struct bt_ctf_field *container;
- struct bt_field_type_common_variant *var_ft = (void *) ft;
+ struct bt_ctf_field_type_common_variant *var_ft = (void *) ft;
struct bt_ctf_field_type *ret_ft = NULL;
BT_ASSERT_PRE_NON_NULL(ft, "Field type");
- BT_ASSERT_PRE_FT_COMMON_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT,
+ BT_ASSERT_PRE_CTF_FT_COMMON_HAS_ID(ft, BT_CTF_FIELD_TYPE_ID_VARIANT,
"Field type");
BT_ASSERT_PRE_NON_NULL(tag_field, "Tag field");
- BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(
- (struct bt_field_common *) tag_field,
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(
+ (struct bt_ctf_field_common *) tag_field,
BT_CTF_FIELD_TYPE_ID_ENUM, "Tag field");
- BT_ASSERT_PRE_FIELD_COMMON_IS_SET((struct bt_field_common *) tag_field,
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET((struct bt_ctf_field_common *) tag_field,
"Tag field");
container = bt_ctf_field_enumeration_borrow_container(tag_field);
ret = bt_ctf_field_integer_signed_get_value(container,
&val);
BT_ASSERT(ret == 0);
- choice_index = bt_field_type_common_variant_find_choice_index(
+ choice_index = bt_ctf_field_type_common_variant_find_choice_index(
(void *) ft, (uint64_t) val, true);
} else {
uint64_t val;
ret = bt_ctf_field_integer_unsigned_get_value(container,
&val);
BT_ASSERT(ret == 0);
- choice_index = bt_field_type_common_variant_find_choice_index(
+ choice_index = bt_ctf_field_type_common_variant_find_choice_index(
(void *) ft, val, false);
}
if (choice_index < 0) {
BT_LIB_LOGW("Cannot find variant field type's field: "
- "%![var-ft-]+wF, %![tag-field-]+wf", ft, tag_field);
+ "var-ft-addr=%p, tag-field-addr=%p", ft, tag_field);
goto end;
}
int64_t bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *ft)
{
- return bt_field_type_common_variant_get_field_count((void *) ft);
+ return bt_ctf_field_type_common_variant_get_field_count((void *) ft);
}
int bt_ctf_field_type_variant_get_field_by_index(struct bt_ctf_field_type *ft,
const char **field_name, struct bt_ctf_field_type **field_type,
uint64_t index)
{
- int ret = bt_field_type_common_variant_borrow_field_by_index(
+ int ret = bt_ctf_field_type_common_variant_borrow_field_by_index(
(void *) ft, field_name, (void *) field_type, index);
if (ret == 0 && field_type) {
struct bt_ctf_field_type *bt_ctf_field_type_array_create(
struct bt_ctf_field_type *element_ft, unsigned int length)
{
- struct bt_field_type_common_array *array = NULL;
+ struct bt_ctf_field_type_common_array *array = NULL;
BT_LOGD("Creating CTF writer array field type object: element-ft-addr=%p, "
"length=%u", element_ft, length);
goto error;
}
- array = g_new0(struct bt_field_type_common_array, 1);
+ array = g_new0(struct bt_ctf_field_type_common_array, 1);
if (!array) {
BT_LOGE_STR("Failed to allocate one array field type.");
goto error;
}
- bt_field_type_common_array_initialize(BT_TO_COMMON(array),
+ bt_ctf_field_type_common_array_initialize(BT_CTF_TO_COMMON(array),
(void *) element_ft, length,
- bt_field_type_common_array_destroy_recursive,
+ bt_ctf_field_type_common_array_destroy_recursive,
&bt_ctf_field_type_array_methods);
array->common.spec.writer.serialize_func =
bt_ctf_field_type_array_serialize_recursive;
struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_field_type(
struct bt_ctf_field_type *ft)
{
- return bt_get(bt_field_type_common_array_borrow_element_field_type(
+ return bt_get(bt_ctf_field_type_common_array_borrow_element_field_type(
(void *) ft));
}
int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *ft)
{
- return bt_field_type_common_array_get_length((void *) ft);
+ return bt_ctf_field_type_common_array_get_length((void *) ft);
}
struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
struct bt_ctf_field_type *element_ft,
const char *length_field_name)
{
- struct bt_field_type_common_sequence *sequence = NULL;
+ struct bt_ctf_field_type_common_sequence *sequence = NULL;
BT_LOGD("Creating CTF writer sequence field type object: element-ft-addr=%p, "
"length-field-name=\"%s\"", element_ft, length_field_name);
goto error;
}
- if (!bt_identifier_is_valid(length_field_name)) {
+ if (!bt_ctf_identifier_is_valid(length_field_name)) {
BT_LOGW("Invalid parameter: length field name is not a valid CTF identifier: "
"length-field-name=\"%s\"", length_field_name);
goto error;
}
- sequence = g_new0(struct bt_field_type_common_sequence, 1);
+ sequence = g_new0(struct bt_ctf_field_type_common_sequence, 1);
if (!sequence) {
BT_LOGE_STR("Failed to allocate one sequence field type.");
goto error;
}
- bt_field_type_common_sequence_initialize(BT_TO_COMMON(sequence),
+ bt_ctf_field_type_common_sequence_initialize(BT_CTF_TO_COMMON(sequence),
(void *) element_ft, length_field_name,
- bt_field_type_common_sequence_destroy_recursive,
+ bt_ctf_field_type_common_sequence_destroy_recursive,
&bt_ctf_field_type_sequence_methods);
sequence->common.spec.writer.serialize_func =
bt_ctf_field_type_sequence_serialize_recursive;
struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_field_type(
struct bt_ctf_field_type *ft)
{
- return bt_get(bt_field_type_common_sequence_borrow_element_field_type(
+ return bt_get(bt_ctf_field_type_common_sequence_borrow_element_field_type(
(void *) ft));
}
const char *bt_ctf_field_type_sequence_get_length_field_name(
struct bt_ctf_field_type *ft)
{
- return bt_field_type_common_sequence_get_length_field_name((void *) ft);
+ return bt_ctf_field_type_common_sequence_get_length_field_name((void *) ft);
}
struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
{
- struct bt_field_type_common_string *string =
- g_new0(struct bt_field_type_common_string, 1);
+ struct bt_ctf_field_type_common_string *string =
+ g_new0(struct bt_ctf_field_type_common_string, 1);
BT_LOGD_STR("Creating CTF writer string field type object.");
return NULL;
}
- bt_field_type_common_string_initialize(BT_TO_COMMON(string),
- bt_field_type_common_string_destroy,
+ bt_ctf_field_type_common_string_initialize(BT_CTF_TO_COMMON(string),
+ bt_ctf_field_type_common_string_destroy,
&bt_ctf_field_type_string_methods);
string->common.spec.writer.serialize_func =
bt_ctf_field_type_string_serialize;
enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
struct bt_ctf_field_type *ft)
{
- return (int) bt_field_type_common_string_get_encoding((void *) ft);
+ return (int) bt_ctf_field_type_common_string_get_encoding((void *) ft);
}
int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *ft,
enum bt_ctf_string_encoding encoding)
{
- return bt_field_type_common_string_set_encoding((void *) ft,
+ return bt_ctf_field_type_common_string_set_encoding((void *) ft,
(int) encoding);
}
int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *ft)
{
- return bt_field_type_common_get_alignment((void *) ft);
+ return bt_ctf_field_type_common_get_alignment((void *) ft);
}
int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *ft,
unsigned int alignment)
{
- return bt_field_type_common_set_alignment((void *) ft, alignment);
+ return bt_ctf_field_type_common_set_alignment((void *) ft, alignment);
}
enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
struct bt_ctf_field_type *ft)
{
- return (int) bt_field_type_common_get_byte_order((void *) ft);
+ return (int) bt_ctf_field_type_common_get_byte_order((void *) ft);
}
int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *ft,
enum bt_ctf_byte_order byte_order)
{
- return bt_field_type_common_set_byte_order((void *) ft,
+ return bt_ctf_field_type_common_set_byte_order((void *) ft,
(int) byte_order);
}
enum bt_ctf_field_type_id bt_ctf_field_type_get_type_id(
struct bt_ctf_field_type *ft)
{
- return (int) bt_field_type_common_get_type_id((void *) ft);
+ return (int) bt_ctf_field_type_common_get_type_id((void *) ft);
}
BT_HIDDEN
struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *ft)
{
- return (void *) bt_field_type_common_copy((void *) ft);
+ return (void *) bt_ctf_field_type_common_copy((void *) ft);
}
static
struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
struct bt_ctf_field_type *ft)
{
- struct bt_field_type_common_integer *int_ft = (void *) ft;
- struct bt_field_type_common_integer *copy_ft;
+ struct bt_ctf_field_type_common_integer *int_ft = (void *) ft;
+ struct bt_ctf_field_type_common_integer *copy_ft;
BT_LOGD("Copying CTF writer integer field type's: addr=%p", ft);
copy_ft = (void *) bt_ctf_field_type_integer_create(int_ft->size);
struct bt_ctf_field_type *ft)
{
size_t i;
- struct bt_field_type_common_enumeration *enum_ft = (void *) ft;
- struct bt_field_type_common_enumeration *copy_ft = NULL;
- struct bt_field_type_common_enumeration *container_copy_ft;
+ struct bt_ctf_field_type_common_enumeration *enum_ft = (void *) ft;
+ struct bt_ctf_field_type_common_enumeration *copy_ft = NULL;
+ struct bt_ctf_field_type_common_enumeration *container_copy_ft;
BT_LOGD("Copying CTF writer enumeration field type's: addr=%p", ft);
/* Copy the source enumeration's container */
BT_LOGD_STR("Copying CTF writer enumeration field type's container field type.");
- container_copy_ft = BT_FROM_COMMON(bt_field_type_common_copy(
- BT_TO_COMMON(enum_ft->container_ft)));
+ container_copy_ft = BT_CTF_FROM_COMMON(bt_ctf_field_type_common_copy(
+ BT_CTF_TO_COMMON(enum_ft->container_ft)));
if (!container_copy_ft) {
BT_LOGE_STR("Cannot copy CTF writer enumeration field type's container field type.");
goto end;
/* Copy all enumaration entries */
for (i = 0; i < enum_ft->entries->len; i++) {
- struct enumeration_mapping *mapping = g_ptr_array_index(
+ struct bt_ctf_enumeration_mapping *mapping = g_ptr_array_index(
enum_ft->entries, i);
- struct enumeration_mapping *copy_mapping = g_new0(
- struct enumeration_mapping, 1);
+ struct bt_ctf_enumeration_mapping *copy_mapping = g_new0(
+ struct bt_ctf_enumeration_mapping, 1);
if (!copy_mapping) {
BT_LOGE_STR("Failed to allocate one enumeration mapping.");
struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
struct bt_ctf_field_type *ft)
{
- struct bt_field_type_common_floating_point *flt_ft = BT_FROM_COMMON(ft);
- struct bt_field_type_common_floating_point *copy_ft;
+ struct bt_ctf_field_type_common_floating_point *flt_ft = BT_CTF_FROM_COMMON(ft);
+ struct bt_ctf_field_type_common_floating_point *copy_ft;
BT_LOGD("Copying CTF writer floating point number field type's: addr=%p", ft);
copy_ft = (void *) bt_ctf_field_type_floating_point_create();
int64_t i;
GHashTableIter iter;
gpointer key, value;
- struct bt_field_type_common_structure *struct_ft = (void *) ft;
- struct bt_field_type_common_structure *copy_ft;
+ struct bt_ctf_field_type_common_structure *struct_ft = (void *) ft;
+ struct bt_ctf_field_type_common_structure *copy_ft;
BT_LOGD("Copying CTF writer structure field type's: addr=%p", ft);
copy_ft = (void *) bt_ctf_field_type_structure_create();
g_array_set_size(copy_ft->fields, struct_ft->fields->len);
for (i = 0; i < struct_ft->fields->len; i++) {
- struct bt_field_type_common_structure_field *entry, *copy_entry;
- struct bt_field_type_common *field_ft_copy;
+ struct bt_ctf_field_type_common_structure_field *entry, *copy_entry;
+ struct bt_ctf_field_type_common *field_ft_copy;
- entry = BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
+ entry = BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
struct_ft, i);
- copy_entry = BT_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
+ copy_entry = BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
copy_ft, i);
BT_LOGD("Copying CTF writer structure field type's field: "
"index=%" PRId64 ", "
int64_t i;
GHashTableIter iter;
gpointer key, value;
- struct bt_field_type_common *tag_ft_copy = NULL;
- struct bt_field_type_common_variant *var_ft = (void *) ft;
- struct bt_field_type_common_variant *copy_ft = NULL;
+ struct bt_ctf_field_type_common *tag_ft_copy = NULL;
+ struct bt_ctf_field_type_common_variant *var_ft = (void *) ft;
+ struct bt_ctf_field_type_common_variant *copy_ft = NULL;
BT_LOGD("Copying CTF writer variant field type's: addr=%p", ft);
if (var_ft->tag_ft) {
BT_LOGD_STR("Copying CTF writer variant field type's tag field type.");
- tag_ft_copy = bt_field_type_common_copy(
- BT_TO_COMMON(var_ft->tag_ft));
+ tag_ft_copy = bt_ctf_field_type_common_copy(
+ BT_CTF_TO_COMMON(var_ft->tag_ft));
if (!tag_ft_copy) {
BT_LOGE_STR("Cannot copy CTF writer variant field type's tag field type.");
goto end;
g_array_set_size(copy_ft->choices, var_ft->choices->len);
for (i = 0; i < var_ft->choices->len; i++) {
- struct bt_field_type_common_variant_choice *entry, *copy_entry;
- struct bt_field_type_common *field_ft_copy;
+ struct bt_ctf_field_type_common_variant_choice *entry, *copy_entry;
+ struct bt_ctf_field_type_common *field_ft_copy;
uint64_t range_i;
- entry = BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft, i);
- copy_entry = BT_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
+ entry = BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(var_ft, i);
+ copy_entry = BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
copy_ft, i);
BT_LOGD("Copying CTF writer variant field type's field: "
"index=%" PRId64 ", "
/* Copy ranges */
copy_entry->ranges = g_array_new(FALSE, TRUE,
- sizeof(struct bt_field_type_common_variant_choice_range));
+ sizeof(struct bt_ctf_field_type_common_variant_choice_range));
BT_ASSERT(copy_entry->ranges);
g_array_set_size(copy_entry->ranges, entry->ranges->len);
if (var_ft->tag_field_path) {
BT_LOGD_STR("Copying CTF writer variant field type's tag field path.");
- copy_ft->tag_field_path = bt_field_path_copy(
+ copy_ft->tag_field_path = bt_ctf_field_path_copy(
var_ft->tag_field_path);
if (!copy_ft->tag_field_path) {
BT_LOGE_STR("Cannot copy CTF writer variant field type's tag field path.");
struct bt_ctf_field_type *bt_ctf_field_type_array_copy_recursive(
struct bt_ctf_field_type *ft)
{
- struct bt_field_type_common *container_ft_copy = NULL;
- struct bt_field_type_common_array *array_ft = (void *) ft;
- struct bt_field_type_common_array *copy_ft = NULL;
+ struct bt_ctf_field_type_common *container_ft_copy = NULL;
+ struct bt_ctf_field_type_common_array *array_ft = (void *) ft;
+ struct bt_ctf_field_type_common_array *copy_ft = NULL;
BT_LOGD("Copying CTF writer array field type's: addr=%p", ft);
BT_LOGD_STR("Copying CTF writer array field type's element field type.");
- container_ft_copy = bt_field_type_common_copy(array_ft->element_ft);
+ container_ft_copy = bt_ctf_field_type_common_copy(array_ft->element_ft);
if (!container_ft_copy) {
BT_LOGE_STR("Cannot copy CTF writer array field type's element field type.");
goto end;
struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy_recursive(
struct bt_ctf_field_type *ft)
{
- struct bt_field_type_common *container_ft_copy = NULL;
- struct bt_field_type_common_sequence *seq_ft = (void *) ft;
- struct bt_field_type_common_sequence *copy_ft = NULL;
+ struct bt_ctf_field_type_common *container_ft_copy = NULL;
+ struct bt_ctf_field_type_common_sequence *seq_ft = (void *) ft;
+ struct bt_ctf_field_type_common_sequence *copy_ft = NULL;
BT_LOGD("Copying CTF writer sequence field type's: addr=%p", ft);
BT_LOGD_STR("Copying CTF writer sequence field type's element field type.");
- container_ft_copy = bt_field_type_common_copy(seq_ft->element_ft);
+ container_ft_copy = bt_ctf_field_type_common_copy(seq_ft->element_ft);
if (!container_ft_copy) {
BT_LOGE_STR("Cannot copy CTF writer sequence field type's element field type.");
goto end;
if (seq_ft->length_field_path) {
BT_LOGD_STR("Copying CTF writer sequence field type's length field path.");
- copy_ft->length_field_path = bt_field_path_copy(
+ copy_ft->length_field_path = bt_ctf_field_path_copy(
seq_ft->length_field_path);
if (!copy_ft->length_field_path) {
BT_LOGE_STR("Cannot copy CTF writer sequence field type's length field path.");
static
struct bt_ctf_field_type *bt_ctf_field_type_string_copy(struct bt_ctf_field_type *ft)
{
- struct bt_field_type_common_string *string_ft = (void *) ft;
- struct bt_field_type_common_string *copy_ft = NULL;
+ struct bt_ctf_field_type_common_string *string_ft = (void *) ft;
+ struct bt_ctf_field_type_common_string *copy_ft = NULL;
BT_LOGD("Copying CTF writer string field type's: addr=%p", ft);
copy_ft = (void *) bt_ctf_field_type_string_create();
--- /dev/null
+/*
+ * Copyright 2018 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:
+ *
+ * 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.
+ */
+
+#define BT_LOG_TAG "CTF-WRITER-FIELD-WRAPPER"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/ctf-writer/field-wrapper-internal.h>
+#include <babeltrace/ctf-writer/fields-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/object-internal.h>
+#include <glib.h>
+
+BT_HIDDEN
+struct bt_ctf_field_wrapper *bt_ctf_field_wrapper_new(void *data)
+{
+ struct bt_ctf_field_wrapper *field_wrapper =
+ g_new0(struct bt_ctf_field_wrapper, 1);
+
+ BT_LOGD_STR("Creating empty field wrapper object.");
+
+ if (!field_wrapper) {
+ BT_LOGE("Failed to allocate one field wrapper.");
+ goto end;
+ }
+
+ bt_object_init_unique(&field_wrapper->base);
+ BT_LOGD("Created empty field wrapper object: addr=%p",
+ field_wrapper);
+
+end:
+ return field_wrapper;
+}
+
+BT_HIDDEN
+void bt_ctf_field_wrapper_destroy(struct bt_ctf_field_wrapper *field_wrapper)
+{
+ BT_LOGD("Destroying field wrapper: addr=%p", field_wrapper);
+ BT_ASSERT(!field_wrapper->field);
+ BT_LOGD_STR("Putting stream class.");
+ g_free(field_wrapper);
+}
+
+BT_HIDDEN
+struct bt_ctf_field_wrapper *bt_ctf_field_wrapper_create(
+ struct bt_object_pool *pool, struct bt_ctf_field_type *ft)
+{
+ struct bt_ctf_field_wrapper *field_wrapper = NULL;
+
+ BT_ASSERT(pool);
+ BT_ASSERT(ft);
+ field_wrapper = bt_object_pool_create_object(pool);
+ if (!field_wrapper) {
+ BT_LIB_LOGE("Cannot allocate one field wrapper from field wrapper pool: "
+ "%![pool-]+o", pool);
+ goto error;
+ }
+
+ BT_ASSERT(field_wrapper->field);
+ goto end;
+
+error:
+ if (field_wrapper) {
+ bt_ctf_field_wrapper_destroy(field_wrapper);
+ field_wrapper = NULL;
+ }
+
+end:
+ return field_wrapper;
+}
#define BT_LOG_TAG "CTF-WRITER-FIELDS"
#include <babeltrace/lib-logging-internal.h>
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/align-internal.h>
+#include <babeltrace/assert-internal.h>
#include <babeltrace/compat/fcntl-internal.h>
-#include <babeltrace/ctf-writer/fields-internal.h>
+#include <babeltrace/compiler-internal.h>
#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/ctf-writer/fields-internal.h>
#include <babeltrace/ctf-writer/serialize-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/endian-internal.h>
#include <babeltrace/object-internal.h>
#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/endian-internal.h>
-#include <babeltrace/assert-internal.h>
#include <float.h>
#include <inttypes.h>
+#include <inttypes.h>
#include <stdlib.h>
-static struct bt_field_common_methods bt_ctf_field_integer_methods = {
- .set_is_frozen = bt_field_common_generic_set_is_frozen,
- .validate = bt_field_common_generic_validate,
+#define BT_ASSERT_PRE_CTF_FIELD_IS_INT_OR_ENUM(_field, _name) \
+ BT_ASSERT_PRE((_field)->type->id == BT_CTF_FIELD_TYPE_ID_INTEGER || \
+ (_field)->type->id == BT_CTF_FIELD_TYPE_ID_ENUM, \
+ _name " is not an integer or an enumeration field: " \
+ "field-addr=%p", (_field))
+
+BT_HIDDEN
+struct bt_ctf_field_common *bt_ctf_field_common_copy(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common *copy = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(field, "Field");
+ BT_ASSERT(field_type_common_has_known_id(field->type));
+ BT_ASSERT(field->methods->copy);
+ copy = field->methods->copy(field);
+ if (!copy) {
+ BT_LOGW("Cannot create field: ft-addr=%p", field->type);
+ goto end;
+ }
+
+ bt_ctf_field_common_set(copy, field->payload_set);
+
+end:
+ return copy;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_structure_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods,
+ bt_ctf_field_common_create_func field_create_func,
+ GDestroyNotify field_release_func)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_structure *structure_type =
+ BT_CTF_FROM_COMMON(type);
+ struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
+ size_t i;
+
+ BT_LOGD("Initializing common structure field object: ft-addr=%p", type);
+ bt_ctf_field_common_initialize(field, type, is_shared,
+ release_func, methods);
+ structure->fields = g_ptr_array_new_with_free_func(field_release_func);
+ g_ptr_array_set_size(structure->fields, structure_type->fields->len);
+
+ /* Create all fields contained in the structure field. */
+ for (i = 0; i < structure_type->fields->len; i++) {
+ struct bt_ctf_field_common *field;
+ struct bt_ctf_field_type_common_structure_field *struct_field =
+ BT_CTF_FIELD_TYPE_COMMON_STRUCTURE_FIELD_AT_INDEX(
+ structure_type, i);
+ field = field_create_func(struct_field->type);
+ if (!field) {
+ BT_LOGE("Failed to create structure field's member: name=\"%s\", index=%zu",
+ g_quark_to_string(struct_field->name), i);
+ ret = -1;
+ goto end;
+ }
+
+ g_ptr_array_index(structure->fields, i) = field;
+ }
+
+ BT_LOGD("Initialized common structure field object: addr=%p, ft-addr=%p",
+ field, type);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_variant_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods,
+ bt_ctf_field_common_create_func field_create_func,
+ GDestroyNotify field_release_func)
+{
+ int ret = 0;
+ struct bt_ctf_field_type_common_variant *variant_type =
+ BT_CTF_FROM_COMMON(type);
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
+ size_t i;
+
+ BT_LOGD("Initializing common variant field object: ft-addr=%p", type);
+ bt_ctf_field_common_initialize(field, type, is_shared,
+ release_func, methods);
+ ret = bt_ctf_field_type_common_variant_update_choices(type);
+ if (ret) {
+ BT_LOGE("Cannot update common variant field type choices: "
+ "ret=%d", ret);
+ goto end;
+ }
+
+ variant->fields = g_ptr_array_new_with_free_func(field_release_func);
+ g_ptr_array_set_size(variant->fields, variant_type->choices->len);
+
+ /* Create all fields contained in the variant field. */
+ for (i = 0; i < variant_type->choices->len; i++) {
+ struct bt_ctf_field_common *field;
+ struct bt_ctf_field_type_common_variant_choice *var_choice =
+ BT_CTF_FIELD_TYPE_COMMON_VARIANT_CHOICE_AT_INDEX(
+ variant_type, i);
+
+ field = field_create_func(var_choice->type);
+ if (!field) {
+ BT_LOGE("Failed to create variant field's member: name=\"%s\", index=%zu",
+ g_quark_to_string(var_choice->name), i);
+ ret = -1;
+ goto end;
+ }
+
+ g_ptr_array_index(variant->fields, i) = field;
+ }
+
+ BT_LOGD("Initialized common variant field object: addr=%p, ft-addr=%p",
+ field, type);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_string_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods)
+{
+ int ret = 0;
+ struct bt_ctf_field_common_string *string = BT_CTF_FROM_COMMON(field);
+
+ BT_LOGD("Initializing common string field object: ft-addr=%p", type);
+ bt_ctf_field_common_initialize(field, type, is_shared,
+ release_func, methods);
+ string->buf = g_array_sized_new(FALSE, FALSE, sizeof(char), 1);
+ if (!string->buf) {
+ ret = -1;
+ goto end;
+ }
+
+ g_array_index(string->buf, char, 0) = '\0';
+ BT_LOGD("Initialized common string field object: addr=%p, ft-addr=%p",
+ field, type);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_array_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods,
+ bt_ctf_field_common_create_func field_create_func,
+ GDestroyNotify field_destroy_func)
+{
+ struct bt_ctf_field_type_common_array *array_type = BT_CTF_FROM_COMMON(type);
+ struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
+ unsigned int array_length;
+ int ret = 0;
+ uint64_t i;
+
+ BT_LOGD("Initializing common array field object: ft-addr=%p", type);
+ BT_ASSERT(type);
+ bt_ctf_field_common_initialize(field, type, is_shared,
+ release_func, methods);
+ array_length = array_type->length;
+ array->elements = g_ptr_array_sized_new(array_length);
+ if (!array->elements) {
+ ret = -1;
+ goto end;
+ }
+
+ g_ptr_array_set_free_func(array->elements, field_destroy_func);
+ g_ptr_array_set_size(array->elements, array_length);
+
+ for (i = 0; i < array_length; i++) {
+ array->elements->pdata[i] = field_create_func(
+ array_type->element_ft);
+ if (!array->elements->pdata[i]) {
+ ret = -1;
+ goto end;
+ }
+ }
+
+ BT_LOGD("Initialized common array field object: addr=%p, ft-addr=%p",
+ field, type);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_sequence_initialize(struct bt_ctf_field_common *field,
+ struct bt_ctf_field_type_common *type,
+ bool is_shared, bt_object_release_func release_func,
+ struct bt_ctf_field_common_methods *methods,
+ GDestroyNotify field_destroy_func)
+{
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
+ int ret = 0;
+
+ BT_LOGD("Initializing common sequence field object: ft-addr=%p", type);
+ BT_ASSERT(type);
+ bt_ctf_field_common_initialize(field, type, is_shared,
+ release_func, methods);
+ sequence->elements = g_ptr_array_new();
+ if (!sequence->elements) {
+ ret = -1;
+ goto end;
+ }
+
+ g_ptr_array_set_free_func(sequence->elements, field_destroy_func);
+ BT_LOGD("Initialized common sequence field object: addr=%p, ft-addr=%p",
+ field, type);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_generic_validate(struct bt_ctf_field_common *field)
+{
+ return (field && field->payload_set) ? 0 : -1;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_structure_validate_recursive(struct bt_ctf_field_common *field)
+{
+ int64_t i;
+ int ret = 0;
+ struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < structure->fields->len; i++) {
+ ret = bt_ctf_field_common_validate_recursive(
+ (void *) structure->fields->pdata[i]);
+
+ if (ret) {
+ int this_ret;
+ const char *name;
+
+ this_ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
+ field->type, &name, NULL, i);
+ BT_ASSERT(this_ret == 0);
+ BT_ASSERT_PRE_MSG("Invalid structure field's field: "
+ "struct-field-addr=%p, field-name=\"%s\", "
+ "index=%" PRId64 ", field-addr=%p",
+ field, name, i, structure->fields->pdata[i]);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_variant_validate_recursive(struct bt_ctf_field_common *field)
+{
+ int ret = 0;
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ if (!variant->current_field) {
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_field_common_validate_recursive(variant->current_field);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_array_validate_recursive(struct bt_ctf_field_common *field)
+{
+ int64_t i;
+ int ret = 0;
+ struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < array->elements->len; i++) {
+ ret = bt_ctf_field_common_validate_recursive((void *) array->elements->pdata[i]);
+ if (ret) {
+ BT_ASSERT_PRE_MSG("Invalid array field's element field: "
+ "array-field-addr=%p, " PRId64 ", "
+ "elem-field-addr=%p",
+ field, i, array->elements->pdata[i]);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_common_sequence_validate_recursive(struct bt_ctf_field_common *field)
+{
+ size_t i;
+ int ret = 0;
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < sequence->elements->len; i++) {
+ ret = bt_ctf_field_common_validate_recursive(
+ (void *) sequence->elements->pdata[i]);
+ if (ret) {
+ BT_ASSERT_PRE_MSG("Invalid sequence field's element field: "
+ "seq-field-addr=%p, " PRId64 ", "
+ "elem-field-addr=%p",
+ field, i, sequence->elements->pdata[i]);
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_generic_reset(struct bt_ctf_field_common *field)
+{
+ BT_ASSERT(field);
+ field->payload_set = false;
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_structure_reset_recursive(struct bt_ctf_field_common *field)
+{
+ int64_t i;
+ struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < structure->fields->len; i++) {
+ struct bt_ctf_field_common *member = structure->fields->pdata[i];
+
+ if (!member) {
+ /*
+ * Structure members are lazily initialized;
+ * skip if this member has not been allocated
+ * yet.
+ */
+ continue;
+ }
+
+ bt_ctf_field_common_reset_recursive(member);
+ }
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_variant_reset_recursive(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+ variant->current_field = NULL;
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_array_reset_recursive(struct bt_ctf_field_common *field)
+{
+ size_t i;
+ struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < array->elements->len; i++) {
+ struct bt_ctf_field_common *member = array->elements->pdata[i];
+
+ if (!member) {
+ /*
+ * Array elements are lazily initialized; skip
+ * if this member has not been allocated yet.
+ */
+ continue;
+ }
+
+ bt_ctf_field_common_reset_recursive(member);
+ }
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_sequence_reset_recursive(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
+ uint64_t i;
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < sequence->elements->len; i++) {
+ if (sequence->elements->pdata[i]) {
+ bt_ctf_field_common_reset_recursive(
+ sequence->elements->pdata[i]);
+ }
+ }
+
+ sequence->length = 0;
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_generic_set_is_frozen(struct bt_ctf_field_common *field,
+ bool is_frozen)
+{
+ field->frozen = is_frozen;
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_structure_set_is_frozen_recursive(
+ struct bt_ctf_field_common *field, bool is_frozen)
+{
+ uint64_t i;
+ struct bt_ctf_field_common_structure *structure_field =
+ BT_CTF_FROM_COMMON(field);
+
+ BT_LOGD("Freezing structure field object: addr=%p", field);
+
+ for (i = 0; i < structure_field->fields->len; i++) {
+ struct bt_ctf_field_common *struct_field =
+ g_ptr_array_index(structure_field->fields, i);
+
+ BT_LOGD("Freezing structure field's field: field-addr=%p, index=%" PRId64,
+ struct_field, i);
+ bt_ctf_field_common_set_is_frozen_recursive(struct_field,
+ is_frozen);
+ }
+
+ bt_ctf_field_common_generic_set_is_frozen(field, is_frozen);
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_variant_set_is_frozen_recursive(
+ struct bt_ctf_field_common *field, bool is_frozen)
+{
+ uint64_t i;
+ struct bt_ctf_field_common_variant *variant_field = BT_CTF_FROM_COMMON(field);
+
+ BT_LOGD("Freezing variant field object: addr=%p", field);
+
+ for (i = 0; i < variant_field->fields->len; i++) {
+ struct bt_ctf_field_common *var_field =
+ g_ptr_array_index(variant_field->fields, i);
+
+ BT_LOGD("Freezing variant field's field: field-addr=%p, index=%" PRId64,
+ var_field, i);
+ bt_ctf_field_common_set_is_frozen_recursive(var_field, is_frozen);
+ }
+
+ bt_ctf_field_common_generic_set_is_frozen(field, is_frozen);
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_array_set_is_frozen_recursive(
+ struct bt_ctf_field_common *field, bool is_frozen)
+{
+ int64_t i;
+ struct bt_ctf_field_common_array *array_field = BT_CTF_FROM_COMMON(field);
+
+ BT_LOGD("Freezing array field object: addr=%p", field);
+
+ for (i = 0; i < array_field->elements->len; i++) {
+ struct bt_ctf_field_common *elem_field =
+ g_ptr_array_index(array_field->elements, i);
+
+ BT_LOGD("Freezing array field object's element field: "
+ "element-field-addr=%p, index=%" PRId64,
+ elem_field, i);
+ bt_ctf_field_common_set_is_frozen_recursive(elem_field, is_frozen);
+ }
+
+ bt_ctf_field_common_generic_set_is_frozen(field, is_frozen);
+}
+
+BT_HIDDEN
+void bt_ctf_field_common_sequence_set_is_frozen_recursive(
+ struct bt_ctf_field_common *field, bool is_frozen)
+{
+ int64_t i;
+ struct bt_ctf_field_common_sequence *sequence_field =
+ BT_CTF_FROM_COMMON(field);
+
+ BT_LOGD("Freezing sequence field object: addr=%p", field);
+
+ for (i = 0; i < sequence_field->length; i++) {
+ struct bt_ctf_field_common *elem_field =
+ g_ptr_array_index(sequence_field->elements, i);
+
+ BT_LOGD("Freezing sequence field object's element field: "
+ "element-field-addr=%p, index=%" PRId64,
+ elem_field, i);
+ bt_ctf_field_common_set_is_frozen_recursive(elem_field, is_frozen);
+ }
+
+ bt_ctf_field_common_generic_set_is_frozen(field, is_frozen);
+}
+
+BT_HIDDEN
+void _bt_ctf_field_common_set_is_frozen_recursive(struct bt_ctf_field_common *field,
+ bool is_frozen)
+{
+ if (!field) {
+ goto end;
+ }
+
+ BT_LOGD("Setting field object's frozen state: addr=%p, is-frozen=%d",
+ field, is_frozen);
+ BT_ASSERT(field_type_common_has_known_id(field->type));
+ BT_ASSERT(field->methods->set_is_frozen);
+ field->methods->set_is_frozen(field, is_frozen);
+
+end:
+ return;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_generic_is_set(struct bt_ctf_field_common *field)
+{
+ return field && field->payload_set;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_structure_is_set_recursive(
+ struct bt_ctf_field_common *field)
+{
+ bt_bool is_set = BT_FALSE;
+ size_t i;
+ struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < structure->fields->len; i++) {
+ is_set = bt_ctf_field_common_is_set_recursive(
+ structure->fields->pdata[i]);
+ if (!is_set) {
+ goto end;
+ }
+ }
+
+end:
+ return is_set;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_variant_is_set_recursive(struct bt_ctf_field_common *field)
+{
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
+ bt_bool is_set = BT_FALSE;
+
+ BT_ASSERT(field);
+
+ if (variant->current_field) {
+ is_set = bt_ctf_field_common_is_set_recursive(
+ variant->current_field);
+ }
+
+ return is_set;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_array_is_set_recursive(struct bt_ctf_field_common *field)
+{
+ size_t i;
+ bt_bool is_set = BT_FALSE;
+ struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ for (i = 0; i < array->elements->len; i++) {
+ is_set = bt_ctf_field_common_is_set_recursive(array->elements->pdata[i]);
+ if (!is_set) {
+ goto end;
+ }
+ }
+
+end:
+ return is_set;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_field_common_sequence_is_set_recursive(struct bt_ctf_field_common *field)
+{
+ size_t i;
+ bt_bool is_set = BT_FALSE;
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
+
+ BT_ASSERT(field);
+
+ if (!sequence->elements) {
+ goto end;
+ }
+
+ for (i = 0; i < sequence->elements->len; i++) {
+ is_set = bt_ctf_field_common_is_set_recursive(
+ sequence->elements->pdata[i]);
+ if (!is_set) {
+ goto end;
+ }
+ }
+
+end:
+ return is_set;
+}
+
+static struct bt_ctf_field_common_methods bt_ctf_field_integer_methods = {
+ .set_is_frozen = bt_ctf_field_common_generic_set_is_frozen,
+ .validate = bt_ctf_field_common_generic_validate,
.copy = NULL,
- .is_set = bt_field_common_generic_is_set,
- .reset = bt_field_common_generic_reset,
+ .is_set = bt_ctf_field_common_generic_is_set,
+ .reset = bt_ctf_field_common_generic_reset,
};
-static struct bt_field_common_methods bt_ctf_field_floating_point_methods = {
- .set_is_frozen = bt_field_common_generic_set_is_frozen,
- .validate = bt_field_common_generic_validate,
+static struct bt_ctf_field_common_methods bt_ctf_field_floating_point_methods = {
+ .set_is_frozen = bt_ctf_field_common_generic_set_is_frozen,
+ .validate = bt_ctf_field_common_generic_validate,
.copy = NULL,
- .is_set = bt_field_common_generic_is_set,
- .reset = bt_field_common_generic_reset,
+ .is_set = bt_ctf_field_common_generic_is_set,
+ .reset = bt_ctf_field_common_generic_reset,
};
static
void bt_ctf_field_enumeration_set_is_frozen_recursive(
- struct bt_field_common *field, bool is_frozen);
+ struct bt_ctf_field_common *field, bool is_frozen);
static
-int bt_ctf_field_enumeration_validate_recursive(struct bt_field_common *field);
+int bt_ctf_field_enumeration_validate_recursive(struct bt_ctf_field_common *field);
static
bt_bool bt_ctf_field_enumeration_is_set_recursive(
- struct bt_field_common *field);
+ struct bt_ctf_field_common *field);
static
-void bt_ctf_field_enumeration_reset_recursive(struct bt_field_common *field);
+void bt_ctf_field_enumeration_reset_recursive(struct bt_ctf_field_common *field);
-static struct bt_field_common_methods bt_ctf_field_enumeration_methods = {
+static struct bt_ctf_field_common_methods bt_ctf_field_enumeration_methods = {
.set_is_frozen = bt_ctf_field_enumeration_set_is_frozen_recursive,
.validate = bt_ctf_field_enumeration_validate_recursive,
.copy = NULL,
.reset = bt_ctf_field_enumeration_reset_recursive,
};
-static struct bt_field_common_methods bt_ctf_field_string_methods = {
- .set_is_frozen = bt_field_common_generic_set_is_frozen,
- .validate = bt_field_common_generic_validate,
+static struct bt_ctf_field_common_methods bt_ctf_field_string_methods = {
+ .set_is_frozen = bt_ctf_field_common_generic_set_is_frozen,
+ .validate = bt_ctf_field_common_generic_validate,
.copy = NULL,
- .is_set = bt_field_common_generic_is_set,
- .reset = bt_field_common_generic_reset,
+ .is_set = bt_ctf_field_common_generic_is_set,
+ .reset = bt_ctf_field_common_generic_reset,
};
-static struct bt_field_common_methods bt_ctf_field_structure_methods = {
- .set_is_frozen = bt_field_common_structure_set_is_frozen_recursive,
- .validate = bt_field_common_structure_validate_recursive,
+static struct bt_ctf_field_common_methods bt_ctf_field_structure_methods = {
+ .set_is_frozen = bt_ctf_field_common_structure_set_is_frozen_recursive,
+ .validate = bt_ctf_field_common_structure_validate_recursive,
.copy = NULL,
- .is_set = bt_field_common_structure_is_set_recursive,
- .reset = bt_field_common_structure_reset_recursive,
+ .is_set = bt_ctf_field_common_structure_is_set_recursive,
+ .reset = bt_ctf_field_common_structure_reset_recursive,
};
-static struct bt_field_common_methods bt_ctf_field_sequence_methods = {
- .set_is_frozen = bt_field_common_sequence_set_is_frozen_recursive,
- .validate = bt_field_common_sequence_validate_recursive,
+static struct bt_ctf_field_common_methods bt_ctf_field_sequence_methods = {
+ .set_is_frozen = bt_ctf_field_common_sequence_set_is_frozen_recursive,
+ .validate = bt_ctf_field_common_sequence_validate_recursive,
.copy = NULL,
- .is_set = bt_field_common_sequence_is_set_recursive,
- .reset = bt_field_common_sequence_reset_recursive,
+ .is_set = bt_ctf_field_common_sequence_is_set_recursive,
+ .reset = bt_ctf_field_common_sequence_reset_recursive,
};
-static struct bt_field_common_methods bt_ctf_field_array_methods = {
- .set_is_frozen = bt_field_common_array_set_is_frozen_recursive,
- .validate = bt_field_common_array_validate_recursive,
+static struct bt_ctf_field_common_methods bt_ctf_field_array_methods = {
+ .set_is_frozen = bt_ctf_field_common_array_set_is_frozen_recursive,
+ .validate = bt_ctf_field_common_array_validate_recursive,
.copy = NULL,
- .is_set = bt_field_common_array_is_set_recursive,
- .reset = bt_field_common_array_reset_recursive,
+ .is_set = bt_ctf_field_common_array_is_set_recursive,
+ .reset = bt_ctf_field_common_array_reset_recursive,
};
static
-void bt_ctf_field_variant_set_is_frozen_recursive(struct bt_field_common *field,
+void bt_ctf_field_variant_set_is_frozen_recursive(struct bt_ctf_field_common *field,
bool is_frozen);
static
-int bt_ctf_field_variant_validate_recursive(struct bt_field_common *field);
+int bt_ctf_field_variant_validate_recursive(struct bt_ctf_field_common *field);
static
-bt_bool bt_ctf_field_variant_is_set_recursive(struct bt_field_common *field);
+bt_bool bt_ctf_field_variant_is_set_recursive(struct bt_ctf_field_common *field);
static
-void bt_ctf_field_variant_reset_recursive(struct bt_field_common *field);
+void bt_ctf_field_variant_reset_recursive(struct bt_ctf_field_common *field);
-static struct bt_field_common_methods bt_ctf_field_variant_methods = {
+static struct bt_ctf_field_common_methods bt_ctf_field_variant_methods = {
.set_is_frozen = bt_ctf_field_variant_set_is_frozen_recursive,
.validate = bt_ctf_field_variant_validate_recursive,
.copy = NULL,
static
struct bt_ctf_field *(* const field_create_funcs[])(struct bt_ctf_field_type *) = {
- [BT_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_integer_create,
- [BT_FIELD_TYPE_ID_ENUM] = bt_ctf_field_enumeration_create,
- [BT_FIELD_TYPE_ID_FLOAT] = bt_ctf_field_floating_point_create,
- [BT_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_structure_create,
- [BT_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_variant_create,
- [BT_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_array_create,
- [BT_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_create,
- [BT_FIELD_TYPE_ID_STRING] = bt_ctf_field_string_create,
+ [BT_CTF_FIELD_TYPE_ID_INTEGER] = bt_ctf_field_integer_create,
+ [BT_CTF_FIELD_TYPE_ID_ENUM] = bt_ctf_field_enumeration_create,
+ [BT_CTF_FIELD_TYPE_ID_FLOAT] = bt_ctf_field_floating_point_create,
+ [BT_CTF_FIELD_TYPE_ID_STRUCT] = bt_ctf_field_structure_create,
+ [BT_CTF_FIELD_TYPE_ID_VARIANT] = bt_ctf_field_variant_create,
+ [BT_CTF_FIELD_TYPE_ID_ARRAY] = bt_ctf_field_array_create,
+ [BT_CTF_FIELD_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_create,
+ [BT_CTF_FIELD_TYPE_ID_STRING] = bt_ctf_field_string_create,
};
typedef int (*bt_ctf_field_serialize_recursive_func)(
- struct bt_field_common *, struct bt_ctf_stream_pos *,
+ struct bt_ctf_field_common *, struct bt_ctf_stream_pos *,
enum bt_ctf_byte_order);
static
void bt_ctf_field_integer_destroy(struct bt_ctf_field *field)
{
BT_LOGD("Destroying CTF writer integer field object: addr=%p", field);
- bt_field_common_integer_finalize((void *) field);
+ bt_ctf_field_common_integer_finalize((void *) field);
g_free(field);
}
{
BT_LOGD("Destroying CTF writer floating point field object: addr=%p",
field);
- bt_field_common_floating_point_finalize((void *) field);
+ bt_ctf_field_common_floating_point_finalize((void *) field);
g_free(field);
}
static
void bt_ctf_field_enumeration_destroy_recursive(struct bt_ctf_field *field)
{
- struct bt_ctf_field_enumeration *enumeration = BT_FROM_COMMON(field);
+ struct bt_ctf_field_enumeration *enumeration = BT_CTF_FROM_COMMON(field);
BT_LOGD("Destroying CTF writer enumeration field object: addr=%p",
field);
BT_LOGD_STR("Putting container field.");
bt_put(enumeration->container);
- bt_field_common_finalize((void *) field);
+ bt_ctf_field_common_finalize((void *) field);
g_free(field);
}
void bt_ctf_field_structure_destroy_recursive(struct bt_ctf_field *field)
{
BT_LOGD("Destroying CTF writer structure field object: addr=%p", field);
- bt_field_common_structure_finalize_recursive((void *) field);
+ bt_ctf_field_common_structure_finalize_recursive((void *) field);
g_free(field);
}
static
void bt_ctf_field_variant_destroy_recursive(struct bt_ctf_field *field)
{
- struct bt_ctf_field_variant *variant = BT_FROM_COMMON(field);
+ struct bt_ctf_field_variant *variant = BT_CTF_FROM_COMMON(field);
BT_LOGD("Destroying CTF writer variant field object: addr=%p", field);
BT_LOGD_STR("Putting tag field.");
bt_put(variant->tag);
- bt_field_common_variant_finalize_recursive((void *) field);
+ bt_ctf_field_common_variant_finalize_recursive((void *) field);
g_free(field);
}
void bt_ctf_field_array_destroy_recursive(struct bt_ctf_field *field)
{
BT_LOGD("Destroying CTF writer array field object: addr=%p", field);
- bt_field_common_array_finalize_recursive((void *) field);
+ bt_ctf_field_common_array_finalize_recursive((void *) field);
g_free(field);
}
void bt_ctf_field_sequence_destroy_recursive(struct bt_ctf_field *field)
{
BT_LOGD("Destroying CTF writer sequence field object: addr=%p", field);
- bt_field_common_sequence_finalize_recursive((void *) field);
+ bt_ctf_field_common_sequence_finalize_recursive((void *) field);
g_free(field);
}
void bt_ctf_field_string_destroy(struct bt_ctf_field *field)
{
BT_LOGD("Destroying CTF writer string field object: addr=%p", field);
- bt_field_common_string_finalize((void *) field);
+ bt_ctf_field_common_string_finalize((void *) field);
g_free(field);
}
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order)
{
- struct bt_field_common *field_common = (void *) field;
+ struct bt_ctf_field_common *field_common = (void *) field;
bt_ctf_field_serialize_recursive_func serialize_func;
BT_ASSERT(pos);
}
static
-int bt_ctf_field_integer_serialize(struct bt_field_common *field,
+int bt_ctf_field_integer_serialize(struct bt_ctf_field_common *field,
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order)
{
int ret = 0;
- BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field, "Integer field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field, "Integer field");
BT_LOGV("Serializing CTF writer integer field: addr=%p, pos-offset=%" PRId64 ", "
"native-bo=%s", field, pos->offset,
- bt_common_byte_order_string((int) native_byte_order));
+ bt_ctf_byte_order_string((int) native_byte_order));
retry:
ret = bt_ctf_field_integer_write(field, pos, native_byte_order);
}
static
-int bt_ctf_field_enumeration_serialize_recursive(struct bt_field_common *field,
+int bt_ctf_field_enumeration_serialize_recursive(struct bt_ctf_field_common *field,
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order)
{
BT_LOGV("Serializing enumeration field: addr=%p, pos-offset=%" PRId64 ", "
"native-bo=%s", field, pos->offset,
- bt_common_byte_order_string((int) native_byte_order));
+ bt_ctf_byte_order_string((int) native_byte_order));
BT_LOGV_STR("Serializing enumeration field's payload field.");
return bt_ctf_field_serialize_recursive(
(void *) enumeration->container, pos, native_byte_order);
}
static
-int bt_ctf_field_floating_point_serialize(struct bt_field_common *field,
+int bt_ctf_field_floating_point_serialize(struct bt_ctf_field_common *field,
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order)
{
int ret = 0;
- BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field, "Floating point number field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field, "Floating point number field");
BT_LOGV("Serializing floating point number field: addr=%p, pos-offset=%" PRId64 ", "
"native-bo=%s", field, pos->offset,
- bt_common_byte_order_string((int) native_byte_order));
+ bt_ctf_byte_order_string((int) native_byte_order));
retry:
ret = bt_ctf_field_floating_point_write(field, pos,
}
static
-int bt_ctf_field_structure_serialize_recursive(struct bt_field_common *field,
+int bt_ctf_field_structure_serialize_recursive(struct bt_ctf_field_common *field,
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order)
{
int64_t i;
int ret = 0;
- struct bt_field_common_structure *structure = BT_FROM_COMMON(field);
+ struct bt_ctf_field_common_structure *structure = BT_CTF_FROM_COMMON(field);
BT_LOGV("Serializing structure field: addr=%p, pos-offset=%" PRId64 ", "
"native-bo=%s", field, pos->offset,
- bt_common_byte_order_string((int) native_byte_order));
+ bt_ctf_byte_order_string((int) native_byte_order));
while (!bt_ctf_stream_pos_access_ok(pos,
offset_align(pos->offset, field->type->alignment))) {
}
for (i = 0; i < structure->fields->len; i++) {
- struct bt_field_common *member = g_ptr_array_index(
+ struct bt_ctf_field_common *member = g_ptr_array_index(
structure->fields, i);
const char *field_name = NULL;
pos->offset, member, i);
if (!member) {
- ret = bt_field_type_common_structure_borrow_field_by_index(
+ ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
field->type, &field_name, NULL, i);
BT_ASSERT(ret == 0);
BT_LOGW("Cannot serialize structure field's field: field is not set: "
ret = bt_ctf_field_serialize_recursive((void *) member, pos,
native_byte_order);
if (ret) {
- ret = bt_field_type_common_structure_borrow_field_by_index(
+ ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
field->type, &field_name, NULL, i);
BT_ASSERT(ret == 0);
BT_LOGW("Cannot serialize structure field's field: "
}
static
-int bt_ctf_field_variant_serialize_recursive(struct bt_field_common *field,
+int bt_ctf_field_variant_serialize_recursive(struct bt_ctf_field_common *field,
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order)
{
- struct bt_field_common_variant *variant = BT_FROM_COMMON(field);
+ struct bt_ctf_field_common_variant *variant = BT_CTF_FROM_COMMON(field);
BT_LOGV("Serializing variant field: addr=%p, pos-offset=%" PRId64 ", "
"native-bo=%s", field, pos->offset,
- bt_common_byte_order_string((int) native_byte_order));
+ bt_ctf_byte_order_string((int) native_byte_order));
BT_LOGV_STR("Serializing variant field's payload field.");
return bt_ctf_field_serialize_recursive(
(void *) variant->current_field, pos, native_byte_order);
}
static
-int bt_ctf_field_array_serialize_recursive(struct bt_field_common *field,
+int bt_ctf_field_array_serialize_recursive(struct bt_ctf_field_common *field,
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order)
{
int64_t i;
int ret = 0;
- struct bt_field_common_array *array = BT_FROM_COMMON(field);
+ struct bt_ctf_field_common_array *array = BT_CTF_FROM_COMMON(field);
BT_LOGV("Serializing array field: addr=%p, pos-offset=%" PRId64 ", "
"native-bo=%s", field, pos->offset,
- bt_common_byte_order_string((int) native_byte_order));
+ bt_ctf_byte_order_string((int) native_byte_order));
for (i = 0; i < array->elements->len; i++) {
- struct bt_field_common *elem_field =
+ struct bt_ctf_field_common *elem_field =
g_ptr_array_index(array->elements, i);
BT_LOGV("Serializing array field's element field: "
}
static
-int bt_ctf_field_sequence_serialize_recursive(struct bt_field_common *field,
+int bt_ctf_field_sequence_serialize_recursive(struct bt_ctf_field_common *field,
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order)
{
int64_t i;
int ret = 0;
- struct bt_field_common_sequence *sequence = BT_FROM_COMMON(field);
+ struct bt_ctf_field_common_sequence *sequence = BT_CTF_FROM_COMMON(field);
BT_LOGV("Serializing sequence field: addr=%p, pos-offset=%" PRId64 ", "
"native-bo=%s", field, pos->offset,
- bt_common_byte_order_string((int) native_byte_order));
+ bt_ctf_byte_order_string((int) native_byte_order));
for (i = 0; i < sequence->elements->len; i++) {
- struct bt_field_common *elem_field =
+ struct bt_ctf_field_common *elem_field =
g_ptr_array_index(sequence->elements, i);
BT_LOGV("Serializing sequence field's element field: "
}
static
-int bt_ctf_field_string_serialize(struct bt_field_common *field,
+int bt_ctf_field_string_serialize(struct bt_ctf_field_common *field,
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order)
{
int64_t i;
int ret = 0;
- struct bt_field_common_string *string = BT_FROM_COMMON(field);
+ struct bt_ctf_field_common_string *string = BT_CTF_FROM_COMMON(field);
struct bt_ctf_field_type *character_type =
get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
struct bt_ctf_field *character;
- BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field, "String field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(field, "String field");
BT_LOGV("Serializing string field: addr=%p, pos-offset=%" PRId64 ", "
"native-bo=%s", field, pos->offset,
- bt_common_byte_order_string((int) native_byte_order));
+ bt_ctf_byte_order_string((int) native_byte_order));
BT_LOGV_STR("Creating character field from string field's character field type.");
character = bt_ctf_field_create(character_type);
BT_ASSERT_PRE_NON_NULL(type, "Field type");
BT_ASSERT(field_type_common_has_known_id((void *) type));
- BT_ASSERT_PRE(bt_field_type_common_validate((void *) type) == 0,
- "Field type is invalid: %!+wF", type);
+ BT_ASSERT_PRE(bt_ctf_field_type_common_validate((void *) type) == 0,
+ "Field type is invalid: ft-addr=%p", type);
type_id = bt_ctf_field_type_get_type_id(type);
field = field_create_funcs[type_id](type);
if (!field) {
goto end;
}
- bt_field_type_common_freeze((void *) type);
+ bt_ctf_field_type_common_freeze((void *) type);
end:
return field;
struct bt_ctf_field_type *bt_ctf_field_get_type(struct bt_ctf_field *field)
{
- return bt_get(bt_field_common_borrow_type((void *) field));
+ return bt_get(bt_ctf_field_common_borrow_type((void *) field));
}
enum bt_ctf_field_type_id bt_ctf_field_get_type_id(struct bt_ctf_field *field)
{
- struct bt_field_common *field_common = (void *) field;
+ struct bt_ctf_field_common *field_common = (void *) field;
BT_ASSERT_PRE_NON_NULL(field, "Field");
return (int) field_common->type->id;
struct bt_ctf_field *length_field)
{
int ret;
- struct bt_field_common *common_length_field = (void *) length_field;
+ struct bt_ctf_field_common *common_length_field = (void *) length_field;
uint64_t length;
BT_ASSERT_PRE_NON_NULL(length_field, "Length field");
- BT_ASSERT_PRE_FIELD_COMMON_IS_SET((void *) length_field, "Length field");
- BT_ASSERT_PRE(common_length_field->type->id == BT_FIELD_TYPE_ID_INTEGER ||
- common_length_field->type->id == BT_FIELD_TYPE_ID_ENUM,
- "Length field must be an integer or enumeration field: %!+wf",
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET((void *) length_field, "Length field");
+ BT_ASSERT_PRE(common_length_field->type->id == BT_CTF_FIELD_TYPE_ID_INTEGER ||
+ common_length_field->type->id == BT_CTF_FIELD_TYPE_ID_ENUM,
+ "Length field must be an integer or enumeration field: field-addr=%p",
length_field);
- if (common_length_field->type->id == BT_FIELD_TYPE_ID_ENUM) {
+ if (common_length_field->type->id == BT_CTF_FIELD_TYPE_ID_ENUM) {
struct bt_ctf_field_enumeration *enumeration = (void *)
length_field;
ret = bt_ctf_field_integer_unsigned_get_value(length_field, &length);
BT_ASSERT(ret == 0);
- return bt_field_common_sequence_set_length((void *) field,
- length, (bt_field_common_create_func) bt_ctf_field_create);
+ return bt_ctf_field_common_sequence_set_length((void *) field,
+ length, (bt_ctf_field_common_create_func) bt_ctf_field_create);
}
struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
struct bt_ctf_field *field, uint64_t index)
{
- return bt_get(bt_field_common_structure_borrow_field_by_index(
+ return bt_get(bt_ctf_field_common_structure_borrow_field_by_index(
(void *) field, index));
}
struct bt_ctf_field *bt_ctf_field_structure_get_field_by_name(
struct bt_ctf_field *field, const char *name)
{
- return bt_get(bt_field_common_structure_borrow_field_by_name(
+ return bt_get(bt_ctf_field_common_structure_borrow_field_by_name(
(void *) field, name));
}
struct bt_ctf_field *field, uint64_t index)
{
return bt_get(
- bt_field_common_array_borrow_field((void *) field, index));
+ bt_ctf_field_common_array_borrow_field((void *) field, index));
}
struct bt_ctf_field *bt_ctf_field_sequence_get_field(
struct bt_ctf_field *field, uint64_t index)
{
return bt_get(
- bt_field_common_sequence_borrow_field((void *) field, index));
+ bt_ctf_field_common_sequence_borrow_field((void *) field, index));
}
struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field,
{
struct bt_ctf_field_variant *variant_field = (void *) field;
struct bt_ctf_field_enumeration *enum_field = (void *) tag_field;
- struct bt_field_type_common_variant *variant_ft;
- struct bt_field_type_common_enumeration *tag_ft;
+ struct bt_ctf_field_type_common_variant *variant_ft;
+ struct bt_ctf_field_type_common_enumeration *tag_ft;
struct bt_ctf_field *current_field = NULL;
bt_bool is_signed;
uint64_t tag_uval;
BT_ASSERT_PRE_NON_NULL(field, "Variant field");
BT_ASSERT_PRE_NON_NULL(tag_field, "Tag field");
- BT_ASSERT_PRE_FIELD_COMMON_IS_SET((void *) tag_field, "Tag field");
- BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(
- (struct bt_field_common *) tag_field,
- BT_FIELD_TYPE_ID_ENUM, "Tag field");
- BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(
- (struct bt_field_common *) field,
- BT_FIELD_TYPE_ID_VARIANT, "Field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET((void *) tag_field, "Tag field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(
+ (struct bt_ctf_field_common *) tag_field,
+ BT_CTF_FIELD_TYPE_ID_ENUM, "Tag field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(
+ (struct bt_ctf_field_common *) field,
+ BT_CTF_FIELD_TYPE_ID_VARIANT, "Field");
BT_ASSERT_PRE(
- bt_field_common_validate_recursive((void *) tag_field) == 0,
- "Tag field is invalid: %!+wf", tag_field);
- variant_ft = BT_FROM_COMMON(variant_field->common.common.type);
- BT_ASSERT_PRE(bt_field_type_common_compare(
- BT_TO_COMMON(variant_ft->tag_ft), enum_field->common.type) == 0,
- "Unexpected tag field's type: %![expected-ft-]+wF, "
- "%![tag-ft-]+wF", variant_ft->tag_ft,
+ bt_ctf_field_common_validate_recursive((void *) tag_field) == 0,
+ "Tag field is invalid: field-addr=%p", tag_field);
+ variant_ft = BT_CTF_FROM_COMMON(variant_field->common.common.type);
+ BT_ASSERT_PRE(bt_ctf_field_type_common_compare(
+ BT_CTF_TO_COMMON(variant_ft->tag_ft), enum_field->common.type) == 0,
+ "Unexpected tag field's type: expected-ft-addr=%p, "
+ "tag-ft-addr=%p", variant_ft->tag_ft,
enum_field->common.type);
- tag_ft = BT_FROM_COMMON(enum_field->common.type);
+ tag_ft = BT_CTF_FROM_COMMON(enum_field->common.type);
is_signed = tag_ft->container_ft->is_signed;
if (is_signed) {
}
BT_ASSERT(ret == 0);
- ret = bt_field_variant_common_set_tag((void *) field, tag_uval,
+ ret = bt_ctf_field_common_variant_set_tag((void *) field, tag_uval,
is_signed);
if (ret) {
goto end;
struct bt_ctf_field *bt_ctf_field_variant_get_current_field(
struct bt_ctf_field *variant_field)
{
- return bt_get(bt_field_common_variant_borrow_current_field(
+ return bt_get(bt_ctf_field_common_variant_borrow_current_field(
(void *) variant_field));
}
struct bt_ctf_field_enumeration *enumeration = (void *) field;
BT_ASSERT_PRE_NON_NULL(field, "Enumeration field");
- BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID((struct bt_field_common *) field,
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID((struct bt_ctf_field_common *) field,
BT_CTF_FIELD_TYPE_ID_ENUM, "Field");
BT_ASSERT(enumeration->container);
return (void *) enumeration->container;
int bt_ctf_field_integer_signed_get_value(struct bt_ctf_field *field,
int64_t *value)
{
- struct bt_field_common_integer *integer = (void *) field;
+ struct bt_ctf_field_common_integer *integer = (void *) field;
BT_ASSERT_PRE_NON_NULL(field, "Integer field");
BT_ASSERT_PRE_NON_NULL(value, "Value");
- BT_ASSERT_PRE_FIELD_COMMON_IS_SET(BT_TO_COMMON(integer), "Integer field");
- BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(BT_TO_COMMON(integer),
- BT_FIELD_TYPE_ID_INTEGER, "Field");
- BT_ASSERT_PRE(bt_field_type_common_integer_is_signed(
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(BT_CTF_TO_COMMON(integer), "Integer field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer),
+ BT_CTF_FIELD_TYPE_ID_INTEGER, "Field");
+ BT_ASSERT_PRE(bt_ctf_field_type_common_integer_is_signed(
integer->common.type),
- "Field's type is unsigned: %!+_f", field);
+ "Field's type is unsigned: field-addr=%p", field);
*value = integer->payload.signd;
return 0;
}
int64_t value)
{
int ret = 0;
- struct bt_field_common_integer *integer = (void *) field;
- struct bt_field_type_common_integer *integer_type;
+ struct bt_ctf_field_common_integer *integer = (void *) field;
+ struct bt_ctf_field_type_common_integer *integer_type;
BT_ASSERT_PRE_NON_NULL(field, "Integer field");
- BT_ASSERT_PRE_FIELD_COMMON_HOT(BT_TO_COMMON(integer), "Integer field");
- BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(BT_TO_COMMON(integer),
- BT_FIELD_TYPE_ID_INTEGER, "Field");
- integer_type = BT_FROM_COMMON(integer->common.type);
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HOT(BT_CTF_TO_COMMON(integer), "Integer field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer),
+ BT_CTF_FIELD_TYPE_ID_INTEGER, "Field");
+ integer_type = BT_CTF_FROM_COMMON(integer->common.type);
BT_ASSERT_PRE(
- bt_field_type_common_integer_is_signed(integer->common.type),
- "Field's type is unsigned: %!+wf", field);
+ bt_ctf_field_type_common_integer_is_signed(integer->common.type),
+ "Field's type is unsigned: field-addr=%p", field);
BT_ASSERT_PRE(value_is_in_range_signed(integer_type->size, value),
- "Value is out of bounds: value=%" PRId64 ", %![field-]+wf",
+ "Value is out of bounds: value=%" PRId64 ", field-addr=%p",
value, field);
integer->payload.signd = value;
- bt_field_common_set(BT_TO_COMMON(integer), true);
+ bt_ctf_field_common_set(BT_CTF_TO_COMMON(integer), true);
return ret;
}
int bt_ctf_field_integer_unsigned_get_value(struct bt_ctf_field *field,
uint64_t *value)
{
- struct bt_field_common_integer *integer = (void *) field;
+ struct bt_ctf_field_common_integer *integer = (void *) field;
BT_ASSERT_PRE_NON_NULL(field, "Integer field");
BT_ASSERT_PRE_NON_NULL(value, "Value");
- BT_ASSERT_PRE_FIELD_COMMON_IS_SET(BT_TO_COMMON(integer), "Integer field");
- BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(BT_TO_COMMON(integer),
- BT_FIELD_TYPE_ID_INTEGER, "Field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_IS_SET(BT_CTF_TO_COMMON(integer), "Integer field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer),
+ BT_CTF_FIELD_TYPE_ID_INTEGER, "Field");
BT_ASSERT_PRE(
- !bt_field_type_common_integer_is_signed(integer->common.type),
- "Field's type is signed: %!+wf", field);
+ !bt_ctf_field_type_common_integer_is_signed(integer->common.type),
+ "Field's type is signed: field-addr=%p", field);
*value = integer->payload.unsignd;
return 0;
}
int bt_ctf_field_integer_unsigned_set_value(struct bt_ctf_field *field,
uint64_t value)
{
- struct bt_field_common_integer *integer = (void *) field;
- struct bt_field_type_common_integer *integer_type;
+ struct bt_ctf_field_common_integer *integer = (void *) field;
+ struct bt_ctf_field_type_common_integer *integer_type;
BT_ASSERT_PRE_NON_NULL(field, "Integer field");
- BT_ASSERT_PRE_FIELD_COMMON_HOT(BT_TO_COMMON(integer), "Integer field");
- BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(BT_TO_COMMON(integer),
- BT_FIELD_TYPE_ID_INTEGER, "Field");
- integer_type = BT_FROM_COMMON(integer->common.type);
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HOT(BT_CTF_TO_COMMON(integer), "Integer field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(BT_CTF_TO_COMMON(integer),
+ BT_CTF_FIELD_TYPE_ID_INTEGER, "Field");
+ integer_type = BT_CTF_FROM_COMMON(integer->common.type);
BT_ASSERT_PRE(
- !bt_field_type_common_integer_is_signed(integer->common.type),
- "Field's type is signed: %!+wf", field);
+ !bt_ctf_field_type_common_integer_is_signed(integer->common.type),
+ "Field's type is signed: field-addr=%p", field);
BT_ASSERT_PRE(value_is_in_range_unsigned(integer_type->size, value),
- "Value is out of bounds: value=%" PRIu64 ", %![field-]+wf",
+ "Value is out of bounds: value=%" PRIu64 ", field-addr=%p",
value, field);
integer->payload.unsignd = value;
- bt_field_common_set(BT_TO_COMMON(integer), true);
+ bt_ctf_field_common_set(BT_CTF_TO_COMMON(integer), true);
return 0;
}
int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field,
double *value)
{
- return bt_field_common_floating_point_get_value((void *) field, value);
+ return bt_ctf_field_common_floating_point_get_value((void *) field, value);
}
int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field,
double value)
{
- return bt_field_common_floating_point_set_value((void *) field, value);
+ return bt_ctf_field_common_floating_point_set_value((void *) field, value);
}
const char *bt_ctf_field_string_get_value(struct bt_ctf_field *field)
{
- return bt_field_common_string_get_value((void *) field);
+ return bt_ctf_field_common_string_get_value((void *) field);
}
int bt_ctf_field_string_set_value(struct bt_ctf_field *field, const char *value)
{
- return bt_field_common_string_set_value((void *) field, value);
+ return bt_ctf_field_common_string_set_value((void *) field, value);
}
int bt_ctf_field_string_append(struct bt_ctf_field *field, const char *value)
{
- return bt_field_common_string_append((void *) field, value);
+ return bt_ctf_field_common_string_append((void *) field, value);
}
int bt_ctf_field_string_append_len(struct bt_ctf_field *field,
const char *value, unsigned int length)
{
- return bt_field_common_string_append_len((void *) field, value, length);
+ return bt_ctf_field_common_string_append_len((void *) field, value, length);
}
struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
{
- return (void *) bt_field_common_copy((void *) field);
+ return (void *) bt_ctf_field_common_copy((void *) field);
}
static
struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
{
- struct bt_field_common_integer *integer =
- g_new0(struct bt_field_common_integer, 1);
+ struct bt_ctf_field_common_integer *integer =
+ g_new0(struct bt_ctf_field_common_integer, 1);
BT_LOGD("Creating CTF writer integer field object: ft-addr=%p", type);
if (integer) {
- bt_field_common_initialize(BT_TO_COMMON(integer), (void *) type,
+ bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(integer), (void *) type,
true,
(bt_object_release_func) bt_ctf_field_integer_destroy,
&bt_ctf_field_integer_methods);
struct bt_ctf_field *bt_ctf_field_enumeration_create(
struct bt_ctf_field_type *type)
{
- struct bt_field_type_common_enumeration *enum_ft = (void *) type;
+ struct bt_ctf_field_type_common_enumeration *enum_ft = (void *) type;
struct bt_ctf_field_enumeration *enumeration = g_new0(
struct bt_ctf_field_enumeration, 1);
goto end;
}
- bt_field_common_initialize(BT_TO_COMMON(enumeration),
+ bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(enumeration),
(void *) type,
true, (bt_object_release_func)
bt_ctf_field_enumeration_destroy_recursive,
&bt_ctf_field_enumeration_methods);
enumeration->container = (void *) bt_ctf_field_create(
- BT_FROM_COMMON(enum_ft->container_ft));
+ BT_CTF_FROM_COMMON(enum_ft->container_ft));
if (!enumeration->container) {
BT_PUT(enumeration);
goto end;
struct bt_ctf_field *bt_ctf_field_floating_point_create(
struct bt_ctf_field_type *type)
{
- struct bt_field_common_floating_point *floating_point;
+ struct bt_ctf_field_common_floating_point *floating_point;
BT_LOGD("Creating CTF writer floating point number field object: ft-addr=%p", type);
- floating_point = g_new0(struct bt_field_common_floating_point, 1);
+ floating_point = g_new0(struct bt_ctf_field_common_floating_point, 1);
if (floating_point) {
- bt_field_common_initialize(BT_TO_COMMON(floating_point),
+ bt_ctf_field_common_initialize(BT_CTF_TO_COMMON(floating_point),
(void *) type,
true, (bt_object_release_func)
bt_ctf_field_floating_point_destroy,
struct bt_ctf_field *bt_ctf_field_structure_create(
struct bt_ctf_field_type *type)
{
- struct bt_field_common_structure *structure = g_new0(
- struct bt_field_common_structure, 1);
+ struct bt_ctf_field_common_structure *structure = g_new0(
+ struct bt_ctf_field_common_structure, 1);
int iret;
BT_LOGD("Creating CTF writer structure field object: ft-addr=%p", type);
goto end;
}
- iret = bt_field_common_structure_initialize(BT_TO_COMMON(structure),
+ iret = bt_ctf_field_common_structure_initialize(BT_CTF_TO_COMMON(structure),
(void *) type,
true, (bt_object_release_func)
bt_ctf_field_structure_destroy_recursive,
&bt_ctf_field_structure_methods,
- (bt_field_common_create_func) bt_ctf_field_create,
+ (bt_ctf_field_common_create_func) bt_ctf_field_create,
(GDestroyNotify) bt_put);
structure->common.spec.writer.serialize_func =
(bt_ctf_field_serialize_recursive_func) bt_ctf_field_structure_serialize_recursive;
static
struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *type)
{
- struct bt_field_type_common_variant *var_ft = (void *) type;
+ struct bt_ctf_field_type_common_variant *var_ft = (void *) type;
struct bt_ctf_field_variant *variant = g_new0(
struct bt_ctf_field_variant, 1);
goto end;
}
- bt_field_common_variant_initialize(BT_TO_COMMON(BT_TO_COMMON(variant)),
+ bt_ctf_field_common_variant_initialize(BT_CTF_TO_COMMON(BT_CTF_TO_COMMON(variant)),
(void *) type,
true, (bt_object_release_func)
bt_ctf_field_variant_destroy_recursive,
&bt_ctf_field_variant_methods,
- (bt_field_common_create_func) bt_ctf_field_create,
+ (bt_ctf_field_common_create_func) bt_ctf_field_create,
(GDestroyNotify) bt_put);
variant->tag = (void *) bt_ctf_field_create(
- BT_FROM_COMMON(var_ft->tag_ft));
+ BT_CTF_FROM_COMMON(var_ft->tag_ft));
variant->common.common.spec.writer.serialize_func =
(bt_ctf_field_serialize_recursive_func) bt_ctf_field_variant_serialize_recursive;
BT_LOGD("Created CTF writer variant field object: addr=%p, ft-addr=%p",
static
struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *type)
{
- struct bt_field_common_array *array =
- g_new0(struct bt_field_common_array, 1);
+ struct bt_ctf_field_common_array *array =
+ g_new0(struct bt_ctf_field_common_array, 1);
int ret;
BT_LOGD("Creating CTF writer array field object: ft-addr=%p", type);
goto end;
}
- ret = bt_field_common_array_initialize(BT_TO_COMMON(array),
+ ret = bt_ctf_field_common_array_initialize(BT_CTF_TO_COMMON(array),
(void *) type,
true, (bt_object_release_func)
bt_ctf_field_array_destroy_recursive,
&bt_ctf_field_array_methods,
- (bt_field_common_create_func) bt_ctf_field_create,
+ (bt_ctf_field_common_create_func) bt_ctf_field_create,
(GDestroyNotify) bt_put);
array->common.spec.writer.serialize_func =
(bt_ctf_field_serialize_recursive_func) bt_ctf_field_array_serialize_recursive;
static
struct bt_ctf_field *bt_ctf_field_sequence_create(struct bt_ctf_field_type *type)
{
- struct bt_field_common_sequence *sequence = g_new0(
- struct bt_field_common_sequence, 1);
+ struct bt_ctf_field_common_sequence *sequence = g_new0(
+ struct bt_ctf_field_common_sequence, 1);
BT_LOGD("Creating CTF writer sequence field object: ft-addr=%p", type);
if (sequence) {
- bt_field_common_sequence_initialize(BT_TO_COMMON(sequence),
+ bt_ctf_field_common_sequence_initialize(BT_CTF_TO_COMMON(sequence),
(void *) type,
true, (bt_object_release_func)
bt_ctf_field_sequence_destroy_recursive,
static
struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type)
{
- struct bt_field_common_string *string = g_new0(
- struct bt_field_common_string, 1);
+ struct bt_ctf_field_common_string *string = g_new0(
+ struct bt_ctf_field_common_string, 1);
BT_LOGD("Creating CTF writer string field object: ft-addr=%p", type);
if (string) {
- bt_field_common_string_initialize(BT_TO_COMMON(string),
+ bt_ctf_field_common_string_initialize(BT_CTF_TO_COMMON(string),
(void *) type,
true, (bt_object_release_func)
bt_ctf_field_string_destroy,
static
void bt_ctf_field_enumeration_set_is_frozen_recursive(
- struct bt_field_common *field, bool is_frozen)
+ struct bt_ctf_field_common *field, bool is_frozen)
{
struct bt_ctf_field_enumeration *enumeration = (void *) field;
if (enumeration->container) {
- bt_field_common_set_is_frozen_recursive(
+ bt_ctf_field_common_set_is_frozen_recursive(
(void *) enumeration->container, is_frozen);
}
- bt_field_common_generic_set_is_frozen((void *) field, is_frozen);
+ bt_ctf_field_common_generic_set_is_frozen((void *) field, is_frozen);
}
static
-int bt_ctf_field_enumeration_validate_recursive(struct bt_field_common *field)
+int bt_ctf_field_enumeration_validate_recursive(struct bt_ctf_field_common *field)
{
int ret = -1;
struct bt_ctf_field_enumeration *enumeration = (void *) field;
if (enumeration->container) {
- ret = bt_field_common_validate_recursive(
+ ret = bt_ctf_field_common_validate_recursive(
(void *) enumeration->container);
}
}
static
-bt_bool bt_ctf_field_enumeration_is_set_recursive(struct bt_field_common *field)
+bt_bool bt_ctf_field_enumeration_is_set_recursive(struct bt_ctf_field_common *field)
{
bt_bool is_set = BT_FALSE;
struct bt_ctf_field_enumeration *enumeration = (void *) field;
if (enumeration->container) {
- is_set = bt_field_common_is_set_recursive(
+ is_set = bt_ctf_field_common_is_set_recursive(
(void *) enumeration->container);
}
}
static
-void bt_ctf_field_enumeration_reset_recursive(struct bt_field_common *field)
+void bt_ctf_field_enumeration_reset_recursive(struct bt_ctf_field_common *field)
{
struct bt_ctf_field_enumeration *enumeration = (void *) field;
if (enumeration->container) {
- bt_field_common_reset_recursive(
+ bt_ctf_field_common_reset_recursive(
(void *) enumeration->container);
}
- bt_field_common_generic_reset((void *) field);
+ bt_ctf_field_common_generic_reset((void *) field);
}
static
void bt_ctf_field_variant_set_is_frozen_recursive(
- struct bt_field_common *field, bool is_frozen)
+ struct bt_ctf_field_common *field, bool is_frozen)
{
struct bt_ctf_field_variant *variant = (void *) field;
if (variant->tag) {
- bt_field_common_set_is_frozen_recursive(
+ bt_ctf_field_common_set_is_frozen_recursive(
(void *) variant->tag, is_frozen);
}
- bt_field_common_variant_set_is_frozen_recursive((void *) field,
+ bt_ctf_field_common_variant_set_is_frozen_recursive((void *) field,
is_frozen);
}
static
-int bt_ctf_field_variant_validate_recursive(struct bt_field_common *field)
+int bt_ctf_field_variant_validate_recursive(struct bt_ctf_field_common *field)
{
int ret;
struct bt_ctf_field_variant *variant = (void *) field;
if (variant->tag) {
- ret = bt_field_common_validate_recursive(
+ ret = bt_ctf_field_common_validate_recursive(
(void *) variant->tag);
if (ret) {
goto end;
}
}
- ret = bt_field_common_variant_validate_recursive((void *) field);
+ ret = bt_ctf_field_common_variant_validate_recursive((void *) field);
end:
return ret;
}
static
-bt_bool bt_ctf_field_variant_is_set_recursive(struct bt_field_common *field)
+bt_bool bt_ctf_field_variant_is_set_recursive(struct bt_ctf_field_common *field)
{
bt_bool is_set;
struct bt_ctf_field_variant *variant = (void *) field;
if (variant->tag) {
- is_set = bt_field_common_is_set_recursive(
+ is_set = bt_ctf_field_common_is_set_recursive(
(void *) variant->tag);
if (is_set) {
goto end;
}
}
- is_set = bt_field_common_variant_is_set_recursive((void *) field);
+ is_set = bt_ctf_field_common_variant_is_set_recursive((void *) field);
end:
return is_set;
}
static
-void bt_ctf_field_variant_reset_recursive(struct bt_field_common *field)
+void bt_ctf_field_variant_reset_recursive(struct bt_ctf_field_common *field)
{
struct bt_ctf_field_variant *variant = (void *) field;
if (variant->tag) {
- bt_field_common_reset_recursive(
+ bt_ctf_field_common_reset_recursive(
(void *) variant->tag);
}
- bt_field_common_variant_reset_recursive((void *) field);
+ bt_ctf_field_common_variant_reset_recursive((void *) field);
}
BT_ASSERT_PRE_FUNC
static inline bool field_to_set_has_expected_type(
- struct bt_field_common *struct_field,
- const char *name, struct bt_field_common *value)
+ struct bt_ctf_field_common *struct_field,
+ const char *name, struct bt_ctf_field_common *value)
{
bool ret = true;
- struct bt_field_type_common *expected_field_type = NULL;
+ struct bt_ctf_field_type_common *expected_field_type = NULL;
expected_field_type =
- bt_field_type_common_structure_borrow_field_type_by_name(
+ bt_ctf_field_type_common_structure_borrow_field_type_by_name(
struct_field->type, name);
- if (bt_field_type_common_compare(expected_field_type, value->type)) {
+ if (bt_ctf_field_type_common_compare(expected_field_type, value->type)) {
BT_ASSERT_PRE_MSG("Value field's type is different from the expected field type: "
- "%![value-ft-]+_F, %![expected-ft-]+_F", value->type,
+ "value-ft-addr=%p, expected-ft-addr=%p", value->type,
expected_field_type);
ret = false;
goto end;
{
int ret = 0;
GQuark field_quark;
- struct bt_field_common *common_field = (void *) field;
- struct bt_field_common_structure *structure =
- BT_FROM_COMMON(common_field);
- struct bt_field_common *common_value = (void *) value;
+ struct bt_ctf_field_common *common_field = (void *) field;
+ struct bt_ctf_field_common_structure *structure =
+ BT_CTF_FROM_COMMON(common_field);
+ struct bt_ctf_field_common *common_value = (void *) value;
size_t index;
GHashTable *field_name_to_index;
- struct bt_field_type_common_structure *structure_ft;
+ struct bt_ctf_field_type_common_structure *structure_ft;
BT_ASSERT_PRE_NON_NULL(field, "Parent field");
BT_ASSERT_PRE_NON_NULL(name, "Field name");
BT_ASSERT_PRE_NON_NULL(value, "Value field");
- BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(common_field,
- BT_FIELD_TYPE_ID_STRUCT, "Parent field");
+ BT_ASSERT_PRE_CTF_FIELD_COMMON_HAS_TYPE_ID(common_field,
+ BT_CTF_FIELD_TYPE_ID_STRUCT, "Parent field");
BT_ASSERT_PRE(field_to_set_has_expected_type(common_field,
name, common_value),
"Value field's type is different from the expected field type.");
field_quark = g_quark_from_string(name);
- structure_ft = BT_FROM_COMMON(common_field->type);
+ structure_ft = BT_CTF_FROM_COMMON(common_field->type);
field_name_to_index = structure_ft->field_name_to_index;
if (!g_hash_table_lookup_extended(field_name_to_index,
GUINT_TO_POINTER(field_quark), NULL,
#include <glib.h>
#include <babeltrace/ctf-writer/functor-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
+#include <babeltrace/ctf-writer/utils-internal.h>
BT_HIDDEN
void value_exists(gpointer element, gpointer search_query)
{
- if (element == ((struct search_query *)search_query)->value) {
- ((struct search_query *)search_query)->found = 1;
+ if (element == ((struct bt_ctf_search_query *)search_query)->value) {
+ ((struct bt_ctf_search_query *)search_query)->found = 1;
}
}
--- /dev/null
+/*
+ * resolve.c
+ *
+ * Babeltrace - CTF writer: Type resolving internal
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Authors: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * 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:
+ *
+ * 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.
+ */
+
+#define BT_LOG_TAG "CTF-WRITER-RESOLVE"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/ctf-writer/field-path-internal.h>
+#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/ctf-writer/resolve-internal.h>
+#include <babeltrace/ctf-writer/stream-class.h>
+#include <babeltrace/ctf-writer/utils-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/types.h>
+#include <babeltrace/values.h>
+#include <glib.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdlib.h>
+
+typedef GPtrArray type_stack;
+
+/*
+ * A stack frame.
+ *
+ * `type` contains a compound field type (structure, variant, array,
+ * or sequence) and `index` indicates the index of the field type in
+ * the upper frame (-1 for array and sequence field types).
+ *
+ * `type` is owned by the stack frame.
+ */
+struct type_stack_frame {
+ struct bt_ctf_field_type_common *type;
+ int index;
+};
+
+/*
+ * The current context of the resolving engine.
+ *
+ * `scopes` contain the 6 CTF scope field types (see CTF, sect. 7.3.2)
+ * in the following order:
+ *
+ * * Packet header
+ * * Packet context
+ * * Event header
+ * * Stream event context
+ * * Event context
+ * * Event payload
+ */
+struct resolve_context {
+ struct bt_value *environment;
+ struct bt_ctf_field_type_common *scopes[6];
+
+ /* Root scope being visited */
+ enum bt_ctf_scope root_scope;
+ type_stack *type_stack;
+ struct bt_ctf_field_type_common *cur_field_type;
+};
+
+/* TSDL dynamic scope prefixes as defined in CTF Section 7.3.2 */
+static const char * const absolute_path_prefixes[] = {
+ [BT_CTF_SCOPE_ENV] = "env.",
+ [BT_CTF_SCOPE_TRACE_PACKET_HEADER] = "trace.packet.header.",
+ [BT_CTF_SCOPE_STREAM_PACKET_CONTEXT] = "stream.packet.context.",
+ [BT_CTF_SCOPE_STREAM_EVENT_HEADER] = "stream.event.header.",
+ [BT_CTF_SCOPE_STREAM_EVENT_CONTEXT] = "stream.event.context.",
+ [BT_CTF_SCOPE_EVENT_CONTEXT] = "event.context.",
+ [BT_CTF_SCOPE_EVENT_FIELDS] = "event.fields.",
+};
+
+/* Number of path tokens used for the absolute prefixes */
+static const int absolute_path_prefix_ptoken_counts[] = {
+ [BT_CTF_SCOPE_ENV] = 1,
+ [BT_CTF_SCOPE_TRACE_PACKET_HEADER] = 3,
+ [BT_CTF_SCOPE_STREAM_PACKET_CONTEXT] = 3,
+ [BT_CTF_SCOPE_STREAM_EVENT_HEADER] = 3,
+ [BT_CTF_SCOPE_STREAM_EVENT_CONTEXT] = 3,
+ [BT_CTF_SCOPE_EVENT_CONTEXT] = 2,
+ [BT_CTF_SCOPE_EVENT_FIELDS] = 2,
+};
+
+/*
+ * Destroys a type stack frame.
+ */
+static
+void type_stack_destroy_notify(gpointer data)
+{
+ struct type_stack_frame *frame = data;
+
+ BT_PUT(frame->type);
+ g_free(frame);
+}
+
+/*
+ * Creates a type stack.
+ *
+ * Return value is owned by the caller.
+ */
+static
+type_stack *type_stack_create(void)
+{
+ return g_ptr_array_new_with_free_func(type_stack_destroy_notify);
+}
+
+/*
+ * Destroys a type stack.
+ */
+static
+void type_stack_destroy(type_stack *stack)
+{
+ g_ptr_array_free(stack, TRUE);
+}
+
+/*
+ * Pushes a field type onto a type stack.
+ *
+ * `type` is owned by the caller (stack frame gets a new reference).
+ */
+static
+int type_stack_push(type_stack *stack, struct bt_ctf_field_type_common *type)
+{
+ int ret = 0;
+ struct type_stack_frame *frame = NULL;
+
+ if (!stack || !type) {
+ BT_LOGW("Invalid parameter: stack or type is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ frame = g_new0(struct type_stack_frame, 1);
+ if (!frame) {
+ BT_LOGE_STR("Failed to allocate one field type stack frame.");
+ ret = -1;
+ goto end;
+ }
+
+ BT_LOGV("Pushing field type on context's stack: "
+ "ft-addr=%p, stack-size-before=%u", type, stack->len);
+ frame->type = bt_get(type);
+ g_ptr_array_add(stack, frame);
+
+end:
+ return ret;
+}
+
+/*
+ * Checks whether or not `stack` is empty.
+ */
+static
+bt_bool type_stack_empty(type_stack *stack)
+{
+ return stack->len == 0;
+}
+
+/*
+ * Returns the number of frames in `stack`.
+ */
+static
+size_t type_stack_size(type_stack *stack)
+{
+ return stack->len;
+}
+
+/*
+ * Returns the top frame of `stack`.
+ *
+ * Return value is owned by `stack`.
+ */
+static
+struct type_stack_frame *type_stack_peek(type_stack *stack)
+{
+ struct type_stack_frame *entry = NULL;
+
+ if (!stack || type_stack_empty(stack)) {
+ goto end;
+ }
+
+ entry = g_ptr_array_index(stack, stack->len - 1);
+end:
+ return entry;
+}
+
+/*
+ * Returns the frame at index `index` in `stack`.
+ *
+ * Return value is owned by `stack`.
+ */
+static
+struct type_stack_frame *type_stack_at(type_stack *stack,
+ size_t index)
+{
+ struct type_stack_frame *entry = NULL;
+
+ if (!stack || index >= stack->len) {
+ goto end;
+ }
+
+ entry = g_ptr_array_index(stack, index);
+
+end:
+ return entry;
+}
+
+/*
+ * Removes the top frame of `stack`.
+ */
+static
+void type_stack_pop(type_stack *stack)
+{
+ if (!type_stack_empty(stack)) {
+ /*
+ * This will call the frame's destructor and free it, as
+ * well as put its contained field type.
+ */
+ BT_LOGV("Popping context's stack: stack-size-before=%u",
+ stack->len);
+ g_ptr_array_set_size(stack, stack->len - 1);
+ }
+}
+
+/*
+ * Returns the scope field type of `scope` in the context `ctx`.
+ *
+ * Return value is owned by `ctx` on success.
+ */
+static
+struct bt_ctf_field_type_common *get_type_from_ctx(struct resolve_context *ctx,
+ enum bt_ctf_scope scope)
+{
+ BT_ASSERT(scope >= BT_CTF_SCOPE_TRACE_PACKET_HEADER &&
+ scope <= BT_CTF_SCOPE_EVENT_FIELDS);
+
+ return ctx->scopes[scope - BT_CTF_SCOPE_TRACE_PACKET_HEADER];
+}
+
+/*
+ * Returns the CTF scope from a path string. May return
+ * CTF_NODE_UNKNOWN if the path is found to be relative.
+ */
+static
+enum bt_ctf_scope get_root_scope_from_absolute_pathstr(const char *pathstr)
+{
+ enum bt_ctf_scope scope;
+ enum bt_ctf_scope ret = BT_CTF_SCOPE_UNKNOWN;
+ const size_t prefixes_count = sizeof(absolute_path_prefixes) /
+ sizeof(*absolute_path_prefixes);
+
+ for (scope = BT_CTF_SCOPE_ENV; scope < BT_CTF_SCOPE_ENV +
+ prefixes_count; scope++) {
+ /*
+ * Chech if path string starts with a known absolute
+ * path prefix.
+ *
+ * Refer to CTF 7.3.2 STATIC AND DYNAMIC SCOPES.
+ */
+ if (strncmp(pathstr, absolute_path_prefixes[scope],
+ strlen(absolute_path_prefixes[scope]))) {
+ /* Prefix does not match: try the next one */
+ BT_LOGV("Prefix does not match: trying the next one: "
+ "path=\"%s\", path-prefix=\"%s\", scope=%s",
+ pathstr, absolute_path_prefixes[scope],
+ bt_ctf_scope_string(scope));
+ continue;
+ }
+
+ /* Found it! */
+ ret = scope;
+ BT_LOGV("Found root scope from absolute path: "
+ "path=\"%s\", scope=%s", pathstr,
+ bt_ctf_scope_string(scope));
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
+/*
+ * Destroys a path token.
+ */
+static
+void ptokens_destroy_func(gpointer ptoken, gpointer data)
+{
+ g_string_free(ptoken, TRUE);
+}
+
+/*
+ * Destroys a path token list.
+ */
+static
+void ptokens_destroy(GList *ptokens)
+{
+ if (!ptokens) {
+ return;
+ }
+
+ g_list_foreach(ptokens, ptokens_destroy_func, NULL);
+ g_list_free(ptokens);
+}
+
+/*
+ * Returns the string contained in a path token.
+ */
+static
+const char *ptoken_get_string(GList *ptoken)
+{
+ GString *tokenstr = (GString *) ptoken->data;
+
+ return tokenstr->str;
+}
+
+/*
+ * Converts a path string to a path token list, that is, splits the
+ * individual words of a path string into a list of individual
+ * strings.
+ *
+ * Return value is owned by the caller on success.
+ */
+static
+GList *pathstr_to_ptokens(const char *pathstr)
+{
+ const char *at = pathstr;
+ const char *last = at;
+ GList *ptokens = NULL;
+
+ for (;;) {
+ if (*at == '.' || *at == '\0') {
+ GString *tokenstr;
+
+ if (at == last) {
+ /* Error: empty token */
+ BT_LOGW("Empty path token: path=\"%s\", pos=%u",
+ pathstr, (int) (at - pathstr));
+ goto error;
+ }
+
+ tokenstr = g_string_new(NULL);
+ g_string_append_len(tokenstr, last, at - last);
+ ptokens = g_list_append(ptokens, tokenstr);
+ last = at + 1;
+ }
+
+ if (*at == '\0') {
+ break;
+ }
+
+ at++;
+ }
+
+ return ptokens;
+
+error:
+ ptokens_destroy(ptokens);
+ return NULL;
+}
+
+/*
+ * Converts a path token list to a field path object. The path token
+ * list is relative from `type`. The index of the source looking for
+ * its target within `type` is indicated by `src_index`. This can be
+ * `INT_MAX` if the source is contained in `type`.
+ *
+ * `ptokens` is owned by the caller. `field_path` is an output parameter
+ * owned by the caller that must be filled here. `type` is owned by the
+ * caller.
+ */
+static
+int ptokens_to_field_path(GList *ptokens, struct bt_ctf_field_path *field_path,
+ struct bt_ctf_field_type_common *type, int src_index)
+{
+ int ret = 0;
+ GList *cur_ptoken = ptokens;
+ bt_bool first_level_done = BT_FALSE;
+
+ /* Get our own reference */
+ bt_get(type);
+
+ /* Locate target */
+ while (cur_ptoken) {
+ int child_index;
+ struct bt_ctf_field_type_common *child_type;
+ const char *field_name = ptoken_get_string(cur_ptoken);
+ enum bt_ctf_field_type_id type_id =
+ bt_ctf_field_type_common_get_type_id(type);
+
+ BT_LOGV("Current path token: token=\"%s\"", field_name);
+
+ /* Find to which index corresponds the current path token */
+ if (type_id == BT_CTF_FIELD_TYPE_ID_ARRAY ||
+ type_id == BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
+ child_index = -1;
+ } else {
+ child_index = bt_ctf_field_type_common_get_field_index(type,
+ field_name);
+ if (child_index < 0) {
+ /*
+ * Error: field name does not exist or
+ * wrong current type.
+ */
+ BT_LOGW("Cannot get index of field type: "
+ "field-name=\"%s\", src-index=%d, child-index=%d, first-level-done=%d",
+ field_name, src_index, child_index, first_level_done);
+ ret = -1;
+ goto end;
+ } else if (child_index > src_index &&
+ !first_level_done) {
+ BT_LOGW("Child field type is located after source field type: "
+ "field-name=\"%s\", src-index=%d, child-index=%d, first-level-done=%d",
+ field_name, src_index, child_index, first_level_done);
+ ret = -1;
+ goto end;
+ }
+
+ /* Next path token */
+ cur_ptoken = g_list_next(cur_ptoken);
+ first_level_done = BT_TRUE;
+ }
+
+ /* Create new field path entry */
+ g_array_append_val(field_path->indexes, child_index);
+
+ /* Get child field type */
+ child_type = bt_ctf_field_type_common_borrow_field_at_index(type,
+ child_index);
+ if (!child_type) {
+ BT_LOGW("Cannot get child field type: "
+ "field-name=\"%s\", src-index=%d, child-index=%d, first-level-done=%d",
+ field_name, src_index, child_index, first_level_done);
+ ret = -1;
+ goto end;
+ }
+
+ /* Move child type to current type */
+ bt_get(child_type);
+ BT_MOVE(type, child_type);
+ }
+
+end:
+ bt_put(type);
+ return ret;
+}
+
+/*
+ * Converts a known absolute path token list to a field path object
+ * within the resolving context `ctx`.
+ *
+ * `ptokens` is owned by the caller. `field_path` is an output parameter
+ * owned by the caller that must be filled here.
+ */
+static
+int absolute_ptokens_to_field_path(GList *ptokens,
+ struct bt_ctf_field_path *field_path,
+ struct resolve_context *ctx)
+{
+ int ret = 0;
+ GList *cur_ptoken;
+ struct bt_ctf_field_type_common *type;
+
+ /* Skip absolute path tokens */
+ cur_ptoken = g_list_nth(ptokens,
+ absolute_path_prefix_ptoken_counts[field_path->root]);
+
+ /* Start with root type */
+ type = get_type_from_ctx(ctx, field_path->root);
+ if (!type) {
+ /* Error: root type is not available */
+ BT_LOGW("Root field type is not available: "
+ "root-scope=%s",
+ bt_ctf_scope_string(field_path->root));
+ ret = -1;
+ goto end;
+ }
+
+ /* Locate target */
+ ret = ptokens_to_field_path(cur_ptoken, field_path, type, INT_MAX);
+
+end:
+ return ret;
+}
+
+/*
+ * Converts a known relative path token list to a field path object
+ * within the resolving context `ctx`.
+ *
+ * `ptokens` is owned by the caller. `field_path` is an output parameter
+ * owned by the caller that must be filled here.
+ */
+static
+int relative_ptokens_to_field_path(GList *ptokens,
+ struct bt_ctf_field_path *field_path,
+ struct resolve_context *ctx)
+{
+ int ret = 0;
+ int parent_pos_in_stack;
+ struct bt_ctf_field_path *tail_field_path = bt_ctf_field_path_create();
+
+ if (!tail_field_path) {
+ BT_LOGE_STR("Cannot create empty field path.");
+ ret = -1;
+ goto end;
+ }
+
+ parent_pos_in_stack = type_stack_size(ctx->type_stack) - 1;
+
+ while (parent_pos_in_stack >= 0) {
+ struct bt_ctf_field_type_common *parent_type =
+ type_stack_at(ctx->type_stack,
+ parent_pos_in_stack)->type;
+ int cur_index = type_stack_at(ctx->type_stack,
+ parent_pos_in_stack)->index;
+
+ BT_LOGV("Locating target field type from current parent field type: "
+ "parent-pos=%d, parent-ft-addr=%p, cur-index=%d",
+ parent_pos_in_stack, parent_type, cur_index);
+
+ /* Locate target from current parent type */
+ ret = ptokens_to_field_path(ptokens, tail_field_path,
+ parent_type, cur_index);
+ if (ret) {
+ /* Not found... yet */
+ BT_LOGV_STR("Not found at this point.");
+ bt_ctf_field_path_clear(tail_field_path);
+ } else {
+ /* Found: stitch tail field path to head field path */
+ int i = 0;
+ int tail_field_path_len =
+ tail_field_path->indexes->len;
+
+ while (BT_TRUE) {
+ struct bt_ctf_field_type_common *cur_type =
+ type_stack_at(ctx->type_stack, i)->type;
+ int index = type_stack_at(
+ ctx->type_stack, i)->index;
+
+ if (cur_type == parent_type) {
+ break;
+ }
+
+ g_array_append_val(field_path->indexes,
+ index);
+ i++;
+ }
+
+ for (i = 0; i < tail_field_path_len; i++) {
+ int index = g_array_index(
+ tail_field_path->indexes,
+ int, i);
+
+ g_array_append_val(field_path->indexes,
+ index);
+ }
+ break;
+ }
+
+ parent_pos_in_stack--;
+ }
+
+ if (parent_pos_in_stack < 0) {
+ /* Not found: look in previous scopes */
+ field_path->root--;
+
+ while (field_path->root >= BT_CTF_SCOPE_TRACE_PACKET_HEADER) {
+ struct bt_ctf_field_type_common *root_type;
+ bt_ctf_field_path_clear(field_path);
+
+ BT_LOGV("Looking into potential root scope: scope=%s",
+ bt_ctf_scope_string(field_path->root));
+ root_type = get_type_from_ctx(ctx, field_path->root);
+ if (!root_type) {
+ field_path->root--;
+ continue;
+ }
+
+ /* Locate target in previous scope */
+ ret = ptokens_to_field_path(ptokens, field_path,
+ root_type, INT_MAX);
+ if (ret) {
+ /* Not found yet */
+ BT_LOGV_STR("Not found in this scope.");
+ field_path->root--;
+ continue;
+ }
+
+ /* Found */
+ BT_LOGV_STR("Found in this scope.");
+ break;
+ }
+ }
+
+end:
+ BT_PUT(tail_field_path);
+ return ret;
+}
+
+/*
+ * Converts a path string to a field path object within the resolving
+ * context `ctx`.
+ *
+ * Return value is owned by the caller on success.
+ */
+static
+struct bt_ctf_field_path *pathstr_to_field_path(const char *pathstr,
+ struct resolve_context *ctx)
+{
+ int ret;
+ enum bt_ctf_scope root_scope;
+ GList *ptokens = NULL;
+ struct bt_ctf_field_path *field_path = NULL;
+
+ /* Create field path */
+ field_path = bt_ctf_field_path_create();
+ if (!field_path) {
+ BT_LOGE_STR("Cannot create empty field path.");
+ ret = -1;
+ goto end;
+ }
+
+ /* Convert path string to path tokens */
+ ptokens = pathstr_to_ptokens(pathstr);
+ if (!ptokens) {
+ BT_LOGW("Cannot convert path string to path tokens: "
+ "path=\"%s\"", pathstr);
+ ret = -1;
+ goto end;
+ }
+
+ /* Absolute or relative path? */
+ root_scope = get_root_scope_from_absolute_pathstr(pathstr);
+
+ if (root_scope == BT_CTF_SCOPE_UNKNOWN) {
+ /* Relative path: start with current root scope */
+ field_path->root = ctx->root_scope;
+ BT_LOGV("Detected relative path: starting with current root scope: "
+ "scope=%s", bt_ctf_scope_string(field_path->root));
+ ret = relative_ptokens_to_field_path(ptokens, field_path, ctx);
+ if (ret) {
+ BT_LOGW("Cannot get relative field path of path string: "
+ "path=\"%s\", start-scope=%s, end-scope=%s",
+ pathstr, bt_ctf_scope_string(ctx->root_scope),
+ bt_ctf_scope_string(field_path->root));
+ goto end;
+ }
+ } else if (root_scope == BT_CTF_SCOPE_ENV) {
+ BT_LOGW("Sequence field types referring the trace environment are not supported as of this version: "
+ "path=\"%s\"", pathstr);
+ ret = -1;
+ goto end;
+ } else {
+ /* Absolute path: use found root scope */
+ field_path->root = root_scope;
+ BT_LOGV("Detected absolute path: using root scope: "
+ "scope=%s", bt_ctf_scope_string(field_path->root));
+ ret = absolute_ptokens_to_field_path(ptokens, field_path, ctx);
+ if (ret) {
+ BT_LOGW("Cannot get absolute field path of path string: "
+ "path=\"%s\", root-scope=%s",
+ pathstr, bt_ctf_scope_string(root_scope));
+ goto end;
+ }
+ }
+
+ if (ret == 0) {
+ GString *field_path_pretty =
+ bt_ctf_field_path_string(field_path);
+ const char *field_path_pretty_str =
+ field_path_pretty ? field_path_pretty->str : NULL;
+
+ BT_LOGV("Found field path: path=\"%s\", field-path=\"%s\"",
+ pathstr, field_path_pretty_str);
+
+ if (field_path_pretty) {
+ g_string_free(field_path_pretty, TRUE);
+ }
+ }
+
+end:
+ if (ret) {
+ BT_PUT(field_path);
+ }
+
+ ptokens_destroy(ptokens);
+ return field_path;
+}
+
+/*
+ * Retrieves a field type by following the field path `field_path` in
+ * the resolving context `ctx`.
+ *
+ * Return value is owned by the caller on success.
+ */
+static
+struct bt_ctf_field_type_common *field_path_to_field_type(
+ struct bt_ctf_field_path *field_path,
+ struct resolve_context *ctx)
+{
+ int i;
+ struct bt_ctf_field_type_common *type;
+
+ /* Start with root type */
+ type = get_type_from_ctx(ctx, field_path->root);
+ bt_get(type);
+ if (!type) {
+ /* Error: root type is not available */
+ BT_LOGW("Root field type is not available: root-scope=%s",
+ bt_ctf_scope_string(field_path->root));
+ goto error;
+ }
+
+ /* Locate target */
+ for (i = 0; i < field_path->indexes->len; i++) {
+ struct bt_ctf_field_type_common *child_type;
+ int child_index =
+ g_array_index(field_path->indexes, int, i);
+
+ /* Get child field type */
+ child_type = bt_ctf_field_type_common_borrow_field_at_index(type,
+ child_index);
+ if (!child_type) {
+ BT_LOGW("Cannot get field type: "
+ "parent-ft-addr=%p, index=%d", type, i);
+ goto error;
+ }
+
+ /* Move child type to current type */
+ bt_get(child_type);
+ BT_MOVE(type, child_type);
+ }
+
+ return type;
+
+error:
+ BT_PUT(type);
+ return type;
+}
+
+/*
+ * Returns the equivalent field path object of the context type stack.
+ *
+ * Return value is owned by the caller on success.
+ */
+static
+struct bt_ctf_field_path *get_ctx_stack_field_path(struct resolve_context *ctx)
+{
+ int i;
+ struct bt_ctf_field_path *field_path;
+
+ /* Create field path */
+ field_path = bt_ctf_field_path_create();
+ if (!field_path) {
+ BT_LOGE_STR("Cannot create empty field path.");
+ goto error;
+ }
+
+ field_path->root = ctx->root_scope;
+
+ for (i = 0; i < type_stack_size(ctx->type_stack); i++) {
+ struct type_stack_frame *frame;
+
+ frame = type_stack_at(ctx->type_stack, i);
+ g_array_append_val(field_path->indexes, frame->index);
+ }
+
+ return field_path;
+
+error:
+ BT_PUT(field_path);
+ return field_path;
+}
+
+/*
+ * Returns the lowest common ancestor of two field path objects
+ * having the same root scope.
+ *
+ * `field_path1` and `field_path2` are owned by the caller.
+ */
+static
+int get_field_paths_lca_index(struct bt_ctf_field_path *field_path1,
+ struct bt_ctf_field_path *field_path2)
+{
+ int lca_index = 0;
+ int field_path1_len, field_path2_len;
+
+ if (BT_LOG_ON_VERBOSE) {
+ GString *field_path1_pretty =
+ bt_ctf_field_path_string(field_path1);
+ GString *field_path2_pretty =
+ bt_ctf_field_path_string(field_path2);
+ const char *field_path1_pretty_str =
+ field_path1_pretty ? field_path1_pretty->str : NULL;
+ const char *field_path2_pretty_str =
+ field_path2_pretty ? field_path2_pretty->str : NULL;
+
+ BT_LOGV("Finding lowest common ancestor (LCA) between two field paths: "
+ "field-path-1=\"%s\", field-path-2=\"%s\"",
+ field_path1_pretty_str, field_path2_pretty_str);
+
+ if (field_path1_pretty) {
+ g_string_free(field_path1_pretty, TRUE);
+ }
+
+ if (field_path2_pretty) {
+ g_string_free(field_path2_pretty, TRUE);
+ }
+ }
+
+ /*
+ * Start from both roots and find the first mismatch.
+ */
+ BT_ASSERT(field_path1->root == field_path2->root);
+ field_path1_len = field_path1->indexes->len;
+ field_path2_len = field_path2->indexes->len;
+
+ while (BT_TRUE) {
+ int target_index, ctx_index;
+
+ if (lca_index == field_path2_len ||
+ lca_index == field_path1_len) {
+ /*
+ * This means that both field paths never split.
+ * This is invalid because the target cannot be
+ * an ancestor of the source.
+ */
+ BT_LOGW("Source field type is an ancestor of target field type or vice versa: "
+ "lca-index=%d, field-path-1-len=%d, "
+ "field-path-2-len=%d",
+ lca_index, field_path1_len, field_path2_len);
+ lca_index = -1;
+ break;
+ }
+
+ target_index = g_array_index(field_path1->indexes, int,
+ lca_index);
+ ctx_index = g_array_index(field_path2->indexes, int,
+ lca_index);
+
+ if (target_index != ctx_index) {
+ /* LCA index is the previous */
+ break;
+ }
+
+ lca_index++;
+ }
+
+ BT_LOGV("Found LCA: lca-index=%d", lca_index);
+ return lca_index;
+}
+
+/*
+ * Validates a target field path.
+ *
+ * `target_field_path` and `target_type` are owned by the caller.
+ */
+static
+int validate_target_field_path(struct bt_ctf_field_path *target_field_path,
+ struct bt_ctf_field_type_common *target_type,
+ struct resolve_context *ctx)
+{
+ int ret = 0;
+ struct bt_ctf_field_path *ctx_field_path;
+ int target_field_path_len = target_field_path->indexes->len;
+ int lca_index;
+ enum bt_ctf_field_type_id ctx_cur_field_type_id;
+ enum bt_ctf_field_type_id target_type_id;
+
+ /* Get context field path */
+ ctx_field_path = get_ctx_stack_field_path(ctx);
+ if (!ctx_field_path) {
+ BT_LOGW_STR("Cannot get field path from context's stack.");
+ ret = -1;
+ goto end;
+ }
+
+ /*
+ * Make sure the target is not a root.
+ */
+ if (target_field_path_len == 0) {
+ BT_LOGW_STR("Target field path's length is 0 (targeting the root).");
+ ret = -1;
+ goto end;
+ }
+
+ /*
+ * Make sure the root of the target field path is not located
+ * after the context field path's root.
+ */
+ if (target_field_path->root > ctx_field_path->root) {
+ BT_LOGW("Target field type is located after source field type: "
+ "target-root=%s, source-root=%s",
+ bt_ctf_scope_string(target_field_path->root),
+ bt_ctf_scope_string(ctx_field_path->root));
+ ret = -1;
+ goto end;
+ }
+
+ if (target_field_path->root == ctx_field_path->root) {
+ int target_index, ctx_index;
+
+ /*
+ * Find the index of the lowest common ancestor of both field
+ * paths.
+ */
+ lca_index = get_field_paths_lca_index(target_field_path,
+ ctx_field_path);
+ if (lca_index < 0) {
+ BT_LOGW_STR("Cannot get least common ancestor.");
+ ret = -1;
+ goto end;
+ }
+
+ /*
+ * Make sure the target field path is located before the
+ * context field path.
+ */
+ target_index = g_array_index(target_field_path->indexes,
+ int, lca_index);
+ ctx_index = g_array_index(ctx_field_path->indexes,
+ int, lca_index);
+
+ if (target_index >= ctx_index) {
+ BT_LOGW("Target field type's index is greater than or equal to source field type's index in LCA: "
+ "lca-index=%d, target-index=%d, source-index=%d",
+ lca_index, target_index, ctx_index);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ /*
+ * Make sure the target type has the right type and properties.
+ */
+ ctx_cur_field_type_id = bt_ctf_field_type_common_get_type_id(
+ ctx->cur_field_type);
+ target_type_id = bt_ctf_field_type_common_get_type_id(target_type);
+
+ switch (ctx_cur_field_type_id) {
+ case BT_CTF_FIELD_TYPE_ID_VARIANT:
+ if (target_type_id != BT_CTF_FIELD_TYPE_ID_ENUM) {
+ BT_LOGW("Variant field type's tag field type is not an enumeration field type: "
+ "tag-ft-addr=%p, tag-ft-id=%s",
+ target_type,
+ bt_ctf_field_type_id_string(target_type_id));
+ ret = -1;
+ goto end;
+ }
+ break;
+ case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ if (target_type_id != BT_CTF_FIELD_TYPE_ID_INTEGER ||
+ bt_ctf_field_type_common_integer_is_signed(target_type)) {
+ BT_LOGW("Sequence field type's length field type is not an unsigned integer field type: "
+ "length-ft-addr=%p, length-ft-id=%s",
+ target_type,
+ bt_ctf_field_type_id_string(target_type_id));
+ ret = -1;
+ goto end;
+ }
+ break;
+ default:
+ abort();
+ }
+
+end:
+ BT_PUT(ctx_field_path);
+ return ret;
+}
+
+/*
+ * Resolves a variant or sequence field type `type`.
+ *
+ * `type` is owned by the caller.
+ */
+static
+int resolve_sequence_or_variant_type(struct bt_ctf_field_type_common *type,
+ struct resolve_context *ctx)
+{
+ int ret = 0;
+ const char *pathstr;
+ enum bt_ctf_field_type_id type_id = bt_ctf_field_type_common_get_type_id(type);
+ struct bt_ctf_field_path *target_field_path = NULL;
+ struct bt_ctf_field_type_common *target_type = NULL;
+ GString *target_field_path_pretty = NULL;
+ const char *target_field_path_pretty_str;
+
+
+ /* Get path string */
+ switch (type_id) {
+ case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ pathstr =
+ bt_ctf_field_type_common_sequence_get_length_field_name(type);
+ break;
+ case BT_CTF_FIELD_TYPE_ID_VARIANT:
+ pathstr =
+ bt_ctf_field_type_common_variant_get_tag_name(type);
+ break;
+ default:
+ abort();
+ }
+
+ if (!pathstr) {
+ BT_LOGW_STR("Cannot get path string.");
+ ret = -1;
+ goto end;
+ }
+
+ /* Get target field path out of path string */
+ target_field_path = pathstr_to_field_path(pathstr, ctx);
+ if (!target_field_path) {
+ BT_LOGW("Cannot get target field path for path string: "
+ "path=\"%s\"", pathstr);
+ ret = -1;
+ goto end;
+ }
+
+ target_field_path_pretty = bt_ctf_field_path_string(target_field_path);
+ target_field_path_pretty_str =
+ target_field_path_pretty ? target_field_path_pretty->str : NULL;
+
+ /* Get target field type */
+ target_type = field_path_to_field_type(target_field_path, ctx);
+ if (!target_type) {
+ BT_LOGW("Cannot get target field type for path string: "
+ "path=\"%s\", target-field-path=\"%s\"",
+ pathstr, target_field_path_pretty_str);
+ ret = -1;
+ goto end;
+ }
+
+ ret = validate_target_field_path(target_field_path, target_type, ctx);
+ if (ret) {
+ BT_LOGW("Invalid target field path for path string: "
+ "path=\"%s\", target-field-path=\"%s\"",
+ pathstr, target_field_path_pretty_str);
+ goto end;
+ }
+
+ /* Set target field path and target field type */
+ switch (type_id) {
+ case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ ret = bt_ctf_field_type_common_sequence_set_length_field_path(
+ type, target_field_path);
+ if (ret) {
+ BT_LOGW("Cannot set sequence field type's length field path: "
+ "ret=%d, ft-addr=%p, path=\"%s\", target-field-path=\"%s\"",
+ ret, type, pathstr,
+ target_field_path_pretty_str);
+ goto end;
+ }
+ break;
+ case BT_CTF_FIELD_TYPE_ID_VARIANT:
+ ret = bt_ctf_field_type_common_variant_set_tag_field_path(
+ type, target_field_path);
+ if (ret) {
+ BT_LOGW("Cannot set varaint field type's tag field path: "
+ "ret=%d, ft-addr=%p, path=\"%s\", target-field-path=\"%s\"",
+ ret, type, pathstr,
+ target_field_path_pretty_str);
+ goto end;
+ }
+
+ ret = bt_ctf_field_type_common_variant_set_tag_field_type(
+ type, target_type);
+ if (ret) {
+ BT_LOGW("Cannot set varaint field type's tag field type: "
+ "ret=%d, ft-addr=%p, path=\"%s\", target-field-path=\"%s\"",
+ ret, type, pathstr,
+ target_field_path_pretty_str);
+ goto end;
+ }
+ break;
+ default:
+ abort();
+ }
+
+end:
+ if (target_field_path_pretty) {
+ g_string_free(target_field_path_pretty, TRUE);
+ }
+
+ BT_PUT(target_field_path);
+ BT_PUT(target_type);
+ return ret;
+}
+
+/*
+ * Resolves a field type `type`.
+ *
+ * `type` is owned by the caller.
+ */
+static
+int resolve_type(struct bt_ctf_field_type_common *type, struct resolve_context *ctx)
+{
+ int ret = 0;
+ enum bt_ctf_field_type_id type_id;
+
+ if (!type) {
+ /* Type is not available; still valid */
+ goto end;
+ }
+
+ type_id = bt_ctf_field_type_common_get_type_id(type);
+ ctx->cur_field_type = type;
+
+ /* Resolve sequence/variant field type */
+ switch (type_id) {
+ case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ case BT_CTF_FIELD_TYPE_ID_VARIANT:
+ ret = resolve_sequence_or_variant_type(type, ctx);
+ if (ret) {
+ BT_LOGW("Cannot resolve sequence field type's length or variant field type's tag: "
+ "ret=%d, ft-addr=%p", ret, type);
+ goto end;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Recurse into compound types */
+ switch (type_id) {
+ case BT_CTF_FIELD_TYPE_ID_STRUCT:
+ case BT_CTF_FIELD_TYPE_ID_VARIANT:
+ case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ case BT_CTF_FIELD_TYPE_ID_ARRAY:
+ {
+ int64_t field_count, f_index;
+
+ ret = type_stack_push(ctx->type_stack, type);
+ if (ret) {
+ BT_LOGW("Cannot push field type on context's stack: "
+ "ft-addr=%p", type);
+ goto end;
+ }
+
+ field_count = bt_ctf_field_type_common_get_field_count(type);
+ if (field_count < 0) {
+ BT_LOGW("Cannot get field type's field count: "
+ "ret=%" PRId64 ", ft-addr=%p",
+ field_count, type);
+ ret = field_count;
+ goto end;
+ }
+
+ for (f_index = 0; f_index < field_count; f_index++) {
+ struct bt_ctf_field_type_common *child_type =
+ bt_ctf_field_type_common_borrow_field_at_index(type,
+ f_index);
+
+ if (!child_type) {
+ BT_LOGW("Cannot get field type's child field: "
+ "ft-addr=%p, index=%" PRId64 ", "
+ "count=%" PRId64, type, f_index,
+ field_count);
+ ret = -1;
+ goto end;
+ }
+
+ if (type_id == BT_CTF_FIELD_TYPE_ID_ARRAY||
+ type_id == BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
+ type_stack_peek(ctx->type_stack)->index = -1;
+ } else {
+ type_stack_peek(ctx->type_stack)->index =
+ f_index;
+ }
+
+ BT_LOGV("Resolving field type's child field type: "
+ "parent-ft-addr=%p, child-ft-addr=%p, "
+ "index=%" PRId64 ", count=%" PRId64,
+ type, child_type, f_index, field_count);
+ ret = resolve_type(child_type, ctx);
+ if (ret) {
+ goto end;
+ }
+ }
+
+ type_stack_pop(ctx->type_stack);
+ break;
+ }
+ default:
+ break;
+ }
+
+end:
+ return ret;
+}
+
+/*
+ * Resolves the root field type corresponding to the scope `root_scope`.
+ */
+static
+int resolve_root_type(enum bt_ctf_scope root_scope, struct resolve_context *ctx)
+{
+ int ret;
+
+ BT_ASSERT(type_stack_size(ctx->type_stack) == 0);
+ ctx->root_scope = root_scope;
+ ret = resolve_type(get_type_from_ctx(ctx, root_scope), ctx);
+ ctx->root_scope = BT_CTF_SCOPE_UNKNOWN;
+
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_resolve_types(
+ struct bt_value *environment,
+ struct bt_ctf_field_type_common *packet_header_type,
+ struct bt_ctf_field_type_common *packet_context_type,
+ struct bt_ctf_field_type_common *event_header_type,
+ struct bt_ctf_field_type_common *stream_event_ctx_type,
+ struct bt_ctf_field_type_common *event_context_type,
+ struct bt_ctf_field_type_common *event_payload_type,
+ enum bt_ctf_resolve_flag flags)
+{
+ int ret = 0;
+ struct resolve_context ctx = {
+ .environment = environment,
+ .scopes = {
+ packet_header_type,
+ packet_context_type,
+ event_header_type,
+ stream_event_ctx_type,
+ event_context_type,
+ event_payload_type,
+ },
+ .root_scope = BT_CTF_SCOPE_UNKNOWN,
+ };
+
+ BT_LOGV("Resolving field types: "
+ "packet-header-ft-addr=%p, "
+ "packet-context-ft-addr=%p, "
+ "event-header-ft-addr=%p, "
+ "stream-event-context-ft-addr=%p, "
+ "event-context-ft-addr=%p, "
+ "event-payload-ft-addr=%p",
+ packet_header_type, packet_context_type, event_header_type,
+ stream_event_ctx_type, event_context_type, event_payload_type);
+
+ /* Initialize type stack */
+ ctx.type_stack = type_stack_create();
+ if (!ctx.type_stack) {
+ BT_LOGE_STR("Cannot create field type stack.");
+ ret = -1;
+ goto end;
+ }
+
+ /* Resolve packet header type */
+ if (flags & BT_CTF_RESOLVE_FLAG_PACKET_HEADER) {
+ ret = resolve_root_type(BT_CTF_SCOPE_TRACE_PACKET_HEADER, &ctx);
+ if (ret) {
+ BT_LOGW("Cannot resolve trace packet header field type: "
+ "ret=%d", ret);
+ goto end;
+ }
+ }
+
+ /* Resolve packet context type */
+ if (flags & BT_CTF_RESOLVE_FLAG_PACKET_CONTEXT) {
+ ret = resolve_root_type(BT_CTF_SCOPE_STREAM_PACKET_CONTEXT, &ctx);
+ if (ret) {
+ BT_LOGW("Cannot resolve stream packet context field type: "
+ "ret=%d", ret);
+ goto end;
+ }
+ }
+
+ /* Resolve event header type */
+ if (flags & BT_CTF_RESOLVE_FLAG_EVENT_HEADER) {
+ ret = resolve_root_type(BT_CTF_SCOPE_STREAM_EVENT_HEADER, &ctx);
+ if (ret) {
+ BT_LOGW("Cannot resolve stream event header field type: "
+ "ret=%d", ret);
+ goto end;
+ }
+ }
+
+ /* Resolve stream event context type */
+ if (flags & BT_CTF_RESOLVE_FLAG_STREAM_EVENT_CTX) {
+ ret = resolve_root_type(BT_CTF_SCOPE_STREAM_EVENT_CONTEXT, &ctx);
+ if (ret) {
+ BT_LOGW("Cannot resolve stream event context field type: "
+ "ret=%d", ret);
+ goto end;
+ }
+ }
+
+ /* Resolve event context type */
+ if (flags & BT_CTF_RESOLVE_FLAG_EVENT_CONTEXT) {
+ ret = resolve_root_type(BT_CTF_SCOPE_EVENT_CONTEXT, &ctx);
+ if (ret) {
+ BT_LOGW("Cannot resolve event context field type: "
+ "ret=%d", ret);
+ goto end;
+ }
+ }
+
+ /* Resolve event payload type */
+ if (flags & BT_CTF_RESOLVE_FLAG_EVENT_PAYLOAD) {
+ ret = resolve_root_type(BT_CTF_SCOPE_EVENT_FIELDS, &ctx);
+ if (ret) {
+ BT_LOGW("Cannot resolve event payload field type: "
+ "ret=%d", ret);
+ goto end;
+ }
+ }
+
+ BT_LOGV_STR("Resolved field types.");
+
+end:
+ type_stack_destroy(ctx.type_stack);
+
+ return ret;
+}
#define BT_LOG_TAG "CTF-WRITER-SERIALIZE"
#include <babeltrace/lib-logging-internal.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <babeltrace/ctf-writer/fields.h>
-#include <babeltrace/ctf-writer/field-types.h>
-#include <babeltrace/ctf-writer/serialize-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
#include <babeltrace/align-internal.h>
-#include <babeltrace/mmap-align-internal.h>
-#include <babeltrace/endian-internal.h>
#include <babeltrace/bitfield-internal.h>
+#include <babeltrace/common-internal.h>
#include <babeltrace/compat/fcntl-internal.h>
+#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/ctf-writer/field-types.h>
+#include <babeltrace/ctf-writer/fields-internal.h>
+#include <babeltrace/ctf-writer/fields.h>
+#include <babeltrace/ctf-writer/serialize-internal.h>
+#include <babeltrace/ctf-writer/utils-internal.h>
+#include <babeltrace/endian-internal.h>
+#include <babeltrace/mmap-align-internal.h>
#include <babeltrace/types.h>
-#include <babeltrace/common-internal.h>
#include <glib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
#if (FLT_RADIX != 2)
# error "Unsupported floating point radix"
}
BT_HIDDEN
-int bt_ctf_field_integer_write(struct bt_field_common *field,
+int bt_ctf_field_integer_write(struct bt_ctf_field_common *field,
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order)
{
- struct bt_field_type_common_integer *int_type =
- BT_FROM_COMMON(field->type);
- struct bt_field_common_integer *int_field = BT_FROM_COMMON(field);
+ struct bt_ctf_field_type_common_integer *int_type =
+ BT_CTF_FROM_COMMON(field->type);
+ struct bt_ctf_field_common_integer *int_field = BT_CTF_FROM_COMMON(field);
enum bt_ctf_byte_order byte_order;
union intval value;
byte_order = (int) int_type->user_byte_order;
- if ((int) byte_order == BT_BYTE_ORDER_NATIVE) {
+ if ((int) byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
byte_order = native_byte_order;
}
BT_HIDDEN
int bt_ctf_field_floating_point_write(
- struct bt_field_common *field,
+ struct bt_ctf_field_common *field,
struct bt_ctf_stream_pos *pos,
enum bt_ctf_byte_order native_byte_order)
{
- struct bt_field_type_common_floating_point *flt_type =
- BT_FROM_COMMON(field->type);
- struct bt_field_common_floating_point *flt_field = BT_FROM_COMMON(field);
+ struct bt_ctf_field_type_common_floating_point *flt_type =
+ BT_CTF_FROM_COMMON(field->type);
+ struct bt_ctf_field_common_floating_point *flt_field = BT_CTF_FROM_COMMON(field);
enum bt_ctf_byte_order byte_order;
union intval value;
unsigned int size;
byte_order = (int) flt_type->user_byte_order;
- if ((int) byte_order == BT_BYTE_ORDER_NATIVE) {
+ if ((int) byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
byte_order = native_byte_order;
}
#define BT_LOG_TAG "CTF-WRITER-STREAM-CLASS"
#include <babeltrace/lib-logging-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-writer/writer-internal.h>
-#include <babeltrace/ctf-writer/stream-class-internal.h>
-#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/align-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/ctf-writer/clock-class-internal.h>
+#include <babeltrace/ctf-writer/event-class-internal.h>
#include <babeltrace/ctf-writer/event-internal.h>
#include <babeltrace/ctf-writer/event.h>
+#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/ctf-writer/field-wrapper-internal.h>
+#include <babeltrace/ctf-writer/fields-internal.h>
+#include <babeltrace/ctf-writer/stream-class-internal.h>
#include <babeltrace/ctf-writer/trace.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/ctf-writer/utils-internal.h>
+#include <babeltrace/ctf-writer/utils.h>
+#include <babeltrace/ctf-writer/validation-internal.h>
+#include <babeltrace/ctf-writer/visitor-internal.h>
+#include <babeltrace/ctf-writer/writer-internal.h>
+#include <babeltrace/endian-internal.h>
+#include <babeltrace/ref.h>
#include <inttypes.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+BT_HIDDEN
+int bt_ctf_stream_class_common_initialize(struct bt_ctf_stream_class_common *stream_class,
+ const char *name, bt_object_release_func release_func)
+{
+ BT_LOGD("Initializing common stream class object: name=\"%s\"", name);
+
+ bt_object_init_shared_with_parent(&stream_class->base, release_func);
+ stream_class->name = g_string_new(name);
+ stream_class->event_classes = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) bt_object_try_spec_release);
+ if (!stream_class->event_classes) {
+ BT_LOGE_STR("Failed to allocate a GPtrArray.");
+ goto error;
+ }
+
+ stream_class->event_classes_ht = g_hash_table_new_full(g_int64_hash,
+ g_int64_equal, g_free, NULL);
+ if (!stream_class->event_classes_ht) {
+ BT_LOGE_STR("Failed to allocate a GHashTable.");
+ goto error;
+ }
+
+ BT_LOGD("Initialized common stream class object: addr=%p, name=\"%s\"",
+ stream_class, name);
+ return 0;
+
+error:
+ return -1;
+}
+
+BT_HIDDEN
+void bt_ctf_stream_class_common_finalize(struct bt_ctf_stream_class_common *stream_class)
+{
+ BT_LOGD("Finalizing common stream class: addr=%p, name=\"%s\", id=%" PRId64,
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+ bt_put(stream_class->clock_class);
+
+ if (stream_class->event_classes_ht) {
+ g_hash_table_destroy(stream_class->event_classes_ht);
+ }
+ if (stream_class->event_classes) {
+ BT_LOGD_STR("Destroying event classes.");
+ g_ptr_array_free(stream_class->event_classes, TRUE);
+ }
+
+ if (stream_class->name) {
+ g_string_free(stream_class->name, TRUE);
+ }
+
+ BT_LOGD_STR("Putting event header field type.");
+ bt_put(stream_class->event_header_field_type);
+ BT_LOGD_STR("Putting packet context field type.");
+ bt_put(stream_class->packet_context_field_type);
+ BT_LOGD_STR("Putting event context field type.");
+ bt_put(stream_class->event_context_field_type);
+}
+
+static
+void event_class_exists(gpointer element, gpointer query)
+{
+ struct bt_ctf_event_class_common *event_class_a = element;
+ struct bt_ctf_search_query *search_query = query;
+ struct bt_ctf_event_class_common *event_class_b = search_query->value;
+ int64_t id_a, id_b;
+
+ if (search_query->value == element) {
+ search_query->found = 1;
+ goto end;
+ }
+
+ /*
+ * Two event classes cannot share the same ID in a given
+ * stream class.
+ */
+ id_a = bt_ctf_event_class_common_get_id(event_class_a);
+ id_b = bt_ctf_event_class_common_get_id(event_class_b);
+
+ if (id_a < 0 || id_b < 0) {
+ /* at least one ID is not set: will be automatically set later */
+ goto end;
+ }
+
+ if (id_a == id_b) {
+ BT_LOGW("Event class with this ID already exists in the stream class: "
+ "id=%" PRId64 ", name=\"%s\"",
+ id_a, bt_ctf_event_class_common_get_name(event_class_a));
+ search_query->found = 1;
+ goto end;
+ }
+
+end:
+ return;
+}
+
+BT_HIDDEN
+int bt_ctf_stream_class_common_add_event_class(
+ struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_event_class_common *event_class,
+ bt_ctf_validation_flag_copy_field_type_func copy_field_type_func)
+{
+ int ret = 0;
+ int64_t *event_id = NULL;
+ struct bt_ctf_trace_common *trace = NULL;
+ struct bt_ctf_stream_class_common *old_stream_class = NULL;
+ struct bt_ctf_validation_output validation_output = { 0 };
+ struct bt_ctf_field_type_common *packet_header_type = NULL;
+ struct bt_ctf_field_type_common *packet_context_type = NULL;
+ struct bt_ctf_field_type_common *event_header_type = NULL;
+ struct bt_ctf_field_type_common *stream_event_ctx_type = NULL;
+ struct bt_ctf_field_type_common *event_context_type = NULL;
+ struct bt_ctf_field_type_common *event_payload_type = NULL;
+ const enum bt_ctf_validation_flag validation_flags =
+ BT_CTF_VALIDATION_FLAG_EVENT;
+ struct bt_ctf_clock_class *expected_clock_class = NULL;
+
+ BT_ASSERT(copy_field_type_func);
+
+ if (!stream_class || !event_class) {
+ BT_LOGW("Invalid parameter: stream class or event class is NULL: "
+ "stream-class-addr=%p, event-class-addr=%p",
+ stream_class, event_class);
+ ret = -1;
+ goto end;
+ }
+
+ BT_LOGD("Adding event class to stream class: "
+ "stream-class-addr=%p, stream-class-name=\"%s\", "
+ "stream-class-id=%" PRId64 ", event-class-addr=%p, "
+ "event-class-name=\"%s\", event-class-id=%" PRId64,
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class),
+ event_class,
+ bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class));
+ trace = bt_ctf_stream_class_common_borrow_trace(stream_class);
+
+ if (stream_class->frozen) {
+ /*
+ * We only check that the event class to be added has a
+ * single class which matches the stream class's
+ * expected clock class if the stream class is frozen.
+ * If it's not, then this event class is added "as is"
+ * and the validation will be performed when calling
+ * either bt_ctf_trace_add_stream_class() or
+ * bt_ctf_event_create(). This is because the stream class's
+ * field types (packet context, event header, event
+ * context) could change before the next call to one of
+ * those two functions.
+ */
+ expected_clock_class = bt_get(stream_class->clock_class);
+
+ /*
+ * At this point, `expected_clock_class` can be NULL,
+ * and bt_ctf_event_class_validate_single_clock_class()
+ * below can set it.
+ */
+ ret = bt_ctf_event_class_common_validate_single_clock_class(
+ event_class, &expected_clock_class);
+ if (ret) {
+ BT_LOGW("Event class contains a field type which is not "
+ "recursively mapped to its stream class's "
+ "expected clock class: "
+ "stream-class-addr=%p, "
+ "stream-class-id=%" PRId64 ", "
+ "stream-class-name=\"%s\", "
+ "expected-clock-class-addr=%p, "
+ "expected-clock-class-name=\"%s\"",
+ stream_class,
+ bt_ctf_stream_class_common_get_id(stream_class),
+ bt_ctf_stream_class_common_get_name(stream_class),
+ expected_clock_class,
+ expected_clock_class ?
+ bt_ctf_clock_class_get_name(expected_clock_class) :
+ NULL);
+ goto end;
+ }
+ }
+
+ event_id = g_new(int64_t, 1);
+ if (!event_id) {
+ BT_LOGE_STR("Failed to allocate one int64_t.");
+ ret = -1;
+ goto end;
+ }
+
+ /* Check for duplicate event classes */
+ struct bt_ctf_search_query query = { .value = event_class, .found = 0 };
+ g_ptr_array_foreach(stream_class->event_classes, event_class_exists,
+ &query);
+ if (query.found) {
+ BT_LOGW_STR("Another event class part of this stream class has the same ID.");
+ ret = -1;
+ goto end;
+ }
+
+ old_stream_class = bt_ctf_event_class_common_borrow_stream_class(event_class);
+ if (old_stream_class) {
+ /* Event class is already associated to a stream class. */
+ BT_LOGW("Event class is already part of another stream class: "
+ "event-class-stream-class-addr=%p, "
+ "event-class-stream-class-name=\"%s\", "
+ "event-class-stream-class-id=%" PRId64,
+ old_stream_class,
+ bt_ctf_stream_class_common_get_name(old_stream_class),
+ bt_ctf_stream_class_common_get_id(old_stream_class));
+ ret = -1;
+ goto end;
+ }
+
+ if (trace) {
+ /*
+ * If the stream class is associated with a trace, then
+ * both those objects are frozen. Also, this event class
+ * is about to be frozen.
+ *
+ * Therefore the event class must be validated here.
+ * The trace and stream class should be valid at this
+ * point.
+ */
+ BT_ASSERT(trace->valid);
+ BT_ASSERT(stream_class->valid);
+ packet_header_type =
+ bt_ctf_trace_common_borrow_packet_header_field_type(trace);
+ packet_context_type =
+ bt_ctf_stream_class_common_borrow_packet_context_field_type(
+ stream_class);
+ event_header_type =
+ bt_ctf_stream_class_common_borrow_event_header_field_type(
+ stream_class);
+ stream_event_ctx_type =
+ bt_ctf_stream_class_common_borrow_event_context_field_type(
+ stream_class);
+ event_context_type =
+ bt_ctf_event_class_common_borrow_context_field_type(
+ event_class);
+ event_payload_type =
+ bt_ctf_event_class_common_borrow_payload_field_type(
+ event_class);
+ ret = bt_ctf_validate_class_types(
+ trace->environment, packet_header_type,
+ packet_context_type, event_header_type,
+ stream_event_ctx_type, event_context_type,
+ event_payload_type, trace->valid,
+ stream_class->valid, event_class->valid,
+ &validation_output, validation_flags,
+ copy_field_type_func);
+
+ if (ret) {
+ /*
+ * This means something went wrong during the
+ * validation process, not that the objects are
+ * invalid.
+ */
+ BT_LOGE("Failed to validate event class: ret=%d", ret);
+ goto end;
+ }
+
+ if ((validation_output.valid_flags & validation_flags) !=
+ validation_flags) {
+ /* Invalid event class */
+ BT_LOGW("Invalid trace, stream class, or event class: "
+ "valid-flags=0x%x",
+ validation_output.valid_flags);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ /* Only set an event ID if none was explicitly set before */
+ *event_id = bt_ctf_event_class_common_get_id(event_class);
+ if (*event_id < 0) {
+ BT_LOGV("Event class has no ID: automatically setting it: "
+ "id=%" PRId64, stream_class->next_event_id);
+
+ if (bt_ctf_event_class_common_set_id(event_class,
+ stream_class->next_event_id)) {
+ BT_LOGE("Cannot set event class's ID: id=%" PRId64,
+ stream_class->next_event_id);
+ ret = -1;
+ goto end;
+ }
+ stream_class->next_event_id++;
+ *event_id = stream_class->next_event_id;
+ }
+
+ bt_object_set_parent(&event_class->base, &stream_class->base);
+
+ if (trace) {
+ /*
+ * At this point we know that the function will be
+ * successful. Therefore we can replace the event
+ * class's field types with what's in the validation
+ * output structure and mark this event class as valid.
+ */
+ bt_ctf_validation_replace_types(NULL, NULL, event_class,
+ &validation_output, validation_flags);
+ event_class->valid = 1;
+
+ /*
+ * Put what was not moved in
+ * bt_ctf_validation_replace_types().
+ */
+ bt_ctf_validation_output_put_types(&validation_output);
+ }
+
+ /* Add to the event classes of the stream class */
+ g_ptr_array_add(stream_class->event_classes, event_class);
+ g_hash_table_insert(stream_class->event_classes_ht, event_id,
+ event_class);
+ event_id = NULL;
+
+ /* Freeze the event class */
+ bt_ctf_event_class_common_freeze(event_class);
+
+ /*
+ * It is safe to set the stream class's unique clock class
+ * now if the stream class is frozen.
+ */
+ if (stream_class->frozen && expected_clock_class) {
+ BT_ASSERT(!stream_class->clock_class ||
+ stream_class->clock_class == expected_clock_class);
+ BT_MOVE(stream_class->clock_class, expected_clock_class);
+ }
+
+ BT_LOGD("Added event class to stream class: "
+ "stream-class-addr=%p, stream-class-name=\"%s\", "
+ "stream-class-id=%" PRId64 ", event-class-addr=%p, "
+ "event-class-name=\"%s\", event-class-id=%" PRId64,
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class),
+ event_class,
+ bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class));
+
+end:
+ bt_ctf_validation_output_put_types(&validation_output);
+ bt_put(expected_clock_class);
+ g_free(event_id);
+ return ret;
+}
+
+static
+int64_t get_event_class_count(void *element)
+{
+ return bt_ctf_stream_class_get_event_class_count(
+ (struct bt_ctf_stream_class *) element);
+}
+
+static
+void *get_event_class(void *element, int i)
+{
+ return bt_ctf_stream_class_get_event_class_by_index(
+ (struct bt_ctf_stream_class *) element, i);
+}
+
+static
+int visit_event_class(void *object, bt_ctf_visitor visitor,void *data)
+{
+ struct bt_ctf_visitor_object obj = {
+ .object = object,
+ .type = BT_CTF_VISITOR_OBJECT_TYPE_EVENT_CLASS
+ };
+
+ return visitor(&obj, data);
+}
+
+BT_HIDDEN
+int bt_ctf_stream_class_common_visit(struct bt_ctf_stream_class_common *stream_class,
+ bt_ctf_visitor visitor, void *data)
+{
+ int ret;
+ struct bt_ctf_visitor_object obj = {
+ .object = stream_class,
+ .type = BT_CTF_VISITOR_OBJECT_TYPE_STREAM_CLASS
+ };
+
+ if (!stream_class || !visitor) {
+ BT_LOGW("Invalid parameter: stream class or visitor is NULL: "
+ "stream-class-addr=%p, visitor=%p",
+ stream_class, visitor);
+ ret = -1;
+ goto end;
+ }
+
+ ret = visitor_helper(&obj, get_event_class_count,
+ get_event_class,
+ visit_event_class, visitor, data);
+ BT_LOGV("visitor_helper() returned: ret=%d", ret);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_stream_class_visit(struct bt_ctf_stream_class *stream_class,
+ bt_ctf_visitor visitor, void *data)
+{
+ return bt_ctf_stream_class_common_visit(BT_CTF_FROM_COMMON(stream_class),
+ visitor, data);
+}
+
+BT_HIDDEN
+void bt_ctf_stream_class_common_freeze(struct bt_ctf_stream_class_common *stream_class)
+{
+ if (!stream_class || stream_class->frozen) {
+ return;
+ }
+
+ BT_LOGD("Freezing stream class: addr=%p, name=\"%s\", id=%" PRId64,
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+ stream_class->frozen = 1;
+ bt_ctf_field_type_common_freeze(stream_class->event_header_field_type);
+ bt_ctf_field_type_common_freeze(stream_class->packet_context_field_type);
+ bt_ctf_field_type_common_freeze(stream_class->event_context_field_type);
+ bt_ctf_clock_class_freeze(stream_class->clock_class);
+}
+
+BT_HIDDEN
+int bt_ctf_stream_class_common_validate_single_clock_class(
+ struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_clock_class **expected_clock_class)
+{
+ int ret;
+ uint64_t i;
+
+ BT_ASSERT(stream_class);
+ BT_ASSERT(expected_clock_class);
+ ret = bt_ctf_field_type_common_validate_single_clock_class(
+ stream_class->packet_context_field_type,
+ expected_clock_class);
+ if (ret) {
+ BT_LOGW("Stream class's packet context field type "
+ "is not recursively mapped to the "
+ "expected clock class: "
+ "stream-class-addr=%p, "
+ "stream-class-name=\"%s\", "
+ "stream-class-id=%" PRId64 ", "
+ "ft-addr=%p",
+ stream_class,
+ bt_ctf_stream_class_common_get_name(stream_class),
+ stream_class->id,
+ stream_class->packet_context_field_type);
+ goto end;
+ }
+
+ ret = bt_ctf_field_type_common_validate_single_clock_class(
+ stream_class->event_header_field_type,
+ expected_clock_class);
+ if (ret) {
+ BT_LOGW("Stream class's event header field type "
+ "is not recursively mapped to the "
+ "expected clock class: "
+ "stream-class-addr=%p, "
+ "stream-class-name=\"%s\", "
+ "stream-class-id=%" PRId64 ", "
+ "ft-addr=%p",
+ stream_class,
+ bt_ctf_stream_class_common_get_name(stream_class),
+ stream_class->id,
+ stream_class->event_header_field_type);
+ goto end;
+ }
+
+ ret = bt_ctf_field_type_common_validate_single_clock_class(
+ stream_class->event_context_field_type,
+ expected_clock_class);
+ if (ret) {
+ BT_LOGW("Stream class's event context field type "
+ "is not recursively mapped to the "
+ "expected clock class: "
+ "stream-class-addr=%p, "
+ "stream-class-name=\"%s\", "
+ "stream-class-id=%" PRId64 ", "
+ "ft-addr=%p",
+ stream_class,
+ bt_ctf_stream_class_common_get_name(stream_class),
+ stream_class->id,
+ stream_class->event_context_field_type);
+ goto end;
+ }
+
+ for (i = 0; i < stream_class->event_classes->len; i++) {
+ struct bt_ctf_event_class_common *event_class =
+ g_ptr_array_index(stream_class->event_classes, i);
+
+ BT_ASSERT(event_class);
+ ret = bt_ctf_event_class_common_validate_single_clock_class(
+ event_class, expected_clock_class);
+ if (ret) {
+ BT_LOGW("Stream class's event class contains a "
+ "field type which is not recursively mapped to "
+ "the expected clock class: "
+ "stream-class-addr=%p, "
+ "stream-class-name=\"%s\", "
+ "stream-class-id=%" PRId64,
+ stream_class,
+ bt_ctf_stream_class_common_get_name(stream_class),
+ stream_class->id);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
static
int init_event_header(struct bt_ctf_stream_class *stream_class)
BT_LOGD("Destroying CTF writer stream class: addr=%p, name=\"%s\", id=%" PRId64,
stream_class, bt_ctf_stream_class_get_name(stream_class),
bt_ctf_stream_class_get_id(stream_class));
- bt_stream_class_common_finalize(BT_TO_COMMON(stream_class));
+ bt_ctf_stream_class_common_finalize(BT_CTF_TO_COMMON(stream_class));
bt_put(stream_class->clock);
g_free(stream_class);
}
goto error;
}
- ret = bt_stream_class_common_initialize(BT_TO_COMMON(stream_class),
+ ret = bt_ctf_stream_class_common_initialize(BT_CTF_TO_COMMON(stream_class),
name, bt_ctf_stream_class_destroy);
if (ret) {
- /* bt_stream_class_common_initialize() logs errors */
+ /* bt_ctf_stream_class_common_initialize() logs errors */
goto error;
}
goto end;
}
- BT_ASSERT(((struct bt_field_type_common *) ft)->id ==
- BT_FIELD_TYPE_ID_INTEGER);
+ BT_ASSERT(((struct bt_ctf_field_type_common *) ft)->id ==
+ BT_CTF_FIELD_TYPE_ID_INTEGER);
mapped_clock_class =
bt_ctf_field_type_integer_get_mapped_clock_class(ft);
if (!mapped_clock_class) {
ft);
}
- ret = bt_field_type_common_integer_set_mapped_clock_class_no_check_frozen(
- (void *) ft_copy,
- BT_TO_COMMON(stream_class->clock->clock_class));
+ ret = bt_ctf_field_type_common_integer_set_mapped_clock_class_no_check_frozen(
+ (void *) ft_copy, stream_class->clock->clock_class);
BT_ASSERT(ret == 0);
- ret = bt_field_type_common_structure_replace_field(
+ ret = bt_ctf_field_type_common_structure_replace_field(
(void *) parent_ft, field_name, (void *) ft_copy);
bt_put(ft_copy);
BT_LOGV("Automatically mapped field type to stream class's clock class: "
* 1 -> 0 -> 1 -> 0 -> ..., provoking an endless loop of destruction
* and serialization.
*/
- trace = BT_FROM_COMMON(bt_stream_class_common_borrow_trace(
- BT_TO_COMMON(stream_class)));
+ trace = BT_CTF_FROM_COMMON(bt_ctf_stream_class_common_borrow_trace(
+ BT_CTF_TO_COMMON(stream_class)));
BT_ASSERT(trace);
packet_header_type = bt_ctf_trace_get_packet_header_field_type(trace);
trace = NULL;
struct bt_ctf_trace *bt_ctf_stream_class_get_trace(
struct bt_ctf_stream_class *stream_class)
{
- return bt_get(bt_stream_class_common_borrow_trace(
- BT_TO_COMMON(stream_class)));
+ return bt_get(bt_ctf_stream_class_common_borrow_trace(
+ BT_CTF_TO_COMMON(stream_class)));
}
const char *bt_ctf_stream_class_get_name(
struct bt_ctf_stream_class *stream_class)
{
- return bt_stream_class_common_get_name(BT_TO_COMMON(stream_class));
+ return bt_ctf_stream_class_common_get_name(BT_CTF_TO_COMMON(stream_class));
}
int bt_ctf_stream_class_set_name(
struct bt_ctf_stream_class *stream_class, const char *name)
{
- return bt_stream_class_common_set_name(BT_TO_COMMON(stream_class),
+ return bt_ctf_stream_class_common_set_name(BT_CTF_TO_COMMON(stream_class),
name);
}
int64_t bt_ctf_stream_class_get_id(
struct bt_ctf_stream_class *stream_class)
{
- return bt_stream_class_common_get_id(BT_TO_COMMON(stream_class));
+ return bt_ctf_stream_class_common_get_id(BT_CTF_TO_COMMON(stream_class));
}
int bt_ctf_stream_class_set_id(
struct bt_ctf_stream_class *stream_class, uint64_t id)
{
- return bt_stream_class_common_set_id(BT_TO_COMMON(stream_class), id);
+ return bt_ctf_stream_class_common_set_id(BT_CTF_TO_COMMON(stream_class), id);
}
struct bt_ctf_field_type *bt_ctf_stream_class_get_packet_context_type(
struct bt_ctf_stream_class *stream_class)
{
return bt_get(
- bt_stream_class_common_borrow_packet_context_field_type(
- BT_TO_COMMON(stream_class)));
+ bt_ctf_stream_class_common_borrow_packet_context_field_type(
+ BT_CTF_TO_COMMON(stream_class)));
}
int bt_ctf_stream_class_set_packet_context_type(
struct bt_ctf_stream_class *stream_class,
struct bt_ctf_field_type *packet_context_type)
{
- return bt_stream_class_common_set_packet_context_field_type(
- BT_TO_COMMON(stream_class), (void *) packet_context_type);
+ return bt_ctf_stream_class_common_set_packet_context_field_type(
+ BT_CTF_TO_COMMON(stream_class), (void *) packet_context_type);
}
struct bt_ctf_field_type *
struct bt_ctf_stream_class *stream_class)
{
return bt_get(
- bt_stream_class_common_borrow_event_header_field_type(
- BT_TO_COMMON(stream_class)));
+ bt_ctf_stream_class_common_borrow_event_header_field_type(
+ BT_CTF_TO_COMMON(stream_class)));
}
int bt_ctf_stream_class_set_event_header_type(
struct bt_ctf_stream_class *stream_class,
struct bt_ctf_field_type *event_header_type)
{
- return bt_stream_class_common_set_event_header_field_type(
- BT_TO_COMMON(stream_class), (void *) event_header_type);
+ return bt_ctf_stream_class_common_set_event_header_field_type(
+ BT_CTF_TO_COMMON(stream_class), (void *) event_header_type);
}
struct bt_ctf_field_type *
struct bt_ctf_stream_class *stream_class)
{
return bt_get(
- bt_stream_class_common_borrow_event_context_field_type(
- BT_TO_COMMON(stream_class)));
+ bt_ctf_stream_class_common_borrow_event_context_field_type(
+ BT_CTF_TO_COMMON(stream_class)));
}
int bt_ctf_stream_class_set_event_context_type(
struct bt_ctf_stream_class *stream_class,
struct bt_ctf_field_type *event_context_type)
{
- return bt_stream_class_common_set_event_context_field_type(
- BT_TO_COMMON(stream_class), (void *) event_context_type);
+ return bt_ctf_stream_class_common_set_event_context_field_type(
+ BT_CTF_TO_COMMON(stream_class), (void *) event_context_type);
}
int64_t bt_ctf_stream_class_get_event_class_count(
struct bt_ctf_stream_class *stream_class)
{
- return bt_stream_class_common_get_event_class_count(
- BT_TO_COMMON(stream_class));
+ return bt_ctf_stream_class_common_get_event_class_count(
+ BT_CTF_TO_COMMON(stream_class));
}
struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_index(
struct bt_ctf_stream_class *stream_class, uint64_t index)
{
return bt_get(
- bt_stream_class_common_borrow_event_class_by_index(
- BT_TO_COMMON(stream_class), index));
+ bt_ctf_stream_class_common_borrow_event_class_by_index(
+ BT_CTF_TO_COMMON(stream_class), index));
}
struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_id(
struct bt_ctf_stream_class *stream_class, uint64_t id)
{
return bt_get(
- bt_stream_class_common_borrow_event_class_by_id(
- BT_TO_COMMON(stream_class), id));
+ bt_ctf_stream_class_common_borrow_event_class_by_id(
+ BT_CTF_TO_COMMON(stream_class), id));
}
int bt_ctf_stream_class_add_event_class(
struct bt_ctf_stream_class *stream_class,
struct bt_ctf_event_class *event_class)
{
- return bt_stream_class_common_add_event_class(
- BT_TO_COMMON(stream_class), BT_TO_COMMON(event_class),
- (bt_validation_flag_copy_field_type_func) bt_ctf_field_type_copy);
+ return bt_ctf_stream_class_common_add_event_class(
+ BT_CTF_TO_COMMON(stream_class), BT_CTF_TO_COMMON(event_class),
+ (bt_ctf_validation_flag_copy_field_type_func) bt_ctf_field_type_copy);
}
#define BT_LOG_TAG "CTF-WRITER-STREAM"
#include <babeltrace/lib-logging-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-writer/writer-internal.h>
-#include <babeltrace/ctf-writer/stream.h>
-#include <babeltrace/ctf-writer/stream-internal.h>
-#include <babeltrace/ctf-writer/stream-class-internal.h>
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/align-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/ctf-writer/event-class-internal.h>
+#include <babeltrace/ctf-writer/event-internal.h>
#include <babeltrace/ctf-writer/field-types.h>
#include <babeltrace/ctf-writer/fields-internal.h>
+#include <babeltrace/ctf-writer/stream-class-internal.h>
+#include <babeltrace/ctf-writer/stream-class.h>
+#include <babeltrace/ctf-writer/stream-internal.h>
+#include <babeltrace/ctf-writer/stream.h>
#include <babeltrace/ctf-writer/trace-internal.h>
-#include <babeltrace/ctf-writer/event-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/assert-pre-internal.h>
-#include <unistd.h>
-#include <stdint.h>
+#include <babeltrace/ctf-writer/trace.h>
+#include <babeltrace/ctf-writer/writer-internal.h>
+#include <babeltrace/ref.h>
#include <inttypes.h>
+#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_object_release_func release_func)
+{
+ int ret = 0;
+ struct bt_ctf_trace_common *trace = NULL;
+
+ bt_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_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;
+}
static
void bt_ctf_stream_destroy(struct bt_object *obj);
BT_LOGW("Invalid parameter: field's type is not an integer field type: "
"field-addr=%p, ft-addr=%p, ft-id=%s",
field, field_type,
- bt_common_field_type_id_string((int)
+ bt_ctf_field_type_id_string((int)
bt_ctf_field_type_get_type_id(field_type)));
ret = -1;
goto end;
int visit_field_update_clock_value(struct bt_ctf_field *field, uint64_t *val)
{
int ret = 0;
- struct bt_field_common *field_common = (void *) field;
+ struct bt_ctf_field_common *field_common = (void *) field;
if (!field) {
goto end;
case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
{
uint64_t i;
- int64_t len = bt_field_common_sequence_get_length(
+ int64_t len = bt_ctf_field_common_sequence_get_length(
(void *) field);
if (len < 0) {
stream->packet_context, "timestamp_begin");
struct bt_ctf_field *ts_end_field = bt_ctf_field_structure_get_field_by_name(
stream->packet_context, "timestamp_end");
- struct bt_field_common *packet_context =
+ struct bt_ctf_field_common *packet_context =
(void *) stream->packet_context;
uint64_t i;
int64_t len;
"event-class-name=\"%s\"",
stream, bt_ctf_stream_get_name(stream),
i, event,
- bt_event_class_common_get_id(event->common.class),
- bt_event_class_common_get_name(event->common.class));
+ bt_ctf_event_class_common_get_id(event->common.class),
+ bt_ctf_event_class_common_get_name(event->common.class));
goto end;
}
}
g_string_assign(filename, "stream");
append_ids:
- stream_class_id = bt_stream_class_common_get_id(stream->common.stream_class);
+ stream_class_id = bt_ctf_stream_class_common_get_id(stream->common.stream_class);
BT_ASSERT(stream_class_id >= 0);
BT_ASSERT(stream->common.id >= 0);
g_string_append_printf(filename, "-%" PRId64 "-%" PRId64,
id = stream_class->next_stream_id;
}
- ret = bt_stream_common_initialize(BT_TO_COMMON(stream),
- BT_TO_COMMON(stream_class), name, id, bt_ctf_stream_destroy);
+ ret = bt_ctf_stream_common_initialize(BT_CTF_TO_COMMON(stream),
+ BT_CTF_TO_COMMON(stream_class), name, id, bt_ctf_stream_destroy);
if (ret) {
- /* bt_stream_common_initialize() logs errors */
+ /* bt_ctf_stream_common_initialize() logs errors */
goto error;
}
- trace = BT_FROM_COMMON(bt_stream_class_common_borrow_trace(
- BT_TO_COMMON(stream_class)));
+ trace = BT_CTF_FROM_COMMON(bt_ctf_stream_class_common_borrow_trace(
+ BT_CTF_TO_COMMON(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\", "
struct bt_ctf_field *id_field = NULL, *timestamp_field = NULL;
struct bt_ctf_clock_class *mapped_clock_class = NULL;
struct bt_ctf_stream_class *stream_class =
- BT_FROM_COMMON(bt_stream_common_borrow_class(
- BT_TO_COMMON(stream)));
+ BT_CTF_FROM_COMMON(bt_ctf_stream_common_borrow_class(
+ BT_CTF_TO_COMMON(stream)));
int64_t event_class_id;
BT_ASSERT(event);
id_field = bt_ctf_field_structure_get_field_by_name(
(void *) event->common.header_field->field, "id");
- event_class_id = bt_event_class_common_get_id(event->common.class);
+ event_class_id = bt_ctf_event_class_common_get_id(event->common.class);
BT_ASSERT(event_class_id >= 0);
if (id_field && bt_ctf_field_get_type_id(id_field) == BT_CTF_FIELD_TYPE_ID_INTEGER) {
!bt_ctf_field_is_set_recursive(timestamp_field)) {
mapped_clock_class =
bt_ctf_field_type_integer_get_mapped_clock_class(
- (void *) ((struct bt_field_common *) timestamp_field)->type);
+ (void *) ((struct bt_ctf_field_common *) timestamp_field)->type);
if (mapped_clock_class) {
uint64_t timestamp;
"stream-addr=%p, stream-name=\"%s\", event-addr=%p, "
"event-class-name=\"%s\", event-class-id=%" PRId64,
stream, bt_ctf_stream_get_name(stream), event,
- bt_event_class_common_get_name(
- bt_event_common_borrow_class(BT_TO_COMMON(event))),
- bt_event_class_common_get_id(
- bt_event_common_borrow_class(BT_TO_COMMON(event))));
+ bt_ctf_event_class_common_get_name(
+ bt_ctf_event_common_borrow_class(BT_CTF_TO_COMMON(event))),
+ bt_ctf_event_class_common_get_id(
+ bt_ctf_event_common_borrow_class(BT_CTF_TO_COMMON(event))));
/*
* The event is not supposed to have a parent stream at this
/* Make sure the various scopes of the event are set */
BT_LOGV_STR("Validating event to append.");
- BT_ASSERT_PRE(bt_event_common_validate(BT_TO_COMMON(event)) == 0,
- "Invalid event: %!+we", event);
+ BT_ASSERT_PRE(bt_ctf_event_common_validate(BT_CTF_TO_COMMON(event)) == 0,
+ "Invalid event: event-addr=%p", event);
/* Save the new event and freeze it */
BT_LOGV_STR("Freezing the event to append.");
- bt_event_common_set_is_frozen(BT_TO_COMMON(event), true);
+ bt_ctf_event_common_set_is_frozen(BT_CTF_TO_COMMON(event), true);
g_ptr_array_add(stream->events, event);
/*
"stream-addr=%p, stream-name=\"%s\", event-addr=%p, "
"event-class-name=\"%s\", event-class-id=%" PRId64,
stream, bt_ctf_stream_get_name(stream), event,
- bt_event_class_common_get_name(
- bt_event_common_borrow_class(BT_TO_COMMON(event))),
- bt_event_class_common_get_id(
- bt_event_common_borrow_class(BT_TO_COMMON(event))));
+ bt_ctf_event_class_common_get_name(
+ bt_ctf_event_common_borrow_class(BT_CTF_TO_COMMON(event))),
+ bt_ctf_event_class_common_get_id(
+ bt_ctf_event_common_borrow_class(BT_CTF_TO_COMMON(event))));
end:
return ret;
}
field_type = bt_ctf_field_get_type(field);
- if (bt_field_type_common_compare((void *) field_type,
+ if (bt_ctf_field_type_common_compare((void *) field_type,
stream->common.stream_class->packet_context_field_type)) {
BT_LOGW("Invalid parameter: packet context's field type is different from the stream's packet context field type: "
"stream-addr=%p, stream-name=\"%s\", "
field_type = bt_ctf_field_get_type(field);
BT_ASSERT(field_type);
- if (bt_field_type_common_compare((void *) field_type,
+ if (bt_ctf_field_type_common_compare((void *) field_type,
trace->common.packet_header_field_type)) {
BT_LOGW("Invalid parameter: packet header's field type is different from the stream's packet header field type: "
"stream-addr=%p, stream-name=\"%s\", "
member = bt_ctf_field_structure_get_field_by_name(structure, name);
if (member) {
- bt_field_common_reset_recursive((void *) member);
+ bt_ctf_field_common_reset_recursive((void *) member);
bt_put(member);
}
}
BT_LOGV("Flushing stream's current packet: stream-addr=%p, "
"stream-name=\"%s\", packet-index=%u", stream,
bt_ctf_stream_get_name(stream), stream->flushed_packet_count);
- trace = BT_FROM_COMMON(bt_stream_class_common_borrow_trace(
+ trace = BT_CTF_FROM_COMMON(bt_ctf_stream_class_common_borrow_trace(
stream->common.stream_class));
BT_ASSERT(trace);
native_byte_order = bt_ctf_trace_get_native_byte_order(trace);
struct bt_ctf_event *event = g_ptr_array_index(
stream->events, i);
struct bt_ctf_event_class *event_class =
- BT_FROM_COMMON(bt_event_common_borrow_class(
- BT_TO_COMMON(event)));
+ BT_CTF_FROM_COMMON(bt_ctf_event_common_borrow_class(
+ BT_CTF_TO_COMMON(event)));
BT_LOGV("Serializing event: index=%zu, event-addr=%p, "
"event-class-name=\"%s\", event-class-id=%" PRId64 ", "
BT_LOGD("Destroying CTF writer stream object: addr=%p, name=\"%s\"",
stream, bt_ctf_stream_get_name(stream));
- bt_stream_common_finalize(BT_TO_COMMON(stream));
+ bt_ctf_stream_common_finalize(BT_CTF_TO_COMMON(stream));
(void) bt_ctf_stream_pos_fini(&stream->pos);
if (stream->pos.fd >= 0) {
BT_LOGW("Invalid parameter: field's type is not an integer field type: "
"field-addr=%p, ft-addr=%p, ft-id=%s",
integer, field_type,
- bt_common_field_type_id_string((int)
+ bt_ctf_field_type_id_string((int)
bt_ctf_field_type_get_type_id(field_type)));
ret = -1;
goto end;
struct bt_ctf_stream_class *bt_ctf_stream_get_class(
struct bt_ctf_stream *stream)
{
- return bt_get(bt_stream_common_borrow_class(BT_TO_COMMON(stream)));
+ return bt_get(bt_ctf_stream_common_borrow_class(BT_CTF_TO_COMMON(stream)));
}
const char *bt_ctf_stream_get_name(struct bt_ctf_stream *stream)
{
- return bt_stream_common_get_name(BT_TO_COMMON(stream));
+ return bt_ctf_stream_common_get_name(BT_CTF_TO_COMMON(stream));
}
int64_t bt_ctf_stream_get_id(struct bt_ctf_stream *stream)
{
- return bt_stream_common_get_id(BT_TO_COMMON(stream));
+ return bt_ctf_stream_common_get_id(BT_CTF_TO_COMMON(stream));
}
#define BT_LOG_TAG "CTF-WRITER-TRACE"
#include <babeltrace/lib-logging-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/ctf-writer/attributes-internal.h>
+#include <babeltrace/ctf-writer/clock-class-internal.h>
#include <babeltrace/ctf-writer/clock-internal.h>
-#include <babeltrace/ctf-writer/trace-internal.h>
+#include <babeltrace/ctf-writer/event-class-internal.h>
+#include <babeltrace/ctf-writer/event.h>
+#include <babeltrace/ctf-writer/event-internal.h>
+#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/ctf-writer/field-wrapper-internal.h>
+#include <babeltrace/ctf-writer/functor-internal.h>
#include <babeltrace/ctf-writer/stream-class-internal.h>
+#include <babeltrace/ctf-writer/stream-internal.h>
+#include <babeltrace/ctf-writer/trace-internal.h>
+#include <babeltrace/ctf-writer/utils-internal.h>
+#include <babeltrace/ctf-writer/utils.h>
+#include <babeltrace/ctf-writer/validation-internal.h>
+#include <babeltrace/ctf-writer/visitor-internal.h>
#include <babeltrace/ctf-writer/writer-internal.h>
-#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/endian-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/types.h>
+#include <babeltrace/values-internal.h>
+#include <babeltrace/values.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DEFAULT_IDENTIFIER_SIZE 128
+#define DEFAULT_METADATA_STRING_SIZE 4096
+
+BT_HIDDEN
+int bt_ctf_trace_common_initialize(struct bt_ctf_trace_common *trace,
+ bt_object_release_func release_func)
+{
+ int ret = 0;
+
+ BT_LOGD_STR("Initializing common trace object.");
+ trace->native_byte_order = BT_CTF_BYTE_ORDER_UNSPECIFIED;
+ bt_object_init_shared_with_parent(&trace->base, release_func);
+ trace->clock_classes = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) bt_put);
+ if (!trace->clock_classes) {
+ BT_LOGE_STR("Failed to allocate one GPtrArray.");
+ goto error;
+ }
+
+ trace->streams = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) bt_object_try_spec_release);
+ if (!trace->streams) {
+ BT_LOGE_STR("Failed to allocate one GPtrArray.");
+ goto error;
+ }
+
+ trace->stream_classes = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) bt_object_try_spec_release);
+ if (!trace->stream_classes) {
+ BT_LOGE_STR("Failed to allocate one GPtrArray.");
+ goto error;
+ }
+
+ /* Create the environment array object */
+ trace->environment = bt_ctf_attributes_create();
+ if (!trace->environment) {
+ BT_LOGE_STR("Cannot create empty attributes object.");
+ goto error;
+ }
+
+ BT_LOGD("Initialized common trace object: addr=%p", trace);
+ goto end;
+
+error:
+ ret = -1;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_trace_common_finalize(struct bt_ctf_trace_common *trace)
+{
+ BT_LOGD("Finalizing common trace object: addr=%p, name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace));
+
+ if (trace->environment) {
+ BT_LOGD_STR("Destroying environment attributes.");
+ bt_ctf_attributes_destroy(trace->environment);
+ }
+
+ if (trace->name) {
+ g_string_free(trace->name, TRUE);
+ }
+
+ if (trace->clock_classes) {
+ BT_LOGD_STR("Putting clock classes.");
+ g_ptr_array_free(trace->clock_classes, TRUE);
+ }
+
+ if (trace->streams) {
+ BT_LOGD_STR("Destroying streams.");
+ g_ptr_array_free(trace->streams, TRUE);
+ }
+
+ if (trace->stream_classes) {
+ BT_LOGD_STR("Destroying stream classes.");
+ g_ptr_array_free(trace->stream_classes, TRUE);
+ }
+
+ BT_LOGD_STR("Putting packet header field type.");
+ bt_put(trace->packet_header_field_type);
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_name(struct bt_ctf_trace_common *trace, const char *name)
+{
+ int ret = 0;
+
+ if (!trace) {
+ BT_LOGW_STR("Invalid parameter: trace is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!name) {
+ BT_LOGW_STR("Invalid parameter: name is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (trace->frozen) {
+ BT_LOGW("Invalid parameter: trace is frozen: "
+ "addr=%p, name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace));
+ ret = -1;
+ goto end;
+ }
+
+ trace->name = trace->name ? g_string_assign(trace->name, name) :
+ g_string_new(name);
+ if (!trace->name) {
+ BT_LOGE_STR("Failed to allocate one GString.");
+ ret = -1;
+ goto end;
+ }
+
+ BT_LOGV("Set trace's name: addr=%p, name=\"%s\"", trace, name);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_uuid(struct bt_ctf_trace_common *trace,
+ const unsigned char *uuid)
+{
+ int ret = 0;
+
+ if (!trace) {
+ BT_LOGW_STR("Invalid parameter: trace is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!uuid) {
+ BT_LOGW_STR("Invalid parameter: UUID is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (trace->frozen) {
+ BT_LOGW("Invalid parameter: trace is frozen: "
+ "addr=%p, name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace));
+ ret = -1;
+ goto end;
+ }
+
+ memcpy(trace->uuid, uuid, BABELTRACE_UUID_LEN);
+ trace->uuid_set = BT_TRUE;
+ BT_LOGV("Set trace's UUID: addr=%p, name=\"%s\", "
+ "uuid=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
+ trace, bt_ctf_trace_common_get_name(trace),
+ (unsigned int) uuid[0],
+ (unsigned int) uuid[1],
+ (unsigned int) uuid[2],
+ (unsigned int) uuid[3],
+ (unsigned int) uuid[4],
+ (unsigned int) uuid[5],
+ (unsigned int) uuid[6],
+ (unsigned int) uuid[7],
+ (unsigned int) uuid[8],
+ (unsigned int) uuid[9],
+ (unsigned int) uuid[10],
+ (unsigned int) uuid[11],
+ (unsigned int) uuid[12],
+ (unsigned int) uuid[13],
+ (unsigned int) uuid[14],
+ (unsigned int) uuid[15]);
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_environment_field(struct bt_ctf_trace_common *trace,
+ const char *name, struct bt_value *value)
+{
+ int ret = 0;
+
+ if (!trace) {
+ BT_LOGW_STR("Invalid parameter: trace is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!name) {
+ BT_LOGW_STR("Invalid parameter: name is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!value) {
+ BT_LOGW_STR("Invalid parameter: value is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!bt_ctf_identifier_is_valid(name)) {
+ BT_LOGW("Invalid parameter: environment field's name is not a valid CTF identifier: "
+ "trace-addr=%p, trace-name=\"%s\", "
+ "env-name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace), name);
+ ret = -1;
+ goto end;
+ }
+
+ if (!bt_value_is_integer(value) && !bt_value_is_string(value)) {
+ BT_LOGW("Invalid parameter: environment field's value is not an integer or string value: "
+ "trace-addr=%p, trace-name=\"%s\", "
+ "env-name=\"%s\", env-value-type=%s",
+ trace, bt_ctf_trace_common_get_name(trace), name,
+ bt_value_type_string(bt_value_get_type(value)));
+ ret = -1;
+ goto end;
+ }
+
+ if (trace->frozen) {
+ /*
+ * New environment fields may be added to a frozen trace,
+ * but existing fields may not be changed.
+ *
+ * The object passed is frozen like all other attributes.
+ */
+ struct bt_value *attribute =
+ bt_ctf_attributes_borrow_field_value_by_name(
+ trace->environment, name);
+
+ if (attribute) {
+ BT_LOGW("Invalid parameter: trace is frozen and environment field already exists with this name: "
+ "trace-addr=%p, trace-name=\"%s\", "
+ "env-name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace), name);
+ ret = -1;
+ goto end;
+ }
+
+ bt_value_freeze(value);
+ }
+
+ ret = bt_ctf_attributes_set_field_value(trace->environment, name,
+ value);
+ if (ret) {
+ BT_LOGE("Cannot set environment field's value: "
+ "trace-addr=%p, trace-name=\"%s\", "
+ "env-name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace), name);
+ } else {
+ BT_LOGV("Set environment field's value: "
+ "trace-addr=%p, trace-name=\"%s\", "
+ "env-name=\"%s\", value-addr=%p",
+ trace, bt_ctf_trace_common_get_name(trace), name, value);
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_environment_field_string(struct bt_ctf_trace_common *trace,
+ const char *name, const char *value)
+{
+ int ret = 0;
+ struct bt_value *env_value_string_obj = NULL;
+
+ if (!value) {
+ BT_LOGW_STR("Invalid parameter: value is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ env_value_string_obj = bt_value_string_create_init(value);
+ if (!env_value_string_obj) {
+ BT_LOGE_STR("Cannot create string value object.");
+ ret = -1;
+ goto end;
+ }
+
+ /* bt_ctf_trace_common_set_environment_field() logs errors */
+ ret = bt_ctf_trace_common_set_environment_field(trace, name,
+ env_value_string_obj);
+
+end:
+ bt_put(env_value_string_obj);
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_environment_field_integer(
+ struct bt_ctf_trace_common *trace, const char *name, int64_t value)
+{
+ int ret = 0;
+ struct bt_value *env_value_integer_obj = NULL;
+
+ env_value_integer_obj = bt_value_integer_create_init(value);
+ if (!env_value_integer_obj) {
+ BT_LOGE_STR("Cannot create integer value object.");
+ ret = -1;
+ goto end;
+ }
+
+ /* bt_ctf_trace_common_set_environment_field() logs errors */
+ ret = bt_ctf_trace_common_set_environment_field(trace, name,
+ env_value_integer_obj);
+
+end:
+ bt_put(env_value_integer_obj);
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_add_clock_class(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_clock_class *clock_class)
+{
+ int ret = 0;
+
+ if (!trace) {
+ BT_LOGW_STR("Invalid parameter: trace is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!bt_ctf_clock_class_is_valid(clock_class)) {
+ BT_LOGW("Invalid parameter: clock class is invalid: "
+ "trace-addr=%p, trace-name=\"%s\", "
+ "clock-class-addr=%p, clock-class-name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace),
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ ret = -1;
+ goto end;
+ }
+
+ /* Check for duplicate clock classes */
+ if (bt_ctf_trace_common_has_clock_class(trace, clock_class)) {
+ BT_LOGW("Invalid parameter: clock class already exists in trace: "
+ "trace-addr=%p, trace-name=\"%s\", "
+ "clock-class-addr=%p, clock-class-name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace),
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+ ret = -1;
+ goto end;
+ }
+
+ bt_get(clock_class);
+ g_ptr_array_add(trace->clock_classes, clock_class);
+
+ if (trace->frozen) {
+ BT_LOGV_STR("Freezing added clock class because trace is frozen.");
+ bt_ctf_clock_class_freeze(clock_class);
+ }
+
+ BT_LOGV("Added clock class to trace: "
+ "trace-addr=%p, trace-name=\"%s\", "
+ "clock-class-addr=%p, clock-class-name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace),
+ clock_class, bt_ctf_clock_class_get_name(clock_class));
+
+end:
+ return ret;
+}
+
+static
+bool packet_header_field_type_is_valid(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_field_type_common *packet_header_type)
+{
+ int ret;
+ bool is_valid = true;
+ struct bt_ctf_field_type_common *field_type = NULL;
+
+ if (!packet_header_type) {
+ /*
+ * No packet header field type: trace must have only
+ * one stream. At this point the stream class being
+ * added is not part of the trace yet, so we validate
+ * that the trace contains no stream classes yet.
+ */
+ if (trace->stream_classes->len >= 1) {
+ BT_LOGW_STR("Invalid packet header field type: "
+ "packet header field type does not exist but there's more than one stream class in the trace.");
+ goto invalid;
+ }
+
+ /* No packet header field type: valid at this point */
+ goto end;
+ }
+
+ /* Packet header field type, if it exists, must be a structure */
+ if (packet_header_type->id != BT_CTF_FIELD_TYPE_ID_STRUCT) {
+ BT_LOGW("Invalid packet header field type: must be a structure field type if it exists: "
+ "ft-addr=%p, ft-id=%s",
+ packet_header_type,
+ bt_ctf_field_type_id_string(packet_header_type->id));
+ goto invalid;
+ }
+
+ /*
+ * If there's a `magic` field, it must be a 32-bit unsigned
+ * integer field type. Also it must be the first field of the
+ * packet header field type.
+ */
+ field_type = bt_ctf_field_type_common_structure_borrow_field_type_by_name(
+ packet_header_type, "magic");
+ if (field_type) {
+ const char *field_name;
+
+ if (field_type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid packet header field type: `magic` field must be an integer field type: "
+ "magic-ft-addr=%p, magic-ft-id=%s",
+ field_type,
+ bt_ctf_field_type_id_string(field_type->id));
+ goto invalid;
+ }
+
+ if (bt_ctf_field_type_common_integer_is_signed(field_type)) {
+ BT_LOGW("Invalid packet header field type: `magic` field must be an unsigned integer field type: "
+ "magic-ft-addr=%p", field_type);
+ goto invalid;
+ }
+
+ if (bt_ctf_field_type_common_integer_get_size(field_type) != 32) {
+ BT_LOGW("Invalid packet header field type: `magic` field must be a 32-bit unsigned integer field type: "
+ "magic-ft-addr=%p, magic-ft-size=%u",
+ field_type,
+ bt_ctf_field_type_common_integer_get_size(field_type));
+ goto invalid;
+ }
+
+ ret = bt_ctf_field_type_common_structure_borrow_field_by_index(
+ packet_header_type, &field_name, NULL, 0);
+ BT_ASSERT(ret == 0);
+
+ if (strcmp(field_name, "magic") != 0) {
+ BT_LOGW("Invalid packet header field type: `magic` field must be the first field: "
+ "magic-ft-addr=%p, first-field-name=\"%s\"",
+ field_type, field_name);
+ goto invalid;
+ }
+ }
+
+ /*
+ * If there's a `uuid` field, it must be an array field type of
+ * length 16 with an 8-bit unsigned integer element field type.
+ */
+ field_type = bt_ctf_field_type_common_structure_borrow_field_type_by_name(
+ packet_header_type, "uuid");
+ if (field_type) {
+ struct bt_ctf_field_type_common *elem_ft;
+
+ if (field_type->id != BT_CTF_FIELD_TYPE_ID_ARRAY) {
+ BT_LOGW("Invalid packet header field type: `uuid` field must be an array field type: "
+ "uuid-ft-addr=%p, uuid-ft-id=%s",
+ field_type,
+ bt_ctf_field_type_id_string(field_type->id));
+ goto invalid;
+ }
+
+ if (bt_ctf_field_type_common_array_get_length(field_type) != 16) {
+ BT_LOGW("Invalid packet header field type: `uuid` array field type's length must be 16: "
+ "uuid-ft-addr=%p, uuid-ft-length=%" PRId64,
+ field_type,
+ bt_ctf_field_type_common_array_get_length(field_type));
+ goto invalid;
+ }
+
+ elem_ft = bt_ctf_field_type_common_array_borrow_element_field_type(field_type);
+ BT_ASSERT(elem_ft);
+
+ if (elem_ft->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid packet header field type: `uuid` field's element field type must be an integer field type: "
+ "elem-ft-addr=%p, elem-ft-id=%s",
+ elem_ft,
+ bt_ctf_field_type_id_string(elem_ft->id));
+ goto invalid;
+ }
+
+ if (bt_ctf_field_type_common_integer_is_signed(elem_ft)) {
+ BT_LOGW("Invalid packet header field type: `uuid` field's element field type must be an unsigned integer field type: "
+ "elem-ft-addr=%p", elem_ft);
+ goto invalid;
+ }
+
+ if (bt_ctf_field_type_common_integer_get_size(elem_ft) != 8) {
+ BT_LOGW("Invalid packet header field type: `uuid` field's element field type must be an 8-bit unsigned integer field type: "
+ "elem-ft-addr=%p, elem-ft-size=%u",
+ elem_ft,
+ bt_ctf_field_type_common_integer_get_size(elem_ft));
+ goto invalid;
+ }
+ }
+
+ /*
+ * The `stream_id` field must exist if there's more than one
+ * stream classes in the trace.
+ */
+ field_type = bt_ctf_field_type_common_structure_borrow_field_type_by_name(
+ packet_header_type, "stream_id");
+
+ if (!field_type && trace->stream_classes->len >= 1) {
+ BT_LOGW_STR("Invalid packet header field type: "
+ "`stream_id` field does not exist but there's more than one stream class in the trace.");
+ goto invalid;
+ }
+
+ /*
+ * If there's a `stream_id` field, it must be an unsigned
+ * integer field type.
+ */
+ if (field_type) {
+ if (field_type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid packet header field type: `stream_id` field must be an integer field type: "
+ "stream-id-ft-addr=%p, stream-id-ft-id=%s",
+ field_type,
+ bt_ctf_field_type_id_string(field_type->id));
+ goto invalid;
+ }
+
+ if (bt_ctf_field_type_common_integer_is_signed(field_type)) {
+ BT_LOGW("Invalid packet header field type: `stream_id` field must be an unsigned integer field type: "
+ "stream-id-ft-addr=%p", field_type);
+ goto invalid;
+ }
+ }
+
+ /*
+ * If there's a `packet_seq_num` field, it must be an unsigned
+ * integer field type.
+ */
+ field_type = bt_ctf_field_type_common_structure_borrow_field_type_by_name(
+ packet_header_type, "packet_seq_num");
+ if (field_type) {
+ if (field_type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid packet header field type: `packet_seq_num` field must be an integer field type: "
+ "stream-id-ft-addr=%p, packet-seq-num-ft-id=%s",
+ field_type,
+ bt_ctf_field_type_id_string(field_type->id));
+ goto invalid;
+ }
+
+ if (bt_ctf_field_type_common_integer_is_signed(field_type)) {
+ BT_LOGW("Invalid packet header field type: `packet_seq_num` field must be an unsigned integer field type: "
+ "packet-seq-num-ft-addr=%p", field_type);
+ goto invalid;
+ }
+ }
+
+ goto end;
+
+invalid:
+ is_valid = false;
+
+end:
+ return is_valid;
+}
+
+static
+bool packet_context_field_type_is_valid(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_field_type_common *packet_context_type,
+ bool check_ts_begin_end_mapped)
+{
+ bool is_valid = true;
+ struct bt_ctf_field_type_common *field_type = NULL;
+
+ if (!packet_context_type) {
+ /* No packet context field type: valid at this point */
+ goto end;
+ }
+
+ /* Packet context field type, if it exists, must be a structure */
+ if (packet_context_type->id != BT_CTF_FIELD_TYPE_ID_STRUCT) {
+ BT_LOGW("Invalid packet context field type: must be a structure field type if it exists: "
+ "ft-addr=%p, ft-id=%s",
+ packet_context_type,
+ bt_ctf_field_type_id_string(packet_context_type->id));
+ goto invalid;
+ }
+
+ /*
+ * If there's a `packet_size` field, it must be an unsigned
+ * integer field type.
+ */
+ field_type = bt_ctf_field_type_common_structure_borrow_field_type_by_name(
+ packet_context_type, "packet_size");
+ if (field_type) {
+ if (field_type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid packet context field type: `packet_size` field must be an integer field type: "
+ "packet-size-ft-addr=%p, packet-size-ft-id=%s",
+ field_type,
+ bt_ctf_field_type_id_string(field_type->id));
+ goto invalid;
+ }
+
+ if (bt_ctf_field_type_common_integer_is_signed(field_type)) {
+ BT_LOGW("Invalid packet context field type: `packet_size` field must be an unsigned integer field type: "
+ "packet-size-ft-addr=%p", field_type);
+ goto invalid;
+ }
+ }
+
+ /*
+ * If there's a `content_size` field, it must be an unsigned
+ * integer field type.
+ */
+ field_type = bt_ctf_field_type_common_structure_borrow_field_type_by_name(
+ packet_context_type, "content_size");
+ if (field_type) {
+ if (field_type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid packet context field type: `content_size` field must be an integer field type: "
+ "content-size-ft-addr=%p, content-size-ft-id=%s",
+ field_type,
+ bt_ctf_field_type_id_string(field_type->id));
+ goto invalid;
+ }
+
+ if (bt_ctf_field_type_common_integer_is_signed(field_type)) {
+ BT_LOGW("Invalid packet context field type: `content_size` field must be an unsigned integer field type: "
+ "content-size-ft-addr=%p", field_type);
+ goto invalid;
+ }
+ }
+
+ /*
+ * If there's a `events_discarded` field, it must be an unsigned
+ * integer field type.
+ */
+ field_type = bt_ctf_field_type_common_structure_borrow_field_type_by_name(
+ packet_context_type, "events_discarded");
+ if (field_type) {
+ if (field_type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid packet context field type: `events_discarded` field must be an integer field type: "
+ "events-discarded-ft-addr=%p, events-discarded-ft-id=%s",
+ field_type,
+ bt_ctf_field_type_id_string(field_type->id));
+ goto invalid;
+ }
+
+ if (bt_ctf_field_type_common_integer_is_signed(field_type)) {
+ BT_LOGW("Invalid packet context field type: `events_discarded` field must be an unsigned integer field type: "
+ "events-discarded-ft-addr=%p", field_type);
+ goto invalid;
+ }
+ }
+
+ /*
+ * If there's a `timestamp_begin` field, it must be an unsigned
+ * integer field type. Also, if the trace is not a CTF writer's
+ * trace, then we cannot automatically set the mapped clock
+ * class of this field, so it must have a mapped clock class.
+ */
+ field_type = bt_ctf_field_type_common_structure_borrow_field_type_by_name(
+ packet_context_type, "timestamp_begin");
+ if (field_type) {
+ if (field_type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid packet context field type: `timestamp_begin` field must be an integer field type: "
+ "timestamp-begin-ft-addr=%p, timestamp-begin-ft-id=%s",
+ field_type,
+ bt_ctf_field_type_id_string(field_type->id));
+ goto invalid;
+ }
+
+ if (bt_ctf_field_type_common_integer_is_signed(field_type)) {
+ BT_LOGW("Invalid packet context field type: `timestamp_begin` field must be an unsigned integer field type: "
+ "timestamp-begin-ft-addr=%p", field_type);
+ goto invalid;
+ }
+
+ if (check_ts_begin_end_mapped) {
+ struct bt_ctf_clock_class *clock_class =
+ bt_ctf_field_type_common_integer_borrow_mapped_clock_class(
+ field_type);
+
+ if (!clock_class) {
+ BT_LOGW("Invalid packet context field type: `timestamp_begin` field must be mapped to a clock class: "
+ "timestamp-begin-ft-addr=%p", field_type);
+ goto invalid;
+ }
+ }
+ }
-#define DEFAULT_IDENTIFIER_SIZE 128
-#define DEFAULT_METADATA_STRING_SIZE 4096
+ /*
+ * If there's a `timestamp_end` field, it must be an unsigned
+ * integer field type. Also, if the trace is not a CTF writer's
+ * trace, then we cannot automatically set the mapped clock
+ * class of this field, so it must have a mapped clock class.
+ */
+ field_type = bt_ctf_field_type_common_structure_borrow_field_type_by_name(
+ packet_context_type, "timestamp_end");
+ if (field_type) {
+ if (field_type->id != BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ BT_LOGW("Invalid packet context field type: `timestamp_end` field must be an integer field type: "
+ "timestamp-end-ft-addr=%p, timestamp-end-ft-id=%s",
+ field_type,
+ bt_ctf_field_type_id_string(field_type->id));
+ goto invalid;
+ }
+
+ if (bt_ctf_field_type_common_integer_is_signed(field_type)) {
+ BT_LOGW("Invalid packet context field type: `timestamp_end` field must be an unsigned integer field type: "
+ "timestamp-end-ft-addr=%p", field_type);
+ goto invalid;
+ }
+
+ if (check_ts_begin_end_mapped) {
+ struct bt_ctf_clock_class *clock_class =
+ bt_ctf_field_type_common_integer_borrow_mapped_clock_class(
+ field_type);
+
+ if (!clock_class) {
+ BT_LOGW("Invalid packet context field type: `timestamp_end` field must be mapped to a clock class: "
+ "timestamp-end-ft-addr=%p", field_type);
+ goto invalid;
+ }
+ }
+ }
+
+ goto end;
+
+invalid:
+ is_valid = false;
+
+end:
+ return is_valid;
+}
+
+static
+bool event_header_field_type_is_valid(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_field_type_common *event_header_type)
+{
+ bool is_valid = true;
+ struct bt_ctf_field_type_common *field_type = NULL;
+
+ /*
+ * We do not validate that the `timestamp` field exists here
+ * because CTF does not require this exact name to be mapped to
+ * a clock class.
+ */
+
+ if (!event_header_type) {
+ /*
+ * No event header field type: stream class must have
+ * only one event class.
+ */
+ if (bt_ctf_stream_class_common_get_event_class_count(stream_class) > 1) {
+ BT_LOGW_STR("Invalid event header field type: "
+ "event header field type does not exist but there's more than one event class in the stream class.");
+ goto invalid;
+ }
+
+ /* No event header field type: valid at this point */
+ goto end;
+ }
+
+ /* Event header field type, if it exists, must be a structure */
+ if (event_header_type->id != BT_CTF_FIELD_TYPE_ID_STRUCT) {
+ BT_LOGW("Invalid event header field type: must be a structure field type if it exists: "
+ "ft-addr=%p, ft-id=%s",
+ event_header_type,
+ bt_ctf_field_type_id_string(event_header_type->id));
+ goto invalid;
+ }
+
+ /*
+ * If there's an `id` field, it must be an unsigned integer
+ * field type or an enumeration field type with an unsigned
+ * integer container field type.
+ */
+ field_type = bt_ctf_field_type_common_structure_borrow_field_type_by_name(
+ event_header_type, "id");
+ if (field_type) {
+ struct bt_ctf_field_type_common *int_ft;
+
+ if (field_type->id == BT_CTF_FIELD_TYPE_ID_INTEGER) {
+ int_ft = field_type;
+ } else if (field_type->id == BT_CTF_FIELD_TYPE_ID_ENUM) {
+ int_ft = bt_ctf_field_type_common_enumeration_borrow_container_field_type(
+ field_type);
+ } else {
+ BT_LOGW("Invalid event header field type: `id` field must be an integer or enumeration field type: "
+ "id-ft-addr=%p, id-ft-id=%s",
+ field_type,
+ bt_ctf_field_type_id_string(field_type->id));
+ goto invalid;
+ }
+
+ BT_ASSERT(int_ft);
+ if (bt_ctf_field_type_common_integer_is_signed(int_ft)) {
+ BT_LOGW("Invalid event header field type: `id` field must be an unsigned integer or enumeration field type: "
+ "id-ft-addr=%p", int_ft);
+ goto invalid;
+ }
+ }
+
+ goto end;
+
+invalid:
+ is_valid = false;
+
+end:
+ return is_valid;
+}
+
+static
+int check_packet_header_type_has_no_clock_class(struct bt_ctf_trace_common *trace)
+{
+ int ret = 0;
+
+ if (trace->packet_header_field_type) {
+ struct bt_ctf_clock_class *clock_class = NULL;
+
+ ret = bt_ctf_field_type_common_validate_single_clock_class(
+ trace->packet_header_field_type,
+ &clock_class);
+ bt_put(clock_class);
+ if (ret || clock_class) {
+ BT_LOGW("Trace's packet header field type cannot "
+ "contain a field type which is mapped to "
+ "a clock class: "
+ "trace-addr=%p, trace-name=\"%s\", "
+ "clock-class-name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace),
+ clock_class ?
+ bt_ctf_clock_class_get_name(clock_class) :
+ NULL);
+ ret = -1;
+ }
+ }
+
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_add_stream_class(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_stream_class_common *stream_class,
+ bt_ctf_validation_flag_copy_field_type_func copy_field_type_func,
+ struct bt_ctf_clock_class *init_expected_clock_class,
+ int (*map_clock_classes_func)(struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_field_type_common *packet_context_field_type,
+ struct bt_ctf_field_type_common *event_header_field_type),
+ bool check_ts_begin_end_mapped)
+{
+ int ret;
+ int64_t i;
+ int64_t stream_id;
+ struct bt_ctf_validation_output trace_sc_validation_output = { 0 };
+ struct bt_ctf_validation_output *ec_validation_outputs = NULL;
+ const enum bt_ctf_validation_flag trace_sc_validation_flags =
+ BT_CTF_VALIDATION_FLAG_TRACE |
+ BT_CTF_VALIDATION_FLAG_STREAM;
+ const enum bt_ctf_validation_flag ec_validation_flags =
+ BT_CTF_VALIDATION_FLAG_EVENT;
+ struct bt_ctf_field_type_common *packet_header_type = NULL;
+ struct bt_ctf_field_type_common *packet_context_type = NULL;
+ struct bt_ctf_field_type_common *event_header_type = NULL;
+ struct bt_ctf_field_type_common *stream_event_ctx_type = NULL;
+ int64_t event_class_count;
+ struct bt_ctf_trace_common *current_parent_trace = NULL;
+ struct bt_ctf_clock_class *expected_clock_class =
+ bt_get(init_expected_clock_class);
+
+ BT_ASSERT(copy_field_type_func);
+
+ if (!trace) {
+ BT_LOGW_STR("Invalid parameter: trace is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!stream_class) {
+ BT_LOGW_STR("Invalid parameter: stream class is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ BT_LOGD("Adding stream class to trace: "
+ "trace-addr=%p, trace-name=\"%s\", "
+ "stream-class-addr=%p, stream-class-name=\"%s\", "
+ "stream-class-id=%" PRId64,
+ trace, bt_ctf_trace_common_get_name(trace),
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+
+ current_parent_trace = bt_ctf_stream_class_common_borrow_trace(stream_class);
+ if (current_parent_trace) {
+ /* Stream class is already associated to a trace, abort. */
+ BT_LOGW("Invalid parameter: stream class is already part of a trace: "
+ "stream-class-trace-addr=%p, "
+ "stream-class-trace-name=\"%s\"",
+ current_parent_trace,
+ bt_ctf_trace_common_get_name(current_parent_trace));
+ ret = -1;
+ goto end;
+ }
+
+ event_class_count =
+ bt_ctf_stream_class_common_get_event_class_count(stream_class);
+ BT_ASSERT(event_class_count >= 0);
+
+ if (!stream_class->frozen) {
+ /*
+ * Stream class is not frozen yet. Validate that the
+ * stream class contains at most a single clock class
+ * because the previous
+ * bt_ctf_stream_class_common_add_event_class() calls did
+ * not make this validation since the stream class's
+ * direct field types (packet context, event header,
+ * event context) could change afterwards. This stream
+ * class is about to be frozen and those field types
+ * won't be changed if this function succeeds.
+ *
+ * At this point we're also sure that the stream class's
+ * clock, if any, has the same class as the stream
+ * class's expected clock class, if any. This is why, if
+ * bt_ctf_stream_class_common_validate_single_clock_class()
+ * succeeds below, the call to
+ * bt_ctf_stream_class_map_clock_class() at the end of this
+ * function is safe because it maps to the same, single
+ * clock class.
+ */
+ ret = bt_ctf_stream_class_common_validate_single_clock_class(
+ stream_class, &expected_clock_class);
+ if (ret) {
+ BT_LOGW("Invalid parameter: stream class or one of its "
+ "event classes contains a field type which is "
+ "not recursively mapped to the expected "
+ "clock class: "
+ "stream-class-addr=%p, "
+ "stream-class-id=%" PRId64 ", "
+ "stream-class-name=\"%s\", "
+ "expected-clock-class-addr=%p, "
+ "expected-clock-class-name=\"%s\"",
+ stream_class, bt_ctf_stream_class_common_get_id(stream_class),
+ bt_ctf_stream_class_common_get_name(stream_class),
+ expected_clock_class,
+ expected_clock_class ?
+ bt_ctf_clock_class_get_name(expected_clock_class) :
+ NULL);
+ goto end;
+ }
+ }
+
+ ret = check_packet_header_type_has_no_clock_class(trace);
+ if (ret) {
+ /* check_packet_header_type_has_no_clock_class() logs errors */
+ goto end;
+ }
+
+ /*
+ * We're about to freeze both the trace and the stream class.
+ * Also, each event class contained in this stream class are
+ * already frozen.
+ *
+ * This trace, this stream class, and all its event classes
+ * should be valid at this point.
+ *
+ * Validate trace and stream class first, then each event
+ * class of this stream class can be validated individually.
+ */
+ packet_header_type =
+ bt_ctf_trace_common_borrow_packet_header_field_type(trace);
+ packet_context_type =
+ bt_ctf_stream_class_common_borrow_packet_context_field_type(stream_class);
+ event_header_type =
+ bt_ctf_stream_class_common_borrow_event_header_field_type(stream_class);
+ stream_event_ctx_type =
+ bt_ctf_stream_class_common_borrow_event_context_field_type(stream_class);
+
+ BT_LOGD("Validating trace and stream class field types.");
+ ret = bt_ctf_validate_class_types(trace->environment,
+ packet_header_type, packet_context_type, event_header_type,
+ stream_event_ctx_type, NULL, NULL, trace->valid,
+ stream_class->valid, 1, &trace_sc_validation_output,
+ trace_sc_validation_flags, copy_field_type_func);
+
+ if (ret) {
+ /*
+ * This means something went wrong during the validation
+ * process, not that the objects are invalid.
+ */
+ BT_LOGE("Failed to validate trace and stream class field types: "
+ "ret=%d", ret);
+ goto end;
+ }
+
+ if ((trace_sc_validation_output.valid_flags &
+ trace_sc_validation_flags) !=
+ trace_sc_validation_flags) {
+ /* Invalid trace/stream class */
+ BT_LOGW("Invalid trace or stream class field types: "
+ "valid-flags=0x%x",
+ trace_sc_validation_output.valid_flags);
+ ret = -1;
+ goto end;
+ }
+
+ if (event_class_count > 0) {
+ ec_validation_outputs = g_new0(struct bt_ctf_validation_output,
+ event_class_count);
+ if (!ec_validation_outputs) {
+ BT_LOGE_STR("Failed to allocate one validation output structure.");
+ ret = -1;
+ goto end;
+ }
+ }
+
+ /* Validate each event class individually */
+ for (i = 0; i < event_class_count; i++) {
+ struct bt_ctf_event_class_common *event_class =
+ bt_ctf_stream_class_common_borrow_event_class_by_index(
+ stream_class, i);
+ struct bt_ctf_field_type_common *event_context_type = NULL;
+ struct bt_ctf_field_type_common *event_payload_type = NULL;
+
+ event_context_type =
+ bt_ctf_event_class_common_borrow_context_field_type(
+ event_class);
+ event_payload_type =
+ bt_ctf_event_class_common_borrow_payload_field_type(
+ event_class);
+
+ /*
+ * It is important to use the field types returned by
+ * the previous trace and stream class validation here
+ * because copies could have been made.
+ */
+ BT_LOGD("Validating event class's field types: "
+ "addr=%p, name=\"%s\", id=%" PRId64,
+ event_class, bt_ctf_event_class_common_get_name(event_class),
+ bt_ctf_event_class_common_get_id(event_class));
+ ret = bt_ctf_validate_class_types(trace->environment,
+ trace_sc_validation_output.packet_header_type,
+ trace_sc_validation_output.packet_context_type,
+ trace_sc_validation_output.event_header_type,
+ trace_sc_validation_output.stream_event_ctx_type,
+ event_context_type, event_payload_type,
+ 1, 1, event_class->valid, &ec_validation_outputs[i],
+ ec_validation_flags, copy_field_type_func);
+
+ if (ret) {
+ BT_LOGE("Failed to validate event class field types: "
+ "ret=%d", ret);
+ goto end;
+ }
+
+ if ((ec_validation_outputs[i].valid_flags &
+ ec_validation_flags) != ec_validation_flags) {
+ /* Invalid event class */
+ BT_LOGW("Invalid event class field types: "
+ "valid-flags=0x%x",
+ ec_validation_outputs[i].valid_flags);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ stream_id = bt_ctf_stream_class_common_get_id(stream_class);
+ if (stream_id < 0) {
+ stream_id = trace->next_stream_id++;
+ if (stream_id < 0) {
+ BT_LOGE_STR("No more stream class IDs available.");
+ ret = -1;
+ goto end;
+ }
+
+ /* Try to assign a new stream id */
+ for (i = 0; i < trace->stream_classes->len; i++) {
+ if (stream_id == bt_ctf_stream_class_common_get_id(
+ trace->stream_classes->pdata[i])) {
+ /* Duplicate stream id found */
+ BT_LOGW("Duplicate stream class ID: "
+ "id=%" PRId64, (int64_t) stream_id);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ if (bt_ctf_stream_class_common_set_id_no_check(stream_class,
+ stream_id)) {
+ /* TODO Should retry with a different stream id */
+ BT_LOGE("Cannot set stream class's ID: "
+ "id=%" PRId64, (int64_t) stream_id);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ /*
+ * At this point all the field types in the validation output
+ * are valid. Validate the semantics of some scopes according to
+ * the CTF specification.
+ */
+ if (!packet_header_field_type_is_valid(trace,
+ trace_sc_validation_output.packet_header_type)) {
+ BT_LOGW_STR("Invalid trace's packet header field type.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!packet_context_field_type_is_valid(trace,
+ stream_class,
+ trace_sc_validation_output.packet_context_type,
+ check_ts_begin_end_mapped)) {
+ BT_LOGW_STR("Invalid stream class's packet context field type.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!event_header_field_type_is_valid(trace,
+ stream_class,
+ trace_sc_validation_output.event_header_type)) {
+ BT_LOGW_STR("Invalid steam class's event header field type.");
+ ret = -1;
+ goto end;
+ }
+
+ /*
+ * Now is the time to automatically map specific field types of
+ * the stream class's packet context and event header field
+ * types to the stream class's clock's class if they are not
+ * mapped to a clock class yet. We do it here because we know
+ * that after this point, everything is frozen so it won't be
+ * possible for the user to modify the stream class's clock, or
+ * to map those field types to other clock classes.
+ */
+ if (map_clock_classes_func) {
+ if (map_clock_classes_func(stream_class,
+ trace_sc_validation_output.packet_context_type,
+ trace_sc_validation_output.event_header_type)) {
+ /* map_clock_classes_func() logs errors */
+ ret = -1;
+ goto end;
+ }
+ }
+
+ bt_object_set_parent(&stream_class->base, &trace->base);
+ g_ptr_array_add(trace->stream_classes, stream_class);
+
+ /*
+ * At this point we know that the function will be successful.
+ * Therefore we can replace the trace and stream class field
+ * types with what's in their validation output structure and
+ * mark them as valid. We can also replace the field types of
+ * all the event classes of the stream class and mark them as
+ * valid.
+ */
+ bt_ctf_validation_replace_types(trace, stream_class, NULL,
+ &trace_sc_validation_output, trace_sc_validation_flags);
+ trace->valid = 1;
+ stream_class->valid = 1;
+
+ /*
+ * Put what was not moved in bt_ctf_validation_replace_types().
+ */
+ bt_ctf_validation_output_put_types(&trace_sc_validation_output);
+
+ for (i = 0; i < event_class_count; i++) {
+ struct bt_ctf_event_class_common *event_class =
+ bt_ctf_stream_class_common_borrow_event_class_by_index(
+ stream_class, i);
+
+ bt_ctf_validation_replace_types(NULL, NULL, event_class,
+ &ec_validation_outputs[i], ec_validation_flags);
+ event_class->valid = 1;
+
+ /*
+ * Put what was not moved in
+ * bt_ctf_validation_replace_types().
+ */
+ bt_ctf_validation_output_put_types(&ec_validation_outputs[i]);
+ }
+
+ /*
+ * Freeze the trace and the stream class.
+ */
+ bt_ctf_stream_class_common_freeze(stream_class);
+ bt_ctf_trace_common_freeze(trace);
+
+ /*
+ * It is safe to set the stream class's unique clock class
+ * now because the stream class is frozen.
+ */
+ if (expected_clock_class) {
+ BT_MOVE(stream_class->clock_class, expected_clock_class);
+ }
+
+ BT_LOGD("Added stream class to trace: "
+ "trace-addr=%p, trace-name=\"%s\", "
+ "stream-class-addr=%p, stream-class-name=\"%s\", "
+ "stream-class-id=%" PRId64,
+ trace, bt_ctf_trace_common_get_name(trace),
+ stream_class, bt_ctf_stream_class_common_get_name(stream_class),
+ bt_ctf_stream_class_common_get_id(stream_class));
+
+end:
+ if (ret) {
+ bt_object_set_parent(&stream_class->base, NULL);
+
+ if (ec_validation_outputs) {
+ for (i = 0; i < event_class_count; i++) {
+ bt_ctf_validation_output_put_types(
+ &ec_validation_outputs[i]);
+ }
+ }
+ }
+
+ g_free(ec_validation_outputs);
+ bt_ctf_validation_output_put_types(&trace_sc_validation_output);
+ bt_put(expected_clock_class);
+ return ret;
+}
+
+BT_HIDDEN
+bt_bool bt_ctf_trace_common_has_clock_class(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_clock_class *clock_class)
+{
+ struct bt_ctf_search_query query = { .value = clock_class, .found = 0 };
+
+ BT_ASSERT(trace);
+ BT_ASSERT(clock_class);
+
+ g_ptr_array_foreach(trace->clock_classes, value_exists, &query);
+ return query.found;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_native_byte_order(struct bt_ctf_trace_common *trace,
+ enum bt_ctf_byte_order byte_order, bool allow_unspecified)
+{
+ int ret = 0;
+
+ if (!trace) {
+ BT_LOGW_STR("Invalid parameter: trace is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (trace->frozen) {
+ BT_LOGW("Invalid parameter: trace is frozen: "
+ "addr=%p, name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace));
+ ret = -1;
+ goto end;
+ }
+
+ if (byte_order == BT_CTF_BYTE_ORDER_UNSPECIFIED && !allow_unspecified) {
+ BT_LOGW("Invalid parameter: BT_CTF_BYTE_ORDER_UNSPECIFIED byte order is not allowed: "
+ "addr=%p, name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace));
+ ret = -1;
+ goto end;
+ }
+
+ if (byte_order != BT_CTF_BYTE_ORDER_LITTLE_ENDIAN &&
+ byte_order != BT_CTF_BYTE_ORDER_BIG_ENDIAN &&
+ byte_order != BT_CTF_BYTE_ORDER_NETWORK) {
+ BT_LOGW("Invalid parameter: invalid byte order: "
+ "addr=%p, name=\"%s\", bo=%s",
+ trace, bt_ctf_trace_common_get_name(trace),
+ bt_ctf_byte_order_string(byte_order));
+ ret = -1;
+ goto end;
+ }
+
+ trace->native_byte_order = byte_order;
+ BT_LOGV("Set trace's native byte order: "
+ "addr=%p, name=\"%s\", bo=%s",
+ trace, bt_ctf_trace_common_get_name(trace),
+ bt_ctf_byte_order_string(byte_order));
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_common_set_packet_header_field_type(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_field_type_common *packet_header_type)
+{
+ int ret = 0;
+
+ if (!trace) {
+ BT_LOGW_STR("Invalid parameter: trace is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (trace->frozen) {
+ BT_LOGW("Invalid parameter: trace is frozen: "
+ "addr=%p, name=\"%s\"",
+ trace, bt_ctf_trace_common_get_name(trace));
+ ret = -1;
+ goto end;
+ }
+
+ /* packet_header_type must be a structure. */
+ if (packet_header_type &&
+ packet_header_type->id != BT_CTF_FIELD_TYPE_ID_STRUCT) {
+ BT_LOGW("Invalid parameter: packet header field type must be a structure field type if it exists: "
+ "addr=%p, name=\"%s\", ft-addr=%p, ft-id=%s",
+ trace, bt_ctf_trace_common_get_name(trace),
+ packet_header_type,
+ bt_ctf_field_type_id_string(packet_header_type->id));
+ ret = -1;
+ goto end;
+ }
+
+ bt_put(trace->packet_header_field_type);
+ trace->packet_header_field_type = bt_get(packet_header_type);
+ BT_LOGV("Set trace's packet header field type: "
+ "addr=%p, name=\"%s\", packet-context-ft-addr=%p",
+ trace, bt_ctf_trace_common_get_name(trace), packet_header_type);
+end:
+ return ret;
+}
+
+static
+int64_t get_stream_class_count(void *element)
+{
+ return bt_ctf_trace_get_stream_class_count(
+ (struct bt_ctf_trace *) element);
+}
+
+static
+void *get_stream_class(void *element, int i)
+{
+ return bt_ctf_trace_get_stream_class_by_index(
+ (struct bt_ctf_trace *) element, i);
+}
+
+static
+int visit_stream_class(void *object, bt_ctf_visitor visitor,void *data)
+{
+ return bt_ctf_stream_class_visit(object, visitor, data);
+}
+
+int bt_ctf_trace_visit(struct bt_ctf_trace *trace,
+ bt_ctf_visitor visitor, void *data)
+{
+ int ret;
+ struct bt_ctf_visitor_object obj = {
+ .object = trace,
+ .type = BT_CTF_VISITOR_OBJECT_TYPE_TRACE
+ };
+
+ if (!trace) {
+ BT_LOGW_STR("Invalid parameter: trace is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ if (!visitor) {
+ BT_LOGW_STR("Invalid parameter: visitor is NULL.");
+ ret = -1;
+ goto end;
+ }
+
+ BT_LOGV("Visiting trace: addr=%p, name=\"%s\"",
+ trace, bt_ctf_trace_get_name(trace));
+ ret = visitor_helper(&obj, get_stream_class_count,
+ get_stream_class, visit_stream_class, visitor, data);
+end:
+ return ret;
+}
static
void bt_ctf_trace_destroy(struct bt_object *obj)
BT_LOGD("Destroying CTF writer trace object: addr=%p, name=\"%s\"",
trace, bt_ctf_trace_get_name(trace));
- bt_trace_common_finalize(BT_TO_COMMON(trace));
+ bt_ctf_trace_common_finalize(BT_CTF_TO_COMMON(trace));
g_free(trace);
}
goto error;
}
- ret = bt_trace_common_initialize(BT_TO_COMMON(trace),
+ ret = bt_ctf_trace_common_initialize(BT_CTF_TO_COMMON(trace),
bt_ctf_trace_destroy);
if (ret) {
- /* bt_trace_common_initialize() logs errors */
+ /* bt_ctf_trace_common_initialize() logs errors */
goto error;
}
const unsigned char *bt_ctf_trace_get_uuid(struct bt_ctf_trace *trace)
{
- return bt_trace_common_get_uuid(BT_TO_COMMON(trace));
+ return bt_ctf_trace_common_get_uuid(BT_CTF_TO_COMMON(trace));
}
int bt_ctf_trace_set_uuid(struct bt_ctf_trace *trace,
const unsigned char *uuid)
{
- return bt_trace_common_set_uuid(BT_TO_COMMON(trace), uuid);
+ return bt_ctf_trace_common_set_uuid(BT_CTF_TO_COMMON(trace), uuid);
}
int bt_ctf_trace_set_environment_field(struct bt_ctf_trace *trace,
const char *name, struct bt_value *value)
{
- return bt_trace_common_set_environment_field(BT_TO_COMMON(trace),
+ return bt_ctf_trace_common_set_environment_field(BT_CTF_TO_COMMON(trace),
name, value);
}
int bt_ctf_trace_set_environment_field_string(struct bt_ctf_trace *trace,
const char *name, const char *value)
{
- return bt_trace_common_set_environment_field_string(BT_TO_COMMON(trace),
+ return bt_ctf_trace_common_set_environment_field_string(BT_CTF_TO_COMMON(trace),
name, value);
}
int bt_ctf_trace_set_environment_field_integer(
struct bt_ctf_trace *trace, const char *name, int64_t value)
{
- return bt_trace_common_set_environment_field_integer(
- BT_TO_COMMON(trace), name, value);
+ return bt_ctf_trace_common_set_environment_field_integer(
+ BT_CTF_TO_COMMON(trace), name, value);
}
int64_t bt_ctf_trace_get_environment_field_count(struct bt_ctf_trace *trace)
{
- return bt_trace_common_get_environment_field_count(BT_TO_COMMON(trace));
+ return bt_ctf_trace_common_get_environment_field_count(BT_CTF_TO_COMMON(trace));
}
const char *
bt_ctf_trace_get_environment_field_name_by_index(struct bt_ctf_trace *trace,
uint64_t index)
{
- return bt_trace_common_get_environment_field_name_by_index(
- BT_TO_COMMON(trace), index);
+ return bt_ctf_trace_common_get_environment_field_name_by_index(
+ BT_CTF_TO_COMMON(trace), index);
}
struct bt_value *bt_ctf_trace_get_environment_field_value_by_index(
struct bt_ctf_trace *trace, uint64_t index)
{
- return bt_get(bt_trace_common_borrow_environment_field_value_by_index(
- BT_TO_COMMON(trace), index));
+ return bt_get(bt_ctf_trace_common_borrow_environment_field_value_by_index(
+ BT_CTF_TO_COMMON(trace), index));
}
struct bt_value *bt_ctf_trace_get_environment_field_value_by_name(
struct bt_ctf_trace *trace, const char *name)
{
- return bt_get(bt_trace_common_borrow_environment_field_value_by_name(
- BT_TO_COMMON(trace), name));
+ return bt_get(bt_ctf_trace_common_borrow_environment_field_value_by_name(
+ BT_CTF_TO_COMMON(trace), name));
}
+BT_HIDDEN
int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace,
struct bt_ctf_clock_class *clock_class)
{
- return bt_trace_common_add_clock_class(BT_TO_COMMON(trace),
+ return bt_ctf_trace_common_add_clock_class(BT_CTF_TO_COMMON(trace),
(void *) clock_class);
}
+BT_HIDDEN
int64_t bt_ctf_trace_get_clock_class_count(struct bt_ctf_trace *trace)
{
- return bt_trace_common_get_clock_class_count(BT_TO_COMMON(trace));
+ return bt_ctf_trace_common_get_clock_class_count(BT_CTF_TO_COMMON(trace));
}
+BT_HIDDEN
struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_index(
struct bt_ctf_trace *trace, uint64_t index)
{
- return bt_get(bt_trace_common_borrow_clock_class_by_index(
- BT_TO_COMMON(trace), index));
+ return bt_get(bt_ctf_trace_common_borrow_clock_class_by_index(
+ BT_CTF_TO_COMMON(trace), index));
}
static
-int map_clock_classes_func(struct bt_stream_class_common *stream_class,
- struct bt_field_type_common *packet_context_type,
- struct bt_field_type_common *event_header_type)
+int map_clock_classes_func(struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_field_type_common *packet_context_type,
+ struct bt_ctf_field_type_common *event_header_type)
{
int ret = bt_ctf_stream_class_map_clock_class(
- BT_FROM_COMMON(stream_class),
- BT_FROM_COMMON(packet_context_type),
- BT_FROM_COMMON(event_header_type));
+ BT_CTF_FROM_COMMON(stream_class),
+ BT_CTF_FROM_COMMON(packet_context_type),
+ BT_CTF_FROM_COMMON(event_header_type));
if (ret) {
BT_LOGW_STR("Cannot automatically map selected stream class's field types to stream class's clock's class.");
struct bt_ctf_stream_class *stream_class)
{
int ret = 0;
- struct bt_clock_class *expected_clock_class = NULL;
+ struct bt_ctf_clock_class *expected_clock_class = NULL;
if (!trace) {
BT_LOGW_STR("Invalid parameter: trace is NULL.");
BT_LOGW("Stream class's clock's class is not part of the trace: "
"clock-class-addr=%p, clock-class-name=\"%s\"",
stream_clock_class,
- bt_clock_class_get_name(
- BT_TO_COMMON(stream_clock_class)));
+ bt_ctf_clock_class_get_name(stream_clock_class));
ret = -1;
goto end;
}
if (stream_class->common.clock_class &&
stream_class->common.clock_class !=
- BT_TO_COMMON(stream_class->clock->clock_class)) {
+ stream_class->clock->clock_class) {
/*
* Stream class already has an expected clock
* class, but it does not match its clock's
bt_ctf_stream_class_get_id(stream_class),
bt_ctf_stream_class_get_name(stream_class),
stream_class->common.clock_class,
- bt_clock_class_get_name(stream_class->common.clock_class));
+ bt_ctf_clock_class_get_name(stream_class->common.clock_class));
} else if (!stream_class->common.clock_class) {
/*
* Set expected clock class to stream class's
* clock's class.
*/
- expected_clock_class =
- BT_TO_COMMON(stream_class->clock->clock_class);
+ expected_clock_class = stream_class->clock->clock_class;
}
}
- ret = bt_trace_common_add_stream_class(BT_TO_COMMON(trace),
- BT_TO_COMMON(stream_class),
- (bt_validation_flag_copy_field_type_func) bt_ctf_field_type_copy,
+ ret = bt_ctf_trace_common_add_stream_class(BT_CTF_TO_COMMON(trace),
+ BT_CTF_TO_COMMON(stream_class),
+ (bt_ctf_validation_flag_copy_field_type_func) bt_ctf_field_type_copy,
expected_clock_class, map_clock_classes_func,
false);
int64_t bt_ctf_trace_get_stream_count(struct bt_ctf_trace *trace)
{
- return bt_trace_common_get_stream_count(BT_TO_COMMON(trace));
+ return bt_ctf_trace_common_get_stream_count(BT_CTF_TO_COMMON(trace));
}
struct bt_ctf_stream *bt_ctf_trace_get_stream_by_index(
struct bt_ctf_trace *trace, uint64_t index)
{
- return bt_get(bt_trace_common_borrow_stream_by_index(
- BT_TO_COMMON(trace), index));
+ return bt_get(bt_ctf_trace_common_borrow_stream_by_index(
+ BT_CTF_TO_COMMON(trace), index));
}
int64_t bt_ctf_trace_get_stream_class_count(struct bt_ctf_trace *trace)
{
- return bt_trace_common_get_stream_class_count(BT_TO_COMMON(trace));
+ return bt_ctf_trace_common_get_stream_class_count(BT_CTF_TO_COMMON(trace));
}
struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_index(
struct bt_ctf_trace *trace, uint64_t index)
{
- return bt_get(bt_trace_common_borrow_stream_class_by_index(
- BT_TO_COMMON(trace), index));
+ return bt_get(bt_ctf_trace_common_borrow_stream_class_by_index(
+ BT_CTF_TO_COMMON(trace), index));
}
struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_id(
struct bt_ctf_trace *trace, uint64_t id)
{
- return bt_get(bt_trace_common_borrow_stream_class_by_id(
- BT_TO_COMMON(trace), id));
+ return bt_get(bt_ctf_trace_common_borrow_stream_class_by_id(
+ BT_CTF_TO_COMMON(trace), id));
}
+BT_HIDDEN
struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_name(
struct bt_ctf_trace *trace, const char *name)
{
return bt_get(
- bt_trace_common_borrow_clock_class_by_name(BT_TO_COMMON(trace),
+ bt_ctf_trace_common_borrow_clock_class_by_name(BT_CTF_TO_COMMON(trace),
name));
}
unsigned char *uuid = trace->common.uuid;
int ret = 0;
- if (trace->common.native_byte_order == BT_BYTE_ORDER_NATIVE ||
- trace->common.native_byte_order == BT_BYTE_ORDER_UNSPECIFIED) {
+ if (trace->common.native_byte_order == BT_CTF_BYTE_ORDER_NATIVE ||
+ trace->common.native_byte_order == BT_CTF_BYTE_ORDER_UNSPECIFIED) {
BT_LOGW("Invalid parameter: trace's byte order cannot be BT_CTF_BYTE_ORDER_NATIVE or BT_CTF_BYTE_ORDER_UNSPECIFIED at this point; "
"set it with bt_ctf_trace_set_native_byte_order(): "
"addr=%p, name=\"%s\"",
g_string_append(context->string, "trace {\n");
g_string_append(context->string, "\tmajor = 1;\n");
g_string_append(context->string, "\tminor = 8;\n");
- BT_ASSERT(trace->common.native_byte_order == BT_BYTE_ORDER_LITTLE_ENDIAN ||
- trace->common.native_byte_order == BT_BYTE_ORDER_BIG_ENDIAN ||
- trace->common.native_byte_order == BT_BYTE_ORDER_NETWORK);
+ BT_ASSERT(trace->common.native_byte_order == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
+ trace->common.native_byte_order == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
+ trace->common.native_byte_order == BT_CTF_BYTE_ORDER_NETWORK);
if (trace->common.uuid_set) {
g_string_append_printf(context->string,
}
g_string_append_printf(context->string, "\tbyte_order = %s;\n",
- get_byte_order_string(trace->common.native_byte_order));
+ bt_ctf_get_byte_order_string(trace->common.native_byte_order));
if (trace->common.packet_header_field_type) {
g_string_append(context->string, "\tpacket.header := ");
int64_t i;
int64_t env_size;
- env_size = bt_attributes_get_count(trace->common.environment);
+ env_size = bt_ctf_attributes_get_count(trace->common.environment);
if (env_size <= 0) {
return;
}
struct bt_value *env_field_value_obj = NULL;
const char *entry_name;
- entry_name = bt_attributes_get_field_name(
+ entry_name = bt_ctf_attributes_get_field_name(
trace->common.environment, i);
- env_field_value_obj = bt_attributes_borrow_field_value(
+ env_field_value_obj = bt_ctf_attributes_borrow_field_value(
trace->common.environment, i);
BT_ASSERT(entry_name);
(GFunc) bt_ctf_clock_class_serialize, context);
for (i = 0; i < trace->common.stream_classes->len; i++) {
- /* bt_stream_class_serialize() logs details */
+ /* bt_ctf_stream_class_serialize() logs details */
err = bt_ctf_stream_class_serialize(
trace->common.stream_classes->pdata[i], context);
if (err) {
- /* bt_stream_class_serialize() logs errors */
+ /* bt_ctf_stream_class_serialize() logs errors */
goto error;
}
}
enum bt_ctf_byte_order bt_ctf_trace_get_native_byte_order(
struct bt_ctf_trace *trace)
{
- return (int) bt_trace_common_get_native_byte_order(BT_TO_COMMON(trace));
+ return (int) bt_ctf_trace_common_get_native_byte_order(BT_CTF_TO_COMMON(trace));
}
int bt_ctf_trace_set_native_byte_order(struct bt_ctf_trace *trace,
enum bt_ctf_byte_order byte_order)
{
- return bt_trace_common_set_native_byte_order(BT_TO_COMMON(trace),
+ return bt_ctf_trace_common_set_native_byte_order(BT_CTF_TO_COMMON(trace),
(int) byte_order, false);
}
struct bt_ctf_field_type *bt_ctf_trace_get_packet_header_field_type(
struct bt_ctf_trace *trace)
{
- return bt_get(bt_trace_common_borrow_packet_header_field_type(
- BT_TO_COMMON(trace)));
+ return bt_get(bt_ctf_trace_common_borrow_packet_header_field_type(
+ BT_CTF_TO_COMMON(trace)));
}
int bt_ctf_trace_set_packet_header_field_type(struct bt_ctf_trace *trace,
struct bt_ctf_field_type *packet_header_type)
{
- return bt_trace_common_set_packet_header_field_type(BT_TO_COMMON(trace),
+ return bt_ctf_trace_common_set_packet_header_field_type(BT_CTF_TO_COMMON(trace),
(void *) packet_header_type);
}
const char *bt_ctf_trace_get_name(struct bt_ctf_trace *trace)
{
- return bt_trace_common_get_name(BT_TO_COMMON(trace));
+ return bt_ctf_trace_common_get_name(BT_CTF_TO_COMMON(trace));
}
--- /dev/null
+/*
+ * utils.c
+ *
+ * Babeltrace CTF writer - Utilities
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@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:
+ *
+ * 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.
+ */
+
+#define BT_LOG_TAG "CTF-WRITER-UTILS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/ctf-writer/clock-class-internal.h>
+#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/ctf-writer/utils.h>
+#include <babeltrace/ref.h>
+#include <glib.h>
+#include <stdlib.h>
+
+static
+const char * const reserved_keywords_str[] = {"align", "callsite",
+ "const", "char", "clock", "double", "enum", "env", "event",
+ "floating_point", "float", "integer", "int", "long", "short", "signed",
+ "stream", "string", "struct", "trace", "typealias", "typedef",
+ "unsigned", "variant", "void" "_Bool", "_Complex", "_Imaginary"};
+
+static GHashTable *reserved_keywords_set;
+static int init_done;
+
+static
+void try_init_reserved_keywords(void)
+{
+ size_t i;
+ const size_t reserved_keywords_count =
+ sizeof(reserved_keywords_str) / sizeof(char *);
+
+ if (reserved_keywords_set) {
+ return;
+ }
+
+ reserved_keywords_set = g_hash_table_new(g_direct_hash, g_direct_equal);
+ BT_ASSERT(reserved_keywords_set);
+
+ for (i = 0; i < reserved_keywords_count; i++) {
+ gpointer quark = GINT_TO_POINTER(g_quark_from_string(
+ reserved_keywords_str[i]));
+
+ g_hash_table_insert(reserved_keywords_set, quark, quark);
+ }
+
+ init_done = 1;
+}
+
+static __attribute__((destructor))
+void trace_finalize(void)
+{
+ if (reserved_keywords_set) {
+ g_hash_table_destroy(reserved_keywords_set);
+ }
+}
+
+bt_bool bt_ctf_identifier_is_valid(const char *identifier)
+{
+ bt_bool is_valid = BT_TRUE;
+ char *string = NULL;
+ char *save_ptr, *token;
+
+ if (!identifier) {
+ BT_LOGV_STR("Invalid parameter: input string is NULL.");
+ is_valid = BT_FALSE;
+ goto end;
+ }
+
+ try_init_reserved_keywords();
+
+ if (identifier[0] == '\0') {
+ is_valid = BT_FALSE;
+ goto end;
+ }
+
+ string = strdup(identifier);
+ if (!string) {
+ BT_LOGE("strdup() failed.");
+ is_valid = BT_FALSE;
+ goto end;
+ }
+
+ token = strtok_r(string, " ", &save_ptr);
+ while (token) {
+ if (g_hash_table_lookup_extended(reserved_keywords_set,
+ GINT_TO_POINTER(g_quark_from_string(token)),
+ NULL, NULL)) {
+ is_valid = BT_FALSE;
+ goto end;
+ }
+
+ token = strtok_r(NULL, " ", &save_ptr);
+ }
+end:
+ free(string);
+ return is_valid;
+}
--- /dev/null
+/*
+ * validation.c
+ *
+ * Babeltrace - CTF writer: Validation of trace, stream class, and event class
+ *
+ * Copyright 2016-2018 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:
+ *
+ * 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.
+ */
+
+#define BT_LOG_TAG "CTF-WRITER-VALIDATION"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/ctf-writer/event-class-internal.h>
+#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/ctf-writer/field-types-internal.h>
+#include <babeltrace/ctf-writer/resolve-internal.h>
+#include <babeltrace/ctf-writer/stream-class-internal.h>
+#include <babeltrace/ctf-writer/trace-internal.h>
+#include <babeltrace/ctf-writer/validation-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/values.h>
+
+/*
+ * This function resolves and validates the field types of an event
+ * class. Only `event_context_type` and `event_payload_type` are
+ * resolved and validated; the other field types are used as eventual
+ * resolving targets.
+ *
+ * All parameters are owned by the caller.
+ */
+static
+int validate_event_class_types(struct bt_value *environment,
+ struct bt_ctf_field_type_common *packet_header_type,
+ struct bt_ctf_field_type_common *packet_context_type,
+ struct bt_ctf_field_type_common *event_header_type,
+ struct bt_ctf_field_type_common *stream_event_ctx_type,
+ struct bt_ctf_field_type_common *event_context_type,
+ struct bt_ctf_field_type_common *event_payload_type)
+{
+ int ret = 0;
+
+ BT_LOGV("Validating event class field types: "
+ "packet-header-ft-addr=%p, "
+ "packet-context-ft-addr=%p, "
+ "event-header-ft-addr=%p, "
+ "stream-event-context-ft-addr=%p, "
+ "event-context-ft-addr=%p, "
+ "event-payload-ft-addr=%p",
+ packet_header_type, packet_context_type, event_header_type,
+ stream_event_ctx_type, event_context_type, event_payload_type);
+
+ /* Resolve sequence type lengths and variant type tags first */
+ ret = bt_ctf_resolve_types(environment, packet_header_type,
+ packet_context_type, event_header_type, stream_event_ctx_type,
+ event_context_type, event_payload_type,
+ BT_CTF_RESOLVE_FLAG_EVENT_CONTEXT |
+ BT_CTF_RESOLVE_FLAG_EVENT_PAYLOAD);
+ if (ret) {
+ BT_LOGW("Cannot resolve event class field types: ret=%d",
+ ret);
+ goto end;
+ }
+
+ /* Validate field types individually */
+ if (event_context_type) {
+ ret = bt_ctf_field_type_common_validate(event_context_type);
+ if (ret) {
+ BT_LOGW("Invalid event class's context field type: "
+ "ret=%d", ret);
+ goto end;
+ }
+ }
+
+ if (event_payload_type) {
+ ret = bt_ctf_field_type_common_validate(event_payload_type);
+ if (ret) {
+ BT_LOGW("Invalid event class's payload field type: "
+ "ret=%d", ret);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
+/*
+ * This function resolves and validates the field types of a stream
+ * class. Only `packet_context_type`, `event_header_type`, and
+ * `stream_event_ctx_type` are resolved and validated; the other field
+ * type is used as an eventual resolving target.
+ *
+ * All parameters are owned by the caller.
+ */
+static
+int validate_stream_class_types(struct bt_value *environment,
+ struct bt_ctf_field_type_common *packet_header_type,
+ struct bt_ctf_field_type_common *packet_context_type,
+ struct bt_ctf_field_type_common *event_header_type,
+ struct bt_ctf_field_type_common *stream_event_ctx_type)
+{
+ int ret = 0;
+
+ BT_LOGV("Validating stream class field types: "
+ "packet-header-ft-addr=%p, "
+ "packet-context-ft-addr=%p, "
+ "event-header-ft-addr=%p, "
+ "stream-event-context-ft-addr=%p",
+ packet_header_type, packet_context_type, event_header_type,
+ stream_event_ctx_type);
+
+ /* Resolve sequence type lengths and variant type tags first */
+ ret = bt_ctf_resolve_types(environment, packet_header_type,
+ packet_context_type, event_header_type, stream_event_ctx_type,
+ NULL, NULL,
+ BT_CTF_RESOLVE_FLAG_PACKET_CONTEXT |
+ BT_CTF_RESOLVE_FLAG_EVENT_HEADER |
+ BT_CTF_RESOLVE_FLAG_STREAM_EVENT_CTX);
+ if (ret) {
+ BT_LOGW("Cannot resolve stream class field types: ret=%d",
+ ret);
+ goto end;
+ }
+
+ /* Validate field types individually */
+ if (packet_context_type) {
+ ret = bt_ctf_field_type_common_validate(packet_context_type);
+ if (ret) {
+ BT_LOGW("Invalid stream class's packet context field type: "
+ "ret=%d", ret);
+ goto end;
+ }
+ }
+
+ if (event_header_type) {
+ ret = bt_ctf_field_type_common_validate(event_header_type);
+ if (ret) {
+ BT_LOGW("Invalid stream class's event header field type: "
+ "ret=%d", ret);
+ goto end;
+ }
+ }
+
+ if (stream_event_ctx_type) {
+ ret = bt_ctf_field_type_common_validate(
+ stream_event_ctx_type);
+ if (ret) {
+ BT_LOGW("Invalid stream class's event context field type: "
+ "ret=%d", ret);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
+/*
+ * This function resolves and validates the field types of a trace.
+ *
+ * All parameters are owned by the caller.
+ */
+static
+int validate_trace_types(struct bt_value *environment,
+ struct bt_ctf_field_type_common *packet_header_type)
+{
+ int ret = 0;
+
+ BT_LOGV("Validating event class field types: "
+ "packet-header-ft-addr=%p", packet_header_type);
+
+ /* Resolve sequence type lengths and variant type tags first */
+ ret = bt_ctf_resolve_types(environment, packet_header_type,
+ NULL, NULL, NULL, NULL, NULL,
+ BT_CTF_RESOLVE_FLAG_PACKET_HEADER);
+ if (ret) {
+ BT_LOGW("Cannot resolve trace field types: ret=%d",
+ ret);
+ goto end;
+ }
+
+ /* Validate field types individually */
+ if (packet_header_type) {
+ ret = bt_ctf_field_type_common_validate(packet_header_type);
+ if (ret) {
+ BT_LOGW("Invalid trace's packet header field type: "
+ "ret=%d", ret);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
+/*
+ * Checks whether or not `field_type` contains a variant or a sequence
+ * field type, recursively. Returns 1 if it's the case.
+ *
+ * `field_type` is owned by the caller.
+ */
+static
+int field_type_contains_sequence_or_variant_ft(struct bt_ctf_field_type_common *type)
+{
+ int ret = 0;
+ enum bt_ctf_field_type_id type_id = bt_ctf_field_type_common_get_type_id(type);
+
+ switch (type_id) {
+ case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ case BT_CTF_FIELD_TYPE_ID_VARIANT:
+ ret = 1;
+ goto end;
+ case BT_CTF_FIELD_TYPE_ID_ARRAY:
+ case BT_CTF_FIELD_TYPE_ID_STRUCT:
+ {
+ int i;
+ int field_count = bt_ctf_field_type_common_get_field_count(type);
+
+ if (field_count < 0) {
+ ret = -1;
+ goto end;
+ }
+
+ for (i = 0; i < field_count; ++i) {
+ struct bt_ctf_field_type_common *child_type =
+ bt_ctf_field_type_common_borrow_field_at_index(
+ type, i);
+
+ ret = field_type_contains_sequence_or_variant_ft(
+ child_type);
+ if (ret != 0) {
+ goto end;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_validate_class_types(struct bt_value *environment,
+ struct bt_ctf_field_type_common *packet_header_type,
+ struct bt_ctf_field_type_common *packet_context_type,
+ struct bt_ctf_field_type_common *event_header_type,
+ struct bt_ctf_field_type_common *stream_event_ctx_type,
+ struct bt_ctf_field_type_common *event_context_type,
+ struct bt_ctf_field_type_common *event_payload_type,
+ int trace_valid, int stream_class_valid, int event_class_valid,
+ struct bt_ctf_validation_output *output,
+ enum bt_ctf_validation_flag validate_flags,
+ bt_ctf_validation_flag_copy_field_type_func copy_field_type_func)
+{
+ int ret = 0;
+ int contains_seq_var;
+ int valid_ret;
+
+ BT_LOGV("Validating field types: "
+ "packet-header-ft-addr=%p, "
+ "packet-context-ft-addr=%p, "
+ "event-header-ft-addr=%p, "
+ "stream-event-context-ft-addr=%p, "
+ "event-context-ft-addr=%p, "
+ "event-payload-ft-addr=%p, "
+ "trace-is-valid=%d, stream-class-is-valid=%d, "
+ "event-class-is-valid=%d, validation-flags=%x",
+ packet_header_type, packet_context_type, event_header_type,
+ stream_event_ctx_type, event_context_type, event_payload_type,
+ trace_valid, stream_class_valid, event_class_valid,
+ (unsigned int) validate_flags);
+
+ /* Clean output values */
+ memset(output, 0, sizeof(*output));
+
+ /* Set initial valid flags according to valid parameters */
+ if (trace_valid) {
+ output->valid_flags |= BT_CTF_VALIDATION_FLAG_TRACE;
+ }
+
+ if (stream_class_valid) {
+ output->valid_flags |= BT_CTF_VALIDATION_FLAG_STREAM;
+ }
+
+ if (event_class_valid) {
+ output->valid_flags |= BT_CTF_VALIDATION_FLAG_EVENT;
+ }
+
+ /* Own the type parameters */
+ bt_get(packet_header_type);
+ bt_get(packet_context_type);
+ bt_get(event_header_type);
+ bt_get(stream_event_ctx_type);
+ bt_get(event_context_type);
+ bt_get(event_payload_type);
+
+ /* Validate trace */
+ if ((validate_flags & BT_CTF_VALIDATION_FLAG_TRACE) && !trace_valid) {
+ struct bt_ctf_field_type_common *packet_header_type_copy = NULL;
+
+ /* Create field type copies */
+ if (packet_header_type) {
+ contains_seq_var =
+ field_type_contains_sequence_or_variant_ft(
+ packet_header_type);
+ if (contains_seq_var < 0) {
+ ret = contains_seq_var;
+ goto error;
+ } else if (!contains_seq_var) {
+ /* No copy is needed */
+ packet_header_type_copy = packet_header_type;
+ bt_get(packet_header_type_copy);
+ goto skip_packet_header_type_copy;
+ }
+
+ BT_LOGV_STR("Copying packet header field type because it contains at least one sequence or variant field type.");
+ packet_header_type_copy =
+ copy_field_type_func(packet_header_type);
+ if (!packet_header_type_copy) {
+ ret = -1;
+ BT_LOGE_STR("Cannot copy packet header field type.");
+ goto error;
+ }
+
+ /*
+ * Freeze this copy: if it's returned to the
+ * caller, it cannot be modified any way since
+ * it will be resolved.
+ */
+ bt_ctf_field_type_common_freeze(packet_header_type_copy);
+ }
+
+skip_packet_header_type_copy:
+ /* Put original reference and move copy */
+ BT_MOVE(packet_header_type, packet_header_type_copy);
+
+ /* Validate trace field types */
+ valid_ret = validate_trace_types(environment,
+ packet_header_type);
+ if (valid_ret == 0) {
+ /* Trace is valid */
+ output->valid_flags |= BT_CTF_VALIDATION_FLAG_TRACE;
+ }
+ }
+
+ /* Validate stream class */
+ if ((validate_flags & BT_CTF_VALIDATION_FLAG_STREAM) &&
+ !stream_class_valid) {
+ struct bt_ctf_field_type_common *packet_context_type_copy = NULL;
+ struct bt_ctf_field_type_common *event_header_type_copy = NULL;
+ struct bt_ctf_field_type_common *stream_event_ctx_type_copy = NULL;
+
+ if (packet_context_type) {
+ contains_seq_var =
+ field_type_contains_sequence_or_variant_ft(
+ packet_context_type);
+ if (contains_seq_var < 0) {
+ ret = contains_seq_var;
+ goto error;
+ } else if (!contains_seq_var) {
+ /* No copy is needed */
+ packet_context_type_copy = packet_context_type;
+ bt_get(packet_context_type_copy);
+ goto skip_packet_context_type_copy;
+ }
+
+ BT_LOGV_STR("Copying packet context field type because it contains at least one sequence or variant field type.");
+ packet_context_type_copy =
+ copy_field_type_func(packet_context_type);
+ if (!packet_context_type_copy) {
+ BT_LOGE_STR("Cannot copy packet context field type.");
+ goto sc_validation_error;
+ }
+
+ /*
+ * Freeze this copy: if it's returned to the
+ * caller, it cannot be modified any way since
+ * it will be resolved.
+ */
+ bt_ctf_field_type_common_freeze(packet_context_type_copy);
+ }
+
+skip_packet_context_type_copy:
+ if (event_header_type) {
+ contains_seq_var =
+ field_type_contains_sequence_or_variant_ft(
+ event_header_type);
+ if (contains_seq_var < 0) {
+ ret = contains_seq_var;
+ goto error;
+ } else if (!contains_seq_var) {
+ /* No copy is needed */
+ event_header_type_copy = event_header_type;
+ bt_get(event_header_type_copy);
+ goto skip_event_header_type_copy;
+ }
+
+ BT_LOGV_STR("Copying event header field type because it contains at least one sequence or variant field type.");
+ event_header_type_copy =
+ copy_field_type_func(event_header_type);
+ if (!event_header_type_copy) {
+ BT_LOGE_STR("Cannot copy event header field type.");
+ goto sc_validation_error;
+ }
+
+ /*
+ * Freeze this copy: if it's returned to the
+ * caller, it cannot be modified any way since
+ * it will be resolved.
+ */
+ bt_ctf_field_type_common_freeze(event_header_type_copy);
+ }
+
+skip_event_header_type_copy:
+ if (stream_event_ctx_type) {
+ contains_seq_var =
+ field_type_contains_sequence_or_variant_ft(
+ stream_event_ctx_type);
+ if (contains_seq_var < 0) {
+ ret = contains_seq_var;
+ goto error;
+ } else if (!contains_seq_var) {
+ /* No copy is needed */
+ stream_event_ctx_type_copy =
+ stream_event_ctx_type;
+ bt_get(stream_event_ctx_type_copy);
+ goto skip_stream_event_ctx_type_copy;
+ }
+
+ BT_LOGV_STR("Copying stream event context field type because it contains at least one sequence or variant field type.");
+ stream_event_ctx_type_copy =
+ copy_field_type_func(stream_event_ctx_type);
+ if (!stream_event_ctx_type_copy) {
+ BT_LOGE_STR("Cannot copy stream event context field type.");
+ goto sc_validation_error;
+ }
+
+ /*
+ * Freeze this copy: if it's returned to the
+ * caller, it cannot be modified any way since
+ * it will be resolved.
+ */
+ bt_ctf_field_type_common_freeze(stream_event_ctx_type_copy);
+ }
+
+skip_stream_event_ctx_type_copy:
+ /* Put original references and move copies */
+ BT_MOVE(packet_context_type, packet_context_type_copy);
+ BT_MOVE(event_header_type, event_header_type_copy);
+ BT_MOVE(stream_event_ctx_type, stream_event_ctx_type_copy);
+
+ /* Validate stream class field types */
+ valid_ret = validate_stream_class_types(environment,
+ packet_header_type, packet_context_type,
+ event_header_type, stream_event_ctx_type);
+ if (valid_ret == 0) {
+ /* Stream class is valid */
+ output->valid_flags |= BT_CTF_VALIDATION_FLAG_STREAM;
+ }
+
+ goto sc_validation_done;
+
+sc_validation_error:
+ BT_PUT(packet_context_type_copy);
+ BT_PUT(event_header_type_copy);
+ BT_PUT(stream_event_ctx_type_copy);
+ ret = -1;
+ goto error;
+ }
+
+sc_validation_done:
+ /* Validate event class */
+ if ((validate_flags & BT_CTF_VALIDATION_FLAG_EVENT) &&
+ !event_class_valid) {
+ struct bt_ctf_field_type_common *event_context_type_copy = NULL;
+ struct bt_ctf_field_type_common *event_payload_type_copy = NULL;
+
+ if (event_context_type) {
+ contains_seq_var =
+ field_type_contains_sequence_or_variant_ft(
+ event_context_type);
+ if (contains_seq_var < 0) {
+ ret = contains_seq_var;
+ goto error;
+ } else if (!contains_seq_var) {
+ /* No copy is needed */
+ event_context_type_copy = event_context_type;
+ bt_get(event_context_type_copy);
+ goto skip_event_context_type_copy;
+ }
+
+ BT_LOGV_STR("Copying event context field type because it contains at least one sequence or variant field type.");
+ event_context_type_copy =
+ copy_field_type_func(event_context_type);
+ if (!event_context_type_copy) {
+ BT_LOGE_STR("Cannot copy event context field type.");
+ goto ec_validation_error;
+ }
+
+ /*
+ * Freeze this copy: if it's returned to the
+ * caller, it cannot be modified any way since
+ * it will be resolved.
+ */
+ bt_ctf_field_type_common_freeze(event_context_type_copy);
+ }
+
+skip_event_context_type_copy:
+ if (event_payload_type) {
+ contains_seq_var =
+ field_type_contains_sequence_or_variant_ft(
+ event_payload_type);
+ if (contains_seq_var < 0) {
+ ret = contains_seq_var;
+ goto error;
+ } else if (!contains_seq_var) {
+ /* No copy is needed */
+ event_payload_type_copy = event_payload_type;
+ bt_get(event_payload_type_copy);
+ goto skip_event_payload_type_copy;
+ }
+
+ BT_LOGV_STR("Copying event payload field type because it contains at least one sequence or variant field type.");
+ event_payload_type_copy =
+ copy_field_type_func(event_payload_type);
+ if (!event_payload_type_copy) {
+ BT_LOGE_STR("Cannot copy event payload field type.");
+ goto ec_validation_error;
+ }
+
+ /*
+ * Freeze this copy: if it's returned to the
+ * caller, it cannot be modified any way since
+ * it will be resolved.
+ */
+ bt_ctf_field_type_common_freeze(event_payload_type_copy);
+ }
+
+skip_event_payload_type_copy:
+ /* Put original references and move copies */
+ BT_MOVE(event_context_type, event_context_type_copy);
+ BT_MOVE(event_payload_type, event_payload_type_copy);
+
+ /* Validate event class field types */
+ valid_ret = validate_event_class_types(environment,
+ packet_header_type, packet_context_type,
+ event_header_type, stream_event_ctx_type,
+ event_context_type, event_payload_type);
+ if (valid_ret == 0) {
+ /* Event class is valid */
+ output->valid_flags |= BT_CTF_VALIDATION_FLAG_EVENT;
+ }
+
+ goto ec_validation_done;
+
+ec_validation_error:
+ BT_PUT(event_context_type_copy);
+ BT_PUT(event_payload_type_copy);
+ ret = -1;
+ goto error;
+ }
+
+ec_validation_done:
+ /*
+ * Validation is complete. Move the field types that were used
+ * to validate (and that were possibly altered by the validation
+ * process) to the output values.
+ */
+ BT_MOVE(output->packet_header_type, packet_header_type);
+ BT_MOVE(output->packet_context_type, packet_context_type);
+ BT_MOVE(output->event_header_type, event_header_type);
+ BT_MOVE(output->stream_event_ctx_type, stream_event_ctx_type);
+ BT_MOVE(output->event_context_type, event_context_type);
+ BT_MOVE(output->event_payload_type, event_payload_type);
+ return ret;
+
+error:
+ BT_PUT(packet_header_type);
+ BT_PUT(packet_context_type);
+ BT_PUT(event_header_type);
+ BT_PUT(stream_event_ctx_type);
+ BT_PUT(event_context_type);
+ BT_PUT(event_payload_type);
+ return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_validation_replace_types(struct bt_ctf_trace_common *trace,
+ struct bt_ctf_stream_class_common *stream_class,
+ struct bt_ctf_event_class_common *event_class,
+ struct bt_ctf_validation_output *output,
+ enum bt_ctf_validation_flag replace_flags)
+{
+ if ((replace_flags & BT_CTF_VALIDATION_FLAG_TRACE) && trace) {
+ bt_ctf_field_type_common_freeze(trace->packet_header_field_type);
+ BT_MOVE(trace->packet_header_field_type,
+ output->packet_header_type);
+ }
+
+ if ((replace_flags & BT_CTF_VALIDATION_FLAG_STREAM) && stream_class) {
+ bt_ctf_field_type_common_freeze(stream_class->packet_context_field_type);
+ bt_ctf_field_type_common_freeze(stream_class->event_header_field_type);
+ bt_ctf_field_type_common_freeze(stream_class->event_context_field_type);
+ BT_MOVE(stream_class->packet_context_field_type,
+ output->packet_context_type);
+ BT_MOVE(stream_class->event_header_field_type,
+ output->event_header_type);
+ BT_MOVE(stream_class->event_context_field_type,
+ output->stream_event_ctx_type);
+ }
+
+ if ((replace_flags & BT_CTF_VALIDATION_FLAG_EVENT) && event_class) {
+ bt_ctf_field_type_common_freeze(event_class->context_field_type);
+ bt_ctf_field_type_common_freeze(event_class->payload_field_type);
+ BT_MOVE(event_class->context_field_type, output->event_context_type);
+ BT_MOVE(event_class->payload_field_type, output->event_payload_type);
+ }
+}
+
+BT_HIDDEN
+void bt_ctf_validation_output_put_types(
+ struct bt_ctf_validation_output *output)
+{
+ BT_PUT(output->packet_header_type);
+ BT_PUT(output->packet_context_type);
+ BT_PUT(output->event_header_type);
+ BT_PUT(output->stream_event_ctx_type);
+ BT_PUT(output->event_context_type);
+ BT_PUT(output->event_payload_type);
+}
--- /dev/null
+/*
+ * visitor.c
+ *
+ * Babeltrace CTF writer - Visitor
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@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:
+ *
+ * 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.
+ */
+
+#include <babeltrace/ctf-writer/visitor-internal.h>
+#include <babeltrace/ref.h>
+
+BT_HIDDEN
+int bt_ctf_visitor_helper(struct bt_ctf_visitor_object *root,
+ bt_ctf_child_count_accessor child_counter,
+ bt_ctf_child_accessor child_accessor,
+ bt_ctf_child_visitor child_visitor,
+ bt_ctf_visitor visitor,
+ void *data)
+{
+ int ret, child_count, i;
+
+ ret = visitor(root, data);
+ if (ret) {
+ goto end;
+ }
+
+ child_count = child_counter(root->object);
+ if (child_count < 0) {
+ ret = child_count;
+ goto end;
+ }
+
+ for (i = 0; i < child_count; i++) {
+ void *child;
+
+ child = child_accessor(root->object, i);
+ if (!child) {
+ ret = -1;
+ goto end;
+ }
+ ret = child_visitor(child, visitor, data);
+ BT_PUT(child);
+ if (ret) {
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+enum bt_ctf_visitor_object_type bt_ctf_visitor_object_get_type(
+ struct bt_ctf_visitor_object *object)
+{
+ enum bt_ctf_visitor_object_type ret = BT_CTF_VISITOR_OBJECT_TYPE_UNKNOWN;
+
+ if (!object) {
+ goto end;
+ }
+
+ ret = object->type;
+end:
+ return ret;
+}
+
+void *bt_ctf_visitor_object_get_object(struct bt_ctf_visitor_object *object)
+{
+ void *ret = NULL;
+
+ if (!object) {
+ goto end;
+ }
+
+ ret = object->object;
+end:
+ return ret;
+}
#define BT_LOG_TAG "CTF-WRITER"
#include <babeltrace/lib-logging-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/compat/uuid-internal.h>
+#include <babeltrace/compiler-internal.h>
#include <babeltrace/ctf-writer/clock-internal.h>
#include <babeltrace/ctf-writer/field-types-internal.h>
#include <babeltrace/ctf-writer/fields-internal.h>
#include <babeltrace/ctf-writer/stream-internal.h>
#include <babeltrace/ctf-writer/trace-internal.h>
#include <babeltrace/ctf-writer/writer-internal.h>
-#include <babeltrace/ref.h>
#include <babeltrace/endian-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/compat/uuid-internal.h>
-#include <babeltrace/assert-internal.h>
+#include <babeltrace/ref.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
-#include <errno.h>
#include <unistd.h>
-#include <fcntl.h>
-#include <inttypes.h>
static
void bt_ctf_writer_destroy(struct bt_object *obj);
}
BT_HIDDEN
-const char *get_byte_order_string(enum bt_byte_order byte_order)
+const char *bt_ctf_get_byte_order_string(enum bt_ctf_byte_order byte_order)
{
const char *string;
switch (byte_order) {
- case BT_BYTE_ORDER_LITTLE_ENDIAN:
+ case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
string = "le";
break;
- case BT_BYTE_ORDER_BIG_ENDIAN:
+ case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
string = "be";
break;
- case BT_BYTE_ORDER_NATIVE:
+ case BT_CTF_BYTE_ORDER_NATIVE:
string = "native";
break;
default:
#include <babeltrace/ctf-ir/clock-value-internal.h>
#include <babeltrace/ctf-ir/field-path-internal.h>
#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ctf-writer/field-types-internal.h>
-#include <babeltrace/ctf-writer/fields-internal.h>
-#include <babeltrace/ctf-writer/event-internal.h>
-#include <babeltrace/ctf-writer/stream-class-internal.h>
-#include <babeltrace/ctf-writer/stream-internal.h>
-#include <babeltrace/ctf-writer/trace-internal.h>
-#include <babeltrace/ctf-writer/clock-internal.h>
-#include <babeltrace/ctf-writer/writer-internal.h>
#include <babeltrace/graph/component-class-internal.h>
#include <babeltrace/graph/component-class-sink-colander-internal.h>
#include <babeltrace/graph/component-filter-internal.h>
(void *) field_type);
}
-static inline void format_writer_field_type(char **buf_ch, bool extended,
- const char *prefix, struct bt_ctf_field_type *field_type)
-{
- format_field_type_common(buf_ch, extended, prefix,
- (void *) field_type);
-}
-
static inline void format_field_common_integer_extended(char **buf_ch,
const char *prefix, struct bt_field_common *field)
{
}
}
-static inline void format_writer_field(char **buf_ch, bool extended,
- const char *prefix, struct bt_ctf_field *field)
-{
- struct bt_field_common *common_field = (void *) field;
-
- format_field_common(buf_ch, extended, prefix, (void *) field);
-
- if (!extended) {
- return;
- }
-
- if (!common_field->type) {
- return;
- }
-
- switch (common_field->type->id) {
- case BT_FIELD_TYPE_ID_ENUM:
- {
- struct bt_ctf_field_enumeration *enumeration = (void *) field;
-
- if (enumeration->container) {
- format_writer_field(buf_ch, extended, prefix,
- (void *) enumeration->container);
- }
- break;
- }
- case BT_FIELD_TYPE_ID_VARIANT:
- {
- struct bt_ctf_field_variant *variant = (void *) field;
-
- BUF_APPEND(", %stag-field-addr=%p", PRFIELD(variant->tag));
- break;
- }
- default:
- break;
- }
-}
-
static inline void format_field_path(char **buf_ch, bool extended,
const char *prefix, struct bt_field_path *field_path)
{
&trace->packet_header_field_pool);
}
-static inline void format_writer_trace(char **buf_ch, bool extended,
- const char *prefix, struct bt_ctf_trace *trace)
-{
- format_trace_common(buf_ch, extended, prefix, BT_TO_COMMON(trace));
-}
-
static inline void format_stream_class_common(char **buf_ch, bool extended,
const char *prefix, struct bt_stream_class_common *stream_class,
format_func trace_format_func)
&stream_class->packet_context_field_pool);
}
-static inline void format_writer_stream_class(char **buf_ch, bool extended,
- const char *prefix, struct bt_ctf_stream_class *stream_class)
-{
- format_stream_class_common(buf_ch, extended, prefix,
- BT_TO_COMMON(stream_class), (format_func) format_writer_trace);
-
- if (extended && stream_class->clock) {
- BUF_APPEND(", %sctf-writer-clock-addr=%p, "
- "%sctf-writer-clock-name=\"%s\"",
- PRFIELD(stream_class->clock),
- PRFIELD(bt_clock_class_get_name(
- BT_TO_COMMON(stream_class->clock->clock_class))));
- }
-}
-
static inline void format_event_class_common(char **buf_ch, bool extended,
const char *prefix, struct bt_event_class_common *event_class,
format_func format_stream_class_func,
format_object_pool(buf_ch, extended, prefix, &event_class->event_pool);
}
-static inline void format_writer_event_class(char **buf_ch, bool extended,
- const char *prefix, struct bt_ctf_event_class *event_class)
-{
- format_event_class_common(buf_ch, extended, prefix,
- BT_TO_COMMON(event_class),
- (format_func) format_writer_stream_class,
- (format_func) format_writer_trace);
-}
-
static inline void format_stream_common(char **buf_ch, bool extended,
const char *prefix, struct bt_stream_common *stream,
format_func format_stream_class_func,
format_object_pool(buf_ch, extended, prefix, &stream->packet_pool);
}
-static inline void format_writer_stream(char **buf_ch, bool extended,
- const char *prefix, struct bt_ctf_stream *stream)
-{
- format_stream_common(buf_ch, extended, prefix, BT_TO_COMMON(stream),
- (format_func) format_writer_stream_class,
- (format_func) format_writer_trace);
-
- BUF_APPEND(", %sheader-field-addr=%p, %scontext-field-addr=%p"
- ", %sfd=%d, %smmap-offset=%zu, "
- "%smmap-base-offset=%zu, %spacket-size=%" PRIu64 ", "
- "%soffset=%" PRId64 ", %sevent-count=%u, "
- "%sflushed-packet-count=%u, "
- "%sdiscarded-event-count=%" PRIu64 ", "
- "%ssize=%" PRIu64 ", %slast-ts-end=%" PRIu64,
- PRFIELD(stream->packet_header),
- PRFIELD(stream->packet_context),
- PRFIELD(stream->pos.fd),
- PRFIELD((size_t) stream->pos.mmap_offset),
- PRFIELD((size_t) stream->pos.mmap_base_offset),
- PRFIELD(stream->pos.packet_size),
- PRFIELD(stream->pos.offset),
- PRFIELD(stream->events->len),
- PRFIELD(stream->flushed_packet_count),
- PRFIELD(stream->discarded_events),
- PRFIELD(stream->size), PRFIELD(stream->last_ts_end));
-
- if (stream->events) {
- BUF_APPEND(", %sevent-count=%u", PRFIELD(stream->events->len));
- }
-
- BUF_APPEND(", %sheader-field-addr=%p, %scontext-field-addr=%p"
- ", %sfd=%d, %smmap-offset=%zu, "
- "%smmap-base-offset=%zu, %spacket-size=%" PRIu64 ", "
- "%soffset=%" PRId64 ", "
- "%sflushed-packet-count=%u, "
- "%sdiscarded-event-count=%" PRIu64 ", "
- "%ssize=%" PRIu64 ", %slast-ts-end=%" PRIu64,
- PRFIELD(stream->packet_header),
- PRFIELD(stream->packet_context),
- PRFIELD(stream->pos.fd),
- PRFIELD((size_t) stream->pos.mmap_offset),
- PRFIELD((size_t) stream->pos.mmap_base_offset),
- PRFIELD(stream->pos.packet_size),
- PRFIELD(stream->pos.offset),
- PRFIELD(stream->flushed_packet_count),
- PRFIELD(stream->discarded_events),
- PRFIELD(stream->size), PRFIELD(stream->last_ts_end));
-}
-
static inline void format_packet(char **buf_ch, bool extended,
const char *prefix, struct bt_packet *packet)
{
format_stream(buf_ch, false, tmp_prefix, stream);
}
-static inline void format_writer_event(char **buf_ch, bool extended,
- const char *prefix, struct bt_event *event)
-{
- format_event_common(buf_ch, extended, prefix, BT_TO_COMMON(event),
- (format_func) format_writer_event_class,
- (format_func) format_writer_stream_class,
- (format_func) format_writer_trace);
-}
-
static inline void format_clock_class(char **buf_ch, bool extended,
const char *prefix, struct bt_clock_class *clock_class)
{
}
}
-static inline void format_ctf_writer(char **buf_ch, bool extended,
- const char *prefix, struct bt_ctf_writer *writer)
-{
- /* TODO */
-}
-
static inline void format_stream_class_common_common(char **buf_ch,
bool extended, const char *prefix,
struct bt_stream_class_common *stream_class)
void *obj;
enum {
CAT_DEFAULT,
- CAT_WRITER,
CAT_COMMON,
} cat = CAT_DEFAULT;
fmt_ch++;
}
- if (*fmt_ch == 'w') {
- cat = CAT_WRITER;
- fmt_ch++;
- } else if (*fmt_ch == '_') {
+ if (*fmt_ch == '_') {
cat = CAT_COMMON;
fmt_ch++;
}
abort();
}
break;
- case CAT_WRITER:
- switch (*fmt_ch) {
- case 'F':
- format_writer_field_type(buf_ch, extended, prefix, obj);
- break;
- case 'f':
- format_writer_field(buf_ch, extended, prefix, obj);
- break;
- case 'E':
- format_writer_event_class(buf_ch, extended, prefix, obj);
- break;
- case 'e':
- format_writer_event(buf_ch, extended, prefix, obj);
- break;
- case 'S':
- format_writer_stream_class(buf_ch, extended, prefix, obj);
- break;
- case 's':
- format_writer_stream(buf_ch, extended, prefix, obj);
- break;
- case 't':
- format_writer_trace(buf_ch, extended, prefix, obj);
- break;
- case 'w':
- format_ctf_writer(buf_ch, extended, prefix, obj);
- break;
- default:
- abort();
- }
- break;
case CAT_COMMON:
switch (*fmt_ch) {
case 'F':
type_id = bt_field_get_type_id(field);
switch (type_id) {
- case BT_CTF_FIELD_TYPE_ID_INTEGER:
+ case BT_FIELD_TYPE_ID_INTEGER:
return print_integer(pretty, field);
- case BT_CTF_FIELD_TYPE_ID_FLOAT:
+ case BT_FIELD_TYPE_ID_FLOAT:
{
double v;
}
return BT_COMPONENT_STATUS_OK;
}
- case BT_CTF_FIELD_TYPE_ID_ENUM:
+ case BT_FIELD_TYPE_ID_ENUM:
return print_enum(pretty, field);
- case BT_CTF_FIELD_TYPE_ID_STRING:
+ case BT_FIELD_TYPE_ID_STRING:
{
const char *str;
}
return BT_COMPONENT_STATUS_OK;
}
- case BT_CTF_FIELD_TYPE_ID_STRUCT:
+ case BT_FIELD_TYPE_ID_STRUCT:
return print_struct(pretty, field, print_names, filter_fields,
filter_array_len);
- case BT_CTF_FIELD_TYPE_ID_VARIANT:
+ case BT_FIELD_TYPE_ID_VARIANT:
return print_variant(pretty, field, print_names);
- case BT_CTF_FIELD_TYPE_ID_ARRAY:
+ case BT_FIELD_TYPE_ID_ARRAY:
return print_array(pretty, field, print_names);
- case BT_CTF_FIELD_TYPE_ID_SEQUENCE:
+ case BT_FIELD_TYPE_ID_SEQUENCE:
return print_sequence(pretty, field, print_names);
default:
// TODO: log instead
goto end;
}
- is_signed = bt_ctf_field_type_integer_get_signed(integer_type);
+ is_signed = bt_field_type_integer_is_signed(integer_type);
if (!is_signed) {
ret = bt_field_unsigned_integer_get_value(integer,
&raw_clock_value);
#define DEFAULT_CLOCK_TIME 0
#define DEFAULT_CLOCK_VALUE 0
-#define NR_TESTS 346
+#define NR_TESTS 342
struct bt_utsname {
char sysname[BABELTRACE_HOST_NAME_MAX];
struct bt_utsname name = {"GNU/Linux", "testhost", "4.4.0-87-generic",
"#110-Ubuntu SMP Tue Jul 18 12:55:35 UTC 2017", "x86_64"};
struct bt_ctf_clock *clock, *ret_clock;
- struct bt_ctf_clock_class *ret_clock_class;
struct bt_ctf_stream_class *stream_class, *ret_stream_class;
struct bt_ctf_stream *stream1;
struct bt_ctf_stream *stream;
* class to the writer's trace, thus registering the stream
* class's clock to the trace.
*/
- ok(bt_ctf_trace_get_clock_class_count(trace) == 1,
- "bt_ctf_trace_get_clock_class_count returns the correct number of clocks");
- ret_clock_class = bt_ctf_trace_get_clock_class_by_index(trace, 0);
- ok(strcmp(bt_ctf_clock_class_get_name(ret_clock_class),
- bt_ctf_clock_get_name(clock)) == 0,
- "bt_ctf_trace_get_clock_class returns the right clock instance");
- bt_put(ret_clock_class);
- ret_clock_class = bt_ctf_trace_get_clock_class_by_name(trace, clock_name);
- ok(strcmp(bt_ctf_clock_class_get_name(ret_clock_class),
- bt_ctf_clock_get_name(clock)) == 0,
- "bt_ctf_trace_get_clock_class returns the right clock instance");
- bt_put(ret_clock_class);
- ok(!bt_ctf_trace_get_clock_class_by_name(trace, "random"),
- "bt_ctf_trace_get_clock_by_name fails when the requested clock doesn't exist");
ret_stream_class = bt_ctf_stream_get_class(stream1);
ok(ret_stream_class,