ADC/net/adc_netmsg.h
Timur A. Fatkhullin 65cd65b2d8 ...
2024-06-01 21:40:13 +03:00

110 lines
2.6 KiB
C++

#pragma once
#include <algorithm>
#include <string>
#include <vector>
#include "../common/adc_traits.h"
namespace adc
{
template <traits::adc_output_char_range ByteStorageT = std::string, traits::adc_char_view ByteViewT = std::string_view>
class AdcGenericNetMessage
{
// get a copy of message bytes
template <traits::adc_output_char_range R>
R bytes() const
{
R r;
std::ranges::copy(_bytes, std::back_inserter(r));
return r;
}
virtual ByteStorageT bytes() const { return bytes<ByteStorageT>(); }
// get a view of message bytes
template <traits::adc_char_view R>
R bytesView() const
{
return R{_bytes.begin(), _bytes.end()};
}
virtual ByteViewT bytesView() const { return bytesView<ByteViewT>(); }
protected:
ByteStorageT _bytes;
};
namespace constants
{
static constexpr char ADC_DEFAULT_TOKEN_DELIMITER[] = " ";
static constexpr char ADC_DEFAULT_KEY_PARAM_DELIMITER[] = " ";
static constexpr char ADC_DEFAULT_PARAM_PARAM_DELIMITER[] = " ";
} // namespace constants
template <const char* TOKEN_DELIM = constants::ADC_DEFAULT_TOKEN_DELIMITER,
traits::adc_output_char_range ByteStorageT = std::string,
traits::adc_char_view ByteViewT = std::string_view>
class AdcTokenNetMessage : public AdcGenericNetMessage<ByteStorageT, ByteViewT>
{
using base_t = AdcGenericNetMessage<ByteStorageT, ByteViewT>;
public:
static constexpr std::string_view tokenDelimiter{TOKEN_DELIM};
template <traits::adc_output_char_range R>
R bytes() const
{
R r;
if (_tokens.empty()) {
return r;
}
std::ranges::for_each(_tokens | std::views::take(_tokens.size()), [&r](const auto& el) {
std::ranges::copy(el, std::back_inserter(r));
std::ranges::copy(tokenDelimiter, std::back_inserter(r));
});
std::ranges::copy(_tokens.back(), std::back_inserter(r));
return r;
}
template <std::ranges::range R>
requires std::ranges::view<std::ranges::range_value_t<R>>
R bytesView() const
{
R r;
std::ranges::for_each(_tokens | std::views::take(_tokens.size()), [&r](const auto& el) {
std::ranges::range_value_t<R> v{el.begin(), el.end()};
std::back_inserter(r) = {el.begin(), el.end()};
std::back_inserter(r) = {tokenDelimiter.begin(), tokenDelimiter.end()};
});
std::back_inserter(r) = {_tokens.back().begin(), _tokens.back().end()};
return r;
}
protected:
std::vector<ByteStorageT> _tokens;
};
} // namespace adc