.. _program_listing_file_include_fastcdr_Cdr.h: Program Listing for File Cdr.h ============================== |exhale_lsh| :ref:`Return to documentation for file ` (``include/fastcdr/Cdr.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef _FASTCDR_CDR_H_ #define _FASTCDR_CDR_H_ #include #include #include #include #include #include #include #include #include #include #include #include "fastcdr_dll.h" #include "CdrEncoding.hpp" #include "cdr/fixed_size_string.hpp" #include "detail/container_recursive_inspector.hpp" #include "exceptions/BadParamException.h" #include "exceptions/Exception.h" #include "exceptions/NotEnoughMemoryException.h" #include "FastBuffer.h" #include "xcdr/external.hpp" #include "xcdr/MemberId.hpp" #include "xcdr/optional.hpp" #if !__APPLE__ && !__FreeBSD__ && !__VXWORKS__ #include #else #include #endif // if !__APPLE__ && !__FreeBSD__ && !__VXWORKS__ namespace eprosima { namespace fastcdr { class Cdr; template extern void serialize( Cdr&, const _T&); template extern void deserialize( Cdr&, _T&); class Cdr { public: typedef enum : uint8_t { BIG_ENDIANNESS = 0x0, LITTLE_ENDIANNESS = 0x1 } Endianness; Cdr_DllAPI static const Endianness DEFAULT_ENDIAN; typedef enum { SHORT_HEADER, LONG_HEADER, AUTO_WITH_SHORT_HEADER_BY_DEFAULT, AUTO_WITH_LONG_HEADER_BY_DEFAULT } XCdrHeaderSelection; class state { friend class Cdr; public: Cdr_DllAPI state( const Cdr& cdr); Cdr_DllAPI state( const state& state); Cdr_DllAPI bool operator ==( const state& other_state) const; private: state& operator =( const state& state) = delete; const FastBuffer::iterator offset_; const FastBuffer::iterator origin_; bool swap_bytes_ {false}; size_t last_data_size_ {0}; MemberId next_member_id_; uint32_t member_size_ {0}; XCdrHeaderSelection header_selection_ {XCdrHeaderSelection::AUTO_WITH_SHORT_HEADER_BY_DEFAULT}; XCdrHeaderSelection header_serialized_ {XCdrHeaderSelection::SHORT_HEADER}; EncodingAlgorithmFlag previous_encoding_ {EncodingAlgorithmFlag::PLAIN_CDR2}; }; Cdr_DllAPI Cdr( FastBuffer& cdr_buffer, const Endianness endianness = DEFAULT_ENDIAN, const CdrVersion cdr_version = XCDRv2); Cdr_DllAPI Cdr& read_encapsulation(); Cdr_DllAPI Cdr& serialize_encapsulation(); Cdr_DllAPI CdrVersion get_cdr_version() const; Cdr_DllAPI EncodingAlgorithmFlag get_encoding_flag() const; Cdr_DllAPI bool set_encoding_flag( EncodingAlgorithmFlag encoding_flag); Cdr_DllAPI std::array get_dds_cdr_options() const; Cdr_DllAPI void set_dds_cdr_options( const std::array& options); Cdr_DllAPI void change_endianness( Endianness endianness); Cdr_DllAPI Endianness endianness() const; Cdr_DllAPI bool jump( size_t num_bytes); Cdr_DllAPI void reset(); Cdr_DllAPI char* get_buffer_pointer(); Cdr_DllAPI char* get_current_position(); Cdr_DllAPI size_t get_serialized_data_length() const; inline static size_t alignment( size_t current_alignment, size_t data_size) { return (data_size - (current_alignment % data_size)) & (data_size - 1); } Cdr_DllAPI state get_state() const; Cdr_DllAPI void set_state( const state& state); Cdr_DllAPI bool move_alignment_forward( size_t num_bytes); inline void reset_alignment() { origin_ = offset_; last_data_size_ = 0; } template inline Cdr& operator <<( const _T& value) { if (MEMBER_ID_INVALID == next_member_id_) { serialize(value); } else { serialize_member(next_member_id_, value); } return *this; } template inline Cdr& operator >>( _T& value) { if (MEMBER_ID_INVALID == next_member_id_) { deserialize(value); } else { deserialize_member(value); } return *this; } template::value>::type* = nullptr, typename = void> Cdr& serialize( const _T& value) { eprosima::fastcdr::serialize(*this, value); return *this; } template Cdr& serialize( const _T& value, Endianness endianness) { bool aux_swap = swap_bytes_; swap_bytes_ = (swap_bytes_ && (static_cast(endianness_) == endianness)) || (!swap_bytes_ && (static_cast(endianness_) != endianness)); try { serialize(value); swap_bytes_ = aux_swap; } catch (exception::Exception& ex) { swap_bytes_ = aux_swap; ex.raise(); } return *this; } template::value>::type* = nullptr, typename std::enable_if::type, int32_t>::value>::type* = nullptr> Cdr& serialize( const _T& value) { return serialize(static_cast(value)); } template::value>::type* = nullptr, typename std::enable_if::type, uint32_t>::value>::type* = nullptr> Cdr& serialize( const _T& value) { return serialize(static_cast(value)); } template::value>::type* = nullptr, typename std::enable_if::type, int16_t>::value>::type* = nullptr> Cdr& serialize( const _T& value) { return serialize(static_cast(value)); } template::value>::type* = nullptr, typename std::enable_if::type, uint16_t>::value>::type* = nullptr> Cdr& serialize( const _T& value) { return serialize(static_cast(value)); } template::value>::type* = nullptr, typename std::enable_if::type, int8_t>::value>::type* = nullptr> Cdr& serialize( const _T& value) { return serialize(static_cast(value)); } template::value>::type* = nullptr, typename std::enable_if::type, uint8_t>::value>::type* = nullptr> Cdr& serialize( const _T& value) { return serialize(static_cast(value)); } Cdr_DllAPI Cdr& serialize( const uint8_t& octet_t); Cdr_DllAPI Cdr& serialize( const char char_t); Cdr_DllAPI Cdr& serialize( const int8_t int8); Cdr_DllAPI Cdr& serialize( const uint16_t ushort_t); Cdr_DllAPI Cdr& serialize( const int16_t short_t); Cdr_DllAPI Cdr& serialize( const uint32_t ulong_t); Cdr_DllAPI Cdr& serialize( const int32_t long_t); Cdr_DllAPI Cdr& serialize( const wchar_t wchar); Cdr_DllAPI Cdr& serialize( const uint64_t ulonglong_t); Cdr_DllAPI Cdr& serialize( const int64_t longlong_t); Cdr_DllAPI Cdr& serialize( const float float_t); Cdr_DllAPI Cdr& serialize( const double double_t); Cdr_DllAPI Cdr& serialize( const long double ldouble_t); Cdr_DllAPI Cdr& serialize( const bool bool_t); Cdr_DllAPI Cdr& serialize( char* string_t); Cdr_DllAPI Cdr& serialize( const char* string_t); Cdr_DllAPI Cdr& serialize( const wchar_t* string_t); TEMPLATE_SPEC Cdr& serialize( const std::string& string_t) { // Check there are no null characters in the string. const char* c_str = string_t.c_str(); const auto str_len = strlen(c_str); if (string_t.size() > str_len) { throw exception::BadParamException("The string contains null characters"); } return serialize_sequence(c_str, str_len + 1); } TEMPLATE_SPEC Cdr& serialize( const std::wstring& string_t) { return serialize(string_t.c_str()); } template Cdr& serialize( const fixed_string& value) { return serialize(value.c_str()); } template Cdr& serialize( const std::array<_T, _Size>& array_t) { if (!is_multi_array_primitive(&array_t)) { Cdr::state dheader_state {allocate_xcdrv2_dheader()}; serialize_array(array_t.data(), array_t.size()); set_xcdrv2_dheader(dheader_state); } else { serialize_array(array_t.data(), array_t.size()); } return *this; } template::value && !std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& serialize( const std::vector<_T>& vector_t) { Cdr::state dheader_state {allocate_xcdrv2_dheader()}; serialize(static_cast(vector_t.size())); try { serialize_array(vector_t.data(), vector_t.size()); } catch (exception::Exception& ex) { set_state(dheader_state); ex.raise(); } set_xcdrv2_dheader(dheader_state); return *this; } template::value || std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& serialize( const std::vector<_T>& vector_t) { state state_before_error(*this); serialize(static_cast(vector_t.size())); try { serialize_array(vector_t.data(), vector_t.size()); } catch (exception::Exception& ex) { set_state(state_before_error); ex.raise(); } if (CdrVersion::XCDRv2 == cdr_version_) { serialized_member_size_ = get_serialized_member_size<_T>(); } return *this; } TEMPLATE_SPEC Cdr& serialize( const std::vector& vector_t) { return serialize_bool_sequence(vector_t); } template::value && !std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& serialize( const std::map<_K, _T>& map_t) { Cdr::state dheader_state {allocate_xcdrv2_dheader()}; serialize(static_cast(map_t.size())); try { for (auto it_pair = map_t.begin(); it_pair != map_t.end(); ++it_pair) { serialize(it_pair->first); serialize(it_pair->second); } } catch (exception::Exception& ex) { set_state(dheader_state); ex.raise(); } set_xcdrv2_dheader(dheader_state); return *this; } template::value || std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& serialize( const std::map<_K, _T>& map_t) { state state_(*this); serialize(static_cast(map_t.size())); try { for (auto it_pair = map_t.begin(); it_pair != map_t.end(); ++it_pair) { serialize(it_pair->first); serialize(it_pair->second); } } catch (exception::Exception& ex) { set_state(state_); ex.raise(); } return *this; } template ::type* = nullptr> Cdr& serialize( const std::bitset& value) { return serialize(static_cast(value.to_ulong())); } template ::type* = nullptr> Cdr& serialize( const std::bitset& value) { return serialize(static_cast(value.to_ulong())); } template ::type* = nullptr> Cdr& serialize( const std::bitset& value) { return serialize(static_cast(value.to_ulong())); } template ::type* = nullptr> Cdr& serialize( const std::bitset& value) { return serialize(static_cast(value.to_ullong())); } template Cdr& serialize_array( const _T* value, size_t num_elements) { for (size_t count = 0; count < num_elements; ++count) { serialize(value[count]); } return *this; } template Cdr& serialize_array( const _T* type_t, size_t num_elements, Endianness endianness) { bool aux_swap = swap_bytes_; swap_bytes_ = (swap_bytes_ && (static_cast(endianness_) == endianness)) || (!swap_bytes_ && (static_cast(endianness_) != endianness)); try { serialize_array(type_t, num_elements); swap_bytes_ = aux_swap; } catch (exception::Exception& ex) { swap_bytes_ = aux_swap; ex.raise(); } return *this; } TEMPLATE_SPEC Cdr& serialize_array( const uint8_t* octet_t, size_t num_elements) { return serialize_array(reinterpret_cast(octet_t), num_elements); } Cdr_DllAPI Cdr& serialize_array( const char* char_t, size_t num_elements); TEMPLATE_SPEC Cdr& serialize_array( const int8_t* int8, size_t num_elements) { return serialize_array(reinterpret_cast(int8), num_elements); } TEMPLATE_SPEC Cdr& serialize_array( const uint16_t* ushort_t, size_t num_elements) { return serialize_array(reinterpret_cast(ushort_t), num_elements); } Cdr_DllAPI Cdr& serialize_array( const int16_t* short_t, size_t num_elements); TEMPLATE_SPEC Cdr& serialize_array( const uint32_t* ulong_t, size_t num_elements) { return serialize_array(reinterpret_cast(ulong_t), num_elements); } Cdr_DllAPI Cdr& serialize_array( const int32_t* long_t, size_t num_elements); Cdr_DllAPI Cdr& serialize_array( const wchar_t* wchar, size_t num_elements); TEMPLATE_SPEC Cdr& serialize_array( const uint64_t* ulonglong_t, size_t num_elements) { return serialize_array(reinterpret_cast(ulonglong_t), num_elements); } Cdr_DllAPI Cdr& serialize_array( const int64_t* longlong_t, size_t num_elements); Cdr_DllAPI Cdr& serialize_array( const float* float_t, size_t num_elements); Cdr_DllAPI Cdr& serialize_array( const double* double_t, size_t num_elements); Cdr_DllAPI Cdr& serialize_array( const long double* ldouble_t, size_t num_elements); Cdr_DllAPI Cdr& serialize_array( const bool* bool_t, size_t num_elements); TEMPLATE_SPEC Cdr& serialize_array( const std::string* string_t, size_t num_elements) { for (size_t count = 0; count < num_elements; ++count) { serialize(string_t[count].c_str()); } return *this; } TEMPLATE_SPEC Cdr& serialize_array( const std::wstring* string_t, size_t num_elements) { for (size_t count = 0; count < num_elements; ++count) { serialize(string_t[count].c_str()); } return *this; } template Cdr& serialize_array( const fixed_string* value, size_t num_elements) { for (size_t count = 0; count < num_elements; ++count) { serialize(value[count].c_str()); } return *this; } template::value || std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& serialize_array( const std::vector<_T>& value) { serialize_array(value.data(), value.size()); return *this; } template::value && !std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& serialize_array( const std::vector<_T>& value) { Cdr::state dheader_state {allocate_xcdrv2_dheader()}; serialize_array(value.data(), value.size()); set_xcdrv2_dheader(dheader_state); return *this; } template Cdr& serialize_array( const std::vector<_T>& value, Endianness endianness) { bool aux_swap = swap_bytes_; swap_bytes_ = (swap_bytes_ && (static_cast(endianness_) == endianness)) || (!swap_bytes_ && (static_cast(endianness_) != endianness)); try { serialize_array(value); swap_bytes_ = aux_swap; } catch (exception::Exception& ex) { swap_bytes_ = aux_swap; ex.raise(); } return *this; } TEMPLATE_SPEC Cdr& serialize_array( const std::vector& value) { serialize_bool_array(value); return *this; } template::value && !std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& serialize_sequence( const _T* sequence_t, size_t num_elements) { Cdr::state dheader_state {allocate_xcdrv2_dheader()}; serialize(static_cast(num_elements)); try { serialize_array(sequence_t, num_elements); } catch (exception::Exception& ex) { set_state(dheader_state); ex.raise(); } set_xcdrv2_dheader(dheader_state); return *this; } template::value || std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& serialize_sequence( const _T* sequence_t, size_t num_elements) { state state_before_error(*this); serialize(static_cast(num_elements)); try { serialize_array(sequence_t, num_elements); } catch (exception::Exception& ex) { set_state(state_before_error); ex.raise(); } if (CdrVersion::XCDRv2 == cdr_version_) { serialized_member_size_ = get_serialized_member_size<_T>(); } return *this; } template Cdr& serialize_sequence( const _T* sequence_t, size_t num_elements, Endianness endianness) { bool aux_swap = swap_bytes_; swap_bytes_ = (swap_bytes_ && (static_cast(endianness_) == endianness)) || (!swap_bytes_ && (static_cast(endianness_) != endianness)); try { serialize_sequence(sequence_t, num_elements); swap_bytes_ = aux_swap; } catch (exception::Exception& ex) { swap_bytes_ = aux_swap; ex.raise(); } return *this; } template::value>::type* = nullptr, typename = void> Cdr& deserialize( _T& value) { eprosima::fastcdr::deserialize(*this, value); return *this; } template Cdr& deserialize( _T& value, Endianness endianness) { bool aux_swap = swap_bytes_; swap_bytes_ = (swap_bytes_ && (static_cast(endianness_) == endianness)) || (!swap_bytes_ && (static_cast(endianness_) != endianness)); try { deserialize(value); swap_bytes_ = aux_swap; } catch (exception::Exception& ex) { swap_bytes_ = aux_swap; ex.raise(); } return *this; } template::value>::type* = nullptr, typename std::enable_if::type, int32_t>::value>::type* = nullptr> Cdr& deserialize( _T& value) { int32_t decode_value {0}; deserialize(decode_value); value = static_cast<_T>(decode_value); return *this; } template::value>::type* = nullptr, typename std::enable_if::type, uint32_t>::value>::type* = nullptr> Cdr& deserialize( _T& value) { uint32_t decode_value {0}; deserialize(decode_value); value = static_cast<_T>(decode_value); return *this; } template::value>::type* = nullptr, typename std::enable_if::type, int16_t>::value>::type* = nullptr> Cdr& deserialize( _T& value) { int16_t decode_value {0}; deserialize(decode_value); value = static_cast<_T>(decode_value); return *this; } template::value>::type* = nullptr, typename std::enable_if::type, uint16_t>::value>::type* = nullptr> Cdr& deserialize( _T& value) { uint16_t decode_value {0}; deserialize(decode_value); value = static_cast<_T>(decode_value); return *this; } template::value>::type* = nullptr, typename std::enable_if::type, int8_t>::value>::type* = nullptr> Cdr& deserialize( _T& value) { int8_t decode_value {0}; deserialize(decode_value); value = static_cast<_T>(decode_value); return *this; } template::value>::type* = nullptr, typename std::enable_if::type, uint8_t>::value>::type* = nullptr> Cdr& deserialize( _T& value) { uint8_t decode_value {0}; deserialize(decode_value); value = static_cast<_T>(decode_value); return *this; } TEMPLATE_SPEC Cdr& deserialize( uint8_t& octet_t) { return deserialize(reinterpret_cast(octet_t)); } Cdr_DllAPI Cdr& deserialize( char& char_t); TEMPLATE_SPEC Cdr& deserialize( int8_t& int8) { return deserialize(reinterpret_cast(int8)); } TEMPLATE_SPEC Cdr& deserialize( uint16_t& ushort_t) { return deserialize(reinterpret_cast(ushort_t)); } Cdr_DllAPI Cdr& deserialize( int16_t& short_t); TEMPLATE_SPEC Cdr& deserialize( uint32_t& ulong_t) { return deserialize(reinterpret_cast(ulong_t)); } Cdr_DllAPI Cdr& deserialize( int32_t& long_t); TEMPLATE_SPEC Cdr& deserialize( wchar_t& wchar) { uint16_t ret; deserialize(ret); wchar = static_cast(ret); return *this; } TEMPLATE_SPEC Cdr& deserialize( uint64_t& ulonglong_t) { return deserialize(reinterpret_cast(ulonglong_t)); } Cdr_DllAPI Cdr& deserialize( int64_t& longlong_t); Cdr_DllAPI Cdr& deserialize( float& float_t); Cdr_DllAPI Cdr& deserialize( double& double_t); Cdr_DllAPI Cdr& deserialize( long double& ldouble_t); Cdr_DllAPI Cdr& deserialize( bool& bool_t); Cdr_DllAPI Cdr& deserialize( char*& string_t); Cdr_DllAPI Cdr& deserialize( wchar_t*& string_t); TEMPLATE_SPEC Cdr& deserialize( std::string& string_t) { uint32_t length = 0; const char* str = read_string(length); string_t.assign(str, length); return *this; } TEMPLATE_SPEC Cdr& deserialize( std::wstring& string_t) { uint32_t length = 0; string_t = read_wstring(length); return *this; } template Cdr& deserialize( fixed_string& value) { uint32_t length = 0; const char* str = read_string(length); value.assign(str, length); return *this; } template Cdr& deserialize( std::array<_T, _Size>& array_t) { if (CdrVersion::XCDRv2 == cdr_version_ && !is_multi_array_primitive(&array_t)) { uint32_t dheader {0}; deserialize(dheader); uint32_t count {0}; auto offset = offset_; while (offset_ - offset < dheader && count < _Size) { deserialize_array(&array_t.data()[count], 1); ++count; } if (offset_ - offset != dheader) { throw exception::BadParamException("Member size greater than size specified by DHEADER"); } } else { return deserialize_array(array_t.data(), array_t.size()); } return *this; } template::value && !std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& deserialize( std::vector<_T>& vector_t) { uint32_t sequence_length {0}; if (CdrVersion::XCDRv2 == cdr_version_) { uint32_t dheader {0}; deserialize(dheader); auto offset = offset_; deserialize(sequence_length); if (0 == sequence_length) { vector_t.clear(); return *this; } else { vector_t.resize(sequence_length); } uint32_t count {0}; while (offset_ - offset < dheader && count < sequence_length) { deserialize(vector_t.data()[count]); ++count; } if (offset_ - offset != dheader) { throw exception::BadParamException("Member size differs from the size specified by DHEADER"); } } else { state state_before_error(*this); deserialize(sequence_length); if (sequence_length == 0) { vector_t.clear(); return *this; } if ((end_ - offset_) < sequence_length) { set_state(state_before_error); throw exception::NotEnoughMemoryException( exception::NotEnoughMemoryException::NOT_ENOUGH_MEMORY_MESSAGE_DEFAULT); } try { vector_t.resize(sequence_length); return deserialize_array(vector_t.data(), vector_t.size()); } catch (exception::Exception& ex) { set_state(state_before_error); ex.raise(); } } return *this; } template::value || std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& deserialize( std::vector<_T>& vector_t) { uint32_t sequence_length = 0; state state_before_error(*this); deserialize(sequence_length); if (sequence_length == 0) { vector_t.clear(); return *this; } if ((end_ - offset_) < sequence_length) { set_state(state_before_error); throw exception::NotEnoughMemoryException( exception::NotEnoughMemoryException::NOT_ENOUGH_MEMORY_MESSAGE_DEFAULT); } try { vector_t.resize(sequence_length); return deserialize_array(vector_t.data(), vector_t.size()); } catch (exception::Exception& ex) { set_state(state_before_error); ex.raise(); } return *this; } TEMPLATE_SPEC Cdr& deserialize( std::vector& vector_t) { return deserialize_bool_sequence(vector_t); } template::value && !std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& deserialize( std::map<_K, _T>& map_t) { if (CdrVersion::XCDRv2 == cdr_version_) { uint32_t dheader {0}; deserialize(dheader); auto offset = offset_; uint32_t map_length {0}; deserialize(map_length); map_t.clear(); uint32_t count {0}; while (offset_ - offset < dheader && count < map_length) { _K key; _T val; deserialize(key); deserialize(val); map_t.emplace(std::pair<_K, _T>(std::move(key), std::move(val))); ++count; } if (offset_ - offset != dheader) { throw exception::BadParamException("Member size greater than size specified by DHEADER"); } } else { uint32_t sequence_length = 0; state state_(*this); deserialize(sequence_length); map_t.clear(); try { for (uint32_t i = 0; i < sequence_length; ++i) { _K key; _T value; deserialize(key); deserialize(value); map_t.emplace(std::pair<_K, _T>(std::move(key), std::move(value))); } } catch (exception::Exception& ex) { set_state(state_); ex.raise(); } } return *this; } template::value || std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& deserialize( std::map<_K, _T>& map_t) { uint32_t sequence_length = 0; state state_(*this); deserialize(sequence_length); try { for (uint32_t i = 0; i < sequence_length; ++i) { _K key; _T value; deserialize(key); deserialize(value); map_t.emplace(std::pair<_K, _T>(std::move(key), std::move(value))); } } catch (exception::Exception& ex) { set_state(state_); ex.raise(); } return *this; } template ::type* = nullptr> Cdr& deserialize( std::bitset& value) { uint8_t decode_value {0}; deserialize(decode_value); value = decode_value; return *this; } template ::type* = nullptr> Cdr& deserialize( std::bitset& value) { uint16_t decode_value {0}; deserialize(decode_value); value = decode_value; return *this; } template ::type* = nullptr> Cdr& deserialize( std::bitset& value) { uint32_t decode_value {0}; deserialize(decode_value); value = decode_value; return *this; } template ::type* = nullptr> Cdr& deserialize( std::bitset& value) { uint64_t decode_value {0}; deserialize(decode_value); value = decode_value; return *this; } template Cdr& deserialize_array( _T* value, size_t num_elements) { for (size_t count = 0; count < num_elements; ++count) { deserialize(value[count]); } return *this; } template Cdr& deserialize_array( _T* type_t, size_t num_elements, Endianness endianness) { bool aux_swap = swap_bytes_; swap_bytes_ = (swap_bytes_ && (static_cast(endianness_) == endianness)) || (!swap_bytes_ && (static_cast(endianness_) != endianness)); try { deserialize_array(type_t, num_elements); swap_bytes_ = aux_swap; } catch (exception::Exception& ex) { swap_bytes_ = aux_swap; ex.raise(); } return *this; } TEMPLATE_SPEC Cdr& deserialize_array( uint8_t* octet_t, size_t num_elements) { return deserialize_array(reinterpret_cast(octet_t), num_elements); } Cdr_DllAPI Cdr& deserialize_array( char* char_t, size_t num_elements); TEMPLATE_SPEC Cdr& deserialize_array( int8_t* int8, size_t num_elements) { return deserialize_array(reinterpret_cast(int8), num_elements); } TEMPLATE_SPEC Cdr& deserialize_array( uint16_t* ushort_t, size_t num_elements) { return deserialize_array(reinterpret_cast(ushort_t), num_elements); } Cdr_DllAPI Cdr& deserialize_array( int16_t* short_t, size_t num_elements); TEMPLATE_SPEC Cdr& deserialize_array( uint32_t* ulong_t, size_t num_elements) { return deserialize_array(reinterpret_cast(ulong_t), num_elements); } Cdr_DllAPI Cdr& deserialize_array( int32_t* long_t, size_t num_elements); Cdr_DllAPI Cdr& deserialize_array( wchar_t* wchar, size_t num_elements); TEMPLATE_SPEC Cdr& deserialize_array( uint64_t* ulonglong_t, size_t num_elements) { return deserialize_array(reinterpret_cast(ulonglong_t), num_elements); } Cdr_DllAPI Cdr& deserialize_array( int64_t* longlong_t, size_t num_elements); Cdr_DllAPI Cdr& deserialize_array( float* float_t, size_t num_elements); Cdr_DllAPI Cdr& deserialize_array( double* double_t, size_t num_elements); Cdr_DllAPI Cdr& deserialize_array( long double* ldouble_t, size_t num_elements); Cdr_DllAPI Cdr& deserialize_array( bool* bool_t, size_t num_elements); template::value || std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& deserialize_array( std::vector<_T>& value) { deserialize_array(value.data(), value.size()); return *this; } template::value && !std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& deserialize_array( std::vector<_T>& value) { if (CdrVersion::XCDRv2 == cdr_version_) { uint32_t dheader {0}; deserialize(dheader); uint32_t count {0}; auto offset = offset_; while (offset_ - offset < dheader && count < value.size()) { deserialize_array(&value.data()[count], 1); ++count; } if (offset_ - offset != dheader) { throw exception::BadParamException("Member size greater than size specified by DHEADER"); } } else { return deserialize_array(value.data(), value.size()); } return *this; } template Cdr& deserialize_array( std::vector<_T>& value, Endianness endianness) { bool aux_swap = swap_bytes_; swap_bytes_ = (swap_bytes_ && (static_cast(endianness_) == endianness)) || (!swap_bytes_ && (static_cast(endianness_) != endianness)); try { deserialize_array(value); swap_bytes_ = aux_swap; } catch (exception::Exception& ex) { swap_bytes_ = aux_swap; ex.raise(); } return *this; } TEMPLATE_SPEC Cdr& deserialize_array( std::vector& value) { deserialize_bool_array(value); return *this; } template::value && !std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& deserialize_sequence( _T*& sequence_t, size_t& num_elements) { uint32_t sequence_length {0}; if (CdrVersion::XCDRv2 == cdr_version_) { uint32_t dheader {0}; deserialize(dheader); auto offset = offset_; deserialize(sequence_length); try { sequence_t = reinterpret_cast<_T*>(calloc(sequence_length, sizeof(_T))); uint32_t count {0}; while (offset_ - offset < dheader && count < sequence_length) { deserialize(sequence_t[count]); ++count; } if (offset_ - offset != dheader) { throw exception::BadParamException("Member size greater than size specified by DHEADER"); } } catch (exception::Exception& ex) { free(sequence_t); sequence_t = NULL; ex.raise(); } } else { state state_before_error(*this); deserialize(sequence_length); if ((end_ - offset_) < sequence_length) { set_state(state_before_error); throw exception::NotEnoughMemoryException( exception::NotEnoughMemoryException::NOT_ENOUGH_MEMORY_MESSAGE_DEFAULT); } try { sequence_t = reinterpret_cast<_T*>(calloc(sequence_length, sizeof(_T))); deserialize_array(sequence_t, sequence_length); } catch (exception::Exception& ex) { free(sequence_t); sequence_t = NULL; set_state(state_before_error); ex.raise(); } } num_elements = sequence_length; return *this; } template::value || std::is_arithmetic<_T>::value>::type* = nullptr> Cdr& deserialize_sequence( _T*& sequence_t, size_t& num_elements) { uint32_t sequence_length = 0; state state_before_error(*this); deserialize(sequence_length); try { sequence_t = reinterpret_cast<_T*>(calloc(sequence_length, sizeof(_T))); deserialize_array(sequence_t, sequence_length); } catch (exception::Exception& ex) { free(sequence_t); sequence_t = NULL; set_state(state_before_error); ex.raise(); } num_elements = sequence_length; return *this; } template Cdr& deserialize_sequence( _T*& sequence_t, size_t& num_elements, Endianness endianness) { bool aux_swap = swap_bytes_; swap_bytes_ = (swap_bytes_ && (static_cast(endianness_) == endianness)) || (!swap_bytes_ && (static_cast(endianness_) != endianness)); try { deserialize_sequence(sequence_t, num_elements); swap_bytes_ = aux_swap; } catch (exception::Exception& ex) { swap_bytes_ = aux_swap; ex.raise(); } return *this; } TEMPLATE_SPEC Cdr& deserialize_sequence( std::string*& sequence_t, size_t& num_elements) { return deserialize_string_sequence(sequence_t, num_elements); } TEMPLATE_SPEC Cdr& deserialize_sequence( std::wstring*& sequence_t, size_t& num_elements) { return deserialize_wstring_sequence(sequence_t, num_elements); } template Cdr& serialize_member( const MemberId& member_id, const _T& member_value, XCdrHeaderSelection header_selection = XCdrHeaderSelection::AUTO_WITH_SHORT_HEADER_BY_DEFAULT) { Cdr::state current_state(*this); (this->*begin_serialize_member_)(member_id, true, current_state, header_selection); serialize(member_value); return (this->*end_serialize_member_)(current_state); } template Cdr& serialize_member( const MemberId& member_id, const optional<_T>& member_value, XCdrHeaderSelection header_selection = XCdrHeaderSelection::AUTO_WITH_SHORT_HEADER_BY_DEFAULT) { Cdr::state current_state(*this); (this->*begin_serialize_opt_member_)(member_id, member_value.has_value(), current_state, header_selection); serialize(member_value); return (this->*end_serialize_opt_member_)(current_state); } template Cdr& deserialize_member( _T& member_value) { return deserialize(member_value); } template Cdr& deserialize_member( optional<_T>& member_value) { if (EncodingAlgorithmFlag::PLAIN_CDR == current_encoding_) { Cdr::state current_state(*this); MemberId member_id; xcdr1_deserialize_member_header(member_id, current_state); auto prev_offset = offset_; if (0 < current_state.member_size_) { deserialize(member_value); } if (current_state.member_size_ != offset_ - prev_offset) { throw exception::BadParamException( "Member size provided by member header is not equal to the real decoded member size"); } } else { deserialize(member_value); } return *this; } Cdr_DllAPI Cdr& begin_serialize_type( Cdr::state& current_state, EncodingAlgorithmFlag type_encoding); Cdr_DllAPI Cdr& end_serialize_type( Cdr::state& current_state); Cdr_DllAPI Cdr& deserialize_type( EncodingAlgorithmFlag type_encoding, std::function functor); template Cdr& serialize( const optional<_T>& value) { if (CdrVersion::XCDRv2 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR2 != current_encoding_) { serialize(value.has_value()); } if (value.has_value()) { serialize(*value); } return *this; } template Cdr& serialize( const external<_T>& value) { if (!value) { throw exception::BadParamException("External member is null"); } serialize(*value); return *this; } Cdr_DllAPI Cdr& operator <<( const MemberId& member_id); template Cdr& deserialize( optional<_T>& value) { bool is_present = true; if (CdrVersion::XCDRv2 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR2 != current_encoding_) { deserialize(is_present); } value.reset(is_present); if (is_present) { deserialize(*value); } return *this; } template Cdr& deserialize( external<_T>& value) { if (value.is_locked()) { throw exception::BadParamException("External member is locked"); } if (!value) { value = external<_T>{new typename external<_T>::type()}; } deserialize(*value); return *this; } template Cdr& deserialize( optional>& value) { if (value.has_value() && value.value().is_locked()) { throw exception::BadParamException("External member is locked"); } bool is_present = true; if (CdrVersion::XCDRv2 == cdr_version_ && EncodingAlgorithmFlag::PL_CDR2 != current_encoding_) { deserialize(is_present); } value.reset(is_present); if (is_present) { deserialize(*value); } return *this; } Cdr_DllAPI state allocate_xcdrv2_dheader(); Cdr_DllAPI void set_xcdrv2_dheader( const state& state); private: Cdr( const Cdr&) = delete; Cdr& operator =( const Cdr&) = delete; Cdr_DllAPI Cdr& serialize_bool_array( const std::vector& vector_t); Cdr_DllAPI Cdr& serialize_bool_sequence( const std::vector& vector_t); Cdr_DllAPI Cdr& deserialize_bool_array( std::vector& vector_t); Cdr_DllAPI Cdr& deserialize_bool_sequence( std::vector& vector_t); Cdr_DllAPI Cdr& deserialize_string_sequence( std::string*& sequence_t, size_t& num_elements); Cdr_DllAPI Cdr& deserialize_wstring_sequence( std::wstring*& sequence_t, size_t& num_elements); template Cdr& serialize_array( const std::array<_T, _Size>* array_t, size_t num_elements) { return serialize_array(array_t->data(), num_elements * array_t->size()); } template Cdr& deserialize_array( std::array<_T, _Size>* array_t, size_t num_elements) { return deserialize_array(array_t->data(), num_elements * array_t->size()); } template Cdr& deserialize_array( std::array<_T, _Size>* array_t, size_t num_elements, Endianness endianness) { return deserialize_array(array_t->data(), num_elements * array_t->size(), endianness); } inline size_t alignment( size_t data_size) const { return data_size > last_data_size_ ? (data_size - ((offset_ - origin_) % data_size)) & (data_size - 1) : 0; } inline void make_alignment( size_t align) { offset_ += align; last_data_size_ = 0; } bool resize( size_t min_size_inc); Cdr_DllAPI const char* read_string( uint32_t& length); Cdr_DllAPI const std::wstring read_wstring( uint32_t& length); void xcdr1_serialize_short_member_header( const MemberId& member_id); void xcdr1_end_short_member_header( const MemberId& member_id, size_t member_serialized_size); void xcdr1_serialize_long_member_header( const MemberId& member_id); void xcdr1_end_long_member_header( const MemberId& member_id, size_t member_serialized_size); void xcdr1_change_to_short_member_header( const MemberId& member_id, size_t member_serialized_size); void xcdr1_change_to_long_member_header( const MemberId& member_id, size_t member_serialized_size); Cdr_DllAPI bool xcdr1_deserialize_member_header( MemberId& member_id, Cdr::state& current_state); void xcdr2_serialize_short_member_header( const MemberId& member_id); void xcdr2_end_short_member_header( const MemberId& member_id, size_t member_serialized_size); void xcdr2_serialize_long_member_header( const MemberId& member_id); void xcdr2_end_long_member_header( const MemberId& member_id, size_t member_serialized_size); void xcdr2_change_to_short_member_header( const MemberId& member_id, size_t member_serialized_size); void xcdr2_change_to_long_member_header( const MemberId& member_id, size_t member_serialized_size); void xcdr2_shrink_to_long_member_header( const MemberId& member_id, const FastBuffer::iterator& offset); void xcdr2_deserialize_member_header( MemberId& member_id, Cdr::state& current_state); Cdr& xcdr1_begin_serialize_member( const MemberId& member_id, bool is_present, Cdr::state& current_state, XCdrHeaderSelection header_selection); Cdr& xcdr1_end_serialize_member( const Cdr::state& current_state); Cdr& xcdr1_begin_serialize_opt_member( const MemberId& member_id, bool is_present, Cdr::state& current_state, XCdrHeaderSelection header_selection); Cdr& xcdr1_end_serialize_opt_member( const Cdr::state& current_state); Cdr& xcdr2_begin_serialize_member( const MemberId& member_id, bool is_present, Cdr::state& current_state, XCdrHeaderSelection header_selection); Cdr& xcdr2_end_serialize_member( const Cdr::state& current_state); Cdr& xcdr1_begin_serialize_type( Cdr::state& current_state, EncodingAlgorithmFlag type_encoding) noexcept; Cdr& xcdr1_end_serialize_type( const Cdr::state& current_state); Cdr& xcdr2_begin_serialize_type( Cdr::state& current_state, EncodingAlgorithmFlag type_encoding); Cdr& xcdr2_end_serialize_type( const Cdr::state& current_state); Cdr& xcdr1_deserialize_type( EncodingAlgorithmFlag type_encoding, std::function functor); Cdr& xcdr2_deserialize_type( EncodingAlgorithmFlag type_encoding, std::function functor); Cdr& cdr_begin_serialize_member( const MemberId& member_id, bool is_present, Cdr::state& current_state, XCdrHeaderSelection header_selection); Cdr& cdr_end_serialize_member( const Cdr::state& current_state); Cdr& cdr_begin_serialize_type( Cdr::state& current_state, EncodingAlgorithmFlag type_encoding); Cdr& cdr_end_serialize_type( const Cdr::state& current_state); Cdr& cdr_deserialize_type( EncodingAlgorithmFlag type_encoding, std::function functor); void reset_callbacks(); using begin_serialize_member_functor = Cdr& (Cdr::*)( const MemberId&, bool, Cdr::state&, XCdrHeaderSelection); begin_serialize_member_functor begin_serialize_member_ { nullptr }; using end_serialize_member_functor = Cdr& (Cdr::*)( const Cdr::state&); end_serialize_member_functor end_serialize_member_ { nullptr }; using begin_serialize_opt_member_functor = Cdr& (Cdr::*)( const MemberId&, bool, Cdr::state&, XCdrHeaderSelection); begin_serialize_opt_member_functor begin_serialize_opt_member_ { nullptr }; using end_serialize_memberopt__functor = Cdr& (Cdr::*)( const Cdr::state&); end_serialize_member_functor end_serialize_opt_member_ { nullptr }; using begin_serialize_type_functor = Cdr& (Cdr::*)( Cdr::state&, EncodingAlgorithmFlag); begin_serialize_type_functor begin_serialize_type_ { nullptr }; using end_serialize_type_functor = Cdr& (Cdr::*)( const Cdr::state&); end_serialize_type_functor end_serialize_type_ { nullptr }; using deserialize_type_functor = Cdr& (Cdr::*)( EncodingAlgorithmFlag, std::function); deserialize_type_functor deserialize_type_ { nullptr }; FastBuffer& cdr_buffer_; CdrVersion cdr_version_ {CdrVersion::XCDRv2}; EncodingAlgorithmFlag encoding_flag_ {EncodingAlgorithmFlag::PLAIN_CDR2}; EncodingAlgorithmFlag current_encoding_ {EncodingAlgorithmFlag::PLAIN_CDR2}; std::array options_{{0}}; uint8_t endianness_ {Endianness::LITTLE_ENDIANNESS}; bool swap_bytes_ {false}; size_t last_data_size_ {0}; FastBuffer::iterator offset_; FastBuffer::iterator origin_; FastBuffer::iterator end_; MemberId next_member_id_; size_t align64_ {4}; enum SerializedMemberSizeForNextInt { NO_SERIALIZED_MEMBER_SIZE, SERIALIZED_MEMBER_SIZE, SERIALIZED_MEMBER_SIZE_4, SERIALIZED_MEMBER_SIZE_8 } serialized_member_size_ {NO_SERIALIZED_MEMBER_SIZE}; state initial_state_; bool encapsulation_serialized_ {false}; uint32_t get_long_lc( SerializedMemberSizeForNextInt serialized_member_size); uint32_t get_short_lc( size_t member_serialized_size); template::value || std::is_arithmetic<_T>::value>::type* = nullptr> constexpr SerializedMemberSizeForNextInt get_serialized_member_size() const { return (1 == sizeof(_T) ? SERIALIZED_MEMBER_SIZE : (4 == sizeof(_T) ? SERIALIZED_MEMBER_SIZE_4 : (8 == sizeof(_T) ? SERIALIZED_MEMBER_SIZE_8 : NO_SERIALIZED_MEMBER_SIZE))); } }; } //namespace fastcdr } //namespace eprosima #endif // _CDR_CDR_H_