... add reserved elements conception
This commit is contained in:
parent
cf543feeb5
commit
efa48ee132
179
net/adc_netmsg.h
179
net/adc_netmsg.h
@ -127,7 +127,8 @@ public:
|
||||
}
|
||||
|
||||
bool emp = true;
|
||||
for (const auto& el : _bytes) {
|
||||
for (size_t i = _reservedNum; i < _bytes.size(); ++i) {
|
||||
const auto& el = _bytes[i];
|
||||
if (std::ranges::distance(el.begin(), el.end())) {
|
||||
emp = false;
|
||||
break;
|
||||
@ -143,7 +144,7 @@ public:
|
||||
{
|
||||
R r;
|
||||
|
||||
for (size_t i = 0; i < _bytes.size(); ++i) {
|
||||
for (size_t i = _reservedNum; i < _bytes.size(); ++i) {
|
||||
std::ranges::for_each(storageViewByIndex(i),
|
||||
[&r](const auto& el) { std::ranges::copy(el, std::back_inserter(r)); });
|
||||
}
|
||||
@ -152,7 +153,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual ByteStorageT bytes() const
|
||||
ByteStorageT bytes() const
|
||||
{
|
||||
//
|
||||
return bytes<ByteStorageT>();
|
||||
@ -165,7 +166,7 @@ public:
|
||||
R r;
|
||||
|
||||
|
||||
for (size_t i = 0; i < _bytes.size(); ++i) {
|
||||
for (size_t i = _reservedNum; i < _bytes.size(); ++i) {
|
||||
std::ranges::for_each(storageViewByIndex(i),
|
||||
[&r](const auto& el) { r.emplace_back(el.begin(), el.end()); });
|
||||
}
|
||||
@ -181,9 +182,14 @@ public:
|
||||
|
||||
protected:
|
||||
std::vector<ByteStorageT> _bytes;
|
||||
size_t _reservedNum;
|
||||
|
||||
|
||||
AdcNetMessageSeqInterface() = default;
|
||||
AdcNetMessageSeqInterface(size_t reserved = 0) : _reservedNum(reserved), _bytes()
|
||||
{
|
||||
// reserve the "_reservedNum" first elements
|
||||
_bytes.resize(_reservedNum);
|
||||
}
|
||||
|
||||
// return a sequence of storage element view and possible additional
|
||||
// byte views (e.g. elements delimiter)
|
||||
@ -272,7 +278,7 @@ public:
|
||||
AdcTokenNetMessage() = default;
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
AdcTokenNetMessage(const T& v, const Ts&... vs) : AdcTokenNetMessage()
|
||||
AdcTokenNetMessage(const T& v, const Ts&... vs) : AdcTokenNetMessage() // _reservedNum = 0
|
||||
{
|
||||
setTokens(v, vs...);
|
||||
}
|
||||
@ -289,7 +295,8 @@ public:
|
||||
return r;
|
||||
}
|
||||
|
||||
std::ranges::copy(this->_bytes | std::views::drop(start) | std::views::take(N), std::back_inserter(r));
|
||||
std::ranges::copy(this->_bytes | std::views::drop(start + this->_reservedNum) | std::views::take(N),
|
||||
std::back_inserter(r));
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -306,11 +313,12 @@ public:
|
||||
{
|
||||
R r;
|
||||
|
||||
if (empty() || (start >= this->_bytes.size()) || !N) {
|
||||
if (empty() || (start >= _tokenNumber) || !N) {
|
||||
return r;
|
||||
}
|
||||
|
||||
utils::AdcJoinRange(this->_bytes | std::views::drop(start) | std::views::take(N), tokenDelimiter, r);
|
||||
utils::AdcJoinRange(this->_bytes | std::views::drop(start + this->_reservedNum) | std::views::take(N),
|
||||
tokenDelimiter, r);
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -345,13 +353,16 @@ public:
|
||||
if constexpr (sizeof...(Ts)) {
|
||||
appendTokens(vs...);
|
||||
}
|
||||
|
||||
_tokenNumber = this->_bytes.size() - this->_reservedNum;
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
void setTokens(const T& v, const Ts&... vs)
|
||||
{
|
||||
this->_bytes.clear();
|
||||
this->_bytes.resize(this->_reservedNum);
|
||||
_tokenNumber = 0;
|
||||
|
||||
appendTokens(v, vs...);
|
||||
}
|
||||
@ -366,6 +377,8 @@ public:
|
||||
do {
|
||||
it = std::search(start_it, end, tokenDelimiter.begin(), tokenDelimiter.end());
|
||||
std::copy(start_it, it, std::back_inserter(this->_bytes.emplace_back()));
|
||||
++_tokenNumber;
|
||||
|
||||
start_it = it;
|
||||
std::advance(start_it, tokenDelimiter.size()); // to support not only random-access iterators
|
||||
} while (it != end);
|
||||
@ -376,19 +389,22 @@ public:
|
||||
void setFromBytes(IT begin, IT end)
|
||||
requires std::same_as<std::iter_value_t<IT>, char>
|
||||
{
|
||||
this->_bytes.clear();
|
||||
this->_bytes.resize(this->_reservedNum);
|
||||
_tokenNumber = 0;
|
||||
|
||||
appendFromBytes(begin, end);
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t _tokenNumber;
|
||||
|
||||
virtual std::vector<ByteViewT> storageViewByIndex(size_t idx) const override
|
||||
{
|
||||
const ByteStorageT& el = this->_bytes[idx];
|
||||
std::vector<ByteViewT> vw{{el.begin(), el.end()}};
|
||||
|
||||
auto last_idx = this->_bytes.size() - 1;
|
||||
if (idx < last_idx) { // add delimiter
|
||||
if ((idx < last_idx) && (_tokenNumber > 1)) { // add delimiter
|
||||
vw.emplace_back(tokenDelimiter.begin(), tokenDelimiter.end());
|
||||
}
|
||||
|
||||
@ -421,29 +437,85 @@ public:
|
||||
using base_t::tokens;
|
||||
|
||||
|
||||
AdcKeyTokenNetMessage() = default;
|
||||
AdcKeyTokenNetMessage()
|
||||
{
|
||||
this->_reservedNum = 1; // reserve the first element for keyword
|
||||
this->_bytes.resize(this->_reservedNum);
|
||||
};
|
||||
|
||||
|
||||
template <typename KT, typename T, typename... Ts>
|
||||
AdcKeyTokenNetMessage(const KT& key, const T& tok, const Ts&... toks)
|
||||
AdcKeyTokenNetMessage(const KT& key, const T& tok, const Ts&... toks) : AdcKeyTokenNetMessage()
|
||||
{
|
||||
utils::convertToBytes(this->_bytes.emplace_back(), key);
|
||||
utils::convertToBytes(this->_bytes[0], key);
|
||||
setTokens(tok, toks...);
|
||||
}
|
||||
|
||||
|
||||
virtual ~AdcKeyTokenNetMessage() = default;
|
||||
|
||||
|
||||
// get a copy of message bytes
|
||||
template <traits::adc_output_char_range R>
|
||||
R bytes() const
|
||||
{
|
||||
R r;
|
||||
|
||||
std::ranges::copy(this->_bytes[0], std::back_inserter(r)); // keyword
|
||||
if (this->_tokenNumber) {
|
||||
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
|
||||
});
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
ByteStorageT bytes() const
|
||||
{
|
||||
//
|
||||
return bytes<ByteStorageT>();
|
||||
}
|
||||
|
||||
// get a view of message bytes
|
||||
template <traits::adc_range_of_view_char_range R>
|
||||
R bytesView() const
|
||||
{
|
||||
R r;
|
||||
|
||||
const auto& key = this->_bytes[0];
|
||||
std::back_inserter(r) = {key.begin(), key.end()}; // keyword
|
||||
if (this->_tokenNumber) {
|
||||
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
|
||||
});
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
std::vector<ByteViewT> bytesView() const
|
||||
{
|
||||
//
|
||||
return bytesView<std::vector<ByteViewT>>();
|
||||
}
|
||||
|
||||
template <traits::adc_output_char_range R>
|
||||
R keyBytes() const
|
||||
{
|
||||
R r;
|
||||
|
||||
if (empty()) {
|
||||
const auto& key = this->_bytes[0];
|
||||
if (!std::distance(key.begin(), key.end())) {
|
||||
return r;
|
||||
}
|
||||
|
||||
std::ranges::copy(this->_bytes[0], r);
|
||||
std::ranges::copy(key, std::back_inserter(r));
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -451,18 +523,16 @@ public:
|
||||
|
||||
ByteStorageT keyBytes() const
|
||||
{
|
||||
if (empty()) {
|
||||
return ByteStorageT();
|
||||
}
|
||||
|
||||
return this->_bytes[0];
|
||||
//
|
||||
return keyBytes<ByteStorageT>();
|
||||
}
|
||||
|
||||
|
||||
template <traits::adc_char_view R>
|
||||
R keyView() const
|
||||
{
|
||||
if (empty()) {
|
||||
const auto& key = this->_bytes[0];
|
||||
if (!std::distance(key.begin(), key.end())) {
|
||||
return R();
|
||||
}
|
||||
|
||||
@ -471,60 +541,20 @@ public:
|
||||
|
||||
|
||||
ByteViewT keyView() const
|
||||
{
|
||||
if (empty()) {
|
||||
return ByteViewT();
|
||||
}
|
||||
|
||||
return ByteViewT{this->_bytes[0].begin(), this->_bytes[0].end()};
|
||||
}
|
||||
|
||||
template <std::ranges::output_range<ByteStorageT> R>
|
||||
R tokens(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
|
||||
{
|
||||
// "+1" since the first element is keyword
|
||||
return base_t::template tokens<R>(start + 1, N);
|
||||
}
|
||||
|
||||
std::vector<ByteStorageT> tokens(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
|
||||
{
|
||||
//
|
||||
return tokens<std::vector<ByteStorageT>>(start, N);
|
||||
return keyView<ByteViewT>();
|
||||
}
|
||||
|
||||
template <traits::adc_output_char_range R>
|
||||
R tokensBytes(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
|
||||
{
|
||||
// "+1" since the first element is keyword
|
||||
return base_t::template tokensBytes<ByteStorageT>(start + 1, N);
|
||||
}
|
||||
|
||||
|
||||
ByteStorageT tokensBytes(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
|
||||
{
|
||||
return tokensBytes<ByteStorageT>(start, N);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename KT, typename T, typename... Ts>
|
||||
void setKeyTokens(const KT& key, const T& tok, const Ts&... toks)
|
||||
{
|
||||
this->_bytes.clear();
|
||||
|
||||
utils::convertToBytes(this->_bytes.emplace_back(), key);
|
||||
appendTokens(tok, toks...);
|
||||
setTokens(tok, toks...);
|
||||
utils::convertToBytes(this->_bytes[0], key);
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
void setTokens(const T& v, const Ts&... vs)
|
||||
{
|
||||
this->_bytes.resize(1); // the first element is keyword
|
||||
|
||||
appendTokens(v, vs...);
|
||||
}
|
||||
|
||||
|
||||
template <std::input_iterator IT>
|
||||
void setFromBytes(IT begin, IT end)
|
||||
@ -541,23 +571,6 @@ public:
|
||||
appendFromBytes(it, end); // tokens
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual std::vector<ByteViewT> storageViewByIndex(size_t idx) const override
|
||||
{
|
||||
if (idx == 0) { // the first element is keyword
|
||||
const ByteStorageT& el = this->_bytes[idx];
|
||||
std::vector<ByteViewT> vw{{el.begin(), el.end()}};
|
||||
|
||||
if (this->_bytes.size() > 1) { // there are tokens, so add keyword-to-tokens delimiter
|
||||
vw.emplace_back(keytokenDelimiter.begin(), keytokenDelimiter.end());
|
||||
}
|
||||
|
||||
return vw;
|
||||
} else {
|
||||
return base_t::storageViewByIndex(idx);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace adc
|
||||
|
||||
@ -36,9 +36,11 @@ TEST_CASE("[ADC NET MESSAGE]")
|
||||
}
|
||||
|
||||
auto t2 = msg.bytesView();
|
||||
std::cout << "BYTES VIEW: ";
|
||||
for (auto& el : t2) {
|
||||
std::cout << "BYTES VIEW: [" << el << "]\n";
|
||||
std::cout << "[" << el << "]";
|
||||
}
|
||||
std::cout << "\n";
|
||||
|
||||
|
||||
std::cout << "\n\n---------\n\n";
|
||||
@ -47,7 +49,7 @@ TEST_CASE("[ADC NET MESSAGE]")
|
||||
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";
|
||||
@ -59,9 +61,11 @@ TEST_CASE("[ADC NET MESSAGE]")
|
||||
tmsg.setFromBytes(bb.begin(), bb.end());
|
||||
|
||||
auto t1 = tmsg.bytesView();
|
||||
std::cout << "TOKENS VIEW: ";
|
||||
for (auto& el : t1) {
|
||||
std::cout << "TOKEN VIEW: [" << el << "]\n";
|
||||
std::cout << "[" << el << "]";
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user