OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
fixed_length_framing.hpp
1#pragma once
2#include <ossia/detail/pod_vector.hpp>
3#include <ossia/network/sockets/writers.hpp>
4
5#include <boost/asio/buffer.hpp>
6#include <boost/asio/error.hpp>
7#include <boost/asio/read.hpp>
8#include <boost/asio/write.hpp>
9
10namespace ossia::net
11{
12
13template <typename Socket>
14struct fixed_length_decoder
15{
16 Socket& socket;
17 std::size_t frame_size{64};
18 ossia::pod_vector<char> m_data;
19
20 explicit fixed_length_decoder(Socket& socket)
21 : socket{socket}
22 {
23 }
24
25 template <typename F>
26 void receive(F f)
27 {
28 m_data.resize(frame_size, boost::container::default_init);
29 boost::asio::async_read(
30 socket, boost::asio::mutable_buffer(m_data.data(), frame_size),
31 boost::asio::transfer_exactly(frame_size),
32 [this, f = std::move(f)](boost::system::error_code ec, std::size_t sz) mutable {
33 if(!f.validate_stream(ec))
34 return;
35
36 if(!ec && sz > 0)
37 {
38 try
39 {
40 f((const unsigned char*)m_data.data(), sz);
41 }
42 catch(...)
43 {
44 }
45 }
46
47 this->receive(std::move(f));
48 });
49 }
50};
51
52template <typename Socket>
53struct fixed_length_encoder
54{
55 Socket& socket;
56
57 void write(const char* data, std::size_t sz)
58 {
59 this->do_write(socket, boost::asio::buffer(data, sz));
60 }
61
62 template <typename T>
63 void do_write(T& sock, const boost::asio::const_buffer& buf)
64 {
65 boost::asio::write(sock, buf);
66 }
67
68 template <typename T>
69 void do_write(multi_socket_writer<T>& sock, const boost::asio::const_buffer& buf)
70 {
71 sock.write(buf);
72 }
73};
74
75struct fixed_length_framing
76{
77 template <typename Socket>
78 using encoder = fixed_length_encoder<Socket>;
79 template <typename Socket>
80 using decoder = fixed_length_decoder<Socket>;
81};
82
83}