This commit is contained in:
Timur A. Fatkhullin 2024-10-08 01:50:40 +03:00
parent 7e3aed284c
commit 6bd447c458
4 changed files with 478 additions and 113 deletions

View File

@ -59,6 +59,11 @@ concept adc_range_of_input_char_range =
std::ranges::range<R> && traits::adc_input_char_range<std::ranges::range_value_t<R>>;
template <typename R>
concept adc_range_of_output_char_range =
std::ranges::range<R> && traits::adc_output_char_range<std::ranges::range_value_t<R>>;
template <typename R>
concept adc_range_of_view_or_output_char_range = adc_range_of_view_char_range<R> || adc_output_char_range<R>;

View File

@ -453,15 +453,17 @@ template <const char* DELIMITER = constants::DEFAULT_CONVERTER_DELIMITER>
class AdcDefaultValueConverter
{
public:
static constexpr std::span compositeValueDelimiter{DELIMITER, AdcCharArrSize(DELIMITER)};
template <typename SerializedT, typename ValueT>
static SerializedT serialize(const ValueT& value)
{
SerializedT res;
if constexpr (traits::adc_is_tuple_v<ValueT>) {
AdcCharRangeFromTuple(res, value, DELIMITER);
} else if constexpr (std::ranges::range<ValueT>) {
AdcCharRangeFromValueRange(res, value, DELIMITER);
AdcCharRangeFromTuple(res, value, compositeValueDelimiter);
} else if constexpr (std::ranges::range<ValueT> && !traits::adc_input_char_range<ValueT>) {
AdcCharRangeFromValueRange(res, value, compositeValueDelimiter);
} else {
res = AdcTrivialSerializer<SerializedT>(value);
}
@ -480,9 +482,9 @@ public:
ValueT res;
if constexpr (traits::adc_is_tuple_v<ValueT>) {
AdcTupleFromCharRange(res, svalue, DELIMITER);
} else if constexpr (traits::adc_output_char_range<ValueT>) {
AdcValueRangeFromCharRange(res, svalue, DELIMITER);
AdcTupleFromCharRange(res, svalue, compositeValueDelimiter);
} else if constexpr (std::ranges::range<ValueT> && !traits::adc_output_char_range<ValueT>) {
AdcValueRangeFromCharRange(res, svalue, compositeValueDelimiter);
} else {
res = AdcTrivialDeserializer<ValueT>(svalue);
}
@ -623,4 +625,29 @@ static auto AdcSplitCharRange(R&& r, DR&& delim, size_t start = 0, size_t num =
return res;
}
// FVN-1a hash function
template <traits::adc_input_char_range R>
static constexpr size_t AdcFNV1aHash(const R& r)
{
static_assert(sizeof(size_t) == 8 || sizeof(size_t) == 4, "ONLY FOR 32 or 64-bit size_t!!!");
size_t hash = 0, prime = 0;
if constexpr (sizeof(size_t) == 8) { // 64-bit
prime = 1099511628211UL;
hash = 14695981039346656037UL;
} else if constexpr (sizeof(size_t) == 4) { // 32-bit
prime = 16777619;
hash = 2166136261;
}
std::ranges::for_each(r, [&hash, &prime](const char& ch) {
hash ^= ch;
hash *= prime;
});
return hash;
}
} // namespace adc::utils

View File

@ -15,7 +15,9 @@ namespace constants
static constexpr char ADC_DEFAULT_KEY_VALUE_DELIMITER1[] = " ";
static constexpr char ADC_DEFAULT_KEY_PARAM_DELIMITER[] = " ";
static constexpr char ADC_DEFAULT_PARAM_PARAM_DELIMITER[] = " ";
static constexpr char ADC_DEFAULT_VALUE_DELIMITER[] = " ";
static constexpr char ADC_DEFAULT_COMPOSITE_PARAM_DELIMITER[] = ",";
static constexpr char ADC_DEFAULT_COMPOSITE_VALUE_DELIMITER[] = ",";
} // namespace constants
@ -23,16 +25,32 @@ static constexpr char ADC_DEFAULT_COMPOSITE_PARAM_DELIMITER[] = ",";
template <traits::adc_char_range ByteSeqT,
const char KEY_VALUE_DELIM[] = constants::ADC_DEFAULT_KEY_VALUE_DELIMITER1,
const char VALUE_DELIM[] = constants::ADC_DEFAULT_COMPOSITE_PARAM_DELIMITER>
class AdcKeyValueMessage1
const char VALUE_DELIM[] = constants::ADC_DEFAULT_VALUE_DELIMITER,
const char COMPOSITE_VALUE_DELIM[] = constants::ADC_DEFAULT_COMPOSITE_VALUE_DELIMITER>
class AdcKeyValueMessage
{
public:
static constexpr std::span keyValueDelimiter{KEY_VALUE_DELIM, utils::AdcCharArrSize(KEY_VALUE_DELIM)};
static constexpr std::span valueDelimiter{VALUE_DELIM, utils::AdcCharArrSize(VALUE_DELIM)};
static constexpr size_t keyValueDelimiterSize = utils::AdcCharArrSize(KEY_VALUE_DELIM);
static constexpr std::span keyValueDelimiter{KEY_VALUE_DELIM, keyValueDelimiterSize};
AdcKeyValueMessage1(ByteSeqT& byte_seq) : _byteSequence(byte_seq) {}
static constexpr size_t valueDelimiterSize = utils::AdcCharArrSize(VALUE_DELIM);
static constexpr std::span valueDelimiter{VALUE_DELIM, valueDelimiterSize};
virtual ~AdcKeyValueMessage1() = default;
static constexpr size_t compValueDelimiterSize = utils::AdcCharArrSize(COMPOSITE_VALUE_DELIM);
static constexpr std::span compValueDelimiter{COMPOSITE_VALUE_DELIM, compValueDelimiterSize};
static_assert(keyValueDelimiterSize && valueDelimiterSize && compValueDelimiterSize,
"KEY-VALUE, VALUE-PARTS AND COMPOSITE-VALUE DELIMITERS MUST NOT BE AN EMPTY ARRAY!!!");
AdcKeyValueMessage(ByteSeqT& byte_seq) : _byteSequence(byte_seq) {}
virtual ~AdcKeyValueMessage() = default;
bool empty() const
{
return std::ranges::size(_byteSequence) == 0;
}
template <typename T>
requires(traits::adc_char_view<T> && std::ranges::contiguous_range<ByteSeqT>) ||
@ -111,39 +129,132 @@ public:
}
template <typename KeyT, typename ValueT>
requires traits::adc_output_char_range<ByteSeqT>
AdcKeyValueMessage1& setKeyValue(KeyT&& key, ValueT&& value)
template <typename T>
requires(std::ranges::contiguous_range<ByteSeqT> && traits::adc_char_view<std::ranges::range_value_t<T>>) ||
traits::adc_range_of_output_char_range<T>
auto valueParts(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
if (std::ranges::size(_byteSequence)) {
_byteSequence = _byteSequence();
auto val = value<std::ranges::range_value_t<T>>();
return utils::AdcSplitCharRange<T>(val, valueDelimiter, start, N);
}
auto valueParts(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
if constexpr (std::ranges::contiguous_range<ByteSeqT>) {
return valueParts<std::vector<std::string_view>>(start, N);
} else {
return valueParts<std::vector<std::string>>(start, N);
}
}
template <typename T>
requires traits::adc_output_char_range<T> || traits::adc_char_view<T>
auto joinValueParts(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
T res;
if constexpr (std::ranges::contiguous_range<ByteSeqT>) {
auto pp = valueParts<std::vector<std::span<const char>>>(start, N);
if (pp.size()) {
res = T{pp.front().begin(), pp.back().end()};
}
} else {
utils::AdcJoinRange(valueParts<std::vector<std::vector<const char>>>(start, N), valueDelimiter, res);
}
std::ranges::copy(
utils::AdcDefaultValueConverter<KEY_VALUE_DELIM>::template serialize<ByteSeqT>(std::forward<KeyT>(key)),
std::back_inserter(_byteSequence));
return res;
}
std::ranges::copy(keyValueDelimiter, std::back_inserter(_byteSequence));
std::ranges::copy(
utils::AdcDefaultValueConverter<KEY_VALUE_DELIM>::template serialize(std::forward<ValueT>(value)),
std::back_inserter(_byteSequence));
auto joinValueParts(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
if constexpr (std::ranges::contiguous_range<ByteSeqT>) {
return joinValueParts<std::string_view>(start, N);
} else {
return joinValueParts<std::string>(start, N);
}
}
// template <typename KeyT, typename ValueT>
// requires traits::adc_output_char_range<ByteSeqT>
// AdcKeyValueMessage& setKeyValue(KeyT&& key, ValueT&& value)
// {
// if (std::ranges::size(_byteSequence)) {
// _byteSequence = ByteSeqT();
// }
// std::ranges::copy(
// utils::AdcDefaultValueConverter<VALUE_DELIM>::template serialize<ByteSeqT>(std::forward<KeyT>(key)),
// std::back_inserter(_byteSequence));
// std::ranges::copy(keyValueDelimiter, std::back_inserter(_byteSequence));
// std::ranges::copy(
// utils::AdcDefaultValueConverter<VALUE_DELIM>::template serialize<ByteSeqT>(std::forward<ValueT>(value)),
// std::back_inserter(_byteSequence));
// return *this;
// }
// template <typename ValueT>
// AdcKeyValueMessage& setValue(ValueT&& value)
// requires traits::adc_output_char_range<ByteSeqT>
// {
// std::vector<char> kw;
// std::ranges::copy(key<std::span<const char>>(), std::back_inserter(kw));
// return setKeyValue(kw, std::forward<ValueT>(value));
// }
template <typename KeyT, typename... ValuePartTs>
requires traits::adc_output_char_range<ByteSeqT>
AdcKeyValueMessage& setKeyValue(KeyT&& key, ValuePartTs&&... values)
{
if (std::ranges::size(_byteSequence)) {
_byteSequence = ByteSeqT();
}
std::ranges::copy(utils::AdcDefaultValueConverter<COMPOSITE_VALUE_DELIM>::template serialize<ByteSeqT>(
std::forward<KeyT>(key)),
std::back_inserter(_byteSequence));
if constexpr (sizeof...(ValuePartTs)) {
std::ranges::copy(keyValueDelimiter, std::back_inserter(_byteSequence));
setValueHelper(std::forward<ValuePartTs>(values)...);
}
return *this;
}
template <typename ValueT>
AdcKeyValueMessage1& setValue(ValueT&& value)
template <typename... ValuePartTs>
requires traits::adc_output_char_range<ByteSeqT>
AdcKeyValueMessage& setValue(ValuePartTs&&... values)
{
std::vector<char> kw;
std::ranges::copy(key<std::span<const char>>(), std::back_inserter(kw));
return setKeyValue(kw, std::forward<ValueT>(value));
return setValue(kw, std::forward<ValuePartTs>(values)...);
}
protected:
ByteSeqT& _byteSequence;
template <typename ValuePartT, typename... ValuePartTs>
void setValueHelper(ValuePartT&& value, ValuePartTs&&... values)
{
std::ranges::copy(utils::AdcDefaultValueConverter<COMPOSITE_VALUE_DELIM>::template serialize<ByteSeqT>(
std::forward<ValuePartT>(value)),
std::back_inserter(_byteSequence));
if constexpr (sizeof...(ValuePartTs)) {
std::ranges::copy(valueDelimiter, std::back_inserter(_byteSequence));
setValueHelper(std::forward<ValuePartTs>(values)...);
}
}
};
@ -152,9 +263,9 @@ template <traits::adc_char_range ByteSeqT,
const char* KEY_PARAM_DELIM = constants::ADC_DEFAULT_KEY_PARAM_DELIMITER,
const char* PARAM_PARAM_DELIM = constants::ADC_DEFAULT_PARAM_PARAM_DELIMITER,
const char* COMPOSITE_PARAM_DELIM = constants::ADC_DEFAULT_COMPOSITE_PARAM_DELIMITER>
class AdcDeviceNetMessage : public AdcKeyValueMessage1<ByteSeqT, KEY_PARAM_DELIM, COMPOSITE_PARAM_DELIM>
class AdcDeviceNetMessage : public AdcKeyValueMessage<ByteSeqT, KEY_PARAM_DELIM, COMPOSITE_PARAM_DELIM>
{
using base_t = AdcKeyValueMessage1<ByteSeqT, KEY_PARAM_DELIM, COMPOSITE_PARAM_DELIM>;
using base_t = AdcKeyValueMessage<ByteSeqT, KEY_PARAM_DELIM, COMPOSITE_PARAM_DELIM>;
public:
static constexpr std::span keyParamDelimiter{KEY_PARAM_DELIM, utils::AdcCharArrSize(KEY_PARAM_DELIM)};
@ -166,63 +277,275 @@ public:
AdcDeviceNetMessage(ByteSeqT& byte_seq) : base_t(byte_seq) {}
template <traits::adc_char_view VT>
VT keyword() const
{
std::span<const char> key;
// first, remove spaces at the beginning and end of byte sequence
auto bs = utils::AdcTrimSpacesView<std::span<const char>>(this->_byteSequence);
virtual ~AdcDeviceNetMessage() = default;
auto found = std::ranges::search(bs, keyParamDelimiter);
if (found.empty()) { // only keyword
return VT(bs.begin(), bs.end());
template <typename T>
requires(std::ranges::contiguous_range<ByteSeqT> && traits::adc_char_view<std::ranges::range_value_t<T>>) ||
traits::adc_range_of_output_char_range<T>
auto params(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
auto val = base_t::template value<std::ranges::range_value_t<T>>();
return utils::AdcSplitCharRange<T>(val, paramParamDelimiter, start, N);
}
auto params(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
if constexpr (std::ranges::contiguous_range<ByteSeqT>) {
return params<std::vector<std::string_view>>(start, N);
} else {
return params<std::vector<std::string>>(start, N);
}
key = std::span(bs.begin(), found.begin());
return utils::AdcTrimSpacesView<VT>(key);
}
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()) const
template <typename T>
requires traits::adc_output_char_range<T> || traits::adc_char_view<T>
auto joinParams(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
auto val = base_t::template value<std::ranges::range_value_t<R>>();
T res;
// R res;
// std::ranges::for_each(std::views::split(val, keyParamDelimiter) | std::views::drop(start) |
// std::views::take(N),
// [&res](const auto& el) {
// // remove spaces
// std::back_inserter(res) =
// utils::AdcTrimSpacesView<std::ranges::range_value_t<R>>(el);
// // std::ranges::copy(utils::AdcTrimSpaces(el), std::back_inserter(res));
// });
// return res;
return utils::AdcSplitCharRange<R>(val, paramParamDelimiter, start, N);
}
auto params(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
return params<std::vector<std::string_view>>(start, N);
}
template <traits::adc_output_char_range R>
auto joinParams(size_t start = 0, size_t N = std::numeric_limits<size_t>::max())
{
R res;
utils::AdcJoinRange(params<std::vector<std::span<const char>>>(start, N), paramParamDelimiter, res);
if constexpr (std::ranges::contiguous_range<ByteSeqT>) {
auto pp = params<std::vector<std::span<const char>>>(start, N);
if (pp.size()) {
res = T{pp.front().begin(), pp.back().end()};
}
} else {
utils::AdcJoinRange(params<std::vector<std::vector<const char>>>(start, N), paramParamDelimiter, res);
}
return res;
}
auto joinParams(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
if constexpr (std::ranges::contiguous_range<ByteSeqT>) {
return joinParams<std::string_view>(start, N);
} else {
return joinParams<std::string>(start, N);
}
}
template <traits::adc_input_char_range KeyT, typename... ParamTs>
requires traits::adc_output_char_range<ByteSeqT>
AdcDeviceNetMessage& setKeyParams(KeyT&& key, ParamTs&&... params)
{
this->setKeyValue(std::forward<KeyT>(key), std::string_view());
if constexpr (sizeof...(ParamTs)) {
setParamsHelper(std::forward<ParamTs>(params)...);
}
return *this;
}
protected:
template <typename ParamT, typename... ParamTs>
void setParamsHelper(ParamT&& param, ParamTs&&... params)
{
std::ranges::copy(utils::AdcDefaultValueConverter<COMPOSITE_PARAM_DELIM>::template serialize<ByteSeqT>(
std::forward<ParamT>(param)),
std::back_inserter(this->_byteSequence));
if constexpr (sizeof...(ParamTs)) {
std::ranges::copy(paramParamDelimiter, std::back_inserter(this->_byteSequence));
setParamsHelper(std::forward<ParamTs>(params)...);
}
}
};
template <traits::adc_char_range ByteSeqT,
const char KEY_VALUE_DELIM[] = constants::ADC_DEFAULT_KEY_VALUE_DELIMITER1,
const char VALUE_DELIM[] = constants::ADC_DEFAULT_VALUE_DELIMITER,
const char COMPOSITE_VALUE_DELIM[] = constants::ADC_DEFAULT_COMPOSITE_VALUE_DELIMITER>
class AdcDeviceProtoMessage
: protected AdcKeyValueMessage<ByteSeqT, KEY_VALUE_DELIM, VALUE_DELIM, COMPOSITE_VALUE_DELIM>
{
using base_t = AdcKeyValueMessage<ByteSeqT, KEY_VALUE_DELIM, VALUE_DELIM, COMPOSITE_VALUE_DELIM>;
public:
static constexpr std::string_view ACK_KEY{"ACK"};
static constexpr std::string_view SET_KEY{"SET"};
static constexpr std::string_view GET_KEY{"GET"};
static constexpr std::string_view CMD_KEY{"CMD"};
static constexpr std::string_view ERR_KEY{"ERR"};
static constexpr std::string_view HELLO_KEY{"HELLO"};
static constexpr std::string_view DEVICE_KEY{"DEVICE"};
static constexpr std::string_view NAMES_KEY{"NAMES"};
static constexpr std::array VALID_KEY{ACK_KEY, SET_KEY, GET_KEY, CMD_KEY,
ERR_KEY, HELLO_KEY, DEVICE_KEY, NAMES_KEY};
typedef std::array<size_t, VALID_KEY.size()> keyword_hash_array_t;
enum KEY_IDX : size_t {
ACK_KEY_IDX,
SET_KEY_IDX,
GET_KEY_IDX,
CMD_KEY_IDX,
ERR_KEY_IDX,
HELLO_KEY_IDX,
DEVICE_KEY_IDX,
NAMES_KEY_IDX
};
private: // include here to allow clang compilation
size_t _keyHash = 0;
template <size_t... I>
static constexpr auto computeKeywordHashesImpl(std::index_sequence<I...>)
{
return keyword_hash_array_t{utils::AdcFNV1aHash(VALID_KEY[I])...};
}
template <typename Indices = std::make_index_sequence<VALID_KEY.size()>>
static constexpr auto computeKeywordHashes()
{
return computeKeywordHashesImpl(Indices{});
}
static constexpr keyword_hash_array_t KEY_HASHES = computeKeywordHashes();
auto keyHash()
{
return _keyHash = utils::AdcFNV1aHash(key());
}
bool isKey(size_t idx) const
{
return _keyHash == KEY_HASHES[idx];
}
public:
AdcDeviceProtoMessage(ByteSeqT& byte_seq) : base_t(byte_seq)
{
keyHash();
}
bool isValid() const
{
return std::ranges::any_of(KEY_HASHES, [this](size_t h) { return _keyHash == h; });
}
bool isACK() const
{
return isKey(ACK_KEY_IDX);
}
bool isSET() const
{
return isKey(SET_KEY_IDX);
}
bool isGET() const
{
return isKey(GET_KEY_IDX);
}
bool isCMD() const
{
return isKey(CMD_KEY_IDX);
}
bool isERR() const
{
return isKey(ERR_KEY_IDX);
}
bool isHELLO() const
{
return isKey(HELLO_KEY_IDX);
}
bool isDEVICE() const
{
return isKey(DEVICE_KEY_IDX);
}
bool isNAMES() const
{
return isKey(NAMES_KEY_IDX);
}
template <typename T>
requires(traits::adc_char_view<T> && std::ranges::contiguous_range<ByteSeqT>) ||
traits::adc_output_char_range<T>
auto key() const
{
return base_t::template key<T>();
}
auto key() const
{
return base_t::key();
}
void ack()
{
base_t::setKeyValue(ACK_KEY);
keyHash();
}
template <traits::adc_input_char_range AttrNameT, typename ValueT, typename... ValueTs>
void set(AttrNameT&& attr_name, ValueT&& value, ValueTs&&... values)
{
base_t::setKeyValue(SET_KEY, std::forward<AttrNameT>(attr_name), std::forward<ValueT>(value),
std::forward<ValueTs>(values)...);
keyHash();
}
template <traits::adc_input_char_range AttrNameT>
void get(AttrNameT&& attr_name)
{
base_t::setKeyValue(GET_KEY, std::forward<AttrNameT>(attr_name));
keyHash();
}
template <traits::adc_input_char_range CmdNameT>
void cmd(CmdNameT&& cmd_name)
{
base_t::setKeyValue(CMD_KEY, std::forward<CmdNameT>(cmd_name));
keyHash();
}
void err(const std::error_code& ec)
{
base_t::setKeyValue(ERR_KEY, ec.value(), ec.category(), ec.message());
keyHash();
}
template <traits::adc_input_char_range SenderNameT, typename... ParamTs>
void hello(SenderNameT&& name, ParamTs&&... params)
{
base_t::setKeyValue(HELLO_KEY, std::forward<SenderNameT>(name), std::forward<ParamTs>(params)...);
keyHash();
}
template <traits::adc_input_char_range DevNameT>
void device(DevNameT&& dev_name)
{
base_t::setKeyValue(DEVICE_KEY, std::forward<DevNameT>(dev_name));
keyHash();
}
void names()
{
base_t::setKeyValue(NAMES_KEY);
keyHash();
}
};
} // namespace adc

View File

@ -1,4 +1,3 @@
#include <list>
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest/doctest.h>
#include <iostream>
@ -6,9 +5,11 @@
// #include "../common/adc_utils.h"
// #include "../net/adc_netmessage.h"
#include <list>
#include "../net/adc_device_netmsg.h"
#include "../net/adc_endpoint.h"
#include "../net/adc_netmsg.h"
// #include "../net/adc_netmsg.h"
using namespace adc;
@ -18,59 +19,59 @@ static constexpr char TD[] = "-";
TEST_CASE("[ADC NET MESSAGE]")
{
AdcKeyTokenNetMessage<DD> msg;
// AdcKeyTokenNetMessage<DD> msg;
std::string_view bytes{"SET=POS 1 2 3 4 5"};
// std::string_view bytes{"SET=POS 1 2 3 4 5"};
std::cout << "INPUT BYTES: [" << bytes << "]\n";
// std::cout << "INPUT BYTES: [" << bytes << "]\n";
msg.setFromBytes(bytes.begin(), bytes.end());
// msg.setFromBytes(bytes.begin(), bytes.end());
auto keyv = msg.keyView();
auto keyb = msg.keyBytes();
// auto keyv = msg.keyView();
// auto keyb = msg.keyBytes();
std::cout << "KEY VIEW: [" << keyv << "]\n";
std::cout << "KEY BYTE: [" << keyb << "]\n";
// std::cout << "KEY VIEW: [" << keyv << "]\n";
// std::cout << "KEY BYTE: [" << keyb << "]\n";
auto tks = msg.tokens(1, 3);
for (auto& el : tks) {
std::cout << "TOKEN: [" << el << "]\n";
}
// auto tks = msg.tokens(1, 3);
// for (auto& el : tks) {
// std::cout << "TOKEN: [" << el << "]\n";
// }
auto t2 = msg.bytesView();
std::cout << "BYTES VIEW: ";
for (auto& el : t2) {
std::cout << "[" << el << "]";
}
std::cout << "\n";
// auto t2 = msg.bytesView();
// std::cout << "BYTES VIEW: ";
// for (auto& el : t2) {
// std::cout << "[" << el << "]";
// }
// std::cout << "\n";
std::cout << "\n\n---------\n\n";
// std::cout << "\n\n---------\n\n";
msg.setTokens("FILTER", "A1", "B3");
std::cout << "BYTES: " << msg.bytes() << "\n";
// msg.setTokens("FILTER", "A1", "B3");
// std::cout << "BYTES: " << msg.bytes() << "\n";
std::cout << "TOK BYTES: [" << msg.tokensBytes(1, 1) << "]\n";
// std::cout << "TOK BYTES: [" << msg.tokensBytes(1, 1) << "]\n";
std::cout << "\n\n---------\n\n";
// std::cout << "\n\n---------\n\n";
AdcTokenNetMessage<> tmsg;
std::list<char> bb{'1', ' ', '2', ' ', '3', ' ', '4', ' ', '5'};
// AdcTokenNetMessage<> tmsg;
// std::list<char> bb{'1', ' ', '2', ' ', '3', ' ', '4', ' ', '5'};
tmsg.setFromBytes(bb.begin(), bb.end());
// tmsg.setFromBytes(bb.begin(), bb.end());
auto t1 = tmsg.bytesView();
std::cout << "TOKENS VIEW: ";
for (auto& el : t1) {
std::cout << "[" << el << "]";
}
std::cout << "\n";
// auto t1 = tmsg.bytesView();
// std::cout << "TOKENS VIEW: ";
// for (auto& el : t1) {
// std::cout << "[" << el << "]";
// }
// std::cout << "\n";
std::cout << "\n\n\n";
// std::cout << "\n\n\n";
AdcEndpoint ept(AdcEndpoint::PROTO_ID_LOCAL, "SOCK");
@ -88,12 +89,21 @@ TEST_CASE("[ADC NET MESSAGE]")
AdcDeviceNetMessage md(bs);
std::cout << "KEY = {" << md.keyword() << "}\n";
std::cout << "KEY = {" << md.key() << "}\n";
std::cout << "VALUE = {" << md.value() << "}\n";
for (auto& pp : md.params(2, 2)) {
std::cout << "PAR: {" << pp << "}\n";
}
auto st = md.joinParams(0, 3);
std::cout << "JOIN: {" << st << "}\n";
// md.setKeyValue(11, std::make_tuple("1.1", 33.77));
md.setKeyValue(std::string_view("SET"), std::make_tuple("1.1", 33.77), "OPER", 1.0, 33.44);
std::cout << "BS: " << bs << "\n";
md.setKeyParams(std::string_view("SET_ATTR"), std::make_tuple("1.1", 33.77), 77.33, "DEDE");
std::cout << "BS: " << bs << "\n";
}
/*