diff --git a/rmw_cyclonedds_cpp/src/Serialization.cpp b/rmw_cyclonedds_cpp/src/Serialization.cpp index 15d389134..4eaebd300 100644 --- a/rmw_cyclonedds_cpp/src/Serialization.cpp +++ b/rmw_cyclonedds_cpp/src/Serialization.cpp @@ -33,66 +33,50 @@ namespace rmw_cyclonedds_cpp { - -struct CDRCursor +template +struct CDRCursorBase { - CDRCursor() = default; - ~CDRCursor() = default; - - // don't want to accidentally copy - explicit CDRCursor(CDRCursor const &) = delete; - void operator=(CDRCursor const & x) = delete; - - // virtual functions to be implemented - // get the cursor's current offset. - virtual size_t offset() const = 0; - // advance the cursor. - virtual void advance(size_t n_bytes) = 0; - // Copy bytes to the current cursor location (if needed) and advance the cursor - virtual void put_bytes(const void * data, size_t size) = 0; - virtual bool ignores_data() const = 0; - // Move the logical origin this many places - virtual void rebase(ptrdiff_t relative_origin) = 0; - void align(size_t n_bytes) { assert(n_bytes > 0); - size_t start_offset = offset(); + size_t start_offset = static_cast(this)->offset(); if (n_bytes == 1 || start_offset % n_bytes == 0) { return; } - advance(n_bytes - start_offset % n_bytes); - assert(offset() - start_offset < n_bytes); - assert(offset() % n_bytes == 0); + static_cast(this)->advance(n_bytes - start_offset % n_bytes); + assert(static_cast(this)->offset() - start_offset < n_bytes); + assert(static_cast(this)->offset() % n_bytes == 0); } - ptrdiff_t operator-(const CDRCursor & other) const + + ptrdiff_t operator-(const CDRCursorBase & other) const { - return static_cast(offset()) - static_cast(other.offset()); + return static_cast(static_cast(this)->offset()) - + static_cast(static_cast(other).offset()); } }; -struct SizeCursor : public CDRCursor +struct SizeCursor final : public CDRCursorBase { SizeCursor() : SizeCursor(0) {} explicit SizeCursor(size_t initial_offset) : m_offset(initial_offset) {} - explicit SizeCursor(CDRCursor & c) + explicit SizeCursor(SizeCursor & c) : m_offset(c.offset()) {} size_t m_offset; - size_t offset() const final {return m_offset;} - void advance(size_t n_bytes) final {m_offset += n_bytes;} - void put_bytes(const void *, size_t n_bytes) final {advance(n_bytes);} - bool ignores_data() const final {return true;} - void rebase(ptrdiff_t relative_origin) override + size_t offset() const {return m_offset;} + void advance(size_t n_bytes) {m_offset += n_bytes;} + void put_bytes(const void *, size_t n_bytes) {advance(n_bytes);} + bool ignores_data() const {return true;} + void rebase(ptrdiff_t relative_origin) { // we're moving the *origin* so this has to change in the *opposite* direction m_offset -= relative_origin; } }; -struct DataCursor : public CDRCursor +struct DataCursor final : public CDRCursorBase { const void * origin; void * position; @@ -100,13 +84,13 @@ struct DataCursor : public CDRCursor explicit DataCursor(void * position) : origin(position), position(position) {} - size_t offset() const final {return (const byte *)position - (const byte *)origin;} - void advance(size_t n_bytes) final + size_t offset() const {return (const byte *)position - (const byte *)origin;} + void advance(size_t n_bytes) { std::memset(position, '\0', n_bytes); position = byte_offset(position, n_bytes); } - void put_bytes(const void * bytes, size_t n_bytes) final + void put_bytes(const void * bytes, size_t n_bytes) { if (n_bytes == 0) { return; @@ -114,8 +98,8 @@ struct DataCursor : public CDRCursor std::memcpy(position, bytes, n_bytes); position = byte_offset(position, n_bytes); } - bool ignores_data() const final {return false;} - void rebase(ptrdiff_t relative_origin) final {origin = byte_offset(origin, relative_origin);} + bool ignores_data() const {return false;} + void rebase(ptrdiff_t relative_origin) {origin = byte_offset(origin, relative_origin);} }; enum class EncodingVersion @@ -236,6 +220,7 @@ class CDRWriter : public BaseCDRWriter serialize_top_level(&cursor, request); } + template void serialize_top_level( CDRCursor * cursor, const void * data) const { @@ -257,6 +242,7 @@ class CDRWriter : public BaseCDRWriter } } + template void serialize_top_level( CDRCursor * cursor, const cdds_request_wrapper_t & request) const { @@ -275,6 +261,7 @@ class CDRWriter : public BaseCDRWriter } protected: + template void put_rtps_header(CDRCursor * cursor) const { // beginning of message @@ -297,6 +284,7 @@ class CDRWriter : public BaseCDRWriter cursor->put_bytes(rtps_header.data(), rtps_header.size()); } + template void serialize_u32(CDRCursor * cursor, size_t value) const { assert(value <= std::numeric_limits::max()); @@ -431,6 +419,7 @@ class CDRWriter : public BaseCDRWriter return sizeof_ < max_align ? sizeof_ : max_align; } + template void serialize(CDRCursor * cursor, const void * data, const PrimitiveValueType & value_type) const { cursor->align(get_cdr_alignof_primitive(value_type.type_kind())); @@ -476,6 +465,7 @@ class CDRWriter : public BaseCDRWriter } } + template void serialize(CDRCursor * cursor, const void * data, const U8StringValueType & value_type) const { auto str = value_type.data(data); @@ -485,6 +475,7 @@ class CDRWriter : public BaseCDRWriter cursor->put_bytes(&terminator, 1); } + template void serialize(CDRCursor * cursor, const void * data, const U16StringValueType & value_type) const { auto str = value_type.data(data); @@ -503,12 +494,14 @@ class CDRWriter : public BaseCDRWriter } } + template void serialize(CDRCursor * cursor, const void * data, const ArrayValueType & value_type) const { serialize_many( cursor, value_type.get_data(data), value_type.array_size(), value_type.element_value_type()); } + template void serialize( CDRCursor * cursor, const void * data, const SpanSequenceValueType & value_type) const @@ -519,6 +512,7 @@ class CDRWriter : public BaseCDRWriter cursor, value_type.sequence_contents(data), count, value_type.element_value_type()); } + template void serialize( CDRCursor * cursor, const void * data, const BoolVectorValueType & value_type) const @@ -535,37 +529,17 @@ class CDRWriter : public BaseCDRWriter } } + template void serialize(CDRCursor * cursor, const void * data, const AnyValueType * value_type) const { if (lookup_trivially_serialized(cursor->offset(), value_type)) { cursor->put_bytes(data, value_type->sizeof_type()); } else { -// value_type->apply([&](const auto & vt) {return serialize(cursor, data, vt);}); - if (auto s = dynamic_cast(value_type)) { - return serialize(cursor, data, *s); - } - if (auto s = dynamic_cast(value_type)) { - return serialize(cursor, data, *s); - } - if (auto s = dynamic_cast(value_type)) { - return serialize(cursor, data, *s); - } - if (auto s = dynamic_cast(value_type)) { - return serialize(cursor, data, *s); - } - if (auto s = dynamic_cast(value_type)) { - return serialize(cursor, data, *s); - } - if (auto s = dynamic_cast(value_type)) { - return serialize(cursor, data, *s); - } - if (auto s = dynamic_cast(value_type)) { - return serialize(cursor, data, *s); - } - unreachable(); + value_type->apply([&](const auto & vt) {return serialize(cursor, data, vt);}); } } + template void serialize_many( CDRCursor * cursor, const void * data, size_t count, const AnyValueType * vt) const @@ -600,6 +574,7 @@ class CDRWriter : public BaseCDRWriter } } + template void serialize( CDRCursor * cursor, const void * struct_data, const StructValueType & struct_info) const diff --git a/rmw_cyclonedds_cpp/src/TypeSupport2.hpp b/rmw_cyclonedds_cpp/src/TypeSupport2.hpp index b4b890dfc..4152539ca 100644 --- a/rmw_cyclonedds_cpp/src/TypeSupport2.hpp +++ b/rmw_cyclonedds_cpp/src/TypeSupport2.hpp @@ -394,7 +394,7 @@ class U16StringValueType : public AnyValueType EValueType e_value_type() const final {return EValueType::U16StringValueType;} }; -struct ROSIDLC_StringValueType : public U8StringValueType +struct ROSIDLC_StringValueType final : public U8StringValueType { public: using type = rosidl_runtime_c__String; @@ -416,7 +416,7 @@ struct ROSIDLC_StringValueType : public U8StringValueType size_t sizeof_type() const override {return sizeof(type);} }; -class ROSIDLC_WStringValueType : public U16StringValueType +class ROSIDLC_WStringValueType final : public U16StringValueType { public: using type = rosidl_runtime_c__U16String; @@ -434,7 +434,7 @@ class ROSIDLC_WStringValueType : public U16StringValueType size_t sizeof_type() const override {return sizeof(type);} }; -class ROSIDLCPP_StringValueType : public U8StringValueType +class ROSIDLCPP_StringValueType final : public U8StringValueType { public: using type = std::string; @@ -452,7 +452,7 @@ class ROSIDLCPP_StringValueType : public U8StringValueType size_t sizeof_type() const override {return sizeof(type);} }; -class ROSIDLCPP_U16StringValueType : public U16StringValueType +class ROSIDLCPP_U16StringValueType final : public U16StringValueType { public: using type = std::u16string;