...
This commit is contained in:
parent
6bd447c458
commit
76d8fb6916
@ -13,10 +13,7 @@ namespace constants
|
|||||||
{
|
{
|
||||||
|
|
||||||
static constexpr char ADC_DEFAULT_KEY_VALUE_DELIMITER1[] = " ";
|
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_VALUE_DELIMITER[] = " ";
|
||||||
static constexpr char ADC_DEFAULT_COMPOSITE_PARAM_DELIMITER[] = ",";
|
|
||||||
static constexpr char ADC_DEFAULT_COMPOSITE_VALUE_DELIMITER[] = ",";
|
static constexpr char ADC_DEFAULT_COMPOSITE_VALUE_DELIMITER[] = ",";
|
||||||
|
|
||||||
} // namespace constants
|
} // namespace constants
|
||||||
@ -177,39 +174,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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>
|
template <typename KeyT, typename... ValuePartTs>
|
||||||
requires traits::adc_output_char_range<ByteSeqT>
|
requires traits::adc_output_char_range<ByteSeqT>
|
||||||
AdcKeyValueMessage& setKeyValue(KeyT&& key, ValuePartTs&&... values)
|
AdcKeyValueMessage& setKeyValue(KeyT&& key, ValuePartTs&&... values)
|
||||||
@ -258,104 +222,6 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 AdcKeyValueMessage<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)};
|
|
||||||
|
|
||||||
static constexpr std::span paramParamDelimiter{PARAM_PARAM_DELIM, utils::AdcCharArrSize(PARAM_PARAM_DELIM)};
|
|
||||||
|
|
||||||
static constexpr std::span compParamDelimiter{COMPOSITE_PARAM_DELIM, utils::AdcCharArrSize(COMPOSITE_PARAM_DELIM)};
|
|
||||||
|
|
||||||
|
|
||||||
AdcDeviceNetMessage(ByteSeqT& byte_seq) : base_t(byte_seq) {}
|
|
||||||
|
|
||||||
virtual ~AdcDeviceNetMessage() = default;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
T 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,
|
template <traits::adc_char_range ByteSeqT,
|
||||||
const char KEY_VALUE_DELIM[] = constants::ADC_DEFAULT_KEY_VALUE_DELIMITER1,
|
const char KEY_VALUE_DELIM[] = constants::ADC_DEFAULT_KEY_VALUE_DELIMITER1,
|
||||||
const char VALUE_DELIM[] = constants::ADC_DEFAULT_VALUE_DELIMITER,
|
const char VALUE_DELIM[] = constants::ADC_DEFAULT_VALUE_DELIMITER,
|
||||||
@ -470,21 +336,41 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires(traits::adc_char_view<T> && std::ranges::contiguous_range<ByteSeqT>) ||
|
|
||||||
traits::adc_output_char_range<T>
|
|
||||||
auto key() const
|
auto key() const
|
||||||
{
|
{
|
||||||
return base_t::template key<T>();
|
return base_t::template key<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto key() const
|
auto key() const
|
||||||
{
|
{
|
||||||
return base_t::key();
|
return base_t::key();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto attrs(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
|
||||||
|
{
|
||||||
|
return base_t::template valueParts<T>(start, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto attrs(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
|
||||||
|
{
|
||||||
|
return base_t::valueParts(start, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto joinAttrs(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
|
||||||
|
{
|
||||||
|
return base_t::template joinValueParts<T>(start, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto joinAttrs(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
|
||||||
|
{
|
||||||
|
return base_t::joinValueParts(start, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ack()
|
void ack()
|
||||||
{
|
{
|
||||||
@ -548,4 +434,7 @@ public:
|
|||||||
keyHash();
|
keyHash();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace adc
|
} // namespace adc
|
||||||
|
|||||||
@ -28,6 +28,79 @@ namespace adc
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
class AdcEndpointParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr std::string_view protoHostDelim = "://";
|
||||||
|
static constexpr std::string_view hostPortDelim = ":";
|
||||||
|
static constexpr std::string_view portPathDelim = "/";
|
||||||
|
|
||||||
|
enum proto_id_t : uint8_t {
|
||||||
|
PROTO_ID_LOCAL,
|
||||||
|
PROTO_ID_TCP,
|
||||||
|
PROTO_ID_TLS,
|
||||||
|
PROTO_ID_UDP,
|
||||||
|
PROTO_ID_WS,
|
||||||
|
PROTO_ID_WSS,
|
||||||
|
PROTO_ID_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr std::string_view protoMarkLocal{"local"}; // UNIX domain
|
||||||
|
static constexpr std::string_view protoMarkTCP{"tcp"}; // TCP
|
||||||
|
static constexpr std::string_view protoMarkTLS{"tls"}; // TLS
|
||||||
|
static constexpr std::string_view protoMarkUDP{"udp"}; // UDP
|
||||||
|
static constexpr std::string_view protoMarkWS{"ws"}; // Websocket
|
||||||
|
static constexpr std::string_view protoMarkWSS{"wss"}; // Secure Websocket
|
||||||
|
|
||||||
|
static constexpr std::array validProtoMarks{protoMarkLocal, protoMarkTCP, protoMarkTLS,
|
||||||
|
protoMarkUDP, protoMarkWS, protoMarkWSS};
|
||||||
|
|
||||||
|
|
||||||
|
template <traits::adc_input_char_range R>
|
||||||
|
AdcEndpointParser(const R& ept)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string _proto, _host, _path;
|
||||||
|
int port;
|
||||||
|
|
||||||
|
template <traits::adc_input_char_range R>
|
||||||
|
bool parse(const R& ept)
|
||||||
|
{
|
||||||
|
// at least 'ws://a' (proto, proto-host delimiter and at least a single character of hostname)
|
||||||
|
if (std::ranges::size(ept) < 6) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto found = std::ranges::search(ept, protoHostDelim);
|
||||||
|
if (found.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
std::string_view proto{ept.begin(), found.begin()};
|
||||||
|
for (auto& valid_proto : validProtoMarks) {
|
||||||
|
ok = proto == valid_proto;
|
||||||
|
if (ok) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
_proto.clear();
|
||||||
|
std::ranges::copy(proto, std::back_inserter(_proto));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AdcEndpoint
|
class AdcEndpoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -84,91 +84,21 @@ TEST_CASE("[ADC NET MESSAGE]")
|
|||||||
std::cout << "EPT: [" << ept.endpoint() << "]\n";
|
std::cout << "EPT: [" << ept.endpoint() << "]\n";
|
||||||
|
|
||||||
|
|
||||||
std::string bs = " SET EXP 1.24 0.23652 9.765432 ";
|
std::cout << "\n\n";
|
||||||
|
std::string bs;
|
||||||
|
|
||||||
|
AdcDeviceProtoMessage dpm(bs);
|
||||||
|
|
||||||
|
std::cout << std::boolalpha << "IS VALID: " << dpm.isValid() << "\n";
|
||||||
|
|
||||||
|
dpm.ack();
|
||||||
std::cout << "BS: {" << bs << "}\n";
|
std::cout << "BS: {" << bs << "}\n";
|
||||||
|
std::cout << "BS SZ: " << bs.size() << "\n";
|
||||||
|
|
||||||
AdcDeviceNetMessage md(bs);
|
dpm.set("FILTER", "V", 1.1, std::make_tuple("1.1", 33.77));
|
||||||
|
std::cout << "BS: {" << bs << "}\n";
|
||||||
|
std::cout << "BS SZ: " << bs.size() << "\n";
|
||||||
|
|
||||||
std::cout << "KEY = {" << md.key() << "}\n";
|
std::cout << std::boolalpha << "IS SET: " << dpm.isSET() << "\n";
|
||||||
std::cout << "VALUE = {" << md.value() << "}\n";
|
std::cout << std::boolalpha << "IS VALID: " << dpm.isValid() << "\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";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
TEST_CASE("[ADC NET MESSAGE]")
|
|
||||||
{
|
|
||||||
AdcKeyParamNetMessage<DD> msg;
|
|
||||||
|
|
||||||
std::string_view bytes{"SET=POS 1 2 3 4 5"};
|
|
||||||
|
|
||||||
std::cout << "INPUT BYTES: [" << bytes << "]\n";
|
|
||||||
|
|
||||||
msg.setFromBytes(bytes.begin(), bytes.end());
|
|
||||||
|
|
||||||
std::string key, pars, bb;
|
|
||||||
msg.key(key);
|
|
||||||
std::cout << "KEY: [" << key << "]\n";
|
|
||||||
|
|
||||||
msg.paramsBytes(pars);
|
|
||||||
std::cout << "PARS BYTES: [" << pars << "]\n";
|
|
||||||
pars.clear();
|
|
||||||
msg.paramsBytes(pars, 2, 3);
|
|
||||||
std::cout << "PARS BYTES: [" << pars << "]\n";
|
|
||||||
|
|
||||||
std::list<std::string> ls;
|
|
||||||
msg.params(ls, 0, 3);
|
|
||||||
for (auto& el : ls) {
|
|
||||||
std::cout << "PAR: [" << el << "]\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.bytes(bb);
|
|
||||||
std::cout << "MESSAGE: [" << bb << "]\n";
|
|
||||||
|
|
||||||
REQUIRE_EQ(bb, bytes);
|
|
||||||
|
|
||||||
// msg.setKeyParam("GET", "IMAGE", std::string_view("CROP"), 4, 7, std::make_pair(10, 20));
|
|
||||||
msg.setKeyParam("GET", "IMAGE", std::string_view("CROP"), 4, 7);
|
|
||||||
bb.clear();
|
|
||||||
msg.bytes(bb);
|
|
||||||
|
|
||||||
std::cout << "MSG: [" << bb << "]\n";
|
|
||||||
key.clear();
|
|
||||||
msg.key(key);
|
|
||||||
std::cout << "KEY: [" << key << "]\n";
|
|
||||||
ls.clear();
|
|
||||||
msg.params(ls, 1, 3);
|
|
||||||
for (auto& el : ls) {
|
|
||||||
std::cout << "PAR: [" << el << "]\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ls = {"AAA", "BBB", "CCC"};
|
|
||||||
std::string sr{"RES: "};
|
|
||||||
std::vector<std::string_view> vsv;
|
|
||||||
|
|
||||||
|
|
||||||
auto N = utils::AdcReturnRangeElementsView(ls, std::string_view("<>"), vsv);
|
|
||||||
|
|
||||||
std::cout << "\n\nN = " << N << "\n";
|
|
||||||
for (auto& el : vsv) {
|
|
||||||
std::cout << el << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
N = utils::AdcJoinRange(ls, std::string_view("*"), sr);
|
|
||||||
std::cout << "\n\nN = " << N << "\n";
|
|
||||||
std::cout << sr << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user