From 0d07fb77a60ab8c456fb82005697a0edd058c18d Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Mon, 27 May 2024 02:00:06 +0300 Subject: [PATCH] ... --- net/adc_netmessage.h | 304 ++++++++++++++++++++++++++++++++----------- 1 file changed, 225 insertions(+), 79 deletions(-) diff --git a/net/adc_netmessage.h b/net/adc_netmessage.h index e8a9a38..335827b 100644 --- a/net/adc_netmessage.h +++ b/net/adc_netmessage.h @@ -53,7 +53,7 @@ protected: ByteStorageT _byteStorage; StorageSeqT _storageSequence; - AdcNetMessageInterface() = default; + AdcNetMessageInterface() : _byteStorage(), _storageSequence({_byteStorage}) {}; template AdcNetMessageInterface(const T& v, const Ts&... vs) : AdcNetMessageInterface() @@ -69,12 +69,22 @@ protected: AdcNetMessageInterface& operator=(const AdcNetMessageInterface&) = default; AdcNetMessageInterface& operator=(AdcNetMessageInterface&&) = default; + virtual void updateState() = 0; public: typedef ByteStorageT byte_storage_t; typedef StorageSeqT storage_seq_t; + bool messageEmpty() const { return byteSize() == 0; } + + bool byteStorageEmpty() const + { + size_t sz = std::ranges::distance(_byteStorage.begin(), _byteStorage.end()); + return sz == 0; + } + + template void appendBytes(const T& v, const Ts&... vs) { @@ -88,6 +98,26 @@ public: } } + + template + void appendBytes(const T& v, const Ts&... vs) + { + std::format_to(std::back_inserter(_byteStorage), v); + + if constexpr (sizeof...(Ts)) { + appendBytes(vs...); + } + } + + template + void appendBytes(IterT begin, IterT end) + { + std::copy(begin, end, std::back_inserter(_byteStorage)); + + updateState(); + } + + template void setBytes(const T& v, const Ts&... vs) { @@ -98,18 +128,22 @@ public: } + template + void setBytes(const T& v, const Ts&... vs) + { + _byteStorage = ByteStorageT(); + appendBytes(v, vs...); + + updateState(); + } + + template void setBytes(IterT begin, IterT end) { _byteStorage = ByteStorageT(begin, end); - updateState(); - } - - template - void appendBytes(IterT begin, IterT end) - { - std::copy(begin, end, std::back_inserter(_byteStorage)); + appendBytes(begin, end); updateState(); } @@ -139,9 +173,9 @@ public: }; +/* GENERIC (NOTHING SPECIAL) NETWORK MESSAGE */ -template ByteStorageT = std::vector, - typename MessageViewT = traits::AdcTheSameTypeTag> +template ByteStorageT = std::vector> class AdcGenericNetMessage : public AdcNetMessageInterface, 1>> { @@ -151,50 +185,13 @@ public: using typename base_t::byte_storage_t; using typename base_t::storage_seq_t; - using base_t::appendBytes; - using base_t::setBytes; - - using message_view_t = - std::conditional_t, ByteStorageT, MessageViewT>; - - AdcGenericNetMessage() = default; - - template T, - traits::adc_to_bytes_func_c CONVT = - decltype(utils::AdcDefaultValueConverter<>::serialize)> - AdcGenericNetMessage(T&& v, CONVT&& conv_func = utils::AdcDefaultValueConverter<>::serialize) - : AdcGenericNetMessage() - { - setMessage(std::forward(v), std::forward(conv_func)); - } + // using base_t::appendBytes; + // using base_t::setBytes; + using base_t::base_t; virtual ~AdcGenericNetMessage() = default; - template T, - traits::adc_to_bytes_func_c CONVT = - decltype(utils::AdcDefaultValueConverter<>::serialize)> - void setMessage(T&& v, CONVT&& conv_func = utils::AdcDefaultValueConverter<>::serialize) - { - if constexpr (std::is_same_v) { - this->setBytes(std::forward(v)); - } else { - _messageView(std::forward(v)); - this->_byteStorage = std::forward(conv_func)(_messageView); - } - } - - - message_view_t messageView() const - { - if constexpr (std::is_same_v) { - return this->_byteStorage; - } else { - return _messageView; - } - } - - const storage_seq_t& storageSeq() override { this->_storageSequence[0] = this->_byteStorage; @@ -202,54 +199,203 @@ public: return this->_storageSequence; }; - // factory function +protected: + void updateState() override {} +}; - template CONVT = - decltype(utils::AdcDefaultValueConverter<>::deserialize)> - static AdcGenericNetMessage fromBytes( - BT&& bytes, - CONVT&& conv_func = utils::AdcDefaultValueConverter<>::deserialize) + +namespace constants +{ + +static constexpr char ADC_DEFAULT_TOKEN_DELIMITER[] = " "; +static constexpr char ADC_DEFAULT_KEY_PARAM_DELIMITER[] = " "; +static constexpr char ADC_DEFAULT_PARAM_PARAM_DELIMITER[] = " "; + +} // namespace constants + + +template ByteStorageT = std::vector> +class AdcTokenNetMessage : public AdcGenericNetMessage +{ + using base_t = AdcGenericNetMessage; + +public: + static constexpr std::string_view tokenDelimiter{TOKEN_DELIM}; + + using typename base_t::byte_storage_t; + using typename base_t::storage_seq_t; + + using base_t::base_t; + + virtual ~AdcTokenNetMessage() = default; + + template + void appendTokens(const R& r) { - AdcGenericNetMessage msg; - msg.setBytes(std::forward(bytes)); + using el_t = std::ranges::range_value_t; + static_assert(traits::adc_input_char_range || traits::formattable, + "INVALID TYPE OF INPUT TOKENS!!!"); - if constexpr (!std::is_same_v) { - msg._messageView = conv_func(msg._byteStorage); + size_t n_toks = 0; + if ((n_toks = std::ranges::distance(r.begin(), r.end())) == 0) { + return; } - return msg; + if (!this->byteStorageEmpty()) { + this->appendBytes(tokenDelimiter); + } + + auto v_start = r | std::views::take(n_toks - 1); + for (const auto& el : v_start) { + this->appendBytes(el); + this->appendBytes(tokenDelimiter); + } + + this->appendBytes(*(r.end()--)); // last element } - template CONVT = - decltype(utils::AdcDefaultValueConverter<>::deserialize)> - static AdcGenericNetMessage fromBytes( - IterT begin, - IterT end, - CONVT&& conv_func = utils::AdcDefaultValueConverter<>::deserialize) + template + void setTokens(const R& r) { - AdcGenericNetMessage msg; - msg.setBytes(begin, end); + this->_byteStorage = ByteStorageT(); + appendTokens(r); + } - if constexpr (!std::is_same_v) { - msg._messageView = conv_func(msg._byteStorage); + template R> + void tokens(R& r) + { + if (this->byteStorageEmpty()) { + return; } - return msg; + std::ranges::copy(this->_byteStorage | std::views::split(AdcTokenNetMessage::tokenDelimiter), + std::back_inserter(r)); } protected: - MessageViewT _messageView; + // std::vector _tokens; - void updateState() override + void updateState() override {} +}; + + +template ByteStorageT = std::vector> +class AdcKeyParamNetMessage : public AdcGenericNetMessage +{ + using base_t = AdcGenericNetMessage; + +public: + static constexpr std::string_view keyparamDelimiter{KEY_PARAM_DELIM}; + static constexpr std::string_view paramparamDelimiter{PARAM_PARAM_DELIM}; + + using typename base_t::byte_storage_t; + using typename base_t::storage_seq_t; + + using base_t::base_t; + + virtual ~AdcKeyParamNetMessage() = default; + + // key and params + template + void setKeyParam(KeyT&& key, ParamTs&&... params) { - if constexpr (!std::is_same_v) { + this->_byteStorage = ByteStorageT(); + + if constexpr (sizeof...(ParamTs)) { + this->setBytes(std::forward(key), keyparamDelimiter); + setKeyParamHelper(std::forward(params)...); + } else { + this->setBytes(std::forward(key)); + } + } + + + template + R key() const + { + R val; + + if (this->byteStorageEmpty()) { + return val; + } + + auto v = this->_byteStorage | std::views::split(keyparamDelimiter); + + std::ranges::copy(v | std::views::take(1), std::back_inserter(val)); + + return val; + } + + template R> + R params(size_t start = 0, size_t N = std::numeric_limits::max()) const + { + R pars; + + if (this->byteStorageEmpty() || !N) { + return pars; + } + + auto v = this->_byteStorage | std::views::split(keyparamDelimiter); + + size_t k, num = N, n_pars = std::ranges::distance(v.begin(), v.end()) - 1; + if (!n_pars) { + return; + } + + n_pars = 0; + for (auto& p : v | std::views::drop(1)) { + auto pv = p | std::views::split(paramparamDelimiter); + n_pars += std::ranges::distance(pv.begin(), pv.end()); + if (n_pars < start) { + k = start - n_pars; + continue; + } else { + k = 0; + } + + std::ranges::copy(pv | std::views::drop(k) | std::views::take(num), std::back_inserter(pars)); + num -= std::ranges::distance(pars.begin(), pars.end()); + if (!num) { + break; + } + } + + return pars; + } + + + template + R paramsBytes(size_t start = 0, size_t N = std::numeric_limits::max()) const + { + R pars_bytes; + + if (this->byteStorageEmpty() || !N) { + return pars_bytes; + } + + auto p = params>(start, N); + + if (std::ranges::distance(p.begin(), p.end())) { + } + + return pars_bytes; + } + +protected: + template + void setKeyParamHelper(ParamT&& param, ParamTs&&... params) + { + this->appendBytes(std::forward(param)); + + if constexpr (sizeof...(ParamTs)) { + this->appendBytes(paramparamDelimiter); + setKeyParamHelper(std::forward(params)...); } } }; - - } // namespace adc