2#include <ossia/detail/pod_vector.hpp>
3#include <ossia/network/sockets/writers.hpp>
5#include <boost/asio/buffer.hpp>
6#include <boost/asio/error.hpp>
7#include <boost/asio/read.hpp>
8#include <boost/asio/read_until.hpp>
9#include <boost/asio/streambuf.hpp>
10#include <boost/asio/write.hpp>
11#include <boost/endian/conversion.hpp>
16template <
typename Socket>
17struct line_framing_decoder
20 char delimiter[8] = {0};
21 int32_t m_next_packet_size{};
22 std::vector<char, ossia::pod_allocator_avx2<char>> m_data;
23 uint8_t m_delimiter_len = 0;
25 explicit line_framing_decoder(Socket& socket)
28 m_data.reserve(65535);
34 if(m_delimiter_len == 0)
35 m_delimiter_len = strnlen(delimiter, 8);
39 boost::asio::async_read_until(
40 socket, boost::asio::dynamic_buffer(m_data), (
const char*)delimiter,
41 [
this, f = std::move(f)](boost::system::error_code ec, std::size_t sz)
mutable {
46 new_sz -= m_delimiter_len;
48 read_data(std::move(f), ec, new_sz);
50 this->receive(std::move(f));
55 void read_data(F&& f, boost::system::error_code ec, std::size_t sz)
57 if(!f.validate_stream(ec))
64 f((
const unsigned char*)m_data.data(), sz);
71 this->receive(std::move(f));
75template <
typename Socket>
76struct line_framing_encoder
79 char delimiter[8] = {0};
80 uint8_t delimiter_len = 0;
82 void write(
const char* data, std::size_t sz)
84 if(delimiter_len == 0)
85 delimiter_len = strnlen(delimiter, 8);
88 std::array<boost::asio::const_buffer, 2> bufs = {
89 boost::asio::buffer(data, sz),
90 boost::asio::buffer(delimiter, delimiter_len)};
91 this->do_write(socket, bufs);
95 template <
typename T, std::
size_t N>
96 void do_write(T& sock,
const std::array<boost::asio::const_buffer, N>& bufs)
98 boost::asio::write(sock, bufs);
102 template <
typename T, std::
size_t N>
104 multi_socket_writer<T>& sock,
105 const std::array<boost::asio::const_buffer, N>& bufs)
107 for(
const auto& buf : bufs)
114 template <
typename Socket>
115 using encoder = line_framing_encoder<Socket>;
116 template <
typename Socket>
117 using decoder = line_framing_decoder<Socket>;