From cb9bef9ebeab273b2fdac93450f0fac81effc692 Mon Sep 17 00:00:00 2001 From: Lucio Rossi Date: Wed, 4 Jun 2025 16:22:21 +0200 Subject: [PATCH 1/4] mod: reverted rpclite_utils --- src/decoder.h | 86 ++++++++++++++++++++++++++- src/rpclite_utils.h | 142 -------------------------------------------- src/wrapper.h | 40 ++++++++++++- 3 files changed, 123 insertions(+), 145 deletions(-) delete mode 100644 src/rpclite_utils.h diff --git a/src/decoder.h b/src/decoder.h index 97052bc..cc53377 100644 --- a/src/decoder.h +++ b/src/decoder.h @@ -4,7 +4,6 @@ #include "MsgPack.h" #include "transport.h" #include "dispatcher.h" -#include "rpclite_utils.h" #define NO_MSG -1 @@ -294,6 +293,91 @@ class RpcDecoder { return 0; } + bool unpackArray(MsgPack::Unpacker& unpacker, size_t& size) { + MsgPack::arr_size_t sz; + unpacker.deserialize(sz); + + size = 0; + for (size_t i=0; i bytes; + return unpacker.deserialize(bytes); + } + if (unpacker.isArray()){ + static size_t arr_sz; + return unpackArray(unpacker, arr_sz); + } + if (unpacker.isMap()){ + static size_t map_sz; + return unpackMap(unpacker, map_sz); + } + if (unpacker.isFixExt() || unpacker.isExt()){ + static MsgPack::object::ext e; + return unpacker.deserialize(e); + } + if (unpacker.isTimestamp()){ + static MsgPack::object::timespec t; + return unpacker.deserialize(t); + } + + return false; + } + + }; #endif \ No newline at end of file diff --git a/src/rpclite_utils.h b/src/rpclite_utils.h deleted file mode 100644 index 9f17a44..0000000 --- a/src/rpclite_utils.h +++ /dev/null @@ -1,142 +0,0 @@ -#pragma once -#ifndef RPCLITE_UTILS_H -#define RPCLITE_UTILS_H - -#include -#include - -namespace RpcUtils { -namespace detail { - - -/////////////////////////////////////// -/// --- deserialization helpers --- /// -/////////////////////////////////////// - -bool unpackObject(MsgPack::Unpacker& unpacker); - -bool unpackArray(MsgPack::Unpacker& unpacker, size_t& size) { - MsgPack::arr_size_t sz; - unpacker.deserialize(sz); - - size = 0; - for (size_t i=0; i bytes; - return unpacker.deserialize(bytes); - } - if (unpacker.isArray()){ - static size_t arr_sz; - return unpackArray(unpacker, arr_sz); - } - if (unpacker.isMap()){ - static size_t map_sz; - return unpackMap(unpacker, map_sz); - } - if (unpacker.isFixExt() || unpacker.isExt()){ - static MsgPack::object::ext e; - return unpacker.deserialize(e); - } - if (unpacker.isTimestamp()){ - static MsgPack::object::timespec t; - return unpacker.deserialize(t); - } - - return false; -} - -template -bool deserialize_single(MsgPack::Unpacker& unpacker, T& value) { - if (!unpacker.unpackable(value)) return false; - unpacker.deserialize(value); - return true; -} - - -///////////////////////////// -/// --- tuple helpers --- /// -///////////////////////////// - -template -typename std::enable_if::type -deserialize_tuple(MsgPack::Unpacker&, std::tuple&) { - return true; -} - -template -typename std::enable_if::type -deserialize_tuple(MsgPack::Unpacker& unpacker, std::tuple& out) { - if (!deserialize_single(unpacker, std::get(out))) return false; - return deserialize_tuple(unpacker, out); -} - -template -bool deserialize_all(MsgPack::Unpacker& unpacker, std::tuple& values) { - return deserialize_tuple(unpacker, values); -} - -// Helper to invoke a function with a tuple of arguments -template -auto invoke_with_tuple(F&& f, Tuple&& t, arx::stdx::index_sequence) - -> decltype(f(std::get(std::forward(t))...)) { - return f(std::get(std::forward(t))...); -} - -} // namespace detail -} // namespace RpcUtils - -#endif //RPCLITE_UTILS_H \ No newline at end of file diff --git a/src/wrapper.h b/src/wrapper.h index 3d317be..1f132f8 100644 --- a/src/wrapper.h +++ b/src/wrapper.h @@ -2,14 +2,50 @@ #define RPCLITE_WRAPPER_H #include "error.h" -#include "rpclite_utils.h" -using namespace RpcUtils::detail; #ifdef HANDLE_RPC_ERRORS #include #endif +template +bool deserialize_single(MsgPack::Unpacker& unpacker, T& value) { + if (!unpacker.unpackable(value)) return false; + unpacker.deserialize(value); + return true; +} + + +///////////////////////////// +/// --- tuple helpers --- /// +///////////////////////////// + +template +typename std::enable_if::type +deserialize_tuple(MsgPack::Unpacker&, std::tuple&) { + return true; +} + +template +typename std::enable_if::type +deserialize_tuple(MsgPack::Unpacker& unpacker, std::tuple& out) { + if (!deserialize_single(unpacker, std::get(out))) return false; + return deserialize_tuple(unpacker, out); +} + +template +bool deserialize_all(MsgPack::Unpacker& unpacker, std::tuple& values) { + return deserialize_tuple(unpacker, values); +} + +// Helper to invoke a function with a tuple of arguments +template +auto invoke_with_tuple(F&& f, Tuple&& t, arx::stdx::index_sequence) + -> decltype(f(std::get(std::forward(t))...)) { + return f(std::get(std::forward(t))...); +} + + template class RpcFunctionWrapper; From 812dfe460d320bf75eecc8de24a039c0f4443bf9 Mon Sep 17 00:00:00 2001 From: Lucio Rossi Date: Wed, 4 Jun 2025 17:13:01 +0200 Subject: [PATCH 2/4] mod: rem static packers unpackers from decoder class --- src/decoder.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/decoder.h b/src/decoder.h index cc53377..5e73afe 100644 --- a/src/decoder.h +++ b/src/decoder.h @@ -29,7 +29,7 @@ class RpcDecoder { if (call_type!=CALL_MSG && call_type!=NOTIFY_MSG) return false; - static MsgPack::Packer packer; + MsgPack::Packer packer; packer.clear(); if (call_type == CALL_MSG){ @@ -56,7 +56,7 @@ class RpcDecoder { if (!packet_incoming() || packet_type()!=RESP_MSG) return false; - static MsgPack::Unpacker unpacker; + MsgPack::Unpacker unpacker; size_t bytes_checked = 0; @@ -86,7 +86,7 @@ class RpcDecoder { template bool send_response(const int msg_id, const RpcError& error, const RType& result) { - static MsgPack::Packer packer; + MsgPack::Packer packer; MsgPack::arr_size_t resp_size(RESPONSE_SIZE); MsgPack::object::nil_t nil; @@ -107,8 +107,8 @@ class RpcDecoder { void process_requests(RpcFunctionDispatcher& dispatcher) { if (_packet_type!=CALL_MSG && _packet_type!=NOTIFY_MSG) return; - static MsgPack::Unpacker unpacker; - static MsgPack::Packer packer; + MsgPack::Unpacker unpacker; + MsgPack::Packer packer; size_t bytes_checked = 0; @@ -196,7 +196,7 @@ class RpcDecoder { if (packet_incoming() || buffer_empty()){return;} - static MsgPack::Unpacker unpacker; + MsgPack::Unpacker unpacker; unpacker.clear(); unpacker.feed(_raw_buffer, 2); @@ -275,7 +275,7 @@ class RpcDecoder { size_t bytes_checked = 0; size_t container_size; - static MsgPack::Unpacker unpacker; + MsgPack::Unpacker unpacker; while (bytes_checked < _bytes_stored){ bytes_checked++; From c6b89faf8a3a28c9f294eabc4514bf01d14bdb09 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 5 Jun 2025 15:11:12 +0200 Subject: [PATCH 3/4] bugfix: don't overwrite random memory on flush_buffer() --- src/decoder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/decoder.h b/src/decoder.h index 5e73afe..296b006 100644 --- a/src/decoder.h +++ b/src/decoder.h @@ -263,7 +263,7 @@ class RpcDecoder { inline bool buffer_full() const { return _bytes_stored == BufferSize; } inline bool buffer_empty() const { return _bytes_stored == 0;} inline void flush_buffer() { - uint8_t* discard_buf; + uint8_t discard_buf[CHUNK_SIZE]; while (_transport.read(discard_buf, CHUNK_SIZE) > 0); _bytes_stored = 0; } From 351ca5e8eb008c25d8469cfcfbbcc0e5fda71874 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 5 Jun 2025 15:11:45 +0200 Subject: [PATCH 4/4] speedup decoding considerably --- src/SerialTransport.h | 17 ++--------------- src/client.h | 5 +++-- src/decoder.h | 11 ++++++++--- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/SerialTransport.h b/src/SerialTransport.h index 53c07d3..4cb9f14 100644 --- a/src/SerialTransport.h +++ b/src/SerialTransport.h @@ -30,21 +30,8 @@ class SerialTransport: public ITransport { } size_t read(uint8_t* buffer, size_t size) override { - - size_t r_size = 0; - - while (_stream->available()){ - if (r_size == size){ - return r_size; - } - buffer[r_size] = _stream->read(); - r_size++; - // TODO the following delay is essential for GIGA to work. Is it worth making giga-specific? - delay(1); - } - - return r_size; - + _stream->setTimeout(0); + return _stream->readBytes(buffer, size); } size_t read_byte(uint8_t& r) override { diff --git a/src/client.h b/src/client.h index 5041edb..860f238 100644 --- a/src/client.h +++ b/src/client.h @@ -32,8 +32,9 @@ class RPCClient { RpcError error; // blocking call while (!decoder.get_response(msg_id, result, error)){ - decoder.process(); - delay(1); + if (!decoder.process()) { + delay(1); + } } lastError.code = error.code; diff --git a/src/decoder.h b/src/decoder.h index 296b006..b8c52d0 100644 --- a/src/decoder.h +++ b/src/decoder.h @@ -168,8 +168,12 @@ class RpcDecoder { } - void process(){ - if (advance()) parse_packet(); + bool process(){ + if (advance()) { + parse_packet(); + return true; + } + return false; } // Fill the raw buffer to its capacity @@ -188,8 +192,9 @@ class RpcDecoder { delay(1); } } + return true; } - return true; + return false; } void parse_packet(){