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/streambuf.hpp>
9#include <boost/asio/write.hpp>
10#include <boost/endian/conversion.hpp>
15template <
typename Socket>
16struct size_prefix_decoder
19 int32_t m_next_packet_size{};
20 ossia::pod_vector<char> m_data;
22 explicit size_prefix_decoder(Socket& socket)
25 m_data.reserve(65535);
32 socket.async_read_some(
33 boost::asio::mutable_buffer(&m_next_packet_size,
sizeof(int32_t)),
34 [
this, f = std::move(f)](boost::system::error_code ec, std::size_t sz)
mutable {
35 read_size(std::move(f), ec, sz);
40 void read_size(F&& f, boost::system::error_code ec, std::size_t sz)
42 if(!f.validate_stream(ec))
45 boost::endian::big_to_native_inplace(m_next_packet_size);
46 if(m_next_packet_size <= 0)
49 m_data.resize(m_next_packet_size);
50 boost::asio::async_read(
51 socket, boost::asio::mutable_buffer(m_data.data(), m_next_packet_size),
52 boost::asio::transfer_exactly(m_next_packet_size),
53 [
this, f = std::move(f)](boost::system::error_code ec, std::size_t sz)
mutable {
54 read_data(std::move(f), ec, sz);
59 void read_data(F&& f, boost::system::error_code ec, std::size_t sz)
61 if(!f.validate_stream(ec))
68 f((
const unsigned char*)m_data.data(), sz);
75 this->receive(std::move(f));
79template <
typename Socket>
80struct size_prefix_encoder
84 void write(
const char* data, std::size_t sz)
86 int32_t packet_size = sz;
87 boost::endian::native_to_big_inplace(packet_size);
89 socket, boost::asio::buffer(
90 reinterpret_cast<const char*
>(&packet_size),
sizeof(int32_t)));
91 this->write(socket, boost::asio::buffer(data, sz));
95 void write(T& sock,
const boost::asio::const_buffer& buf)
97 boost::asio::write(sock, buf);
100 template <
typename T>
101 void write(multi_socket_writer<T>& sock,
const boost::asio::const_buffer& buf)
107struct size_prefix_framing
109 template <
typename Socket>
110 using encoder = size_prefix_encoder<Socket>;
111 template <
typename Socket>
112 using decoder = size_prefix_decoder<Socket>;