#ifndef LTTNG_FIELD_H
#define LTTNG_FIELD_H
-#include "trace-class.hpp"
+#include <common/format.hpp>
+
+#include <vendor/optional.hpp>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>
-#include <vendor/optional.hpp>
-
namespace lttng {
namespace sessiond {
namespace trace {
class field_visitor;
class type_visitor;
+enum class byte_order {
+ BIG_ENDIAN_,
+ LITTLE_ENDIAN_,
+};
+
+class field_location {
+public:
+ enum class root {
+ PACKET_HEADER,
+ PACKET_CONTEXT,
+ EVENT_RECORD_HEADER,
+ EVENT_RECORD_COMMON_CONTEXT,
+ EVENT_RECORD_SPECIFIC_CONTEXT,
+ EVENT_RECORD_PAYLOAD,
+ };
+
+ using elements = std::vector<std::string>;
+
+ field_location(root lookup_root, elements elements);
+ bool operator==(const field_location& other) const noexcept;
+
+ const root root_;
+ const elements elements_;
+};
+
/*
* Field, and the various field types, represents fields as exposed by the
* LTTng tracers. These classes do not attempt to describe the complete spectrum of the CTF
HEXADECIMAL = 16,
};
+ enum class role {
+ DEFAULT_CLOCK_TIMESTAMP,
+ /* Packet header field class specific roles. */
+ DATA_STREAM_CLASS_ID,
+ DATA_STREAM_ID,
+ PACKET_MAGIC_NUMBER,
+ /* Packet context field class specific roles. */
+ DISCARDED_EVENT_RECORD_COUNTER_SNAPSHOT,
+ PACKET_CONTENT_LENGTH,
+ PACKET_END_DEFAULT_CLOCK_TIMESTAMP,
+ PACKET_SEQUENCE_NUMBER,
+ PACKET_TOTAL_LENGTH,
+ /* Event record field class roles. */
+ EVENT_RECORD_CLASS_ID,
+ };
+
+ using roles = std::vector<role>;
+
integer_type(unsigned int alignment,
byte_order byte_order,
unsigned int size,
signedness signedness,
- base base);
+ base base,
+ roles roles = {});
virtual void accept(type_visitor& visitor) const override;
const enum byte_order byte_order;
const unsigned int size;
- const signedness signedness;
- const base base;
+ /*
+ * signedness and base are suffixed with '_' to work-around a bug in older
+ * GCCs (before 6) that do not recognize hidden/shadowed enumeration as valid
+ * nested-name-specifiers.
+ */
+ const signedness signedness_;
+ const base base_;
+ const roles roles_;
protected:
virtual bool _is_equal(const type& other) const noexcept override;
enum byte_order byte_order,
unsigned int size,
enum signedness signedness,
- enum base base);
+ enum base base,
+ integer_type::roles roles = {});
virtual void accept(type_visitor& visitor) const = 0;
};
typed_enumeration_type(unsigned int in_alignment,
enum byte_order in_byte_order,
unsigned int in_size,
- enum signedness in_signedness,
enum base in_base,
- const std::shared_ptr<const mappings>& in_mappings) :
+ const std::shared_ptr<const mappings>& in_mappings,
+ integer_type::roles in_roles = {}) :
enumeration_type(in_alignment,
in_byte_order,
in_size,
- in_signedness,
- in_base),
+ std::is_signed<MappingIntegerType>::value ?
+ integer_type::signedness::SIGNED :
+ integer_type::signedness::UNSIGNED,
+ in_base,
+ std::move(in_roles)),
_mappings{std::move(in_mappings)}
{
}
public:
array_type(unsigned int alignment, type::cuptr element_type);
- const type::cuptr element_type;
+ const type::cuptr element_type;
protected:
virtual bool _is_equal(const type& base_other) const noexcept override;
public:
dynamic_length_array_type(unsigned int alignment,
type::cuptr element_type,
- std::string length_field_name);
+ field_location length_field_location);
virtual void accept(type_visitor& visitor) const override final;
- const std::string length_field_name;
+ const field_location length_field_location;
+
+private:
+ virtual bool _is_equal(const type& base_other) const noexcept override final;
+};
+
+class static_length_blob_type : public type {
+public:
+ enum class role {
+ /* Packet header field class specific role. */
+ TRACE_CLASS_UUID,
+ };
+
+ using roles = std::vector<role>;
+
+ static_length_blob_type(unsigned int alignment, uint64_t in_length_bytes, roles roles = {});
+
+ virtual void accept(type_visitor& visitor) const override final;
+
+ const uint64_t length_bytes;
+ const roles roles_;
+
+private:
+ virtual bool _is_equal(const type& base_other) const noexcept override final;
+};
+
+class dynamic_length_blob_type : public type {
+public:
+ dynamic_length_blob_type(unsigned int alignment, field_location length_field_location);
+
+ virtual void accept(type_visitor& visitor) const override final;
+
+ const field_location length_field_location;
private:
virtual bool _is_equal(const type& base_other) const noexcept override final;
string_type(unsigned int alignment, enum encoding encoding);
- const encoding encoding;
+ /*
+ * encoding is suffixed with '_' to work-around a bug in older
+ * GCCs (before 6) that do not recognize hidden/shadowed enumeration as valid
+ * nested-name-specifiers.
+ */
+ const encoding encoding_;
protected:
virtual bool _is_equal(const type& base_other) const noexcept override;
public:
dynamic_length_string_type(unsigned int alignment,
enum encoding in_encoding,
- std::string length_field_name);
+ field_location length_field_location);
virtual void accept(type_visitor& visitor) const override final;
- const std::string length_field_name;
+ const field_location length_field_location;
private:
virtual bool _is_equal(const type& base_other) const noexcept override final;
public:
using choices = std::vector<field::cuptr>;
- variant_type(unsigned int alignment, std::string tag_name, choices in_choices);
+ variant_type(unsigned int alignment,
+ field_location selector_field_location,
+ choices in_choices);
virtual void accept(type_visitor& visitor) const override final;
- const std::string tag_name;
+ const field_location selector_field_location;
const choices _choices;
+;
private:
virtual bool _is_equal(const type& base_other) const noexcept override final;
virtual void visit(const unsigned_enumeration_type& type) = 0;
virtual void visit(const static_length_array_type& type) = 0;
virtual void visit(const dynamic_length_array_type& type) = 0;
+ virtual void visit(const static_length_blob_type& type) = 0;
+ virtual void visit(const dynamic_length_blob_type& type) = 0;
virtual void visit(const null_terminated_string_type& type) = 0;
virtual void visit(const static_length_string_type& type) = 0;
virtual void visit(const dynamic_length_string_type& type) = 0;
} /* namespace sessiond */
} /* namespace lttng */
+/*
+ * Due to a bug in g++ < 7.1, this specialization must be enclosed in the fmt namespace,
+ * see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480.
+ */
+namespace fmt {
+template <>
+struct formatter<lttng::sessiond::trace::field_location> : formatter<std::string> {
+ template <typename FormatCtx>
+ typename FormatCtx::iterator format(
+ const lttng::sessiond::trace::field_location& location, FormatCtx& ctx)
+ {
+ std::string location_str{"["};
+
+ switch (location.root_) {
+ case lttng::sessiond::trace::field_location::root::PACKET_HEADER:
+ location_str += "\"packet-header\"";
+ break;
+ case lttng::sessiond::trace::field_location::root::PACKET_CONTEXT:
+ location_str += "\"packet-context\"";
+ break;
+ case lttng::sessiond::trace::field_location::root::EVENT_RECORD_HEADER:
+ location_str += "\"event-record-header\"";
+ break;
+ case lttng::sessiond::trace::field_location::root::EVENT_RECORD_COMMON_CONTEXT:
+ location_str += "\"event-record-common-context\"";
+ break;
+ case lttng::sessiond::trace::field_location::root::EVENT_RECORD_SPECIFIC_CONTEXT:
+ location_str += "\"event-record-specific-context\"";
+ break;
+ case lttng::sessiond::trace::field_location::root::EVENT_RECORD_PAYLOAD:
+ location_str += "\"event-record-payload\"";
+ break;
+ }
+
+ for (const auto &name : location.elements_) {
+ location_str += ", \"" + name + "\"";
+ }
+
+ location_str += "]";
+ return format_to(ctx.out(), location_str);
+ }
+};
+} /* namespace fmt */
+
#endif /* LTTNG_FIELD_H */