From 28fd5be72727cf0d5b34b7587fbcd3ddc6a27bee Mon Sep 17 00:00:00 2001 From: Johannes Wolf Date: Tue, 20 Aug 2024 10:38:06 +0200 Subject: [PATCH 1/2] cpp: Store compounds real bit size with its pos --- .../extensions/cpp/freemarker/Choice.cpp.ftl | 15 +++++++++++++ .../extensions/cpp/freemarker/Choice.h.ftl | 17 ++++++++++++++- .../freemarker/CompoundConstructor.inc.ftl | 20 ++++++++++++++++++ .../cpp/freemarker/Structure.cpp.ftl | 15 +++++++++++++ .../extensions/cpp/freemarker/Structure.h.ftl | 17 ++++++++++++++- .../extensions/cpp/freemarker/Union.cpp.ftl | 21 +++++++++++++++++++ .../extensions/cpp/freemarker/Union.h.ftl | 17 ++++++++++++++- .../cpp/runtime/src/zserio/IReflectable.h | 14 +++++++++++++ .../cpp/runtime/src/zserio/Reflectable.h | 13 ++++++++++++ 9 files changed, 146 insertions(+), 3 deletions(-) diff --git a/compiler/extensions/cpp/freemarker/Choice.cpp.ftl b/compiler/extensions/cpp/freemarker/Choice.cpp.ftl index e12d2fe8e..d0337adff 100644 --- a/compiler/extensions/cpp/freemarker/Choice.cpp.ftl +++ b/compiler/extensions/cpp/freemarker/Choice.cpp.ftl @@ -291,6 +291,16 @@ ${I}return {}; } + size_t realBitSizeOf() const override + { + <#if withBitPositionCode> + return m_object.realBitSizeOf(); + <#else> + throw ::zserio::CppRuntimeException("Reflectable '${name}': ") << + "Bit position code is disabled by '-withoutBitPositionCode' zserio option!"; + + } + private: <#if isConst>const ${fullName}& m_object; }; @@ -591,6 +601,11 @@ size_t ${name}::bitPosition() const { return m_bitPosition; } + +size_t ${name}::realBitSizeOf() const +{ + return m_realBitSize; +} <#if fieldList?has_content> diff --git a/compiler/extensions/cpp/freemarker/Choice.h.ftl b/compiler/extensions/cpp/freemarker/Choice.h.ftl index a9ceeb9d1..ffafe9b44 100644 --- a/compiler/extensions/cpp/freemarker/Choice.h.ftl +++ b/compiler/extensions/cpp/freemarker/Choice.h.ftl @@ -343,6 +343,21 @@ public: */ size_t bitPosition() const; + + <#if withCodeComments> + /** + * Get the bit size of the parsed blob after reading. This size can differ + * from the one returned by getBitSizeOf() if compression took place. + * + * This feature is experimental and can be removed without any warning! + * + * \note Note that the returned bit size is valid only directly after read! If the Zserio object + * has been changed after reading, the result is unspecified! + * + * \return Size of the object as it was stored in the blob in bits. + */ + + size_t realBitSizeOf() const; private: @@ -360,7 +375,7 @@ private: <@compound_constructor_members compoundConstructorsData/> <#if withBitPositionCode> <#-- Bit position must be before m_objectChoice in order to get initialized first. --> - size_t m_bitPosition; + size_t m_bitPosition, m_realBitSize; <#if fieldList?has_content> ${types.anyHolder.name} m_objectChoice; diff --git a/compiler/extensions/cpp/freemarker/CompoundConstructor.inc.ftl b/compiler/extensions/cpp/freemarker/CompoundConstructor.inc.ftl index 947c7e3a9..6fc547efe 100644 --- a/compiler/extensions/cpp/freemarker/CompoundConstructor.inc.ftl +++ b/compiler/extensions/cpp/freemarker/CompoundConstructor.inc.ftl @@ -36,6 +36,7 @@ ${compoundConstructorsData.compoundName}::${compoundConstructorsData.compoundNam <#if withBitPositionCode> m_bitPosition(0) + m_realBitSize(0) <#if memberInitializationMacroName != ""> <#if (numExtendedFields > 0)> @@ -102,6 +103,7 @@ ${compoundConstructorsData.compoundName}::${compoundConstructorsData.compoundNam <#if withBitPositionCode> m_bitPosition(in.getBitPosition()) + m_realBitSize(0) <#if memberInitializationMacroName != ""> <#if (num_extended_fields(compoundConstructorsData.fieldList) > 0)> @@ -111,6 +113,14 @@ ${compoundConstructorsData.compoundName}::${compoundConstructorsData.compoundNam { + <#-- Determine the real bit size after member initialization took place. --> + <#if withBitPositionCode> + <#if packed> + m_realBitSize = bitSizeOf(context, m_bitPosition); + <#else> + m_realBitSize = bitSizeOf(); + + } @@ -168,6 +178,7 @@ ${compoundConstructorsData.compoundName}::${compoundConstructorsData.compoundNam <@cpp_initializer_list> <#if withBitPositionCode> m_bitPosition(other.m_bitPosition) + m_realBitSize(other.m_realBitSize) <#if (num_extended_fields(compoundConstructorsData.fieldList) > 0)> m_numExtendedFields(other.m_numExtendedFields) @@ -191,6 +202,7 @@ ${compoundConstructorsData.compoundName}::${compoundConstructorsData.compoundNam m_isInitialized(false) <#if withBitPositionCode> m_bitPosition(other.m_bitPosition) + m_realBitSize(other.m_realBitSize) <#if (num_extended_fields(compoundConstructorsData.fieldList) > 0)> m_numExtendedFields(other.m_numExtendedFields) @@ -237,6 +249,7 @@ ${compoundConstructorsData.compoundName}& ${compoundConstructorsData.compoundNam { <#if withBitPositionCode> m_bitPosition = other.m_bitPosition; + m_realBitSize = other.m_realBitSize; <#if (num_extended_fields(compoundConstructorsData.fieldList) > 0)> m_numExtendedFields = other.m_numExtendedFields; @@ -260,6 +273,7 @@ ${compoundConstructorsData.compoundName}& ${compoundConstructorsData.compoundNam m_isInitialized = false; <#if withBitPositionCode> m_bitPosition = other.m_bitPosition; + m_realBitSize = other.m_realBitSize; <#if (num_extended_fields(compoundConstructorsData.fieldList) > 0)> m_numExtendedFields = other.m_numExtendedFields; @@ -306,6 +320,7 @@ ${compoundConstructorsData.compoundName}::${compoundConstructorsData.compoundNam <@cpp_initializer_list> <#if withBitPositionCode> m_bitPosition(other.m_bitPosition) + m_realBitSize(other.m_realBitSize) <#if (num_extended_fields(compoundConstructorsData.fieldList) > 0)> m_numExtendedFields(other.m_numExtendedFields) @@ -329,6 +344,7 @@ ${compoundConstructorsData.compoundName}::${compoundConstructorsData.compoundNam m_isInitialized(false) <#if withBitPositionCode> m_bitPosition(other.m_bitPosition) + m_realBitSize(other.m_realBitSize) <#if (num_extended_fields(compoundConstructorsData.fieldList) > 0)> m_numExtendedFields(other.m_numExtendedFields) @@ -376,6 +392,7 @@ ${compoundConstructorsData.compoundName}& ${compoundConstructorsData.compoundNam { <#if withBitPositionCode> m_bitPosition = other.m_bitPosition; + m_realBitSize = other.m_realBitSize; <#if (num_extended_fields(compoundConstructorsData.fieldList) > 0)> m_numExtendedFields = other.m_numExtendedFields; @@ -399,6 +416,7 @@ ${compoundConstructorsData.compoundName}& ${compoundConstructorsData.compoundNam m_isInitialized = false; <#if withBitPositionCode> m_bitPosition = other.m_bitPosition; + m_realBitSize = other.m_realBitSize; <#if (num_extended_fields(compoundConstructorsData.fieldList) > 0)> m_numExtendedFields = other.m_numExtendedFields; @@ -450,6 +468,7 @@ ${compoundConstructorsData.compoundName}::${compoundConstructorsData.compoundNam <@cpp_initializer_list> <#if withBitPositionCode> m_bitPosition(other.m_bitPosition) + m_realBitSize(other.m_realBitSize) <#if (num_extended_fields(compoundConstructorsData.fieldList) > 0)> m_numExtendedFields(other.m_numExtendedFields) @@ -478,6 +497,7 @@ ${compoundConstructorsData.compoundName}::${compoundConstructorsData.compoundNam m_isInitialized(false) <#if withBitPositionCode> m_bitPosition(other.m_bitPosition) + m_realBitSize(other.m_realBitSize) <#if (num_extended_fields(compoundConstructorsData.fieldList) > 0)> m_numExtendedFields(other.m_numExtendedFields) diff --git a/compiler/extensions/cpp/freemarker/Structure.cpp.ftl b/compiler/extensions/cpp/freemarker/Structure.cpp.ftl index 81a5e0906..0b153d72d 100644 --- a/compiler/extensions/cpp/freemarker/Structure.cpp.ftl +++ b/compiler/extensions/cpp/freemarker/Structure.cpp.ftl @@ -244,6 +244,16 @@ const ${types.typeInfo.name}& ${name}::typeInfo() } + size_t realBitSizeOf() const override + { + <#if withBitPositionCode> + return m_object.realBitSizeOf(); + <#else> + throw ::zserio::CppRuntimeException("Reflectable '${name}': ") << + "Bit position code is disabled by '-withoutBitPositionCode' zserio option!"; + + } + private: <#if isConst>const ${fullName}& m_object; }; @@ -574,6 +584,11 @@ size_t ${name}::bitPosition() const { return m_bitPosition; } + +size_t ${name}::realBitSizeOf() const +{ + return m_realBitSize; +} <#if fieldList?has_content> diff --git a/compiler/extensions/cpp/freemarker/Structure.h.ftl b/compiler/extensions/cpp/freemarker/Structure.h.ftl index 2a8618fe8..fcd1a13c7 100644 --- a/compiler/extensions/cpp/freemarker/Structure.h.ftl +++ b/compiler/extensions/cpp/freemarker/Structure.h.ftl @@ -394,6 +394,21 @@ public: */ size_t bitPosition() const; + + <#if withCodeComments> + /** + * Get the bit size of the parsed blob after reading. This size can differ + * from the one returned by getBitSizeOf() if compression took place. + * + * This feature is experimental and can be removed without any warning! + * + * \note Note that the returned bit size is valid only directly after read! If the Zserio object + * has been changed after reading, the result is unspecified! + * + * \return Size of the object as it was stored in the blob in bits. + */ + + size_t realBitSizeOf() const; private: @@ -421,7 +436,7 @@ private: <@compound_constructor_members compoundConstructorsData/> <#if withBitPositionCode> <#-- Bit position must be before field members in order to get initialized first. --> - size_t m_bitPosition; + size_t m_bitPosition, m_realBitSize; <#if (numExtendedFields > 0)> uint32_t m_numExtendedFields; diff --git a/compiler/extensions/cpp/freemarker/Union.cpp.ftl b/compiler/extensions/cpp/freemarker/Union.cpp.ftl index d8dde300b..2a73dbea9 100644 --- a/compiler/extensions/cpp/freemarker/Union.cpp.ftl +++ b/compiler/extensions/cpp/freemarker/Union.cpp.ftl @@ -62,6 +62,7 @@ ${name}::${name}(const ${name}& other)<#rt> <@cpp_initializer_list> <#if withBitPositionCode> m_bitPosition(other.m_bitPosition) + m_realBitSize(other.m_realBitSize) m_choiceTag(other.m_choiceTag) <#list fieldList as field> @@ -93,6 +94,7 @@ ${name}::${name}(${name}&& other)<#rt> <@cpp_initializer_list> <#if withBitPositionCode> m_bitPosition(other.m_bitPosition) + m_realBitSize(other.m_realBitSize) m_choiceTag(other.m_choiceTag) <#list fieldList as field> @@ -131,6 +133,7 @@ ${name}::${name}(::zserio::NoInitT, const ${name}& other)<#rt> <#if withBitPositionCode> m_bitPosition(other.m_bitPosition) + m_realBitSize(other.m_realBitSize) m_choiceTag(other.m_choiceTag) <#list fieldList as field> @@ -170,6 +173,7 @@ ${name}::${name}(::zserio::NoInitT, ${name}&& other)<#rt> <#if withBitPositionCode> m_bitPosition(other.m_bitPosition) + m_realBitSize(other.m_realBitSize) m_choiceTag(other.m_choiceTag) <#list fieldList as field> @@ -207,6 +211,7 @@ ${name}::${name}(::zserio::PropagateAllocatorT, <@cpp_initializer_list> <#if withBitPositionCode> m_bitPosition(other.m_bitPosition) + m_realBitSize(other.m_realBitSize) m_choiceTag(other.m_choiceTag) <#list fieldList as field> @@ -228,6 +233,7 @@ ${name}::${name}(::zserio::PropagateAllocatorT, ::zserio::NoInitT, <@cpp_initializer_list> <#if withBitPositionCode> m_bitPosition(other.m_bitPosition) + m_realBitSize(other.m_realBitSize) m_choiceTag(other.m_choiceTag) <#list fieldList as field> @@ -388,6 +394,16 @@ const ${types.typeInfo.name}& ${name}::typeInfo() } + size_t realBitSizeOf() const override + { + <#if withBitPositionCode> + return m_object.realBitSizeOf(); + <#else> + throw ::zserio::CppRuntimeException("Reflectable '${name}': ") << + "Bit position code is disabled by '-withoutBitPositionCode' zserio option!"; + + } + private: <#if isConst>const ${fullName}& m_object; }; @@ -722,6 +738,11 @@ size_t ${name}::bitPosition() const { return m_bitPosition; } + +size_t ${name}::realBitSizeOf() const +{ + return m_realBitSize; +} <#if fieldList?has_content> diff --git a/compiler/extensions/cpp/freemarker/Union.h.ftl b/compiler/extensions/cpp/freemarker/Union.h.ftl index 618944a34..10da9554a 100644 --- a/compiler/extensions/cpp/freemarker/Union.h.ftl +++ b/compiler/extensions/cpp/freemarker/Union.h.ftl @@ -340,6 +340,21 @@ public: */ size_t bitPosition() const; + + <#if withCodeComments> + /** + * Get the bit size of the parsed blob after reading. This size can differ + * from the one returned by getBitSizeOf() if compression took place. + * + * This feature is experimental and can be removed without any warning! + * + * \note Note that the returned bit size is valid only directly after read! If the Zserio object + * has been changed after reading, the result is unspecified! + * + * \return Size of the object as it was stored in the blob in bits. + */ + + size_t realBitSizeOf() const; private: @@ -361,7 +376,7 @@ private: <@compound_constructor_members compoundConstructorsData/> <#if withBitPositionCode> <#-- Bit position must be before m_choiceTag and m_objectChoice in order to get initialized first. --> - size_t m_bitPosition; + size_t m_bitPosition, m_realBitSize; ChoiceTag m_choiceTag; <#if fieldList?has_content> diff --git a/compiler/extensions/cpp/runtime/src/zserio/IReflectable.h b/compiler/extensions/cpp/runtime/src/zserio/IReflectable.h index 76aff8b82..c6d8e9bbb 100644 --- a/compiler/extensions/cpp/runtime/src/zserio/IReflectable.h +++ b/compiler/extensions/cpp/runtime/src/zserio/IReflectable.h @@ -522,6 +522,20 @@ class IBasicReflectable * \throw CppRuntimeException If the object was compiled without the bit position feature enabled. */ virtual size_t bitPosition() const = 0; + + /** + * Returns the bit size of the parsed blob of the reflectable object. + * + * This feature is experimental and can be removed without any warning! + * + * \note Note that the returned bit size is valid only directly after read! If the Zserio object + * has been changed after reading, the result is unspecified! + * \note The bit size is only stored for code generated using `-withBitPositionCode` option. + * + * \return The blob size of the objects in bits. + * \throw CppRuntimeException If the object was compiled without the bit position feature enabled. + */ + virtual size_t realBitSizeOf() const = 0; }; /** Typedef to reflectable smart pointer needed for convenience in generated code. */ diff --git a/compiler/extensions/cpp/runtime/src/zserio/Reflectable.h b/compiler/extensions/cpp/runtime/src/zserio/Reflectable.h index 456ce2620..9ead82b6a 100644 --- a/compiler/extensions/cpp/runtime/src/zserio/Reflectable.h +++ b/compiler/extensions/cpp/runtime/src/zserio/Reflectable.h @@ -115,6 +115,7 @@ class ReflectableBase : public IBasicReflectable string toString() const override; size_t bitPosition() const override; + size_t realBitSizeOf() const override; private: const IBasicTypeInfo& m_typeInfo; @@ -3404,6 +3405,11 @@ class ReflectableOwner : public IBasicReflectable return m_reflectable->bitPosition(); } + size_t realBitSizeOf() const override + { + return m_reflectable->realBitSizeOf(); + } + private: T m_object; IBasicReflectablePtr m_reflectable; @@ -4382,6 +4388,13 @@ size_t ReflectableBase::bitPosition() const << getTypeInfo().getSchemaName() << "'!"; } +template +size_t ReflectableBase::realBitSizeOf() const +{ + throw CppRuntimeException("Real bit size is not available for type '") + << getTypeInfo().getSchemaName() << "'!"; +} + template void ReflectableConstAllocatorHolderBase::initializeChildren() { From 31413bec0d623840fcb833657e2d3403b7c88981 Mon Sep 17 00:00:00 2001 From: Johannes Wolf Date: Tue, 20 Aug 2024 14:43:36 +0200 Subject: [PATCH 2/2] Update clang-tidy suppressions --- compiler/extensions/cpp/runtime/ClangTidySuppressions.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/extensions/cpp/runtime/ClangTidySuppressions.txt b/compiler/extensions/cpp/runtime/ClangTidySuppressions.txt index 5a0539630..7879f1644 100644 --- a/compiler/extensions/cpp/runtime/ClangTidySuppressions.txt +++ b/compiler/extensions/cpp/runtime/ClangTidySuppressions.txt @@ -90,7 +90,7 @@ cppcoreguidelines-pro-type-reinterpret-cast:src/zserio/ValidationSqliteUtil.h:99 cppcoreguidelines-pro-type-reinterpret-cast:src/zserio/ValidationSqliteUtil.h:100 # This multiple inheritance is intended and we think that to avoid it would mean much more obscure design. -fuchsia-multiple-inheritance:src/zserio/Reflectable.h:2025 +fuchsia-multiple-inheritance:src/zserio/Reflectable.h:2026 # This is necessary for implementation of low level implementation to mimic standard C++17 abstractions. google-explicit-constructor:src/zserio/OptionalHolder.h:232 @@ -122,8 +122,8 @@ misc-no-recursion:src/zserio/JsonParser.h:163 misc-no-recursion:src/zserio/ReflectableUtil.h:131 misc-no-recursion:src/zserio/ReflectableUtil.h:135 misc-no-recursion:src/zserio/ReflectableUtil.h:146 -misc-no-recursion:src/zserio/Reflectable.h:1953 -misc-no-recursion:src/zserio/Reflectable.h:1987 +misc-no-recursion:src/zserio/Reflectable.h:1954 +misc-no-recursion:src/zserio/Reflectable.h:1988 misc-no-recursion:src/zserio/Walker.h:73 misc-no-recursion:src/zserio/Walker.h:74 misc-no-recursion:src/zserio/Walker.h:75