From: Philippe Proulx Date: Tue, 21 May 2024 17:33:14 +0000 (-0400) Subject: Add CTF IR classes specific to `src.ctf.*` X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=1c70ff4a25e82ac360acc6751b31d45db0d358cd;p=babeltrace.git Add CTF IR classes specific to `src.ctf.*` This patch uses the `ctf::ir` API to expose a source-specific CTF IR API under the `ctf::src` namespace, to be used by both the `src.ctf.fs` and the `src.ctf.lttng-live` component classes. This specific CTF IR API augments the common `ctf::ir` API with user mixins to add the following: • Any field class has a "deep type". See the comment of `ctf::src::FcDeepType` to understand why we need such an enumeration. • The field class, clock class, event record class, data stream class, and trace class classes have an optional equivalent libbabeltrace2 class object. This is a bridge between the CTF IR world and the libbabeltrace2 world to be able to create corresponding libbabeltrace2 messages when decoding a data stream with the CTF IR classes. If a field class has no equivalent libbabeltrace2 class, then the values of its instances aren't transported through messages as field objects. • A clock class object may hold its equivalent libbabeltrace2 class (owned, shared reference). • A trace class object may hold its equivalent libbabeltrace2 class (owned, shared reference). • Boolean and integer field classes have an optional "key value" saving index. See the comment of the `ctf::src::KeyValSavingIndexes` alias to learn more. • Dynamic-length, optional, and variant field classes have a saved key value index. Again, see the comment of `ctf::src::KeyValSavingIndexes` to learn more. • Field class and field location mixins have an optional text location member. This will help with precise metadata stream error reporting. • A trace class contains the maximum number of saved key values for its instance. Once more, see the comment of `ctf::src::KeyValSavingIndexes` to learn more. The new API adds templateless aliases for all the configurable CTF IR types, for example `src::ctf::FixedLenIntFc`. The new API also offers user mixin agnostic functions to create all its CTF IR objects. For example, call ctf::src::createDynLenBlobFc() to create a `ctf::src` dynamic-length BLOB field class. Signed-off-by: Philippe Proulx Change-Id: I854d5562778e05f4c438a4e937758bbce114f951 Reviewed-on: https://review.lttng.org/c/babeltrace/+/7840 Reviewed-on: https://review.lttng.org/c/babeltrace/+/12255 Tested-by: jenkins CI-Build: Simon Marchi --- diff --git a/src/Makefile.am b/src/Makefile.am index a21b7189..fc5d2709 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -685,6 +685,8 @@ plugins_ctf_babeltrace_plugin_ctf_la_SOURCES = \ plugins/ctf/common/src/bfcr/bfcr.cpp \ plugins/ctf/common/src/bfcr/bfcr.hpp \ plugins/ctf/common/src/clk-cls-cfg.hpp \ + plugins/ctf/common/src/metadata/ctf-ir.cpp \ + plugins/ctf/common/src/metadata/ctf-ir.hpp \ plugins/ctf/common/src/msg-iter/msg-iter.cpp \ plugins/ctf/common/src/msg-iter/msg-iter.hpp \ plugins/ctf/fs-sink/fs-sink.cpp \ diff --git a/src/plugins/ctf/common/metadata/ctf-ir.hpp b/src/plugins/ctf/common/metadata/ctf-ir.hpp index 17073f6c..aad3d63a 100644 --- a/src/plugins/ctf/common/metadata/ctf-ir.hpp +++ b/src/plugins/ctf/common/metadata/ctf-ir.hpp @@ -1026,7 +1026,7 @@ public: /* * Length of instances of this field class. */ - const bt2c::DataLen len() const noexcept + bt2c::DataLen len() const noexcept { return _mLen; } diff --git a/src/plugins/ctf/common/src/metadata/ctf-ir.cpp b/src/plugins/ctf/common/src/metadata/ctf-ir.cpp new file mode 100644 index 00000000..6b52ff8b --- /dev/null +++ b/src/plugins/ctf/common/src/metadata/ctf-ir.cpp @@ -0,0 +1,878 @@ +/* + * Copyright (c) 2022 Philippe Proulx + * + * SPDX-License-Identifier: MIT + */ + +#include "cpp-common/bt2c/call.hpp" +#include "cpp-common/bt2s/make-unique.hpp" + +#include "ctf-ir.hpp" + +namespace ctf { +namespace src { +namespace internal { + +void DependentFcMixin::keyFcs(FcSet keyFcs) +{ + _mKeyFcs = std::move(keyFcs); +} + +FieldLocMixin::FieldLocMixin(const bt2c::TextLoc& loc) noexcept : _mLoc {loc} +{ +} + +FcMixin::FcMixin(const bt2c::TextLoc& loc) noexcept : _mLoc {loc} +{ +} + +FcMixin::FcMixin(const FcDeepType deepType, const bt2c::TextLoc& loc) noexcept : + _mDeepType {deepType}, _mLoc {loc} +{ +} + +void ClkClsMixin::sharedLibCls(bt2::ClockClass::Shared cls) noexcept +{ + static_cast&>(*this).libCls(*cls); + _mSharedLibCls = std::move(cls); +} + +void TraceClsMixin::sharedLibCls(bt2::TraceClass::Shared cls) noexcept +{ + static_cast&>(*this).libCls(*cls); + _mSharedLibCls = std::move(cls); +} + +} /* namespace internal */ + +namespace { + +bool isStdBitArrayFc(const unsigned int align, const bt2c::DataLen len) noexcept +{ + return align % 8 == 0 && (*len == 8 || *len == 16 || *len == 32 || *len == 64); +} + +} /* namespace */ + +FieldLoc createFieldLoc(const bt2c::TextLoc& loc, bt2s::optional origin, + FieldLoc::Items items) +{ + return FieldLoc {internal::CtfIrMixins::FieldLoc {loc}, std::move(origin), std::move(items)}; +} + +std::unique_ptr +createFixedLenBitArrayFc(const bt2c::TextLoc& loc, const unsigned int align, + const bt2c::DataLen len, const ByteOrder byteOrder, + const bt2s::optional& bitOrder, OptAttrs attrs) +{ + const auto deepType = bt2c::call([align, len, byteOrder, &bitOrder] { + const auto isRev = FixedLenBitArrayFc::isRev(byteOrder, bitOrder); + const auto isStd = isStdBitArrayFc(align, len); + + if (byteOrder == ByteOrder::Big) { + if (isStd) { + if (isRev) { + switch (*len) { + case 8: + return FcDeepType::FixedLenBitArrayBa8Rev; + case 16: + return FcDeepType::FixedLenBitArrayBa16BeRev; + case 32: + return FcDeepType::FixedLenBitArrayBa32BeRev; + case 64: + return FcDeepType::FixedLenBitArrayBa64BeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 8: + return FcDeepType::FixedLenBitArrayBa8; + case 16: + return FcDeepType::FixedLenBitArrayBa16Be; + case 32: + return FcDeepType::FixedLenBitArrayBa32Be; + case 64: + return FcDeepType::FixedLenBitArrayBa64Be; + default: + bt_common_abort(); + } + } + } else { + if (isRev) { + return FcDeepType::FixedLenBitArrayBeRev; + } else { + return FcDeepType::FixedLenBitArrayBe; + } + } + } else { + /* Little-endian */ + if (isStd) { + if (isRev) { + switch (*len) { + case 8: + return FcDeepType::FixedLenBitArrayBa8Rev; + case 16: + return FcDeepType::FixedLenBitArrayBa16LeRev; + case 32: + return FcDeepType::FixedLenBitArrayBa32LeRev; + case 64: + return FcDeepType::FixedLenBitArrayBa64LeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 8: + return FcDeepType::FixedLenBitArrayBa8; + case 16: + return FcDeepType::FixedLenBitArrayBa16Le; + case 32: + return FcDeepType::FixedLenBitArrayBa32Le; + case 64: + return FcDeepType::FixedLenBitArrayBa64Le; + default: + bt_common_abort(); + } + } + } else { + if (isRev) { + return FcDeepType::FixedLenBitArrayLeRev; + } else { + return FcDeepType::FixedLenBitArrayLe; + } + } + } + }); + + return bt2s::make_unique(internal::CtfIrMixins::Fc {deepType, loc}, + internal::CtfIrMixins::FixedLenBitArrayFc {}, + align, len, byteOrder, bitOrder, std::move(attrs)); +} + +std::unique_ptr +createFixedLenBitMapFc(const bt2c::TextLoc& loc, const unsigned int align, const bt2c::DataLen len, + const ByteOrder byteOrder, FixedLenBitMapFc::Flags flags, + const bt2s::optional& bitOrder, OptAttrs attrs) +{ + const auto deepType = bt2c::call([align, len, byteOrder, &bitOrder] { + const auto isRev = FixedLenBitArrayFc::isRev(byteOrder, bitOrder); + const auto isStd = isStdBitArrayFc(align, len); + + if (byteOrder == ByteOrder::Big) { + if (isStd) { + if (isRev) { + switch (*len) { + case 8: + return FcDeepType::FixedLenBitMapBa8Rev; + case 16: + return FcDeepType::FixedLenBitMapBa16BeRev; + case 32: + return FcDeepType::FixedLenBitMapBa32BeRev; + case 64: + return FcDeepType::FixedLenBitMapBa64BeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 8: + return FcDeepType::FixedLenBitMapBa8; + case 16: + return FcDeepType::FixedLenBitMapBa16Be; + case 32: + return FcDeepType::FixedLenBitMapBa32Be; + case 64: + return FcDeepType::FixedLenBitMapBa64Be; + default: + bt_common_abort(); + } + } + } else { + if (isRev) { + return FcDeepType::FixedLenBitMapBeRev; + } else { + return FcDeepType::FixedLenBitMapBe; + } + } + } else { + /* Little-endian */ + if (isStd) { + if (isRev) { + switch (*len) { + case 8: + return FcDeepType::FixedLenBitMapBa8Rev; + case 16: + return FcDeepType::FixedLenBitMapBa16LeRev; + case 32: + return FcDeepType::FixedLenBitMapBa32LeRev; + case 64: + return FcDeepType::FixedLenBitMapBa64LeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 8: + return FcDeepType::FixedLenBitMapBa8; + case 16: + return FcDeepType::FixedLenBitMapBa16Le; + case 32: + return FcDeepType::FixedLenBitMapBa32Le; + case 64: + return FcDeepType::FixedLenBitMapBa64Le; + default: + bt_common_abort(); + } + } + } else { + if (isRev) { + return FcDeepType::FixedLenBitMapLeRev; + } else { + return FcDeepType::FixedLenBitMapLe; + } + } + } + }); + + return bt2s::make_unique( + internal::CtfIrMixins::Fc {deepType, loc}, internal::CtfIrMixins::FixedLenBitArrayFc {}, + internal::CtfIrMixins::FixedLenBitMapFc {}, align, len, byteOrder, std::move(flags), + bitOrder, std::move(attrs)); +} + +std::unique_ptr +createFixedLenBoolFc(const bt2c::TextLoc& loc, const unsigned int align, const bt2c::DataLen len, + const ByteOrder byteOrder, const bt2s::optional& bitOrder, + OptAttrs attrs) +{ + const auto deepType = bt2c::call([align, len, byteOrder, &bitOrder] { + const auto isRev = FixedLenBitArrayFc::isRev(byteOrder, bitOrder); + const auto isStd = isStdBitArrayFc(align, len); + + if (byteOrder == ByteOrder::Big) { + if (isStd) { + if (isRev) { + switch (*len) { + case 8: + return FcDeepType::FixedLenBoolBa8Rev; + case 16: + return FcDeepType::FixedLenBoolBa16BeRev; + case 32: + return FcDeepType::FixedLenBoolBa32BeRev; + case 64: + return FcDeepType::FixedLenBoolBa64BeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 8: + return FcDeepType::FixedLenBoolBa8; + case 16: + return FcDeepType::FixedLenBoolBa16Be; + case 32: + return FcDeepType::FixedLenBoolBa32Be; + case 64: + return FcDeepType::FixedLenBoolBa64Be; + default: + bt_common_abort(); + } + } + } else { + if (isRev) { + return FcDeepType::FixedLenBoolBeRev; + } else { + return FcDeepType::FixedLenBoolBe; + } + } + } else { + /* Little-endian */ + if (isStd) { + if (isRev) { + switch (*len) { + case 8: + return FcDeepType::FixedLenBoolBa8Rev; + case 16: + return FcDeepType::FixedLenBoolBa16LeRev; + case 32: + return FcDeepType::FixedLenBoolBa32LeRev; + case 64: + return FcDeepType::FixedLenBoolBa64LeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 8: + return FcDeepType::FixedLenBoolBa8; + case 16: + return FcDeepType::FixedLenBoolBa16Le; + case 32: + return FcDeepType::FixedLenBoolBa32Le; + case 64: + return FcDeepType::FixedLenBoolBa64Le; + default: + bt_common_abort(); + } + } + } else { + if (isRev) { + return FcDeepType::FixedLenBoolLeRev; + } else { + return FcDeepType::FixedLenBoolLe; + } + } + } + }); + + return bt2s::make_unique(internal::CtfIrMixins::Fc {deepType, loc}, + internal::CtfIrMixins::FixedLenBitArrayFc {}, + internal::CtfIrMixins::FixedLenBoolFc {}, align, len, + byteOrder, bitOrder, std::move(attrs)); +} + +std::unique_ptr +createFixedLenFloatFc(const bt2c::TextLoc& loc, const unsigned int align, const bt2c::DataLen len, + const ByteOrder byteOrder, const bt2s::optional& bitOrder, + OptAttrs attrs) +{ + const auto deepType = bt2c::call([align, len, byteOrder, &bitOrder] { + const auto isRev = FixedLenBitArrayFc::isRev(byteOrder, bitOrder); + const auto isStd = isStdBitArrayFc(align, len); + + if (byteOrder == ByteOrder::Big) { + if (isStd) { + if (isRev) { + switch (*len) { + case 32: + return FcDeepType::FixedLenFloatBa32BeRev; + case 64: + return FcDeepType::FixedLenFloatBa64BeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 32: + return FcDeepType::FixedLenFloatBa32Be; + case 64: + return FcDeepType::FixedLenFloatBa64Be; + default: + bt_common_abort(); + } + } + } else { + if (isRev) { + switch (*len) { + case 32: + return FcDeepType::FixedLenFloat32BeRev; + case 64: + return FcDeepType::FixedLenFloat64BeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 32: + return FcDeepType::FixedLenFloat32Be; + case 64: + return FcDeepType::FixedLenFloat64Be; + default: + bt_common_abort(); + } + } + } + } else { + /* Little-endian */ + if (isStd) { + if (isRev) { + switch (*len) { + case 32: + return FcDeepType::FixedLenFloatBa32LeRev; + case 64: + return FcDeepType::FixedLenFloatBa64LeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 32: + return FcDeepType::FixedLenFloatBa32Le; + case 64: + return FcDeepType::FixedLenFloatBa64Le; + default: + bt_common_abort(); + } + } + } else { + if (isRev) { + switch (*len) { + case 32: + return FcDeepType::FixedLenFloat32LeRev; + case 64: + return FcDeepType::FixedLenFloat64LeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 32: + return FcDeepType::FixedLenFloat32Le; + case 64: + return FcDeepType::FixedLenFloat64Le; + default: + bt_common_abort(); + } + } + } + } + }); + + return bt2s::make_unique(internal::CtfIrMixins::Fc {deepType, loc}, + internal::CtfIrMixins::FixedLenBitArrayFc {}, align, + len, byteOrder, bitOrder, std::move(attrs)); +} + +std::unique_ptr +createFixedLenUIntFc(const bt2c::TextLoc& loc, const unsigned int align, const bt2c::DataLen len, + const ByteOrder byteOrder, const bt2s::optional& bitOrder, + const DispBase prefDispBase, FixedLenUIntFc::Mappings mappings, + UIntFieldRoles roles, OptAttrs attrs) +{ + const auto deepType = bt2c::call([align, len, byteOrder, &bitOrder, &roles] { + const auto isRev = FixedLenBitArrayFc::isRev(byteOrder, bitOrder); + const auto isStd = isStdBitArrayFc(align, len); + const auto hasRole = !roles.empty(); + + if (byteOrder == ByteOrder::Big) { + if (isStd) { + if (isRev) { + switch (*len) { + case 8: + return hasRole ? FcDeepType::FixedLenUIntBa8RevWithRole : + FcDeepType::FixedLenUIntBa8Rev; + case 16: + return hasRole ? FcDeepType::FixedLenUIntBa16BeRevWithRole : + FcDeepType::FixedLenUIntBa16BeRev; + case 32: + return hasRole ? FcDeepType::FixedLenUIntBa32BeRevWithRole : + FcDeepType::FixedLenUIntBa32BeRev; + case 64: + return hasRole ? FcDeepType::FixedLenUIntBa64BeRevWithRole : + FcDeepType::FixedLenUIntBa64BeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 8: + return hasRole ? FcDeepType::FixedLenUIntBa8WithRole : + FcDeepType::FixedLenUIntBa8; + case 16: + return hasRole ? FcDeepType::FixedLenUIntBa16BeWithRole : + FcDeepType::FixedLenUIntBa16Be; + case 32: + return hasRole ? FcDeepType::FixedLenUIntBa32BeWithRole : + FcDeepType::FixedLenUIntBa32Be; + case 64: + return hasRole ? FcDeepType::FixedLenUIntBa64BeWithRole : + FcDeepType::FixedLenUIntBa64Be; + default: + bt_common_abort(); + } + } + } else { + if (isRev) { + return hasRole ? FcDeepType::FixedLenUIntBeRevWithRole : + FcDeepType::FixedLenUIntBeRev; + } else { + return hasRole ? FcDeepType::FixedLenUIntBeWithRole : + FcDeepType::FixedLenUIntBe; + } + } + } else { + /* Little-endian */ + if (isStd) { + if (isRev) { + switch (*len) { + case 8: + return hasRole ? FcDeepType::FixedLenUIntBa8RevWithRole : + FcDeepType::FixedLenUIntBa8Rev; + case 16: + return hasRole ? FcDeepType::FixedLenUIntBa16LeRevWithRole : + FcDeepType::FixedLenUIntBa16LeRev; + case 32: + return hasRole ? FcDeepType::FixedLenUIntBa32LeRevWithRole : + FcDeepType::FixedLenUIntBa32LeRev; + case 64: + return hasRole ? FcDeepType::FixedLenUIntBa64LeRevWithRole : + FcDeepType::FixedLenUIntBa64LeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 8: + return hasRole ? FcDeepType::FixedLenUIntBa8WithRole : + FcDeepType::FixedLenUIntBa8; + case 16: + return hasRole ? FcDeepType::FixedLenUIntBa16LeWithRole : + FcDeepType::FixedLenUIntBa16Le; + case 32: + return hasRole ? FcDeepType::FixedLenUIntBa32LeWithRole : + FcDeepType::FixedLenUIntBa32Le; + case 64: + return hasRole ? FcDeepType::FixedLenUIntBa64LeWithRole : + FcDeepType::FixedLenUIntBa64Le; + default: + bt_common_abort(); + } + } + } else { + if (isRev) { + return hasRole ? FcDeepType::FixedLenUIntLeRevWithRole : + FcDeepType::FixedLenUIntLeRev; + } else { + return hasRole ? FcDeepType::FixedLenUIntLeWithRole : + FcDeepType::FixedLenUIntLe; + } + } + } + }); + + return bt2s::make_unique( + internal::CtfIrMixins::Fc {deepType, loc}, internal::CtfIrMixins::FixedLenBitArrayFc {}, + internal::CtfIrMixins::FixedLenIntFc {}, internal::CtfIrMixins::FixedLenUIntFc {}, align, + len, byteOrder, bitOrder, prefDispBase, std::move(mappings), std::move(roles), + std::move(attrs)); +} + +std::unique_ptr +createFixedLenSIntFc(const bt2c::TextLoc& loc, const unsigned int align, const bt2c::DataLen len, + const ByteOrder byteOrder, const bt2s::optional& bitOrder, + const DispBase prefDispBase, FixedLenSIntFc::Mappings mappings, OptAttrs attrs) +{ + const auto deepType = bt2c::call([align, len, byteOrder, &bitOrder] { + const auto isRev = FixedLenBitArrayFc::isRev(byteOrder, bitOrder); + const auto isStd = isStdBitArrayFc(align, len); + + if (byteOrder == ByteOrder::Big) { + if (isStd) { + if (isRev) { + switch (*len) { + case 8: + return FcDeepType::FixedLenSIntBa8Rev; + case 16: + return FcDeepType::FixedLenSIntBa16BeRev; + case 32: + return FcDeepType::FixedLenSIntBa32BeRev; + case 64: + return FcDeepType::FixedLenSIntBa64BeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 8: + return FcDeepType::FixedLenSIntBa8; + case 16: + return FcDeepType::FixedLenSIntBa16Be; + case 32: + return FcDeepType::FixedLenSIntBa32Be; + case 64: + return FcDeepType::FixedLenSIntBa64Be; + default: + bt_common_abort(); + } + } + } else { + if (isRev) { + return FcDeepType::FixedLenSIntBeRev; + } else { + return FcDeepType::FixedLenSIntBe; + } + } + } else { + /* Little-endian */ + if (isStd) { + if (isRev) { + switch (*len) { + case 8: + return FcDeepType::FixedLenSIntBa8Rev; + case 16: + return FcDeepType::FixedLenSIntBa16LeRev; + case 32: + return FcDeepType::FixedLenSIntBa32LeRev; + case 64: + return FcDeepType::FixedLenSIntBa64LeRev; + default: + bt_common_abort(); + } + } else { + switch (*len) { + case 8: + return FcDeepType::FixedLenSIntBa8; + case 16: + return FcDeepType::FixedLenSIntBa16Le; + case 32: + return FcDeepType::FixedLenSIntBa32Le; + case 64: + return FcDeepType::FixedLenSIntBa64Le; + default: + bt_common_abort(); + } + } + } else { + if (isRev) { + return FcDeepType::FixedLenSIntLeRev; + } else { + return FcDeepType::FixedLenSIntLe; + } + } + } + }); + + return bt2s::make_unique( + internal::CtfIrMixins::Fc {deepType, loc}, internal::CtfIrMixins::FixedLenBitArrayFc {}, + internal::CtfIrMixins::FixedLenIntFc {}, align, len, byteOrder, bitOrder, prefDispBase, + std::move(mappings), std::move(attrs)); +} + +std::unique_ptr createVarLenUIntFc(const bt2c::TextLoc& loc, + const DispBase prefDispBase, + VarLenUIntFc::Mappings mappings, + UIntFieldRoles roles, OptAttrs attrs) +{ + const auto deepType = roles.empty() ? FcDeepType::VarLenUInt : FcDeepType::VarLenUIntWithRole; + + return bt2s::make_unique(internal::CtfIrMixins::Fc {deepType, loc}, + internal::CtfIrMixins::VarLenIntFc {}, + internal::CtfIrMixins::VarLenUIntFc {}, prefDispBase, + std::move(mappings), std::move(roles), std::move(attrs)); +} + +std::unique_ptr createVarLenSIntFc(const bt2c::TextLoc& loc, + const DispBase prefDispBase, + VarLenSIntFc::Mappings mappings, OptAttrs attrs) +{ + return bt2s::make_unique(internal::CtfIrMixins::Fc {FcDeepType::VarLenSInt, loc}, + internal::CtfIrMixins::VarLenIntFc {}, prefDispBase, + std::move(mappings), std::move(attrs)); +} + +std::unique_ptr +createNullTerminatedStrFc(const bt2c::TextLoc& loc, const StrEncoding encoding, OptAttrs attrs) +{ + const auto deepType = bt2c::call([encoding] { + switch (encoding) { + case StrEncoding::Utf8: + return FcDeepType::NullTerminatedStrUtf8; + case StrEncoding::Utf16Be: + case StrEncoding::Utf16Le: + return FcDeepType::NullTerminatedStrUtf16; + case StrEncoding::Utf32Be: + case StrEncoding::Utf32Le: + return FcDeepType::NullTerminatedStrUtf32; + default: + bt_common_abort(); + } + }); + + return bt2s::make_unique(internal::CtfIrMixins::Fc {deepType, loc}, + encoding, std::move(attrs)); +} + +std::unique_ptr createStaticLenStrFc(const bt2c::TextLoc& loc, + const std::size_t len, + const StrEncoding encoding, OptAttrs attrs) +{ + return bt2s::make_unique( + internal::CtfIrMixins::Fc {FcDeepType::StaticLenStr, loc}, + internal::CtfIrMixins::StaticLenStrFc {}, len, encoding, std::move(attrs)); +} + +std::unique_ptr createDynLenStrFc(const bt2c::TextLoc& loc, FieldLoc lenFieldLoc, + const StrEncoding encoding, OptAttrs attrs) +{ + return bt2s::make_unique(internal::CtfIrMixins::Fc {FcDeepType::DynLenStr, loc}, + internal::CtfIrMixins::DynLenStrFc {}, + std::move(lenFieldLoc), encoding, std::move(attrs)); +} + +std::unique_ptr createStaticLenBlobFc(const bt2c::TextLoc& loc, + const std::size_t len, std::string mediaType, + const bool hasMetadataStreamUuidRole, + OptAttrs attrs) +{ + const auto deepType = hasMetadataStreamUuidRole ? + FcDeepType::StaticLenBlobWithMetadataStreamUuidRole : + FcDeepType::StaticLenBlob; + + return bt2s::make_unique( + internal::CtfIrMixins::Fc {deepType, loc}, internal::CtfIrMixins::StaticLenBlobFc {}, len, + std::move(mediaType), hasMetadataStreamUuidRole, std::move(attrs)); +} + +std::unique_ptr createDynLenBlobFc(const bt2c::TextLoc& loc, FieldLoc lenFieldLoc, + std::string mediaType, OptAttrs attrs) +{ + return bt2s::make_unique(internal::CtfIrMixins::Fc {FcDeepType::DynLenBlob, loc}, + internal::CtfIrMixins::DynLenBlobFc {}, + std::move(lenFieldLoc), std::move(mediaType), + std::move(attrs)); +} + +std::unique_ptr createStaticLenArrayFc(const bt2c::TextLoc& loc, + const std::size_t len, Fc::UP elemFc, + const unsigned int minAlign, + const bool hasMetadataStreamUuidRole, + OptAttrs attrs) +{ + const auto deepType = hasMetadataStreamUuidRole ? + FcDeepType::StaticLenArrayWithMetadataStreamUuidRole : + FcDeepType::StaticLenArray; + + return bt2s::make_unique(internal::CtfIrMixins::Fc {deepType, loc}, + internal::CtfIrMixins::StaticLenArrayFc {}, len, + std::move(elemFc), minAlign, std::move(attrs)); +} + +std::unique_ptr createDynLenArrayFc(const bt2c::TextLoc& loc, FieldLoc lenFieldLoc, + Fc::UP elemFc, const unsigned int minAlign, + OptAttrs attrs) +{ + return bt2s::make_unique( + internal::CtfIrMixins::Fc {FcDeepType::DynLenArray, loc}, + internal::CtfIrMixins::DynLenArrayFc {}, std::move(lenFieldLoc), std::move(elemFc), + minAlign, std::move(attrs)); +} + +StructFieldMemberCls createStructFieldMemberCls(std::string name, Fc::UP fc, OptAttrs attrs) +{ + return StructFieldMemberCls {internal::CtfIrMixins::StructFieldMemberCls {}, std::move(name), + std::move(fc), std::move(attrs)}; +} + +std::unique_ptr createStructFc(const bt2c::TextLoc& loc, + StructFc::MemberClasses&& memberClasses, + const unsigned int minAlign, OptAttrs attrs) +{ + return bt2s::make_unique(internal::CtfIrMixins::Fc {FcDeepType::Struct, loc}, + internal::CtfIrMixins::StructFc {}, std::move(memberClasses), + minAlign, std::move(attrs)); +} + +std::unique_ptr createOptionalFc(const bt2c::TextLoc& loc, Fc::UP fc, + FieldLoc selFieldLoc, OptAttrs attrs) +{ + return bt2s::make_unique( + internal::CtfIrMixins::Fc {FcDeepType::OptionalWithBoolSel, loc}, + internal::CtfIrMixins::OptionalFc {}, internal::CtfIrMixins::OptionalWithBoolSelFc {}, + std::move(fc), std::move(selFieldLoc), std::move(attrs)); +} + +std::unique_ptr createOptionalFc(const bt2c::TextLoc& loc, Fc::UP fc, + FieldLoc selFieldLoc, + UIntRangeSet selFieldRanges, OptAttrs attrs) +{ + return bt2s::make_unique( + internal::CtfIrMixins::Fc {FcDeepType::OptionalWithUIntSel, loc}, + internal::CtfIrMixins::OptionalFc {}, internal::CtfIrMixins::OptionalWithIntSelFc {}, + internal::CtfIrMixins::OptionalWithUIntSelFc {}, std::move(fc), std::move(selFieldLoc), + std::move(selFieldRanges), std::move(attrs)); +} + +std::unique_ptr createOptionalFc(const bt2c::TextLoc& loc, Fc::UP fc, + FieldLoc selFieldLoc, + SIntRangeSet selFieldRanges, OptAttrs attrs) +{ + return bt2s::make_unique( + internal::CtfIrMixins::Fc {FcDeepType::OptionalWithSIntSel, loc}, + internal::CtfIrMixins::OptionalFc {}, internal::CtfIrMixins::OptionalWithIntSelFc {}, + internal::CtfIrMixins::OptionalWithSIntSelFc {}, std::move(fc), std::move(selFieldLoc), + std::move(selFieldRanges), std::move(attrs)); +} + +VariantWithUIntSelFc::Opt createVariantFcOpt(Fc::UP fc, UIntRangeSet selFieldRanges, + bt2s::optional name, OptAttrs attrs) +{ + return VariantWithUIntSelFc::Opt {internal::CtfIrMixins::VariantFcOpt {}, std::move(fc), + std::move(selFieldRanges), std::move(name), std::move(attrs)}; +} + +VariantWithSIntSelFc::Opt createVariantFcOpt(Fc::UP fc, SIntRangeSet selFieldRanges, + bt2s::optional name, OptAttrs attrs) +{ + return VariantWithSIntSelFc::Opt {internal::CtfIrMixins::VariantFcOpt {}, std::move(fc), + std::move(selFieldRanges), std::move(name), std::move(attrs)}; +} + +std::unique_ptr createVariantFc(const bt2c::TextLoc& loc, + VariantWithUIntSelFc::Opts&& opts, + FieldLoc selFieldLoc, OptAttrs attrs) +{ + return bt2s::make_unique( + internal::CtfIrMixins::Fc {FcDeepType::VariantWithUIntSel, loc}, + internal::CtfIrMixins::VariantFc {}, internal::CtfIrMixins::VariantWithUIntSelFc {}, + std::move(opts), std::move(selFieldLoc), std::move(attrs)); +} + +std::unique_ptr createVariantFc(const bt2c::TextLoc& loc, + VariantWithSIntSelFc::Opts&& opts, + FieldLoc selFieldLoc, OptAttrs attrs) +{ + return bt2s::make_unique( + internal::CtfIrMixins::Fc {FcDeepType::VariantWithSIntSel, loc}, + internal::CtfIrMixins::VariantFc {}, internal::CtfIrMixins::VariantWithSIntSelFc {}, + std::move(opts), std::move(selFieldLoc), std::move(attrs)); +} + +ClkCls::SP createClkCls(std::string id, const unsigned long long freq, + bt2s::optional ns, bt2s::optional name, + bt2s::optional uid, const ClkOffset& offset, + bt2s::optional origin, bt2s::optional descr, + bt2s::optional precision, + bt2s::optional accuracy, OptAttrs attrs) +{ + return std::make_shared(internal::CtfIrMixins::ClkCls {}, std::move(id), freq, + std::move(ns), std::move(name), std::move(uid), offset, + std::move(origin), std::move(descr), std::move(precision), + std::move(accuracy), std::move(attrs)); +} + +std::unique_ptr +createEventRecordCls(const unsigned long long id, bt2s::optional ns, + bt2s::optional name, bt2s::optional uid, + Fc::UP specCtxFc, Fc::UP payloadFc, OptAttrs attrs) +{ + return bt2s::make_unique( + internal::CtfIrMixins::EventRecordCls {}, id, std::move(ns), std::move(name), + std::move(uid), std::move(specCtxFc), std::move(payloadFc), std::move(attrs)); +} + +std::unique_ptr +createDataStreamCls(const unsigned long long id, bt2s::optional ns, + bt2s::optional name, bt2s::optional uid, + Fc::UP pktCtxFc, Fc::UP eventRecordHeaderFc, Fc::UP commonEventRecordCtxFc, + ClkCls::SP defClkCls, OptAttrs attrs) +{ + return bt2s::make_unique( + internal::CtfIrMixins::DataStreamCls {}, id, std::move(ns), std::move(name), std::move(uid), + std::move(pktCtxFc), std::move(eventRecordHeaderFc), std::move(commonEventRecordCtxFc), + std::move(defClkCls), std::move(attrs)); +} + +std::unique_ptr createTraceCls(bt2s::optional ns, + bt2s::optional name, + bt2s::optional uid, + bt2::ConstMapValue::Shared env, Fc::UP pktHeaderFc, + OptAttrs attrs) +{ + return bt2s::make_unique(internal::CtfIrMixins::TraceCls {}, std::move(ns), + std::move(name), std::move(uid), std::move(env), + std::move(pktHeaderFc), std::move(attrs)); +} + +} /* namespace src */ +} /* namespace ctf */ diff --git a/src/plugins/ctf/common/src/metadata/ctf-ir.hpp b/src/plugins/ctf/common/src/metadata/ctf-ir.hpp new file mode 100644 index 00000000..c202fa96 --- /dev/null +++ b/src/plugins/ctf/common/src/metadata/ctf-ir.hpp @@ -0,0 +1,1320 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright 2022-2024 Philippe Proulx + */ + +#ifndef BABELTRACE_PLUGINS_CTF_COMMON_SRC_METADATA_CTF_IR_HPP +#define BABELTRACE_PLUGINS_CTF_COMMON_SRC_METADATA_CTF_IR_HPP + +#include +#include +#include + +#include "cpp-common/bt2/trace-ir.hpp" +#include "cpp-common/bt2c/observable.hpp" +#include "cpp-common/bt2c/text-loc.hpp" +#include "cpp-common/vendor/wise-enum/wise_enum.h" + +#include "../../metadata/ctf-ir.hpp" + +namespace ctf { +namespace src { + +/* + * This is the CTF IR API specific to source component classes. + * + * This API defines a few internal user mixins for our needs to reuse + * the common `ctf::ir` API. + * + * In general, if a C++ class C has a libCls() method, then if libCls() + * returns a value for a given instance X, then consider that all the + * dependent field classes of X have a saved key value index (more about + * this below). + */ + +/* clang-format off */ + +/* + * The deep type of a field class is a superset of `ctf::ir::FcType` + * which contains additional, static information about the field class. + * + * For fixed-length and variable-length field classes, this deep type + * incorporates important decoding information, for example: + * + * • Byte order. + * + * • Whether or not the bit order is reversed (unnatural). + * + * • Whether or not it's a "standard" fixed-length bit array. + * + * • Length, if it's a "standard" fixed-length bit array. + * + * • Integer signedness. + * + * • Whether or not the field has a role. + * + * • Whether or not the value of the field has to be saved as a + * key value. + * + * The purpose of the deep type of a field class is to have a single + * `switch` statement in the field reading method of some data stream + * decoder to select its next state and make it easier/possible for the + * compiler to optimize as most common decisions are encoded in there. + * + * For example, if it's known that the next field to read is a + * little-endian, byte-aligned 32-bit unsigned integer field of which + * the data stream decoder needs to save the value, then its deep type + * is `FcDeepType::FixedLenUIntBa32LeSaveVal`, which means the decoder + * will jump to a specific, corresponding reading method directly. The + * latter method can do exactly what's needed to perform such a field + * reading operation efficiently (using bt2c::readFixedLenIntLe()) and + * save its value unconditionally. + * + * The enumerator names below use the following common parts: + * + * `Be`: + * Big-endian. + * + * `Le`: + * Little-endian. + * + * `Rev`: + * Reversed (unnatural) bit order. + * + * `Ba`: + * Byte-aligned (alignment of at least 8 bits). + * + * `8`, `16`, `32`, `64`: + * Fixed 8-bit, 16-bit, 32-bit, or 64-bit length. + * + * `SaveVal`: + * Save the value of the boolean/integer key field. + * + * `WithRole`: + * Unsigned integer field with at least one role. + * + * `WithMetadataStreamUuidRole`: + * Static-length array/BLOB field with the "metadata stream + * UUID" role. + * + * `Utf*`: + * String field with a specific UTF string encoding. + */ +WISE_ENUM_CLASS(FcDeepType, + /* Fixed-length bit array */ + FixedLenBitArrayBa8, + FixedLenBitArrayBe, + FixedLenBitArrayBa16Be, + FixedLenBitArrayBa32Be, + FixedLenBitArrayBa64Be, + FixedLenBitArrayLe, + FixedLenBitArrayBa16Le, + FixedLenBitArrayBa32Le, + FixedLenBitArrayBa64Le, + FixedLenBitArrayBa8Rev, + FixedLenBitArrayBeRev, + FixedLenBitArrayBa16BeRev, + FixedLenBitArrayBa32BeRev, + FixedLenBitArrayBa64BeRev, + FixedLenBitArrayLeRev, + FixedLenBitArrayBa16LeRev, + FixedLenBitArrayBa32LeRev, + FixedLenBitArrayBa64LeRev, + + /* Fixed-length bit map */ + FixedLenBitMapBa8, + FixedLenBitMapBe, + FixedLenBitMapBa16Be, + FixedLenBitMapBa32Be, + FixedLenBitMapBa64Be, + FixedLenBitMapLe, + FixedLenBitMapBa16Le, + FixedLenBitMapBa32Le, + FixedLenBitMapBa64Le, + FixedLenBitMapBa8Rev, + FixedLenBitMapBeRev, + FixedLenBitMapBa16BeRev, + FixedLenBitMapBa32BeRev, + FixedLenBitMapBa64BeRev, + FixedLenBitMapLeRev, + FixedLenBitMapBa16LeRev, + FixedLenBitMapBa32LeRev, + FixedLenBitMapBa64LeRev, + + /* Fixed-length boolean */ + FixedLenBoolBa8, + FixedLenBoolBa8SaveVal, + FixedLenBoolBe, + FixedLenBoolBeSaveVal, + FixedLenBoolBa16Be, + FixedLenBoolBa16BeSaveVal, + FixedLenBoolBa32Be, + FixedLenBoolBa32BeSaveVal, + FixedLenBoolBa64Be, + FixedLenBoolBa64BeSaveVal, + FixedLenBoolLe, + FixedLenBoolLeSaveVal, + FixedLenBoolBa16Le, + FixedLenBoolBa16LeSaveVal, + FixedLenBoolBa32Le, + FixedLenBoolBa32LeSaveVal, + FixedLenBoolBa64Le, + FixedLenBoolBa64LeSaveVal, + FixedLenBoolBa8Rev, + FixedLenBoolBa8RevSaveVal, + FixedLenBoolBeRev, + FixedLenBoolBeRevSaveVal, + FixedLenBoolBa16BeRev, + FixedLenBoolBa16BeRevSaveVal, + FixedLenBoolBa32BeRev, + FixedLenBoolBa32BeRevSaveVal, + FixedLenBoolBa64BeRev, + FixedLenBoolBa64BeRevSaveVal, + FixedLenBoolLeRev, + FixedLenBoolLeRevSaveVal, + FixedLenBoolBa16LeRev, + FixedLenBoolBa16LeRevSaveVal, + FixedLenBoolBa32LeRev, + FixedLenBoolBa32LeRevSaveVal, + FixedLenBoolBa64LeRev, + FixedLenBoolBa64LeRevSaveVal, + + /* Fixed-length floating-point number */ + FixedLenFloat32Be, + FixedLenFloatBa32Be, + FixedLenFloat64Be, + FixedLenFloatBa64Be, + FixedLenFloat32Le, + FixedLenFloatBa32Le, + FixedLenFloat64Le, + FixedLenFloatBa64Le, + FixedLenFloat32BeRev, + FixedLenFloatBa32BeRev, + FixedLenFloat64BeRev, + FixedLenFloatBa64BeRev, + FixedLenFloat32LeRev, + FixedLenFloatBa32LeRev, + FixedLenFloat64LeRev, + FixedLenFloatBa64LeRev, + + /* Fixed-length unsigned integer */ + FixedLenUIntBa8, + FixedLenUIntBa8SaveVal, + FixedLenUIntBa8WithRole, + FixedLenUIntBa8WithRoleSaveVal, + FixedLenUIntBe, + FixedLenUIntBeSaveVal, + FixedLenUIntBeWithRole, + FixedLenUIntBeWithRoleSaveVal, + FixedLenUIntBa16Be, + FixedLenUIntBa16BeSaveVal, + FixedLenUIntBa16BeWithRole, + FixedLenUIntBa16BeWithRoleSaveVal, + FixedLenUIntBa32Be, + FixedLenUIntBa32BeSaveVal, + FixedLenUIntBa32BeWithRole, + FixedLenUIntBa32BeWithRoleSaveVal, + FixedLenUIntBa64Be, + FixedLenUIntBa64BeSaveVal, + FixedLenUIntBa64BeWithRole, + FixedLenUIntBa64BeWithRoleSaveVal, + FixedLenUIntLe, + FixedLenUIntLeSaveVal, + FixedLenUIntLeWithRole, + FixedLenUIntLeWithRoleSaveVal, + FixedLenUIntBa16Le, + FixedLenUIntBa16LeSaveVal, + FixedLenUIntBa16LeWithRole, + FixedLenUIntBa16LeWithRoleSaveVal, + FixedLenUIntBa32Le, + FixedLenUIntBa32LeSaveVal, + FixedLenUIntBa32LeWithRole, + FixedLenUIntBa32LeWithRoleSaveVal, + FixedLenUIntBa64Le, + FixedLenUIntBa64LeSaveVal, + FixedLenUIntBa64LeWithRole, + FixedLenUIntBa64LeWithRoleSaveVal, + FixedLenUIntBa8Rev, + FixedLenUIntBa8RevSaveVal, + FixedLenUIntBa8RevWithRole, + FixedLenUIntBa8RevWithRoleSaveVal, + FixedLenUIntBeRev, + FixedLenUIntBeRevSaveVal, + FixedLenUIntBeRevWithRole, + FixedLenUIntBeRevWithRoleSaveVal, + FixedLenUIntBa16BeRev, + FixedLenUIntBa16BeRevSaveVal, + FixedLenUIntBa16BeRevWithRole, + FixedLenUIntBa16BeRevWithRoleSaveVal, + FixedLenUIntBa32BeRev, + FixedLenUIntBa32BeRevSaveVal, + FixedLenUIntBa32BeRevWithRole, + FixedLenUIntBa32BeRevWithRoleSaveVal, + FixedLenUIntBa64BeRev, + FixedLenUIntBa64BeRevSaveVal, + FixedLenUIntBa64BeRevWithRole, + FixedLenUIntBa64BeRevWithRoleSaveVal, + FixedLenUIntLeRev, + FixedLenUIntLeRevSaveVal, + FixedLenUIntLeRevWithRole, + FixedLenUIntLeRevWithRoleSaveVal, + FixedLenUIntBa16LeRev, + FixedLenUIntBa16LeRevSaveVal, + FixedLenUIntBa16LeRevWithRole, + FixedLenUIntBa16LeRevWithRoleSaveVal, + FixedLenUIntBa32LeRev, + FixedLenUIntBa32LeRevSaveVal, + FixedLenUIntBa32LeRevWithRole, + FixedLenUIntBa32LeRevWithRoleSaveVal, + FixedLenUIntBa64LeRev, + FixedLenUIntBa64LeRevSaveVal, + FixedLenUIntBa64LeRevWithRole, + FixedLenUIntBa64LeRevWithRoleSaveVal, + + /* Fixed-length signed integer */ + FixedLenSIntBa8, + FixedLenSIntBa8SaveVal, + FixedLenSIntBe, + FixedLenSIntBeSaveVal, + FixedLenSIntBa16Be, + FixedLenSIntBa16BeSaveVal, + FixedLenSIntBa32Be, + FixedLenSIntBa32BeSaveVal, + FixedLenSIntBa64Be, + FixedLenSIntBa64BeSaveVal, + FixedLenSIntLe, + FixedLenSIntLeSaveVal, + FixedLenSIntBa16Le, + FixedLenSIntBa16LeSaveVal, + FixedLenSIntBa32Le, + FixedLenSIntBa32LeSaveVal, + FixedLenSIntBa64Le, + FixedLenSIntBa64LeSaveVal, + FixedLenSIntBa8Rev, + FixedLenSIntBa8RevSaveVal, + FixedLenSIntBeRev, + FixedLenSIntBeRevSaveVal, + FixedLenSIntBa16BeRev, + FixedLenSIntBa16BeRevSaveVal, + FixedLenSIntBa32BeRev, + FixedLenSIntBa32BeRevSaveVal, + FixedLenSIntBa64BeRev, + FixedLenSIntBa64BeRevSaveVal, + FixedLenSIntLeRev, + FixedLenSIntLeRevSaveVal, + FixedLenSIntBa16LeRev, + FixedLenSIntBa16LeRevSaveVal, + FixedLenSIntBa32LeRev, + FixedLenSIntBa32LeRevSaveVal, + FixedLenSIntBa64LeRev, + FixedLenSIntBa64LeRevSaveVal, + + /* Variable-length unsigned integer */ + VarLenUInt, + VarLenUIntSaveVal, + VarLenUIntWithRole, + VarLenUIntWithRoleSaveVal, + + /* Variable-length signed integer */ + VarLenSInt, + VarLenSIntSaveVal, + + /* String */ + NullTerminatedStrUtf8, + NullTerminatedStrUtf16, + NullTerminatedStrUtf32, + StaticLenStr, + DynLenStr, + + /* BLOB */ + StaticLenBlob, + StaticLenBlobWithMetadataStreamUuidRole, + DynLenBlob, + + /* Array */ + StaticLenArray, + StaticLenArrayWithMetadataStreamUuidRole, + DynLenArray, + + /* Structure */ + Struct, + + /* Optional */ + OptionalWithBoolSel, + OptionalWithUIntSel, + OptionalWithSIntSel, + + /* Variant */ + VariantWithUIntSel, + VariantWithSIntSel +) + +/* clang-format on */ + +/* + * Vector of key value saving indexes. + * + * The strategy to decode dynamic-length, optional, and variant fields + * (called _dependend_ fields) is for the data stream decoder to save + * the values of _key_ fields (boolean or integer fields) so that it can + * use them afterwards to decode dependent fields. + * + * A field class FC of which the deep type contains `SaveVal` contains + * key value saving indexes IX (keyValSavingIndexes() method). + * keyValSavingIndexes() possibly returns more than one index because + * many dependent fields may depend on the same key field. + * + * When decoding an instance of FC (a key field), the decoder saves its + * value to some vector V at the indexes IX. When decoding a dependent + * field, its class contains an index to retrieve a saved key value (its + * length or selector) from V. + */ +using KeyValSavingIndexes = std::vector; + +namespace internal { + +struct CtfIrMixins; + +} /* namespace internal */ + +/* + * Set of field class pointers. + */ +using FcSet = std::set *>; + +namespace internal { + +/* + * Field location user mixin. + */ +class FieldLocMixin +{ +public: + explicit FieldLocMixin(const bt2c::TextLoc& loc) noexcept; + + /* + * Text location of this field location within the metadata stream. + */ + const bt2c::TextLoc& loc() const noexcept + { + return _mLoc; + } + +private: + /* Text location of this field location within the metadata stream */ + bt2c::TextLoc _mLoc; +}; + +/* + * Clock class user mixin. + */ +class ClkClsMixin +{ +public: + explicit ClkClsMixin() noexcept = default; + + /* + * Sets the equivalent libbabeltrace2 class to `cls` (shared). + */ + void sharedLibCls(bt2::ClockClass::Shared cls) noexcept; + +private: + /* Equivalent libbabeltrace2 class (shared) */ + bt2::ClockClass::Shared _mSharedLibCls; +}; + +template +class KeyFcMixin; + +/* + * Field class user mixin. + */ +class FcMixin +{ + template + friend class KeyFcMixin; + +public: + explicit FcMixin(const bt2c::TextLoc& loc = bt2c::TextLoc {}) noexcept; + + explicit FcMixin(FcDeepType deepType, const bt2c::TextLoc& loc = bt2c::TextLoc {}) noexcept; + + /* + * Text location of this field class within the metadata stream. + */ + const bt2c::TextLoc& loc() const noexcept + { + return _mLoc; + } + + /* + * Deep type of this field class. + */ + FcDeepType deepType() const noexcept + { + return _mDeepType; + } + +private: + /* Deep type of this field class */ + FcDeepType _mDeepType; + + /* Text location of this field class within the metadata stream */ + bt2c::TextLoc _mLoc; +}; + +/* + * Internal mixin for a key field class `FcT`. + * + * See the comment of `ValSavingIndexes` to learn more. + */ +template +class KeyFcMixin +{ +public: + explicit KeyFcMixin() noexcept {}; + + const KeyValSavingIndexes& keyValSavingIndexes() const noexcept + { + return _mKeyValSavingIndexes; + } + + void addKeyValSavingIndex(const std::size_t index) + { + _mKeyValSavingIndexes.push_back(index); + + auto& deepType = static_cast(*this)._mDeepType; + + /* + * At this point we know that the data stream decoder needs to + * save the value of any instance of this field class (a + * key field). + * + * Adjust the deep type of the field class so as to include that + * it's a key one. + */ + deepType = bt2c::call([deepType] { + switch (deepType) { + case FcDeepType::FixedLenBoolBa8: + return FcDeepType::FixedLenBoolBa8SaveVal; + case FcDeepType::FixedLenBoolBe: + return FcDeepType::FixedLenBoolBeSaveVal; + case FcDeepType::FixedLenBoolBa16Be: + return FcDeepType::FixedLenBoolBa16BeSaveVal; + case FcDeepType::FixedLenBoolBa32Be: + return FcDeepType::FixedLenBoolBa32BeSaveVal; + case FcDeepType::FixedLenBoolBa64Be: + return FcDeepType::FixedLenBoolBa64BeSaveVal; + case FcDeepType::FixedLenBoolLe: + return FcDeepType::FixedLenBoolLeSaveVal; + case FcDeepType::FixedLenBoolBa16Le: + return FcDeepType::FixedLenBoolBa16LeSaveVal; + case FcDeepType::FixedLenBoolBa32Le: + return FcDeepType::FixedLenBoolBa32LeSaveVal; + case FcDeepType::FixedLenBoolBa64Le: + return FcDeepType::FixedLenBoolBa64LeSaveVal; + case FcDeepType::FixedLenBoolBa8Rev: + return FcDeepType::FixedLenBoolBa8RevSaveVal; + case FcDeepType::FixedLenBoolBeRev: + return FcDeepType::FixedLenBoolBeRevSaveVal; + case FcDeepType::FixedLenBoolBa16BeRev: + return FcDeepType::FixedLenBoolBa16BeRevSaveVal; + case FcDeepType::FixedLenBoolBa32BeRev: + return FcDeepType::FixedLenBoolBa32BeRevSaveVal; + case FcDeepType::FixedLenBoolBa64BeRev: + return FcDeepType::FixedLenBoolBa64BeRevSaveVal; + case FcDeepType::FixedLenBoolLeRev: + return FcDeepType::FixedLenBoolLeRevSaveVal; + case FcDeepType::FixedLenBoolBa16LeRev: + return FcDeepType::FixedLenBoolBa16LeRevSaveVal; + case FcDeepType::FixedLenBoolBa32LeRev: + return FcDeepType::FixedLenBoolBa32LeRevSaveVal; + case FcDeepType::FixedLenBoolBa64LeRev: + return FcDeepType::FixedLenBoolBa64LeRevSaveVal; + case FcDeepType::FixedLenUIntBa8: + return FcDeepType::FixedLenUIntBa8SaveVal; + case FcDeepType::FixedLenUIntBa8WithRole: + return FcDeepType::FixedLenUIntBa8WithRoleSaveVal; + case FcDeepType::FixedLenUIntBe: + return FcDeepType::FixedLenUIntBeSaveVal; + case FcDeepType::FixedLenUIntBeWithRole: + return FcDeepType::FixedLenUIntBeWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa16Be: + return FcDeepType::FixedLenUIntBa16BeSaveVal; + case FcDeepType::FixedLenUIntBa16BeWithRole: + return FcDeepType::FixedLenUIntBa16BeWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa32Be: + return FcDeepType::FixedLenUIntBa32BeSaveVal; + case FcDeepType::FixedLenUIntBa32BeWithRole: + return FcDeepType::FixedLenUIntBa32BeWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa64Be: + return FcDeepType::FixedLenUIntBa64BeSaveVal; + case FcDeepType::FixedLenUIntBa64BeWithRole: + return FcDeepType::FixedLenUIntBa64BeWithRoleSaveVal; + case FcDeepType::FixedLenUIntLe: + return FcDeepType::FixedLenUIntLeSaveVal; + case FcDeepType::FixedLenUIntLeWithRole: + return FcDeepType::FixedLenUIntLeWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa16Le: + return FcDeepType::FixedLenUIntBa16LeSaveVal; + case FcDeepType::FixedLenUIntBa16LeWithRole: + return FcDeepType::FixedLenUIntBa16LeWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa32Le: + return FcDeepType::FixedLenUIntBa32LeSaveVal; + case FcDeepType::FixedLenUIntBa32LeWithRole: + return FcDeepType::FixedLenUIntBa32LeWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa64Le: + return FcDeepType::FixedLenUIntBa64LeSaveVal; + case FcDeepType::FixedLenUIntBa64LeWithRole: + return FcDeepType::FixedLenUIntBa64LeWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa8Rev: + return FcDeepType::FixedLenUIntBa8RevSaveVal; + case FcDeepType::FixedLenUIntBa8RevWithRole: + return FcDeepType::FixedLenUIntBa8RevWithRoleSaveVal; + case FcDeepType::FixedLenUIntBeRev: + return FcDeepType::FixedLenUIntBeRevSaveVal; + case FcDeepType::FixedLenUIntBeRevWithRole: + return FcDeepType::FixedLenUIntBeRevWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa16BeRev: + return FcDeepType::FixedLenUIntBa16BeRevSaveVal; + case FcDeepType::FixedLenUIntBa16BeRevWithRole: + return FcDeepType::FixedLenUIntBa16BeRevWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa32BeRev: + return FcDeepType::FixedLenUIntBa32BeRevSaveVal; + case FcDeepType::FixedLenUIntBa32BeRevWithRole: + return FcDeepType::FixedLenUIntBa32BeRevWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa64BeRev: + return FcDeepType::FixedLenUIntBa64BeRevSaveVal; + case FcDeepType::FixedLenUIntBa64BeRevWithRole: + return FcDeepType::FixedLenUIntBa64BeRevWithRoleSaveVal; + case FcDeepType::FixedLenUIntLeRev: + return FcDeepType::FixedLenUIntLeRevSaveVal; + case FcDeepType::FixedLenUIntLeRevWithRole: + return FcDeepType::FixedLenUIntLeRevWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa16LeRev: + return FcDeepType::FixedLenUIntBa16LeRevSaveVal; + case FcDeepType::FixedLenUIntBa16LeRevWithRole: + return FcDeepType::FixedLenUIntBa16LeRevWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa32LeRev: + return FcDeepType::FixedLenUIntBa32LeRevSaveVal; + case FcDeepType::FixedLenUIntBa32LeRevWithRole: + return FcDeepType::FixedLenUIntBa32LeRevWithRoleSaveVal; + case FcDeepType::FixedLenUIntBa64LeRev: + return FcDeepType::FixedLenUIntBa64LeRevSaveVal; + case FcDeepType::FixedLenUIntBa64LeRevWithRole: + return FcDeepType::FixedLenUIntBa64LeRevWithRoleSaveVal; + case FcDeepType::FixedLenSIntBa8: + return FcDeepType::FixedLenSIntBa8SaveVal; + case FcDeepType::FixedLenSIntBe: + return FcDeepType::FixedLenSIntBeSaveVal; + case FcDeepType::FixedLenSIntBa16Be: + return FcDeepType::FixedLenSIntBa16BeSaveVal; + case FcDeepType::FixedLenSIntBa32Be: + return FcDeepType::FixedLenSIntBa32BeSaveVal; + case FcDeepType::FixedLenSIntBa64Be: + return FcDeepType::FixedLenSIntBa64BeSaveVal; + case FcDeepType::FixedLenSIntLe: + return FcDeepType::FixedLenSIntLeSaveVal; + case FcDeepType::FixedLenSIntBa16Le: + return FcDeepType::FixedLenSIntBa16LeSaveVal; + case FcDeepType::FixedLenSIntBa32Le: + return FcDeepType::FixedLenSIntBa32LeSaveVal; + case FcDeepType::FixedLenSIntBa64Le: + return FcDeepType::FixedLenSIntBa64LeSaveVal; + case FcDeepType::FixedLenSIntBa8Rev: + return FcDeepType::FixedLenSIntBa8RevSaveVal; + case FcDeepType::FixedLenSIntBeRev: + return FcDeepType::FixedLenSIntBeRevSaveVal; + case FcDeepType::FixedLenSIntBa16BeRev: + return FcDeepType::FixedLenSIntBa16BeRevSaveVal; + case FcDeepType::FixedLenSIntBa32BeRev: + return FcDeepType::FixedLenSIntBa32BeRevSaveVal; + case FcDeepType::FixedLenSIntBa64BeRev: + return FcDeepType::FixedLenSIntBa64BeRevSaveVal; + case FcDeepType::FixedLenSIntLeRev: + return FcDeepType::FixedLenSIntLeRevSaveVal; + case FcDeepType::FixedLenSIntBa16LeRev: + return FcDeepType::FixedLenSIntBa16LeRevSaveVal; + case FcDeepType::FixedLenSIntBa32LeRev: + return FcDeepType::FixedLenSIntBa32LeRevSaveVal; + case FcDeepType::FixedLenSIntBa64LeRev: + return FcDeepType::FixedLenSIntBa64LeRevSaveVal; + case FcDeepType::VarLenUInt: + return FcDeepType::VarLenUIntSaveVal; + case FcDeepType::VarLenUIntWithRole: + return FcDeepType::VarLenUIntWithRoleSaveVal; + case FcDeepType::VarLenSInt: + return FcDeepType::VarLenSIntSaveVal; + default: + return deepType; + } + }); + } + +private: + /* Value saving indexes */ + KeyValSavingIndexes _mKeyValSavingIndexes; +}; + +/* + * Internal mixin for a dependent (dynamic-length, optional, or variant) + * field class. + * + * See the comment of `ValSavingIndexes` to learn more. + */ +class DependentFcMixin +{ +public: + explicit DependentFcMixin() noexcept {}; + + /* + * Index of the saved key value of this field class. + */ + const bt2s::optional& savedKeyValIndex() const noexcept + { + return _mSavedKeyValIndex; + } + + /* + * Sets the index of the saved key value of this field class + * to `savedKeyValIndex`. + * + * ┌────────────────────────────────────────────────────────────┐ + * │ IMPORTANT: Only call this method if you can guarantee that │ + * │ you won't clone `*this` (through Fc::clone()). │ + * └────────────────────────────────────────────────────────────┘ + */ + void savedKeyValIndex(const std::size_t savedKeyValIndex) noexcept + { + _mSavedKeyValIndex = savedKeyValIndex; + } + + /* + * Key field classes of this field class. + */ + const FcSet& keyFcs() noexcept + { + return _mKeyFcs; + } + + /* + * Sets the key field classes of this field class to `keyFcs`. + * + * ┌────────────────────────────────────────────────────────────┐ + * │ IMPORTANT: Only call this method if you can guarantee that │ + * │ you won't clone `*this` (through Fc::clone()). │ + * └────────────────────────────────────────────────────────────┘ + */ + void keyFcs(FcSet keyFcs); + +private: + /* Index of the saved key value of this field class */ + bt2s::optional _mSavedKeyValIndex; + + /* Dependencies of this field class */ + FcSet _mKeyFcs; +}; + +/* + * Trace class user mixin. + */ +class TraceClsMixin +{ +public: + using SavedKeyValCountUpdatedObservable = bt2c::Observable; + +public: + explicit TraceClsMixin() noexcept {}; + + /* + * Sets the equivalent libbabeltrace2 class to `cls` (shared). + */ + void sharedLibCls(bt2::TraceClass::Shared cls) noexcept; + + /* + * Maximum number of saved key values for an instance of this + * trace class. + * + * See the comment of `ValSavingIndexes` to learn more. + */ + std::size_t savedKeyValCount() const noexcept + { + return _mSavedKeyValCount; + } + + /* + * Sets the maximum number of saved key values for an instance of + * this trace class to `savedKeyValCount`. + * + * See the comment of `ValSavingIndexes` to learn more. + */ + void savedKeyValCount(const std::size_t savedKeyValCount) noexcept + { + _mSavedKeyValCount = savedKeyValCount; + _mSavedKeyValCountUpdatedObservable.notify(_mSavedKeyValCount); + } + + /* + * Observable notified when the number of saved keys values required + * by this trace class changes. + */ + SavedKeyValCountUpdatedObservable& savedKeyValCountUpdatedObservable() const + { + return _mSavedKeyValCountUpdatedObservable; + } + +private: + /* Equivalent libbabeltrace2 class (shared) */ + bt2::TraceClass::Shared _mSharedLibCls; + + /* + * Maximum number of saved key values for an instance of this + * trace class. + * + * See the comment of `ValSavingIndexes` to learn more. + */ + std::size_t _mSavedKeyValCount = 0; + + /* + * Observable notified when the number of saved key values required + * by this trace class changes. + */ + mutable SavedKeyValCountUpdatedObservable _mSavedKeyValCountUpdatedObservable; +}; + +/* + * User mixin container. + */ +struct CtfIrMixins final : public ir::DefUserMixins +{ + using FieldLoc = FieldLocMixin; + using ClkCls = ClkClsMixin; + using Fc = FcMixin; + using FixedLenBoolFc = KeyFcMixin>; + using FixedLenIntFc = KeyFcMixin>; + using VarLenIntFc = KeyFcMixin>; + using DynLenStrFc = DependentFcMixin; + using DynLenBlobFc = DependentFcMixin; + using DynLenArrayFc = DependentFcMixin; + using VariantFc = DependentFcMixin; + using OptionalFc = DependentFcMixin; + using TraceCls = TraceClsMixin; +}; + +} /* namespace internal */ + +/* Aliases of the `ctf::src` CTF IR API */ +using ArrayFc = ir::ArrayFc; +using BitOrder = ir::BitOrder; +using BlobFc = ir::BlobFc; +using ByteOrder = ir::ByteOrder; +using ClkCls = ir::ClkCls; +using ClkOffset = ir::ClkOffset; +using ClkOrigin = ir::ClkOrigin; +using ConstFcVisitor = ir::ConstFcVisitor; +using DataStreamCls = ir::DataStreamCls; +using DispBase = ir::DispBase; +using DynLenArrayFc = ir::DynLenArrayFc; +using DynLenBlobFc = ir::DynLenBlobFc; +using DynLenStrFc = ir::DynLenStrFc; +using EventRecordCls = ir::EventRecordCls; +using Fc = ir::Fc; +using FcType = ir::FcType; +using FcVisitor = ir::FcVisitor; +using FieldLoc = ir::FieldLoc; +using FixedLenBitArrayFc = ir::FixedLenBitArrayFc; +using FixedLenBitMapFc = ir::FixedLenBitMapFc; +using FixedLenBoolFc = ir::FixedLenBoolFc; +using FixedLenFloatFc = ir::FixedLenFloatFc; +using FixedLenIntFc = ir::FixedLenIntFc; +using FixedLenSIntFc = ir::FixedLenSIntFc; +using FixedLenUIntFc = ir::FixedLenUIntFc; +using NonNullTerminatedStrFc = ir::NonNullTerminatedStrFc; +using NullTerminatedStrFc = ir::NullTerminatedStrFc; +using OptionalFc = ir::OptionalFc; +using OptionalWithBoolSelFc = ir::OptionalWithBoolSelFc; +using OptionalWithSIntSelFc = ir::OptionalWithSIntSelFc; +using OptionalWithUIntSelFc = ir::OptionalWithUIntSelFc; +using OptAttrs = ir::OptAttrs; +using Scope = ir::Scope; +using StaticLenArrayFc = ir::StaticLenArrayFc; +using StaticLenBlobFc = ir::StaticLenBlobFc; +using StaticLenStrFc = ir::StaticLenStrFc; +using StrEncoding = ir::StrEncoding; +using StrFc = ir::StrFc; +using StructFc = ir::StructFc; +using StructFieldMemberCls = ir::StructFieldMemberCls; +using TraceCls = ir::TraceCls; +using UIntFieldRole = ir::UIntFieldRole; +using UIntFieldRoles = ir::UIntFieldRoles; +using VariantWithSIntSelFc = ir::VariantWithSIntSelFc; +using VariantWithUIntSelFc = ir::VariantWithUIntSelFc; +using VarLenIntFc = ir::VarLenIntFc; +using VarLenSIntFc = ir::VarLenSIntFc; +using VarLenUIntFc = ir::VarLenUIntFc; + +/* + * Creates and returns a field location having the origin `origin` and + * the path items `items`. + */ +FieldLoc createFieldLoc(const bt2c::TextLoc& loc, bt2s::optional origin, + FieldLoc::Items items); + +/* + * Overload without a text location. + */ +inline FieldLoc createFieldLoc(bt2s::optional origin, FieldLoc::Items items) +{ + return createFieldLoc(bt2c::TextLoc {}, std::move(origin), std::move(items)); +} + +/* + * Creates and returns a class of fixed-length bit array fields having + * the alignment `align` bits, the length `len`, the byte order + * `byteOrder`, the bit order `bitOrder`, and the attributes `attrs`. + */ +std::unique_ptr createFixedLenBitArrayFc( + const bt2c::TextLoc& loc, unsigned int align, bt2c::DataLen len, ByteOrder byteOrder, + const bt2s::optional& bitOrder = bt2s::nullopt, OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns a class of fixed-length bit map fields having the + * alignment `align` bits, the length `len`, the byte order `byteOrder`, + * the bit order `bitOrder`, the flags `flags`, and the + * attributes `attrs`. + */ +std::unique_ptr +createFixedLenBitMapFc(const bt2c::TextLoc& loc, unsigned int align, bt2c::DataLen len, + ByteOrder byteOrder, FixedLenBitMapFc::Flags flags, + const bt2s::optional& bitOrder = bt2s::nullopt, + OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns a class of fixed-length boolean fields having the + * alignment `align` bits, the length `len`, the byte order `byteOrder`, + * the bit order `bitOrder`, and the attributes `attrs`. + */ +std::unique_ptr +createFixedLenBoolFc(const bt2c::TextLoc& loc, unsigned int align, bt2c::DataLen len, + ByteOrder byteOrder, const bt2s::optional& bitOrder = bt2s::nullopt, + OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns a class of fixed-length floating point number + * fields having the alignment `align` bits, the length `len`, the byte + * order `byteOrder`, the bit order `bitOrder`, and the + * attributes `attrs`. + */ +std::unique_ptr +createFixedLenFloatFc(const bt2c::TextLoc& loc, unsigned int align, bt2c::DataLen len, + ByteOrder byteOrder, const bt2s::optional& bitOrder = bt2s::nullopt, + OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +inline std::unique_ptr +createFixedLenFloatFc(const unsigned int align, const bt2c::DataLen len, const ByteOrder byteOrder, + const bt2s::optional& bitOrder = bt2s::nullopt, + OptAttrs attrs = OptAttrs {}) +{ + return createFixedLenFloatFc(bt2c::TextLoc {}, align, len, byteOrder, bitOrder, + std::move(attrs)); +} + +/* + * Creates and returns a class of fixed-length unsigned integer fields + * having the alignment `align` bits, the length `len`, the byte order + * `byteOrder`, the bit order `bitOrder`, the preferred display base + * `prefDispBase`, the mappings `mappings`, the roles `roles`, and the + * attributes `attrs`. + */ +std::unique_ptr +createFixedLenUIntFc(const bt2c::TextLoc& loc, unsigned int align, bt2c::DataLen len, + ByteOrder byteOrder, const bt2s::optional& bitOrder = bt2s::nullopt, + DispBase prefDispBase = DispBase::Dec, FixedLenUIntFc::Mappings mappings = {}, + UIntFieldRoles roles = {}, OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +inline std::unique_ptr +createFixedLenUIntFc(const unsigned int align, const bt2c::DataLen len, const ByteOrder byteOrder, + const bt2s::optional& bitOrder = bt2s::nullopt, + const DispBase prefDispBase = DispBase::Dec, + FixedLenUIntFc::Mappings mappings = {}, UIntFieldRoles roles = {}, + OptAttrs attrs = OptAttrs {}) +{ + return createFixedLenUIntFc(bt2c::TextLoc {}, align, len, byteOrder, bitOrder, prefDispBase, + std::move(mappings), std::move(roles), std::move(attrs)); +} + +/* + * Creates and returns a class of fixed-length signed integer fields + * having the alignment `align` bits, the length `len`, the byte order + * `byteOrder`, the bit order `bitOrder`, the preferred display base + * `prefDispBase`, the mappings `mappings`, and the attributes `attrs`. + */ +std::unique_ptr +createFixedLenSIntFc(const bt2c::TextLoc& loc, unsigned int align, bt2c::DataLen len, + ByteOrder byteOrder, const bt2s::optional& bitOrder = bt2s::nullopt, + DispBase prefDispBase = DispBase::Dec, FixedLenSIntFc::Mappings mappings = {}, + OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +inline std::unique_ptr +createFixedLenSIntFc(const unsigned int align, const bt2c::DataLen len, const ByteOrder byteOrder, + const bt2s::optional& bitOrder = bt2s::nullopt, + const DispBase prefDispBase = DispBase::Dec, + FixedLenSIntFc::Mappings mappings = {}, OptAttrs attrs = OptAttrs {}) +{ + return createFixedLenSIntFc(bt2c::TextLoc {}, align, len, byteOrder, bitOrder, prefDispBase, + std::move(mappings), std::move(attrs)); +} + +/* + * Creates and returns a class of variable-length unsigned integer + * fields having the preferred display base `prefDispBase`, the mappings + * `mappings`, the roles `roles`, and the attributes `attrs`. + */ +std::unique_ptr createVarLenUIntFc(const bt2c::TextLoc& loc, + DispBase prefDispBase = DispBase::Dec, + VarLenUIntFc::Mappings mappings = {}, + UIntFieldRoles roles = {}, + OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +inline std::unique_ptr createVarLenUIntFc(const DispBase prefDispBase = DispBase::Dec, + VarLenUIntFc::Mappings mappings = {}, + UIntFieldRoles roles = {}, + OptAttrs attrs = OptAttrs {}) +{ + return createVarLenUIntFc(bt2c::TextLoc {}, prefDispBase, std::move(mappings), std::move(roles), + std::move(attrs)); +} + +/* + * Creates and returns a class of variable-length signed integer fields + * having, the preferred display base `prefDispBase`, the mappings + * `mappings`, and the attributes `attrs`. + */ +std::unique_ptr createVarLenSIntFc(const bt2c::TextLoc& loc, + DispBase prefDispBase = DispBase::Dec, + VarLenSIntFc::Mappings mappings = {}, + OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +inline std::unique_ptr createVarLenSIntFc(const DispBase prefDispBase = DispBase::Dec, + VarLenSIntFc::Mappings mappings = {}, + OptAttrs attrs = OptAttrs {}) +{ + return createVarLenSIntFc(bt2c::TextLoc {}, prefDispBase, std::move(mappings), + std::move(attrs)); +} + +/* + * Creates and returns a class of null-terminated fields having the + * encoding `encoding` and the attributes `attrs`. + */ +std::unique_ptr +createNullTerminatedStrFc(const bt2c::TextLoc& loc, StrEncoding encoding = StrEncoding::Utf8, + OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +std::unique_ptr inline createNullTerminatedStrFc( + const StrEncoding encoding = StrEncoding::Utf8, OptAttrs attrs = OptAttrs {}) +{ + return createNullTerminatedStrFc(bt2c::TextLoc {}, encoding, std::move(attrs)); +} + +/* + * Creates and returns a class of static-length string fields having the + * length `len` bytes, the encoding `encoding`, and the + * attributes `attrs`. + */ +std::unique_ptr createStaticLenStrFc(const bt2c::TextLoc& loc, std::size_t len, + StrEncoding encoding = StrEncoding::Utf8, + OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +inline std::unique_ptr +createStaticLenStrFc(const std::size_t len, const StrEncoding encoding = StrEncoding::Utf8, + OptAttrs attrs = OptAttrs {}) +{ + return createStaticLenStrFc(bt2c::TextLoc {}, len, encoding, std::move(attrs)); +} + +/* + * Creates and returns a class of dynamic-length string fields having + * the length field location `lenFieldLoc`, the encoding `encoding`, and + * the attributes `attrs`. + */ +std::unique_ptr createDynLenStrFc(const bt2c::TextLoc& loc, FieldLoc lenFieldLoc, + StrEncoding encoding = StrEncoding::Utf8, + OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +inline std::unique_ptr +createDynLenStrFc(FieldLoc lenFieldLoc, const StrEncoding encoding = StrEncoding::Utf8, + OptAttrs attrs = OptAttrs {}) +{ + return createDynLenStrFc(bt2c::TextLoc {}, std::move(lenFieldLoc), encoding, std::move(attrs)); +} + +/* + * Creates and returns a class of static-length BLOB fields having the + * length `len` bytes, the media type `mediaType`, the "metadata stream + * Uuid" role if `hasMetadataStreamUuidRole` is true, and the user + * attributes `attrs`. + */ +std::unique_ptr +createStaticLenBlobFc(const bt2c::TextLoc& loc, std::size_t len, + std::string mediaType = ir::defaultBlobMediaType, + bool hasMetadataStreamUuidRole = false, OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns a class of dynamic-length BLOB fields having the + * length field location `lenFieldLoc`, the media type `mediaType`, and + * the attributes `attrs`. + */ +std::unique_ptr createDynLenBlobFc(const bt2c::TextLoc& loc, FieldLoc lenFieldLoc, + std::string mediaType = ir::defaultBlobMediaType, + OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns a class of static-length array fields having the + * length `len`, the element field class `elemFc`, the minimum alignment + * `minAlign` bits, the attributes `attrs`, and the "metadata stream + * Uuid" role if `hasMetadataStreamUuidRole` is true. + */ +std::unique_ptr createStaticLenArrayFc(const bt2c::TextLoc& loc, std::size_t len, + Fc::UP elemFc, unsigned int minAlign = 1, + bool hasMetadataStreamUuidRole = false, + OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +inline std::unique_ptr +createStaticLenArrayFc(const std::size_t len, Fc::UP elemFc, const unsigned int minAlign = 1, + const bool hasMetadataStreamUuidRole = false, OptAttrs attrs = OptAttrs {}) +{ + return createStaticLenArrayFc(bt2c::TextLoc {}, len, std::move(elemFc), minAlign, + hasMetadataStreamUuidRole, std::move(attrs)); +} + +/* + * Creates and returns a class of dynamic-length array fields having the + * length field location `lenFieldLoc`, the element field class + * `elemFc`, the minimum alignment `minAlign` bits, and the user + * attributes `attrs`. + */ +std::unique_ptr createDynLenArrayFc(const bt2c::TextLoc& loc, FieldLoc lenFieldLoc, + Fc::UP elemFc, unsigned int minAlign = 1, + OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +inline std::unique_ptr createDynLenArrayFc(FieldLoc lenFieldLoc, Fc::UP elemFc, + const unsigned int minAlign = 1, + OptAttrs attrs = OptAttrs {}) +{ + return createDynLenArrayFc(bt2c::TextLoc {}, std::move(lenFieldLoc), std::move(elemFc), + minAlign, std::move(attrs)); +} + +/* + * Creates and returns a class of structure field members having the + * name `name`, the field class `fc`, and the attributes `attrs`. + */ +StructFieldMemberCls createStructFieldMemberCls(std::string name, Fc::UP fc, + OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns a class of structure fields having members of + * classes `memberClasses`, the minimum alignment `minAlign` bits, and + * the attributes `attrs`. + */ +std::unique_ptr createStructFc(const bt2c::TextLoc& loc, + StructFc::MemberClasses&& memberClasses = {}, + unsigned int minAlign = 1, OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +inline std::unique_ptr createStructFc(StructFc::MemberClasses&& memberClasses = {}, + const unsigned int minAlign = 1, + OptAttrs attrs = OptAttrs {}) +{ + return createStructFc(bt2c::TextLoc {}, std::move(memberClasses), minAlign, std::move(attrs)); +} + +/* + * Creates and returns a class of optional fields having a boolean + * selector, the optional field class `fc`, the selector field location + * `selFieldLoc`, and the attributes `attrs`. + */ +std::unique_ptr createOptionalFc(const bt2c::TextLoc& loc, Fc::UP fc, + FieldLoc selFieldLoc, + OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns a class of optional fields having an unsigned + * integer selector, the optional field class `fc`, the selector field + * location `selFieldLoc`, the integer selector field ranges + * `selFieldRanges`, and the attributes `attrs`. + */ +std::unique_ptr createOptionalFc(const bt2c::TextLoc& loc, Fc::UP fc, + FieldLoc selFieldLoc, + UIntRangeSet selFieldRanges, + OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns a class of optional fields having a signed + * integer selector, the optional field class `fc`, the selector field + * location `selFieldLoc`, the integer selector field ranges + * `selFieldRanges`, and the attributes `attrs`. + */ +std::unique_ptr createOptionalFc(const bt2c::TextLoc& loc, Fc::UP fc, + FieldLoc selFieldLoc, + SIntRangeSet selFieldRanges, + OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns an option, for the class of a variant field + * having an unsigned integer selector, having the field class `fc`, the + * selector field ranges `selFieldRanges`, the name `name`, and the user + * attributes `attrs`. + */ +VariantWithUIntSelFc::Opt createVariantFcOpt(Fc::UP fc, UIntRangeSet selFieldRanges, + bt2s::optional name, + OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns an option, for the class of a variant field + * having a signed integer selector, having the field class `fc`, the + * selector field ranges `selFieldRanges`, the name `name`, and the user + * attributes `attrs`. + */ +VariantWithSIntSelFc::Opt createVariantFcOpt(Fc::UP fc, SIntRangeSet selFieldRanges, + bt2s::optional name, + OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns a class of variant fields having an unsigned + * integer selector, the options `opts`, the selector field location + * `selFieldLoc`, and the attributes `attrs`. + */ +std::unique_ptr createVariantFc(const bt2c::TextLoc& loc, + VariantWithUIntSelFc::Opts&& opts, + FieldLoc selFieldLoc, + OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +inline std::unique_ptr createVariantFc(VariantWithUIntSelFc::Opts&& opts, + FieldLoc selFieldLoc, + OptAttrs attrs = OptAttrs {}) +{ + return createVariantFc(bt2c::TextLoc {}, std::move(opts), std::move(selFieldLoc), + std::move(attrs)); +} + +/* + * Creates and returns a class of variant fields having a signed integer + * selector, the options `opts`, the selector field location + * `selFieldLoc`, and the attributes `attrs`. + */ +std::unique_ptr createVariantFc(const bt2c::TextLoc& loc, + VariantWithSIntSelFc::Opts&& opts, + FieldLoc selFieldLoc, + OptAttrs attrs = OptAttrs {}); + +/* + * Overload without a text location. + */ +inline std::unique_ptr createVariantFc(VariantWithSIntSelFc::Opts&& opts, + FieldLoc selFieldLoc, + OptAttrs attrs = OptAttrs {}) +{ + return createVariantFc(bt2c::TextLoc {}, std::move(opts), std::move(selFieldLoc), + std::move(attrs)); +} + +/* + * Creates and returns a class, having the ID `id` (unique within its + * trace class), of a clocks having the frequency `freq` Hz, the + * namespace `ns`, the name `name`, the UID `uid`, the offset from + * origin `offset`, the origin `origin`, the description `descr`, the + * precision `precision` cycles, the accuracy `accuracy` cycles, and the + * attributes `attrs`. + */ +ClkCls::SP createClkCls(std::string id, unsigned long long freq, + bt2s::optional ns = bt2s::nullopt, + bt2s::optional name = bt2s::nullopt, + bt2s::optional uid = bt2s::nullopt, + const ClkOffset& offset = ClkOffset {}, + bt2s::optional origin = ClkOrigin {}, + bt2s::optional descr = bt2s::nullopt, + bt2s::optional precision = bt2s::nullopt, + bt2s::optional accuracy = bt2s::nullopt, + OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns a class, having the ID `id`, of event records + * having the namespace `ns`, the name `name`, the UID `uid`, the + * specific context field class `specCtxFc`, the payload field class + * `payloadFc`, and the attributes `attrs`. + */ +std::unique_ptr +createEventRecordCls(unsigned long long id, bt2s::optional ns = bt2s::nullopt, + bt2s::optional name = bt2s::nullopt, + bt2s::optional uid = bt2s::nullopt, Fc::UP specCtxFc = nullptr, + Fc::UP payloadFc = nullptr, OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns a class, having the ID `id`, of data streams + * having the the namespace `ns`, the name `name`, the UID `uid`, the + * packet context field class `pktCtxFc`, the event record header field + * class `eventRecordHeaderFc`, the common event record context field + * class `commonEventRecordCtxFc`, the default clock class `defClkCls`, + * and the attributes `attrs`. + */ +std::unique_ptr +createDataStreamCls(unsigned long long id, bt2s::optional ns = bt2s::nullopt, + bt2s::optional name = bt2s::nullopt, + bt2s::optional uid = bt2s::nullopt, Fc::UP pktCtxFc = nullptr, + Fc::UP eventRecordHeaderFc = nullptr, Fc::UP commonEventRecordCtxFc = nullptr, + ClkCls::SP defClkCls = nullptr, OptAttrs attrs = OptAttrs {}); + +/* + * Creates and returns a class of traces having the the namespace `ns`, + * the name `name`, the UID `uid`, the environment `env`, the packet + * header field class `pktHeaderFc`, and the attributes `attrs`. + */ +std::unique_ptr +createTraceCls(bt2s::optional ns = bt2s::nullopt, + bt2s::optional name = bt2s::nullopt, + bt2s::optional uid = bt2s::nullopt, + bt2::ConstMapValue::Shared env = bt2::ConstMapValue::Shared {}, + Fc::UP pktHeaderFc = nullptr, OptAttrs attrs = OptAttrs {}); + +} /* namespace src */ +} /* namespace ctf */ + +#endif /* BABELTRACE_PLUGINS_CTF_COMMON_SRC_METADATA_CTF_IR_HPP */