From 25f60e561b220916af872c868247374c11112e33 Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Fri, 4 Oct 2024 17:26:15 +0300 Subject: [PATCH] ... --- common/adc_utils.h | 2 +- net/adc_device_netmsg.h | 55 ++++++++++++ net/adc_netmsg.h | 190 +++++++++++++++++++++++++++++++++------- net/adc_netproto.h | 2 + 4 files changed, 214 insertions(+), 35 deletions(-) create mode 100644 net/adc_device_netmsg.h diff --git a/common/adc_utils.h b/common/adc_utils.h index b42f1f2..7362b14 100644 --- a/common/adc_utils.h +++ b/common/adc_utils.h @@ -410,7 +410,7 @@ public: if constexpr (traits::adc_is_tuple_v) { AdcCharRangeFromTuple(res, value, DELIMITER); - } else if constexpr (traits::adc_input_char_range) { + } else if constexpr (std::ranges::range) { AdcCharRangeFromValueRange(res, value, DELIMITER); } else { res = AdcTrivialSerializer(value); diff --git a/net/adc_device_netmsg.h b/net/adc_device_netmsg.h new file mode 100644 index 0000000..aad5c34 --- /dev/null +++ b/net/adc_device_netmsg.h @@ -0,0 +1,55 @@ +#pragma once + +#include "../common/adc_utils.h" +#include "adc_netmsg.h" + +namespace adc +{ + +/* ABSTRACT DEVICE DEFAULT APPLICATION-LEVEL NETWORK PROTOCOL DEFINITIONS */ + +namespace constants +{ + +static constexpr char ADC_DEFAULT_KEY_PARAM_DELIMITER[] = " "; +static constexpr char ADC_DEFAULT_PARAM_PARAM_DELIMITER[] = " "; + +} // namespace constants + + +template +class AdcDeviceNetMessage : protected AdcKeyValueMessage +{ + using base_t = AdcKeyValueMessage; + +public: + static constexpr std::span keyParamDelimiter{constants::ADC_DEFAULT_KEY_PARAM_DELIMITER, + sizeof(constants::ADC_DEFAULT_KEY_PARAM_DELIMITER)}; + + static constexpr std::span paramParamDelimiter{constants::ADC_DEFAULT_PARAM_PARAM_DELIMITER, + sizeof(constants::ADC_DEFAULT_PARAM_PARAM_DELIMITER)}; + + + AdcDeviceNetMessage(ByteSeqT& byte_seq) : base_t(byte_seq) {} + + template + VT keyword() const + { + auto v = utils::AdcTrimSpaces(base_t::template key()); + return VT(v.begin(), v.end()); + } + + auto keyword() const + { + return keyword(); + } + + + template + auto params(size_t start = 0, size_t N = std::numeric_limits::max()) + { + auto val = base_t::template value>(); + } +}; + +} // namespace adc diff --git a/net/adc_netmsg.h b/net/adc_netmsg.h index d7676d0..0e509bd 100644 --- a/net/adc_netmsg.h +++ b/net/adc_netmsg.h @@ -27,7 +27,7 @@ namespace utils template -void convertToBytes(ByteStorageT& res, const T& v, const Ts&... vs) +static void convertToBytes(ByteStorageT& res, const T& v, const Ts&... vs) { if constexpr (std::is_array_v>) { // to handle with trailing '\0' in plain char array convertToBytes(res, std::string_view(v), vs...); @@ -49,6 +49,69 @@ void convertToBytes(ByteStorageT& res, const T& v, const Ts&... vs) } +template +struct AdcTokenManip { + AdcTokenManip(R& byte_seq) : _byteSequence(byte_seq) {} + + template + auto tokens(const DR& delimiter, size_t start = 0, size_t num = std::numeric_limits::max()) + { + std::span dl; + + if constexpr (std::is_array_v) { + dl = std::span(delimiter, sizeof(delimiter) - 1); // remove trailing '\0' + } else { + dl = std::span(delimiter); + } + + return std::views::split(_byteSequence, dl) | std::views::drop(start) | std::views::take(num); + } + + template + AdcTokenManip& addTokens(const DR& delimiter, T&& v, Ts&&... vs) + { + std::span dl; + + if constexpr (std::is_array_v) { + dl = std::span(delimiter, sizeof(delimiter) - 1); // remove trailing '\0' + } else { + dl = std::span(delimiter); + } + + if (std::ranges::size(_byteSequence)) { + std::ranges::copy(dl, std::back_inserter(_byteSequence)); + } + + convertToBytes(_byteSequence, std::forward(v)); + + if constexpr (sizeof...(Ts)) { + addTokens(dl, std::forward(vs)...); + } + + return *this; + } + + + template + AdcTokenManip& setTokens(const DR& delimiter, T&& v, Ts&&... vs) + { + if (std::ranges::size(_byteSequence)) { + if constexpr (traits::adc_has_clear_c) { + _byteSequence.clear(); + } else { + _byteSequence = R(); + } + } + + return addTokens(delimiter, std::forward(v), std::forward(vs)...); + } + + +private: + R& _byteSequence; +}; + + } // namespace utils @@ -219,6 +282,7 @@ namespace constants { static constexpr char ADC_DEFAULT_TOKEN_DELIMITER[] = " "; static constexpr char ADC_DEFAULT_KEY_TOKEN_DELIMITER[] = " "; +static constexpr char ADC_DEFAULT_KEY_VALUE_DELIMITER[] = " "; } // namespace constants @@ -545,47 +609,97 @@ public: template -class AdcTokenMessage +class AdcTokenMessage : utils::AdcTokenManip { + using base_t = utils::AdcTokenManip; + public: static constexpr std::span tokenDelimiter{DELIM, sizeof(DELIM) - 1}; // "-1" to remove trailing '\0' - AdcTokenMessage(R& byte_seq) : _byteSequence(byte_seq) {} + AdcTokenMessage(R& byte_seq) : base_t(byte_seq) {} - auto parts(size_t start_idx = 0, size_t N = std::numeric_limits::max()) - { - return tokens(start_idx, N); - } + // auto tokens(size_t start = 0, size_t num = std::numeric_limits::max()) + // { + // std::vector> res; + // std::ranges::for_each(base_t::tokens(tokenDelimiter, start, num), + // [&res](const auto& el) { res.emplace_back(el.begin(), el.end()); }); - template - auto addParts(T&& part, Ts&&... parts) - { - return addToken(std::forward(part), std::forward(parts)...); - } + // return res; + // } - auto tokens(size_t start_idx = 0, size_t N = std::numeric_limits::max()) + template + auto tokens(RT& res, size_t start = 0, size_t num = std::numeric_limits::max()) { - return std::views::split(_byteSequence, tokenDelimiter) | std::views::drop(start_idx) | std::views::take(N); + std::ranges::for_each(base_t::tokens(tokenDelimiter, start, num), + [&res](const auto& el) { res.emplace_back(el.begin(), el.end()); }); + + return &res; } template AdcTokenMessage& addTokens(TokT&& token, TokTs&&... tokens) { - if (std::ranges::size(_byteSequence)) { - std::ranges::copy(tokenDelimiter, std::back_inserter(_byteSequence)); - } - - utils::convertToBytes(_byteSequence, std::forward(token)); - - if constexpr (sizeof...(TokTs)) { - addTokens(std::forward(tokens)...); - } + base_t::addTokens(tokenDelimiter, std::forward(token), std::forward(tokens)...); return *this; } template AdcTokenMessage& setTokens(TokT&& token, TokTs&&... tokens) + { + base_t::setTokens(tokenDelimiter, std::forward(token), std::forward(tokens)...); + return *this; + } + +protected: + R& _byteSequence; +}; + + +template +class AdcKeyValueMessage +{ +public: + static constexpr std::span keyvalueDelimiter{KEY_VALUE_DELIM, sizeof(KEY_VALUE_DELIM) - 1}; + + AdcKeyValueMessage(R& byte_seq) : _byteSequence(byte_seq) {} + + template + auto key() const + { + auto r = std::ranges::search(_byteSequence, keyvalueDelimiter); + if (r.empty()) { + return VT(); + } + + return VT(_byteSequence.begin(), r.begin()); + } + + auto key() const + { + return key(); + } + + template + auto value() const + { + auto r = std::ranges::search(_byteSequence, keyvalueDelimiter); + if (r.empty()) { + return VT(); + } + + return VT(r.end(), _byteSequence.end()); + } + + + auto value() const + { + return value(); + } + + + template + AdcKeyValueMessage& setKeyValue(KeyT&& key, ValueT&& value) { if (std::ranges::size(_byteSequence)) { if constexpr (traits::adc_has_clear_c) { @@ -595,21 +709,29 @@ public: } } - return addTokens(std::forward(token), std::forward(tokens)...); + utils::convertToBytes(_byteSequence, std::forward(key)); + std::ranges::copy(keyvalueDelimiter, std::back_inserter(_byteSequence)); + utils::convertToBytes(_byteSequence, std::forward(value)); + + return *this; } -protected: - R& _byteSequence; -}; + template + AdcKeyValueMessage& setValue(ValueT&& value) + { + if (std::ranges::size(_byteSequence)) { + if constexpr (traits::adc_has_clear_c) { + _byteSequence.clear(); + } else { + _byteSequence = R(); + } + } + std::vector kw; + std::ranges::copy(key>(), std::back_inserter(kw)); -template -class AdcKeyValueMessage -{ -public: - AdcKeyValueMessage(R& byte_seq) : _byteSequence(byte_seq) {} + return setKeyValue(kw, std::forward(value)); + } protected: R& _byteSequence; diff --git a/net/adc_netproto.h b/net/adc_netproto.h index ac7be78..c57359c 100644 --- a/net/adc_netproto.h +++ b/net/adc_netproto.h @@ -27,6 +27,8 @@ static constexpr char ADC_DEFAULT_NETPROTO_STARTMARK[] = "\n\t\r\v\r\t\n"; } // namespace constants +/* SESSION-LEVEL PROTOCOLS */ + template struct AdcStopSeqSessionProto { static constexpr std::string_view STOP_SEQ{STOPSEQ};