diff --git a/src/core/src/serialization/ecal_serialize_common.cpp b/src/core/src/serialization/ecal_serialize_common.cpp index 6862cce..992a0e6 100644 --- a/src/core/src/serialization/ecal_serialize_common.cpp +++ b/src/core/src/serialization/ecal_serialize_common.cpp @@ -83,7 +83,7 @@ namespace eCAL /////////////////////////////////////////////// // bytes /////////////////////////////////////////////// - bool encode_bytes_field(pb_ostream_t* stream, const pb_field_iter_t* field, void* const* arg) + bool encode_bytes_field_nano_bytes(pb_ostream_t* stream, const pb_field_iter_t* field, void* const* arg) { if (arg == nullptr) return false; if (*arg == nullptr) return false; @@ -99,10 +99,28 @@ namespace eCAL { if (nano_bytes.length == 0) return; - pb_callback.funcs.encode = &encode_bytes_field; + pb_callback.funcs.encode = &encode_bytes_field_nano_bytes; pb_callback.arg = (void*)(&nano_bytes); } + bool encode_bytes_field_vec(pb_ostream_t* stream, const pb_field_iter_t* field, void* const* arg) + { + if (arg == nullptr) return false; + if (*arg == nullptr) return false; + + if (!pb_encode_tag_for_field(stream, field)) + return false; + + auto* vec = (std::vector*)(*arg); + return pb_encode_string(stream, (pb_byte_t*)vec->data(), vec->size()); + } + + void encode_bytes(pb_callback_t& pb_callback, const std::vector& vec) + { + pb_callback.funcs.encode = &encode_bytes_field_vec; + pb_callback.arg = (void*)(&vec); + } + bool decode_bytes_field(pb_istream_t* stream, const pb_field_iter_t* /*field*/, void** arg) { if (arg == nullptr) return false; diff --git a/src/core/src/serialization/ecal_serialize_common.h b/src/core/src/serialization/ecal_serialize_common.h index 20b7fd3..634cc96 100644 --- a/src/core/src/serialization/ecal_serialize_common.h +++ b/src/core/src/serialization/ecal_serialize_common.h @@ -50,6 +50,7 @@ namespace eCAL void decode_string(pb_callback_t& pb_callback, std::string& str); void encode_bytes(pb_callback_t& pb_callback, const SNanoBytes& nano_bytes); + void encode_bytes(pb_callback_t& pb_callback, const std::vector& vec); void decode_bytes(pb_callback_t& pb_callback, std::vector& vec); void encode_map(pb_callback_t& pb_callback, const std::map& str_map); diff --git a/src/core/src/serialization/ecal_serialize_sample_payload.cpp b/src/core/src/serialization/ecal_serialize_sample_payload.cpp index 5172431..64de574 100644 --- a/src/core/src/serialization/ecal_serialize_sample_payload.cpp +++ b/src/core/src/serialization/ecal_serialize_sample_payload.cpp @@ -81,15 +81,18 @@ namespace // topic content pb_sample_.has_content = true; - pb_sample_.content.id = payload_.content.id; + pb_sample_.content.id = payload_.content.id; pb_sample_.content.clock = payload_.content.clock; - pb_sample_.content.time = payload_.content.time; - pb_sample_.content.hash = payload_.content.hash; - pb_sample_.content.size = payload_.content.size; + pb_sample_.content.time = payload_.content.time; + pb_sample_.content.hash = payload_.content.hash; + pb_sample_.content.size = payload_.content.size; // topic content payload eCAL::nanopb::encode_bytes(pb_sample_.content.payload, nano_bytes_); + // padding + eCAL::nanopb::encode_bytes(pb_sample_.padding, payload_.padding); + /////////////////////////////////////////////// // evaluate byte size /////////////////////////////////////////////// @@ -154,6 +157,9 @@ namespace payload_.content.payload.type = eCAL::Payload::pl_vec; eCAL::nanopb::decode_bytes(pb_sample.content.payload, payload_.content.payload.vec); + // padding + eCAL::nanopb::decode_bytes(pb_sample.padding, payload_.padding); + /////////////////////////////////////////////// // decode it /////////////////////////////////////////////// diff --git a/src/core/src/serialization/ecal_struct_sample_payload.h b/src/core/src/serialization/ecal_struct_sample_payload.h index 0279c8b..47b033a 100644 --- a/src/core/src/serialization/ecal_struct_sample_payload.h +++ b/src/core/src/serialization/ecal_struct_sample_payload.h @@ -77,6 +77,7 @@ namespace eCAL eCmdType cmd_type = bct_none; // payload command type Topic topic; // topic information Content content; // topic content + std::vector padding; // padding to artificially increase the size of the message. This is a workaround for TCP topics, to get the actual user-payload 8-byte-aligned. REMOVE ME IN ECAL6 }; } } diff --git a/src/core/src/serialization/nanopb/ecal.pb.h b/src/core/src/serialization/nanopb/ecal.pb.h index 60a5d6a..20c8437 100644 --- a/src/core/src/serialization/nanopb/ecal.pb.h +++ b/src/core/src/serialization/nanopb/ecal.pb.h @@ -35,7 +35,7 @@ typedef struct _eCAL_pb_Content { int64_t clock; /* internal used clock */ int64_t time; /* time the content was updated */ pb_callback_t payload; /* octet stream */ - int32_t size; /* size (additional for none payload "header only samples") */ + int32_t size; /* size (redundant for compatibility) */ int64_t hash; /* unique hash for that sample */ } eCAL_pb_Content; diff --git a/src/core/src/serialization/nanopb/layer.pb.c b/src/core/src/serialization/nanopb/layer.pb.c index e2dc733..876144d 100644 --- a/src/core/src/serialization/nanopb/layer.pb.c +++ b/src/core/src/serialization/nanopb/layer.pb.c @@ -12,9 +12,6 @@ PB_BIND(eCAL_pb_LayerParUdpMC, eCAL_pb_LayerParUdpMC, AUTO) PB_BIND(eCAL_pb_LayerParShm, eCAL_pb_LayerParShm, AUTO) -PB_BIND(eCAL_pb_LayerParInproc, eCAL_pb_LayerParInproc, AUTO) - - PB_BIND(eCAL_pb_LayerParTcp, eCAL_pb_LayerParTcp, AUTO) diff --git a/src/core/src/serialization/nanopb/layer.pb.h b/src/core/src/serialization/nanopb/layer.pb.h index 2965be9..9abe83c 100644 --- a/src/core/src/serialization/nanopb/layer.pb.h +++ b/src/core/src/serialization/nanopb/layer.pb.h @@ -13,8 +13,11 @@ typedef enum _eCAL_pb_eTLayerType { eCAL_pb_eTLayerType_tl_none = 0, /* undefined */ eCAL_pb_eTLayerType_tl_ecal_udp_mc = 1, /* ecal udp multicast */ + /* 2 = ecal udp unicast (not supported anymore) + 3 = ecal udp metal (not supported anymore) */ eCAL_pb_eTLayerType_tl_ecal_shm = 4, /* ecal shared memory */ eCAL_pb_eTLayerType_tl_ecal_tcp = 5, /* ecal tcp */ + /* 42 = inproc (not supported anymore) */ eCAL_pb_eTLayerType_tl_all = 255 /* all layer */ } eCAL_pb_eTLayerType; @@ -27,10 +30,6 @@ typedef struct _eCAL_pb_LayerParShm { pb_callback_t memory_file_list; /* list of memory file names */ } eCAL_pb_LayerParShm; -typedef struct _eCAL_pb_LayerParInproc { - char dummy_field; -} eCAL_pb_LayerParInproc; - typedef struct _eCAL_pb_LayerParTcp { int32_t port; /* tcp writers port number */ } eCAL_pb_LayerParTcp; @@ -40,6 +39,7 @@ typedef struct _eCAL_pb_ConnnectionPar { eCAL_pb_LayerParUdpMC layer_par_udpmc; /* parameter for ecal udp multicast */ bool has_layer_par_shm; eCAL_pb_LayerParShm layer_par_shm; /* parameter for ecal shared memory */ + /* 3 = parameter for ecal inner process */ bool has_layer_par_tcp; eCAL_pb_LayerParTcp layer_par_tcp; /* parameter for ecal tcp */ } eCAL_pb_ConnnectionPar; @@ -66,20 +66,17 @@ extern "C" { - #define eCAL_pb_TLayer_type_ENUMTYPE eCAL_pb_eTLayerType /* Initializer values for message structs */ #define eCAL_pb_LayerParUdpMC_init_default {0} #define eCAL_pb_LayerParShm_init_default {{{NULL}, NULL}} -#define eCAL_pb_LayerParInproc_init_default {0} #define eCAL_pb_LayerParTcp_init_default {0} #define eCAL_pb_ConnnectionPar_init_default {false, eCAL_pb_LayerParUdpMC_init_default, false, eCAL_pb_LayerParShm_init_default, false, eCAL_pb_LayerParTcp_init_default} #define eCAL_pb_TLayer_init_default {_eCAL_pb_eTLayerType_MIN, 0, 0, false, eCAL_pb_ConnnectionPar_init_default} #define eCAL_pb_LayerParUdpMC_init_zero {0} #define eCAL_pb_LayerParShm_init_zero {{{NULL}, NULL}} -#define eCAL_pb_LayerParInproc_init_zero {0} #define eCAL_pb_LayerParTcp_init_zero {0} #define eCAL_pb_ConnnectionPar_init_zero {false, eCAL_pb_LayerParUdpMC_init_zero, false, eCAL_pb_LayerParShm_init_zero, false, eCAL_pb_LayerParTcp_init_zero} #define eCAL_pb_TLayer_init_zero {_eCAL_pb_eTLayerType_MIN, 0, 0, false, eCAL_pb_ConnnectionPar_init_zero} @@ -106,11 +103,6 @@ X(a, CALLBACK, REPEATED, STRING, memory_file_list, 1) #define eCAL_pb_LayerParShm_CALLBACK pb_default_field_callback #define eCAL_pb_LayerParShm_DEFAULT NULL -#define eCAL_pb_LayerParInproc_FIELDLIST(X, a) \ - -#define eCAL_pb_LayerParInproc_CALLBACK NULL -#define eCAL_pb_LayerParInproc_DEFAULT NULL - #define eCAL_pb_LayerParTcp_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, INT32, port, 1) #define eCAL_pb_LayerParTcp_CALLBACK NULL @@ -137,7 +129,6 @@ X(a, STATIC, OPTIONAL, MESSAGE, par_layer, 5) extern const pb_msgdesc_t eCAL_pb_LayerParUdpMC_msg; extern const pb_msgdesc_t eCAL_pb_LayerParShm_msg; -extern const pb_msgdesc_t eCAL_pb_LayerParInproc_msg; extern const pb_msgdesc_t eCAL_pb_LayerParTcp_msg; extern const pb_msgdesc_t eCAL_pb_ConnnectionPar_msg; extern const pb_msgdesc_t eCAL_pb_TLayer_msg; @@ -145,7 +136,6 @@ extern const pb_msgdesc_t eCAL_pb_TLayer_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define eCAL_pb_LayerParUdpMC_fields &eCAL_pb_LayerParUdpMC_msg #define eCAL_pb_LayerParShm_fields &eCAL_pb_LayerParShm_msg -#define eCAL_pb_LayerParInproc_fields &eCAL_pb_LayerParInproc_msg #define eCAL_pb_LayerParTcp_fields &eCAL_pb_LayerParTcp_msg #define eCAL_pb_ConnnectionPar_fields &eCAL_pb_ConnnectionPar_msg #define eCAL_pb_TLayer_fields &eCAL_pb_TLayer_msg @@ -155,7 +145,6 @@ extern const pb_msgdesc_t eCAL_pb_TLayer_msg; /* eCAL_pb_ConnnectionPar_size depends on runtime parameters */ /* eCAL_pb_TLayer_size depends on runtime parameters */ #define ECAL_PB_LAYER_PB_H_MAX_SIZE eCAL_pb_LayerParTcp_size -#define eCAL_pb_LayerParInproc_size 0 #define eCAL_pb_LayerParTcp_size 11 #define eCAL_pb_LayerParUdpMC_size 0 diff --git a/src/core/src/util/ecal_expmap.h b/src/core/src/util/ecal_expmap.h index 229a0f5..b9a321b 100644 --- a/src/core/src/util/ecal_expmap.h +++ b/src/core/src/util/ecal_expmap.h @@ -66,9 +66,11 @@ namespace eCAL friend class const_iterator; public: - using value_type = std::pair; - using pointer = std::pair*; - using reference = std::pair&; + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::pair; + using difference_type = std::ptrdiff_t; + using pointer = std::pair*; + using reference = std::pair&; explicit iterator(const typename key_to_value_type::iterator _it) : it(_it) @@ -102,9 +104,11 @@ namespace eCAL class const_iterator { public: - using value_type = std::pair; - using pointer = std::pair*; - using reference = std::pair&; + using iterator_category = std::bidirectional_iterator_tag; + using value_type = std::pair; + using difference_type = std::ptrdiff_t; + using pointer = std::pair*; + using reference = std::pair&; explicit const_iterator(const iterator& other) : it(other.it) diff --git a/src/protobuf/ecal.proto b/src/protobuf/ecal.proto index bf1ba16..8786162 100644 --- a/src/protobuf/ecal.proto +++ b/src/protobuf/ecal.proto @@ -31,9 +31,9 @@ message Content // topic content int64 id = 1; // sample id int64 clock = 2; // internal used clock int64 time = 3; // time the content was updated - int64 hash = 7; // unique hash for that sample - int32 size = 6; // size (additional for none payload "header only samples") bytes payload = 4; // octet stream + int32 size = 6; // size (redundant for compatibility) + int64 hash = 7; // unique hash for that sample } enum eCmdType // command type diff --git a/src/protobuf/layer.proto b/src/protobuf/layer.proto index d6de62d..b6af045 100644 --- a/src/protobuf/layer.proto +++ b/src/protobuf/layer.proto @@ -30,10 +30,6 @@ message LayerParShm repeated string memory_file_list = 1; // list of memory file names } -message LayerParInproc -{ -} - message LayerParTcp { int32 port = 1; // tcp writers port number @@ -43,6 +39,7 @@ message ConnnectionPar // connection parameter for read { LayerParUdpMC layer_par_udpmc = 1; // parameter for ecal udp multicast LayerParShm layer_par_shm = 2; // parameter for ecal shared memory + // 3 = parameter for ecal inner process LayerParTcp layer_par_tcp = 4; // parameter for ecal tcp } @@ -50,8 +47,11 @@ enum eTLayerType // transport layer { tl_none = 0; // undefined tl_ecal_udp_mc = 1; // ecal udp multicast + // 2 = ecal udp unicast (not supported anymore) + // 3 = ecal udp metal (not supported anymore) tl_ecal_shm = 4; // ecal shared memory tl_ecal_tcp = 5; // ecal tcp + // 42 = inproc (not supported anymore) tl_all = 255; // all layer } diff --git a/tests/serialization_test/src/common_generate.cpp b/tests/serialization_test/src/common_generate.cpp index ab7eab7..a5cd9a7 100644 --- a/tests/serialization_test/src/common_generate.cpp +++ b/tests/serialization_test/src/common_generate.cpp @@ -19,6 +19,7 @@ #include #include +#include namespace eCAL { @@ -36,4 +37,18 @@ namespace eCAL return result; } + + std::vector GenerateRandomVector(size_t length) + { + std::vector result; + result.reserve(length); + + for (size_t i = 0; i < length; ++i) + { + char random_byte = rand() % 256; // Generates a random byte (0-255) + result.push_back(random_byte); + } + + return result; + } } diff --git a/tests/serialization_test/src/payload_compare.cpp b/tests/serialization_test/src/payload_compare.cpp index 9be97ab..a4ae16b 100644 --- a/tests/serialization_test/src/payload_compare.cpp +++ b/tests/serialization_test/src/payload_compare.cpp @@ -75,6 +75,11 @@ namespace eCAL } } + // compare padding + if (sample1.padding != sample2.padding) { + return false; + } + // all comparisons passed, samples are equal return true; } diff --git a/tests/serialization_test/src/payload_generate.cpp b/tests/serialization_test/src/payload_generate.cpp index 9ebf01f..6731adf 100644 --- a/tests/serialization_test/src/payload_generate.cpp +++ b/tests/serialization_test/src/payload_generate.cpp @@ -24,6 +24,7 @@ namespace eCAL { std::string GenerateString(size_t length); + std::vector GenerateRandomVector(size_t length); namespace Payload { @@ -105,6 +106,7 @@ namespace eCAL sample.cmd_type = static_cast(rand() % 17); // command type sample.topic = GenerateTopic(); sample.content = GenerateContent(payload_vec); + sample.padding = GenerateRandomVector(8); return sample; }