...
This commit is contained in:
parent
0d62c9defc
commit
0e937bb2d7
@ -46,6 +46,7 @@ if (ASIO_LIBRARY)
|
||||
set(ADC_NETWORK_HEADERS ${ADC_NETWORK_HEADERS}
|
||||
net/asio/adc_netservice_asio.h
|
||||
net/asio/adc_netsession_asio.h
|
||||
net/asio/adc_device_netserver_asio.h
|
||||
)
|
||||
|
||||
add_compile_definitions(PUBLIC USE_ASIO_LIBRARY)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../common/adc_traits.h"
|
||||
#include "../common/adc_utils.h"
|
||||
|
||||
namespace adc
|
||||
{
|
||||
@ -38,10 +39,7 @@ struct AdcStopSeqSessionProto {
|
||||
|
||||
typedef std::string proto_ident_t;
|
||||
|
||||
proto_ident_t ident() const
|
||||
{
|
||||
return "STOP SEQUENCE PROTO";
|
||||
}
|
||||
proto_ident_t ident() const { return "STOP SEQUENCE PROTO"; }
|
||||
|
||||
// template <traits::adc_input_char_range R>
|
||||
// auto search(const R& r)
|
||||
@ -143,6 +141,132 @@ struct AdcStopSeqSessionProto {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// session protocol for datagram-kind message (e.g. UDP, seqpacket)
|
||||
// The protocol does not contain any special characters, so to/fromProto methods
|
||||
// return just a copy/one-element-array-of-vew/view of input byte
|
||||
// sequence.
|
||||
struct AdcDatagramSessionProto {
|
||||
typedef std::string proto_ident_t;
|
||||
|
||||
proto_ident_t ident() const { return "DATAGRAM PROTO"; }
|
||||
|
||||
template <traits::adc_input_char_range R>
|
||||
auto search(const R& r)
|
||||
{
|
||||
if constexpr (std::ranges::viewable_range<R>) {
|
||||
return std::ranges::subrange(r.begin(), r.end());
|
||||
} else {
|
||||
R res;
|
||||
std::ranges::copy(r, std::back_inserter(res));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
template <traits::adc_input_char_range R>
|
||||
auto toProto(const R& r)
|
||||
{
|
||||
if constexpr (std::ranges::viewable_range<R>) {
|
||||
return std::array{std::ranges::subrange(r.begin(), r.end())};
|
||||
} else {
|
||||
R res;
|
||||
std::ranges::copy(r, std::back_inserter(res));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
template <traits::adc_input_char_range R>
|
||||
auto fromProto(const R& r)
|
||||
{
|
||||
if constexpr (std::ranges::viewable_range<R>) {
|
||||
return std::ranges::subrange(r.begin(), r.end());
|
||||
} else {
|
||||
R res;
|
||||
std::ranges::copy(r, std::back_inserter(res));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <const char* START_MARK = constants::ADC_DEFAULT_NETPROTO_STARTMARK, size_t SIZE_FIELD_LEN = 8>
|
||||
struct AdcBinaryBlobSessionProto {
|
||||
static constexpr size_t startMarkSize = utils::AdcCharArrSize(START_MARK);
|
||||
static constexpr std::span<const char> startMark{START_MARK, startMarkSize};
|
||||
|
||||
static_assert(startMarkSize, "START MARK SEQUENCE MUST NOT BE AN EMPTY ONE!");
|
||||
static_assert(SIZE_FIELD_LEN > 0, "LENGTH OF SIZE FILED MUST BE GREATER THAN 0!");
|
||||
|
||||
static constexpr size_t headerSize = startMarkSize + SIZE_FIELD_LEN;
|
||||
|
||||
typedef std::string proto_ident_t;
|
||||
|
||||
proto_ident_t ident() const { return "BINARY BLOB PROTO"; }
|
||||
|
||||
template <traits::adc_input_char_range R>
|
||||
auto search(const R& r)
|
||||
{
|
||||
size_t r_size = std::ranges::size(r);
|
||||
if (r_size < headerSize) {
|
||||
return std::ranges::subrange(r.begin(), r.begin());
|
||||
}
|
||||
|
||||
auto found = std::ranges::search(r, startMark);
|
||||
if (found.empty()) {
|
||||
return std::ranges::subrange(r.begin(), r.begin());
|
||||
}
|
||||
|
||||
std::string len;
|
||||
std::ranges::copy(found.end(), found.end() + SIZE_FIELD_LEN, std::back_inserter(len));
|
||||
|
||||
// NOTE: HERE ONE EXPECTS A HEXIMAL NUMBER!!!
|
||||
size_t blob_size;
|
||||
auto end_ptr = len.c_str() + len.size();
|
||||
auto [ptr, ec] = std::from_chars(len.c_str(), end_ptr, blob_size, 16);
|
||||
if (ec != std::errc{} || ptr != end_ptr) {
|
||||
return std::ranges::subrange(r.begin(), r.begin());
|
||||
}
|
||||
|
||||
if (blob_size == 0) { // just start mark and size field (zero-length blob)
|
||||
return std::ranges::subrange(r.begin(), found.end() + SIZE_FIELD_LEN);
|
||||
}
|
||||
|
||||
if ((r_size - headerSize) < blob_size) { // not enough of data
|
||||
return std::ranges::subrange(r.begin(), r.begin());
|
||||
}
|
||||
|
||||
return std::ranges::subrange(r.begin(), r.begin() + headerSize + blob_size);
|
||||
}
|
||||
|
||||
template <traits::adc_input_char_range R>
|
||||
auto toProto(const R& r)
|
||||
{
|
||||
static const std::string fmt = std::string{"{:0"} + std::to_string(SIZE_FIELD_LEN) + std::string{"X}"};
|
||||
|
||||
if constexpr (std::ranges::viewable_range<R>) {
|
||||
// return
|
||||
} else {
|
||||
R res;
|
||||
std::ranges::copy(startMark, std::back_inserter(res));
|
||||
std::format_to(std::back_inserter(res), fmt, std::ranges::size(r));
|
||||
std::ranges::copy(r, std::back_inserter(res));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <traits::adc_input_char_range R>
|
||||
auto fromProto(const R& r)
|
||||
{
|
||||
if constexpr (std::ranges::viewable_range<R>) {
|
||||
return std::ranges::subrange(r.begin() + headerSize, r.end());
|
||||
} else {
|
||||
R res;
|
||||
std::ranges::copy(r | std::views::drop(headerSize), std::back_inserter(res));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename InetT, const char* STOPSEQ = constants::ADC_DEFAULT_NETPROTO_STOPSEQ>
|
||||
struct AdcNetProtoStopSeq : InetT {
|
||||
static constexpr std::string_view stopSeq{STOPSEQ};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user