From: Philippe Proulx Date: Thu, 7 Dec 2023 20:38:33 +0000 (+0000) Subject: cpp-common/bt2: add `CommonBlobField` and `CommonDynamicBlobField` X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=a613491dee7fb65d1a7d1a49f1d0363e49a19122;p=babeltrace.git cpp-common/bt2: add `CommonBlobField` and `CommonDynamicBlobField` Use `CommonBlobField::data()` to access the data pointer and data length (bytes) of the BLOB field as a `bt2s::span`. A `BlobField::data()` returns `bt2s::span` while `ConstBlobField::data()` returns `bt2s::span`. Use `CommonDynamicBlobField::length()` to set the length of a dynamic BLOB field (like `CommonDynamicArrayField::length()`). Signed-off-by: Philippe Proulx Change-Id: I3d9f9417e262a5fbbc9b7bb8f3d690d6628f7988 Reviewed-on: https://review.lttng.org/c/babeltrace/+/12713 --- diff --git a/src/cpp-common/bt2/field.hpp b/src/cpp-common/bt2/field.hpp index 05e1c244..aca49d49 100644 --- a/src/cpp-common/bt2/field.hpp +++ b/src/cpp-common/bt2/field.hpp @@ -14,6 +14,7 @@ #include "common/assert.h" #include "cpp-common/bt2c/c-string-view.hpp" +#include "cpp-common/bt2s/span.hpp" #include "borrowed-object.hpp" #include "field-class.hpp" @@ -50,6 +51,12 @@ class CommonDoublePrecisionRealField; template class CommonStringField; +template +class CommonBlobField; + +template +class CommonDynamicBlobField; + template class CommonStructureField; @@ -181,6 +188,16 @@ public: return this->cls().isString(); } + bool isBlob() const noexcept + { + return this->cls().isBlob(); + } + + bool isDynamicBlob() const noexcept + { + return this->cls().isDynamicBlob(); + } + bool isStructure() const noexcept { return this->cls().isStructure(); @@ -221,6 +238,8 @@ public: CommonSinglePrecisionRealField asSinglePrecisionReal() const noexcept; CommonDoublePrecisionRealField asDoublePrecisionReal() const noexcept; CommonStringField asString() const noexcept; + CommonBlobField asBlob() const noexcept; + CommonDynamicBlobField asDynamicBlob() const noexcept; CommonStructureField asStructure() const noexcept; CommonArrayField asArray() const noexcept; CommonDynamicArrayField asDynamicArray() const noexcept; @@ -1047,6 +1066,171 @@ struct TypeDescr : public StringFieldTypeDescr { }; +template +struct CommonBlobFieldSpec; + +template <> +struct CommonBlobFieldSpec final +{ + using Data = std::uint8_t; + + static Data *data(bt_field * const libObjPtr) noexcept + { + return bt_field_blob_get_data(libObjPtr); + } +}; + +template <> +struct CommonBlobFieldSpec final +{ + using Data = const std::uint8_t; + + static Data *data(const bt_field * const libObjPtr) noexcept + { + return bt_field_blob_get_data_const(libObjPtr); + } +}; + +} /* namespace internal */ + +template +class CommonBlobField : public CommonField +{ +private: + using typename CommonField::_ThisCommonField; + +protected: + using _ThisCommonBlobField = CommonBlobField; + +public: + using typename CommonField::LibObjPtr; + +public: + explicit CommonBlobField(const LibObjPtr libObjPtr) noexcept : _ThisCommonField {libObjPtr} + { + BT_ASSERT_DBG(this->isBlob()); + } + + template + CommonBlobField(const CommonBlobField val) noexcept : _ThisCommonField {val} + { + } + + template + CommonBlobField operator=(const CommonBlobField val) noexcept + { + _ThisCommonField::operator=(val); + return *this; + } + + CommonBlobField asConst() const noexcept + { + return CommonBlobField {*this}; + } + + bt2s::span::Data> data() const noexcept + { + return {internal::CommonBlobFieldSpec::data(this->libObjPtr()), this->length()}; + } + + std::uint64_t length() const noexcept + { + return bt_field_blob_get_length(this->libObjPtr()); + } +}; + +using BlobField = CommonBlobField; +using ConstBlobField = CommonBlobField; + +namespace internal { + +struct BlobFieldTypeDescr +{ + using Const = ConstBlobField; + using NonConst = BlobField; +}; + +template <> +struct TypeDescr : public BlobFieldTypeDescr +{ +}; + +template <> +struct TypeDescr : public BlobFieldTypeDescr +{ +}; + +} /* namespace internal */ + +template +class CommonDynamicBlobField final : public CommonBlobField +{ +private: + using typename CommonBlobField::_ThisCommonBlobField; + +public: + using typename CommonBlobField::LibObjPtr; + +public: + explicit CommonDynamicBlobField(const LibObjPtr libObjPtr) noexcept : + _ThisCommonBlobField {libObjPtr} + { + BT_ASSERT_DBG(this->isDynamicBlob()); + } + + template + CommonDynamicBlobField(const CommonDynamicBlobField val) noexcept : + _ThisCommonBlobField {val} + { + } + + template + CommonDynamicBlobField operator=(const CommonDynamicBlobField val) noexcept + { + _ThisCommonBlobField::operator=(val); + return *this; + } + + std::uint64_t length() const noexcept + { + return _ThisCommonBlobField::length(); + } + + CommonDynamicBlobField length(const std::uint64_t length) const + { + static_assert(!std::is_const::value, + "Not available with `bt2::ConstDynamicBlobField`."); + + if (bt_field_blob_dynamic_set_length(this->libObjPtr(), length) == + BT_FIELD_DYNAMIC_BLOB_SET_LENGTH_STATUS_MEMORY_ERROR) { + throw MemoryError {}; + } + + return *this; + } +}; + +using DynamicBlobField = CommonDynamicBlobField; +using ConstDynamicBlobField = CommonDynamicBlobField; + +namespace internal { + +struct DynamicBlobFieldTypeDescr +{ + using Const = ConstDynamicBlobField; + using NonConst = DynamicBlobField; +}; + +template <> +struct TypeDescr : public DynamicBlobFieldTypeDescr +{ +}; + +template <> +struct TypeDescr : public DynamicBlobFieldTypeDescr +{ +}; + template struct CommonStructureFieldSpec; @@ -1605,6 +1789,20 @@ CommonStringField CommonField::asString() const noexcept return CommonStringField {this->libObjPtr()}; } +template +CommonBlobField CommonField::asBlob() const noexcept +{ + BT_ASSERT_DBG(this->isBlob()); + return CommonBlobField {this->libObjPtr()}; +} + +template +CommonDynamicBlobField CommonField::asDynamicBlob() const noexcept +{ + BT_ASSERT_DBG(this->isDynamicBlob()); + return CommonDynamicBlobField {this->libObjPtr()}; +} + template CommonStructureField CommonField::asStructure() const noexcept {