X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Ffield.hpp;h=a774d133a0978d0c59e0ce08f3a2865f675e23b4;hb=88277a52069ed0135254ce29da617ebb6ecddbb8;hp=79017416617efb22a168633cd1dec65a34559132;hpb=e7360180aa8c4d8f5bfec86a6a020bbc616ff2c0;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/field.hpp b/src/bin/lttng-sessiond/field.hpp index 790174166..a774d133a 100644 --- a/src/bin/lttng-sessiond/field.hpp +++ b/src/bin/lttng-sessiond/field.hpp @@ -8,15 +8,16 @@ #ifndef LTTNG_FIELD_H #define LTTNG_FIELD_H -#include "trace-class.hpp" +#include +#include + +#include #include #include #include #include -#include - namespace lttng { namespace sessiond { namespace trace { @@ -24,6 +25,31 @@ 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; + + 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 @@ -52,14 +78,20 @@ private: class field { public: + using uptr = std::unique_ptr; using cuptr = std::unique_ptr; field(std::string name, type::cuptr type); void accept(field_visitor& visitor) const; bool operator==(const field& other) const noexcept; + const type& get_type() const; + type::cuptr move_type() noexcept; + const std::string name; - const type::cuptr _type; + +private: + type::cuptr _type; }; class integer_type : public type { @@ -173,14 +205,13 @@ class enumeration_mapping { public: using range_t = enumeration_mapping_range; - enumeration_mapping(const enumeration_mapping& other) = delete; + enumeration_mapping(const enumeration_mapping& other) = default; enumeration_mapping(const enumeration_mapping&& other) : name{std::move(other.name)}, range{other.range} { } - /* Mapping with an implicit value. */ - enumeration_mapping(std::string in_name) : name{std::move(in_name)} + enumeration_mapping(std::string in_name, MappingIntegerType value) : name{std::move(in_name)}, range{value, value} { } @@ -189,7 +220,12 @@ public: } const std::string name; - const nonstd::optional range; + /* + * Only one range per mapping is supported for the moment as + * the tracers (and CTF 1.8) can't express multiple ranges per + * mapping, which is allowed by CTF 2. + */ + const range_t range; }; template @@ -224,13 +260,13 @@ public: integer_type::signedness::UNSIGNED, in_base, std::move(in_roles)), - _mappings{std::move(in_mappings)} + mappings_{std::move(in_mappings)} { } virtual void accept(type_visitor& visitor) const override final; - const std::shared_ptr _mappings; + const std::shared_ptr mappings_; private: virtual bool _is_equal(const type& base_other) const noexcept override final @@ -238,7 +274,7 @@ private: const auto& other = static_cast&>( base_other); - return integer_type::_is_equal(base_other) && *this->_mappings == *other._mappings; + return integer_type::_is_equal(base_other) && *this->mappings_ == *other.mappings_; } }; @@ -274,11 +310,11 @@ class dynamic_length_array_type : public array_type { 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; @@ -288,7 +324,7 @@ class static_length_blob_type : public type { public: enum class role { /* Packet header field class specific role. */ - TRACE_CLASS_UUID, + METADATA_STREAM_UUID, }; using roles = std::vector; @@ -306,11 +342,11 @@ private: class dynamic_length_blob_type : public type { public: - dynamic_length_blob_type(unsigned int alignment, std::string length_field_name); + dynamic_length_blob_type(unsigned int alignment, 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; @@ -352,10 +388,10 @@ class dynamic_length_string_type : public string_type { 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; @@ -375,25 +411,64 @@ public: virtual void accept(type_visitor& visitor) const override final; - const fields _fields; + const fields fields_; private: virtual bool _is_equal(const type& base_other) const noexcept override final; }; +template class variant_type : public type { -public: - using choices = std::vector; + static_assert(std::is_same::value || + std::is_same::value, + "Variant mapping integer type must be one of those allowed by typed_enumeration_type"); - variant_type(unsigned int alignment, std::string tag_name, choices in_choices); +public: + using choice = std::pair, type::cuptr>; + using choices = std::vector; + + variant_type(unsigned int in_alignment, + field_location in_selector_field_location, + choices in_choices) : + type(in_alignment), + selector_field_location{std::move(in_selector_field_location)}, + choices_{std::move(in_choices)} + { + } virtual void accept(type_visitor& visitor) const override final; - const std::string tag_name; - const choices _choices; + const field_location selector_field_location; + const choices choices_; +; private: - virtual bool _is_equal(const type& base_other) const noexcept override final; + static bool _choices_are_equal(const choices& a, const choices& b) + { + if (a.size() != b.size()) { + return false; + } + + return true; + + return std::equal(a.cbegin(), a.cend(), b.cbegin(), + [](const choice& choice_a, const choice& choice_b) { + return choice_a.first == choice_b.first && + *choice_a.second == *choice_b.second; + }); + } + + virtual bool _is_equal(const type& base_other) const noexcept override final + { + const auto& other = static_cast(base_other); + + return selector_field_location == other.selector_field_location && + _choices_are_equal(choices_, other.choices_); + } }; class field_visitor { @@ -420,7 +495,8 @@ public: virtual void visit(const static_length_string_type& type) = 0; virtual void visit(const dynamic_length_string_type& type) = 0; virtual void visit(const structure_type& type) = 0; - virtual void visit(const variant_type& type) = 0; + virtual void visit(const variant_type& type) = 0; + virtual void visit(const variant_type& type) = 0; protected: type_visitor() = default; @@ -430,4 +506,48 @@ protected: } /* 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 : formatter { + template + 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 */