...
This commit is contained in:
parent
22e20bb52f
commit
25f60e561b
@ -410,7 +410,7 @@ public:
|
|||||||
|
|
||||||
if constexpr (traits::adc_is_tuple_v<ValueT>) {
|
if constexpr (traits::adc_is_tuple_v<ValueT>) {
|
||||||
AdcCharRangeFromTuple(res, value, DELIMITER);
|
AdcCharRangeFromTuple(res, value, DELIMITER);
|
||||||
} else if constexpr (traits::adc_input_char_range<ValueT>) {
|
} else if constexpr (std::ranges::range<ValueT>) {
|
||||||
AdcCharRangeFromValueRange(res, value, DELIMITER);
|
AdcCharRangeFromValueRange(res, value, DELIMITER);
|
||||||
} else {
|
} else {
|
||||||
res = AdcTrivialSerializer<SerializedT>(value);
|
res = AdcTrivialSerializer<SerializedT>(value);
|
||||||
|
|||||||
55
net/adc_device_netmsg.h
Normal file
55
net/adc_device_netmsg.h
Normal file
@ -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 <traits::adc_output_char_range ByteSeqT>
|
||||||
|
class AdcDeviceNetMessage : protected AdcKeyValueMessage<ByteSeqT, constants::ADC_DEFAULT_KEY_PARAM_DELIMITER>
|
||||||
|
{
|
||||||
|
using base_t = AdcKeyValueMessage<ByteSeqT, constants::ADC_DEFAULT_KEY_PARAM_DELIMITER>;
|
||||||
|
|
||||||
|
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 <traits::adc_char_view VT>
|
||||||
|
VT keyword() const
|
||||||
|
{
|
||||||
|
auto v = utils::AdcTrimSpaces(base_t::template key<VT>());
|
||||||
|
return VT(v.begin(), v.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto keyword() const
|
||||||
|
{
|
||||||
|
return keyword<std::string_view>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <traits::adc_range_of_view_char_range R>
|
||||||
|
auto params(size_t start = 0, size_t N = std::numeric_limits<size_t>::max())
|
||||||
|
{
|
||||||
|
auto val = base_t::template value<std::ranges::range_value_t<R>>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace adc
|
||||||
190
net/adc_netmsg.h
190
net/adc_netmsg.h
@ -27,7 +27,7 @@ namespace utils
|
|||||||
|
|
||||||
|
|
||||||
template <typename ByteStorageT, typename T, typename... Ts>
|
template <typename ByteStorageT, typename T, typename... Ts>
|
||||||
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<std::remove_cvref_t<T>>) { // to handle with trailing '\0' in plain char array
|
if constexpr (std::is_array_v<std::remove_cvref_t<T>>) { // to handle with trailing '\0' in plain char array
|
||||||
convertToBytes(res, std::string_view(v), vs...);
|
convertToBytes(res, std::string_view(v), vs...);
|
||||||
@ -49,6 +49,69 @@ void convertToBytes(ByteStorageT& res, const T& v, const Ts&... vs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <traits::adc_output_char_range R>
|
||||||
|
struct AdcTokenManip {
|
||||||
|
AdcTokenManip(R& byte_seq) : _byteSequence(byte_seq) {}
|
||||||
|
|
||||||
|
template <traits::adc_input_char_range DR>
|
||||||
|
auto tokens(const DR& delimiter, size_t start = 0, size_t num = std::numeric_limits<size_t>::max())
|
||||||
|
{
|
||||||
|
std::span<const char> dl;
|
||||||
|
|
||||||
|
if constexpr (std::is_array_v<DR>) {
|
||||||
|
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 <traits::adc_input_char_range DR, typename T, typename... Ts>
|
||||||
|
AdcTokenManip& addTokens(const DR& delimiter, T&& v, Ts&&... vs)
|
||||||
|
{
|
||||||
|
std::span<const char> dl;
|
||||||
|
|
||||||
|
if constexpr (std::is_array_v<DR>) {
|
||||||
|
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<T>(v));
|
||||||
|
|
||||||
|
if constexpr (sizeof...(Ts)) {
|
||||||
|
addTokens(dl, std::forward<Ts>(vs)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <traits::adc_input_char_range DR, typename T, typename... Ts>
|
||||||
|
AdcTokenManip& setTokens(const DR& delimiter, T&& v, Ts&&... vs)
|
||||||
|
{
|
||||||
|
if (std::ranges::size(_byteSequence)) {
|
||||||
|
if constexpr (traits::adc_has_clear_c<R>) {
|
||||||
|
_byteSequence.clear();
|
||||||
|
} else {
|
||||||
|
_byteSequence = R();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return addTokens(delimiter, std::forward<T>(v), std::forward<Ts>(vs)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
R& _byteSequence;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|
||||||
|
|
||||||
@ -219,6 +282,7 @@ namespace constants
|
|||||||
{
|
{
|
||||||
static constexpr char ADC_DEFAULT_TOKEN_DELIMITER[] = " ";
|
static constexpr char ADC_DEFAULT_TOKEN_DELIMITER[] = " ";
|
||||||
static constexpr char ADC_DEFAULT_KEY_TOKEN_DELIMITER[] = " ";
|
static constexpr char ADC_DEFAULT_KEY_TOKEN_DELIMITER[] = " ";
|
||||||
|
static constexpr char ADC_DEFAULT_KEY_VALUE_DELIMITER[] = " ";
|
||||||
|
|
||||||
} // namespace constants
|
} // namespace constants
|
||||||
|
|
||||||
@ -545,47 +609,97 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
template <traits::adc_output_char_range R, const char* DELIM = constants::ADC_DEFAULT_TOKEN_DELIMITER>
|
template <traits::adc_output_char_range R, const char* DELIM = constants::ADC_DEFAULT_TOKEN_DELIMITER>
|
||||||
class AdcTokenMessage
|
class AdcTokenMessage : utils::AdcTokenManip<R>
|
||||||
{
|
{
|
||||||
|
using base_t = utils::AdcTokenManip<R>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr std::span tokenDelimiter{DELIM, sizeof(DELIM) - 1}; // "-1" to remove trailing '\0'
|
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<size_t>::max())
|
// auto tokens(size_t start = 0, size_t num = std::numeric_limits<size_t>::max())
|
||||||
{
|
// {
|
||||||
return tokens(start_idx, N);
|
// std::vector<std::span<const char>> res;
|
||||||
}
|
// std::ranges::for_each(base_t::tokens(tokenDelimiter, start, num),
|
||||||
|
// [&res](const auto& el) { res.emplace_back(el.begin(), el.end()); });
|
||||||
|
|
||||||
template <typename T, typename... Ts>
|
// return res;
|
||||||
auto addParts(T&& part, Ts&&... parts)
|
// }
|
||||||
{
|
|
||||||
return addToken(std::forward<T>(part), std::forward<Ts>(parts)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto tokens(size_t start_idx = 0, size_t N = std::numeric_limits<size_t>::max())
|
template <traits::adc_range_of_view_char_range RT>
|
||||||
|
auto tokens(RT& res, size_t start = 0, size_t num = std::numeric_limits<size_t>::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 <typename TokT, typename... TokTs>
|
template <typename TokT, typename... TokTs>
|
||||||
AdcTokenMessage& addTokens(TokT&& token, TokTs&&... tokens)
|
AdcTokenMessage& addTokens(TokT&& token, TokTs&&... tokens)
|
||||||
{
|
{
|
||||||
if (std::ranges::size(_byteSequence)) {
|
base_t::addTokens(tokenDelimiter, std::forward<TokT>(token), std::forward<TokTs>(tokens)...);
|
||||||
std::ranges::copy(tokenDelimiter, std::back_inserter(_byteSequence));
|
|
||||||
}
|
|
||||||
|
|
||||||
utils::convertToBytes(_byteSequence, std::forward<TokT>(token));
|
|
||||||
|
|
||||||
if constexpr (sizeof...(TokTs)) {
|
|
||||||
addTokens(std::forward<TokTs>(tokens)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TokT, typename... TokTs>
|
template <typename TokT, typename... TokTs>
|
||||||
AdcTokenMessage& setTokens(TokT&& token, TokTs&&... tokens)
|
AdcTokenMessage& setTokens(TokT&& token, TokTs&&... tokens)
|
||||||
|
{
|
||||||
|
base_t::setTokens(tokenDelimiter, std::forward<TokT>(token), std::forward<TokTs>(tokens)...);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
R& _byteSequence;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <traits::adc_output_char_range R, const char* KEY_VALUE_DELIM = constants::ADC_DEFAULT_KEY_VALUE_DELIMITER>
|
||||||
|
class AdcKeyValueMessage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr std::span keyvalueDelimiter{KEY_VALUE_DELIM, sizeof(KEY_VALUE_DELIM) - 1};
|
||||||
|
|
||||||
|
AdcKeyValueMessage(R& byte_seq) : _byteSequence(byte_seq) {}
|
||||||
|
|
||||||
|
template <traits::adc_char_view VT>
|
||||||
|
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<std::string_view>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <traits::adc_char_view VT>
|
||||||
|
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<std::string_view>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename KeyT, typename ValueT>
|
||||||
|
AdcKeyValueMessage& setKeyValue(KeyT&& key, ValueT&& value)
|
||||||
{
|
{
|
||||||
if (std::ranges::size(_byteSequence)) {
|
if (std::ranges::size(_byteSequence)) {
|
||||||
if constexpr (traits::adc_has_clear_c<R>) {
|
if constexpr (traits::adc_has_clear_c<R>) {
|
||||||
@ -595,21 +709,29 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return addTokens(std::forward<TokT>(token), std::forward<TokTs>(tokens)...);
|
utils::convertToBytes(_byteSequence, std::forward<KeyT>(key));
|
||||||
|
std::ranges::copy(keyvalueDelimiter, std::back_inserter(_byteSequence));
|
||||||
|
utils::convertToBytes(_byteSequence, std::forward<ValueT>(value));
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
template <typename ValueT>
|
||||||
R& _byteSequence;
|
AdcKeyValueMessage& setValue(ValueT&& value)
|
||||||
};
|
{
|
||||||
|
if (std::ranges::size(_byteSequence)) {
|
||||||
|
if constexpr (traits::adc_has_clear_c<R>) {
|
||||||
|
_byteSequence.clear();
|
||||||
|
} else {
|
||||||
|
_byteSequence = R();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> kw;
|
||||||
|
std::ranges::copy(key<std::span<const char>>(), std::back_inserter(kw));
|
||||||
|
|
||||||
template <traits::adc_output_char_range R,
|
return setKeyValue(kw, std::forward<ValueT>(value));
|
||||||
const char* KEY_TOKEN_DELIM = constants::ADC_DEFAULT_KEY_TOKEN_DELIMITER,
|
}
|
||||||
const char* TOKEN_DELIM = constants::ADC_DEFAULT_TOKEN_DELIMITER>
|
|
||||||
class AdcKeyValueMessage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AdcKeyValueMessage(R& byte_seq) : _byteSequence(byte_seq) {}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
R& _byteSequence;
|
R& _byteSequence;
|
||||||
|
|||||||
@ -27,6 +27,8 @@ static constexpr char ADC_DEFAULT_NETPROTO_STARTMARK[] = "\n\t\r\v\r\t\n";
|
|||||||
} // namespace constants
|
} // namespace constants
|
||||||
|
|
||||||
|
|
||||||
|
/* SESSION-LEVEL PROTOCOLS */
|
||||||
|
|
||||||
template <const char* STOPSEQ = constants::ADC_DEFAULT_NETPROTO_STOPSEQ>
|
template <const char* STOPSEQ = constants::ADC_DEFAULT_NETPROTO_STOPSEQ>
|
||||||
struct AdcStopSeqSessionProto {
|
struct AdcStopSeqSessionProto {
|
||||||
static constexpr std::string_view STOP_SEQ{STOPSEQ};
|
static constexpr std::string_view STOP_SEQ{STOPSEQ};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user