diff --git a/net/adc_netproto.h b/net/adc_netproto.h index 6f70f09..8fa5d9f 100644 --- a/net/adc_netproto.h +++ b/net/adc_netproto.h @@ -1 +1,115 @@ #pragma once + +#include "../common/adc_traits.h" + +namespace adc +{ + +namespace traits +{ + +template +concept adc_netproto_c = adc_range_of_view_char_range && requires(T t, const R& r) { + { t.toLowLevel(r) } -> std::same_as; + { t.fromLowLevel(r) } -> std::same_as; +}; + +} // namespace traits + + +namespace constants +{ + +static constexpr char ADC_DEFAULT_NETPROTO_STOPSEQ[] = "\n"; + +} // namespace constants + + +template +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 + 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 + 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 + 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 + 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::pair 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