...
This commit is contained in:
parent
efa48ee132
commit
6b8ab5031b
@ -1 +1,115 @@
|
||||
#pragma once
|
||||
|
||||
#include "../common/adc_traits.h"
|
||||
|
||||
namespace adc
|
||||
{
|
||||
|
||||
namespace traits
|
||||
{
|
||||
|
||||
template <typename T, typename R>
|
||||
concept adc_netproto_c = adc_range_of_view_char_range<R> && requires(T t, const R& r) {
|
||||
{ t.toLowLevel(r) } -> std::same_as<R>;
|
||||
{ t.fromLowLevel(r) } -> std::same_as<R>;
|
||||
};
|
||||
|
||||
} // namespace traits
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
|
||||
static constexpr char ADC_DEFAULT_NETPROTO_STOPSEQ[] = "\n";
|
||||
|
||||
} // namespace constants
|
||||
|
||||
|
||||
template <typename InetT, const char* STOPSEQ = constants::ADC_DEFAULT_NETPROTO_STOPSEQ>
|
||||
struct AdcNetProtoStopSeq : InetT {
|
||||
static constexpr std::string_view stopSeq = STOPSEQ;
|
||||
static constexpr size_t stopSeqSize = stopSeq.size();
|
||||
|
||||
using typename InetT::socket;
|
||||
|
||||
/* range of char range's views */
|
||||
|
||||
template <traits::adc_range_of_view_char_range R>
|
||||
R toLowLevel(const R& r)
|
||||
{
|
||||
R res = r;
|
||||
|
||||
// just add to the back of the range "stop sequence" element
|
||||
std::back_inserter(res) = {stopSeq.begin(), stopSeq.end()};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
template <traits::adc_range_of_view_char_range R>
|
||||
R fromLowLevel(const R& r)
|
||||
{
|
||||
R res;
|
||||
|
||||
auto N = std::distance(r.begin(), r.end());
|
||||
|
||||
if (!N) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// just remove the last element (it is assumed the last element is the stop sequence)
|
||||
std::ranges::copy(r | std::views::take(N - 1), std::back_inserter(res));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* range of char */
|
||||
|
||||
template <traits::adc_output_char_range R>
|
||||
R toLowLevel(const R& r)
|
||||
{
|
||||
R res = r;
|
||||
|
||||
// just add to the back of the "stop sequence"
|
||||
std::ranges::copy(stopSeq, std::back_inserter(res));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
template <traits::adc_output_char_range R>
|
||||
R fromLowLevel(const R& r)
|
||||
{
|
||||
R res;
|
||||
|
||||
auto N = std::distance(r.begin(), r.end());
|
||||
|
||||
if (N <= stopSeq) { // !!!!!!!!!!!
|
||||
return res;
|
||||
}
|
||||
|
||||
// remove stopSeqSize bytes from the back of the input range
|
||||
std::ranges::copy(r | std::views::take(N - stopSeqSize), std::back_inserter(res));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* from iterators to the input range */
|
||||
|
||||
template <std::input_iterator IT>
|
||||
std::pair<IT, IT> fromLowLevel(IT begin, IT end)
|
||||
{
|
||||
auto N = std::distance(begin, end);
|
||||
if (N <= stopSeqSize) { // !!!!!!!!
|
||||
return std::make_pair(end, end);
|
||||
}
|
||||
|
||||
std::advance(end, -stopSeqSize);
|
||||
|
||||
return std::make_pair(begin, end);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace adc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user