...
This commit is contained in:
parent
8bcc8edbb0
commit
7e3aed284c
@ -5,6 +5,7 @@
|
||||
#include <limits>
|
||||
#include <ranges>
|
||||
#include <regex>
|
||||
#include <utility>
|
||||
|
||||
#include "../common/adc_traits.h"
|
||||
|
||||
@ -12,6 +13,12 @@
|
||||
namespace adc::utils
|
||||
{
|
||||
|
||||
// compile-time size of zero-terminated char array
|
||||
static consteval size_t AdcCharArrSize(const char* arr)
|
||||
{
|
||||
return *arr ? 1 + AdcCharArrSize(arr + 1) : 0;
|
||||
}
|
||||
|
||||
static bool AdcIsSpace(char in) noexcept
|
||||
{
|
||||
static constexpr auto ws = {' ', '\t', '\n', '\v', '\r', '\f'};
|
||||
@ -542,4 +549,78 @@ static size_t AdcReturnRangeElementsView(const R& r, const RD& delim, RO& ro)
|
||||
return N;
|
||||
}
|
||||
|
||||
|
||||
template <std::ranges::range ResT, traits::adc_char_range R, traits::adc_input_char_range DR>
|
||||
requires(std::ranges::contiguous_range<R> && traits::adc_char_view<std::ranges::range_value_t<ResT>>) ||
|
||||
traits::adc_output_char_range<std::ranges::range_value_t<ResT>>
|
||||
static auto AdcSplitCharRange(R&& r, DR&& delim, size_t start = 0, size_t num = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
ResT res;
|
||||
using el_t = std::ranges::range_value_t<ResT>;
|
||||
|
||||
if (num == 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
size_t last_el = num;
|
||||
if (start) { // to prevent overflowing
|
||||
if (num < (std::numeric_limits<size_t>::max() - start + 1)) {
|
||||
last_el = start + num - 1;
|
||||
}
|
||||
} else {
|
||||
if (num < (std::numeric_limits<size_t>::max())) {
|
||||
last_el = num - 1;
|
||||
}
|
||||
}
|
||||
|
||||
auto begin = std::forward<R>(r).begin();
|
||||
auto end = std::forward<R>(r).end();
|
||||
|
||||
auto it_el = begin;
|
||||
auto it_next = begin;
|
||||
|
||||
size_t i_el = 0;
|
||||
|
||||
auto prev = std::ranges::search(std::forward<R>(r), std::forward<DR>(delim));
|
||||
|
||||
do {
|
||||
if (prev.begin() != begin) {
|
||||
if (i_el >= start) {
|
||||
std::back_inserter(res) = el_t(it_el, prev.begin());
|
||||
}
|
||||
|
||||
++i_el;
|
||||
if (i_el > last_el) {
|
||||
break;
|
||||
}
|
||||
|
||||
it_el = prev.end();
|
||||
}
|
||||
|
||||
if (prev.end() == end) {
|
||||
break;
|
||||
}
|
||||
|
||||
it_next = prev.end();
|
||||
|
||||
auto next = std::ranges::search(it_next, end, std::forward<DR>(delim).begin(), std::forward<DR>(delim).end());
|
||||
|
||||
while (it_next == next.begin()) {
|
||||
it_next = next.end();
|
||||
|
||||
next = std::ranges::search(it_next, end, std::forward<DR>(delim).begin(), std::forward<DR>(delim).end());
|
||||
|
||||
if (next.empty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
prev = next;
|
||||
|
||||
} while (true);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace adc::utils
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include "../common/adc_utils.h"
|
||||
// #include "adc_netmsg.h"
|
||||
|
||||
@ -21,13 +22,13 @@ 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>
|
||||
const char KEY_VALUE_DELIM[] = constants::ADC_DEFAULT_KEY_VALUE_DELIMITER1,
|
||||
const char VALUE_DELIM[] = constants::ADC_DEFAULT_COMPOSITE_PARAM_DELIMITER>
|
||||
class AdcKeyValueMessage1
|
||||
{
|
||||
public:
|
||||
static constexpr std::span keyValueDelimiter{KEY_VALUE_DELIM, sizeof(KEY_VALUE_DELIM) - 1};
|
||||
static constexpr std::span valueDelimiter{VALUE_DELIM, sizeof(VALUE_DELIM) - 1};
|
||||
static constexpr std::span keyValueDelimiter{KEY_VALUE_DELIM, utils::AdcCharArrSize(KEY_VALUE_DELIM)};
|
||||
static constexpr std::span valueDelimiter{VALUE_DELIM, utils::AdcCharArrSize(VALUE_DELIM)};
|
||||
|
||||
AdcKeyValueMessage1(ByteSeqT& byte_seq) : _byteSequence(byte_seq) {}
|
||||
|
||||
@ -42,9 +43,9 @@ public:
|
||||
auto bs = utils::AdcTrimSpacesView<T>(_byteSequence, utils::AdcTrimType::TRIM_LEFT);
|
||||
auto found = std::ranges::search(bs, keyValueDelimiter);
|
||||
|
||||
// if (found.empty) { // no value
|
||||
// return bs;
|
||||
// }
|
||||
if (found.empty()) { // no value
|
||||
return bs;
|
||||
}
|
||||
|
||||
return utils::AdcTrimSpacesView<T>(std::span<const char>(bs.begin(), found.begin()),
|
||||
utils::AdcTrimType::TRIM_RIGHT);
|
||||
@ -83,13 +84,9 @@ public:
|
||||
{
|
||||
if constexpr (traits::adc_char_view<T> && std::ranges::contiguous_range<ByteSeqT>) {
|
||||
auto bs = utils::AdcTrimSpacesView<T>(_byteSequence, utils::AdcTrimType::TRIM_LEFT);
|
||||
|
||||
auto found = std::ranges::search(bs, keyValueDelimiter);
|
||||
|
||||
// if (found.empty()) { // no value
|
||||
// return T();
|
||||
// }
|
||||
|
||||
return T(found.end(), _byteSequence.end());
|
||||
return T(found.end(), bs.end());
|
||||
} else {
|
||||
T res;
|
||||
|
||||
@ -97,7 +94,7 @@ public:
|
||||
|
||||
auto found = std::ranges::search(bs, keyValueDelimiter);
|
||||
if (!found.empty()) {
|
||||
std::ranges::copy(found.end(), _byteSequence.end(), std::back_inserter(res));
|
||||
std::ranges::copy(found.end(), bs.end(), std::back_inserter(res));
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -160,11 +157,11 @@ class AdcDeviceNetMessage : public AdcKeyValueMessage1<ByteSeqT, KEY_PARAM_DELIM
|
||||
using base_t = AdcKeyValueMessage1<ByteSeqT, KEY_PARAM_DELIM, COMPOSITE_PARAM_DELIM>;
|
||||
|
||||
public:
|
||||
static constexpr std::span keyParamDelimiter{KEY_PARAM_DELIM, sizeof(KEY_PARAM_DELIM) - 1};
|
||||
static constexpr std::span keyParamDelimiter{KEY_PARAM_DELIM, utils::AdcCharArrSize(KEY_PARAM_DELIM)};
|
||||
|
||||
static constexpr std::span paramParamDelimiter{PARAM_PARAM_DELIM, sizeof(PARAM_PARAM_DELIM) - 1};
|
||||
static constexpr std::span paramParamDelimiter{PARAM_PARAM_DELIM, utils::AdcCharArrSize(PARAM_PARAM_DELIM)};
|
||||
|
||||
static constexpr std::span compParamDelimiter{COMPOSITE_PARAM_DELIM, sizeof(COMPOSITE_PARAM_DELIM) - 1};
|
||||
static constexpr std::span compParamDelimiter{COMPOSITE_PARAM_DELIM, utils::AdcCharArrSize(COMPOSITE_PARAM_DELIM)};
|
||||
|
||||
|
||||
AdcDeviceNetMessage(ByteSeqT& byte_seq) : base_t(byte_seq) {}
|
||||
@ -172,9 +169,6 @@ public:
|
||||
template <traits::adc_char_view VT>
|
||||
VT keyword() const
|
||||
{
|
||||
// auto v = utils::AdcTrimSpaces(base_t::template key<VT>());
|
||||
// return VT(std::begin(v), std::end(v));
|
||||
|
||||
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);
|
||||
@ -197,24 +191,25 @@ public:
|
||||
|
||||
|
||||
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 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<R>>();
|
||||
|
||||
// auto p = utils::AdcTokenManip(val).tokens(start, N);
|
||||
// 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));
|
||||
// });
|
||||
|
||||
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 res;
|
||||
return utils::AdcSplitCharRange<R>(val, paramParamDelimiter, start, N);
|
||||
}
|
||||
|
||||
auto params(size_t start = 0, size_t N = std::numeric_limits<size_t>::max())
|
||||
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);
|
||||
}
|
||||
|
||||
@ -505,9 +505,9 @@ public:
|
||||
std::ranges::copy(keytokenDelimiter, std::back_inserter(r)); // keyword-to-token delimiter
|
||||
}
|
||||
|
||||
std::ranges::for_each(base_t::template bytesView(), [&r](const auto& el) {
|
||||
std::ranges::copy(el, std::back_inserter(r)); // token
|
||||
});
|
||||
// std::ranges::for_each(base_t::template bytesView(), [&r](const auto& el) {
|
||||
// std::ranges::copy(el, std::back_inserter(r)); // token
|
||||
// });
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -531,9 +531,9 @@ public:
|
||||
std::back_inserter(r) = {keytokenDelimiter.begin(), keytokenDelimiter.end()}; // keyword-to-token delimiter
|
||||
}
|
||||
|
||||
std::ranges::for_each(base_t::template bytesView(), [&r](const auto& el) {
|
||||
std::back_inserter(r) = {el.begin(), el.end()}; // token
|
||||
});
|
||||
// std::ranges::for_each(base_t::template bytesView(), [&r](const auto& el) {
|
||||
// std::back_inserter(r) = {el.begin(), el.end()}; // token
|
||||
// });
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -90,8 +90,9 @@ TEST_CASE("[ADC NET MESSAGE]")
|
||||
|
||||
std::cout << "KEY = {" << md.keyword() << "}\n";
|
||||
std::cout << "KEY = {" << md.key() << "}\n";
|
||||
for (auto& pp : md.params(1, 2)) {
|
||||
std::cout << "PAR: " << pp << "\n";
|
||||
std::cout << "VALUE = {" << md.value() << "}\n";
|
||||
for (auto& pp : md.params(2, 2)) {
|
||||
std::cout << "PAR: {" << pp << "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user