OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
framing.hpp
1#pragma once
2#include <ossia/network/sockets/cobs_framing.hpp>
3#include <ossia/network/sockets/fixed_length_framing.hpp>
4#include <ossia/network/sockets/size_prefix_framing.hpp>
5#include <ossia/network/sockets/slip_framing.hpp>
6#include <ossia/network/sockets/stx_etx_framing.hpp>
7#include <ossia/network/sockets/tcp_socket.hpp>
8#include <ossia/network/sockets/udp_socket.hpp>
9#include <ossia/network/sockets/unix_socket.hpp>
10#include <ossia/network/sockets/var_size_prefix_framing.hpp>
11#include <ossia/network/sockets/writers.hpp>
12
13namespace ossia::net
14{
15
16template <typename Base, typename Framing>
17struct framed_listener : public Base
18{
19 using proto = typename Base::proto;
20 using socket = typename proto::socket;
21 using decoder = typename Framing::template decoder<socket>;
22
23 template <typename F>
24 framed_listener(socket&& sock, F f)
25 : Base{std::move(sock)}
26 , m_decoder{this->m_socket}
27 {
28 m_decoder.receive(stream_processor<framed_listener, F>{*this, std::move(f)});
29 }
30
31 decoder m_decoder;
32};
33
34template <typename Base, typename Framing>
35struct framed_server : Base
36{
37public:
38 using proto = typename Base::proto;
39 using socket = typename proto::socket;
40 using listener = framed_listener<typename Base::listener, Framing>;
41 using encoder =
42 typename Framing::template encoder<multi_socket_writer<std::unique_ptr<listener>>>;
43 using decoder = typename Framing::template decoder<socket>;
44
45 template <typename... Args>
46 framed_server(Args&&... args)
47 : Base{std::forward<Args>(args)...}
48 , m_writer{m_sockets}
49 , m_encoder{m_writer}
50 {
51 }
52
53 template <typename F>
54 void close(F f)
55 {
56 this->m_context.post([this, f] {
57 for(auto& sock : m_sockets)
58 {
59 sock.close();
60 }
61 f();
62 });
63 }
64
65 template <typename F>
66 void listen(F f)
67 {
68 this->m_acceptor.async_accept(
69 [this, f = std::move(f)](std::error_code ec, socket socket) {
70 if(!ec)
71 {
72 m_sockets.push_back(std::make_unique<listener>(std::move(socket), f));
73 }
74
75 listen(std::move(f));
76 });
77 }
78
79 void write(const char* data, std::size_t sz)
80 {
81 m_encoder.write(data, sz);
82 }
83
84 std::vector<std::unique_ptr<listener>> m_sockets;
85 multi_socket_writer<std::unique_ptr<listener>> m_writer;
86 encoder m_encoder;
87};
88
89template <typename Base, typename Framing>
90struct framed_client : Base
91{
92 using socket = typename Base::socket;
93 using encoder = typename Framing::template encoder<socket>;
94 using decoder = typename Framing::template decoder<socket>;
95
96 template <typename... Args>
97 framed_client(Args&&... args)
98 : Base{std::forward<Args>(args)...}
99 , m_encoder{this->m_socket}
100 , m_decoder{this->m_socket}
101 {
102 }
103
104 template <typename F>
105 void receive(F f)
106 {
107 m_decoder.receive(stream_processor<framed_client, F>{*this, std::move(f)});
108 }
109
110 void write(const char* data, std::size_t sz)
111 {
112 m_encoder.write(data, sz);
113 }
114
115 encoder m_encoder;
116 decoder m_decoder;
117};
118
119template <typename Base, typename Framing>
120struct framed_socket : Base
121{
122 using socket = typename Base::socket;
123 using encoder = typename Framing::template encoder<socket>;
124 using decoder = typename Framing::template decoder<socket>;
125
126 template <typename... Args>
127 framed_socket(Args&&... args)
128 : Base{std::forward<Args>(args)...}
129 , m_encoder{this->m_socket}
130 , m_decoder{this->m_socket}
131 {
132 }
133
134 template <typename F>
135 void listen(F f)
136 {
137 Base::open();
138 m_decoder.receive(stream_processor<framed_socket, F>{*this, std::move(f)});
139 }
140
141 template <typename F>
142 void receive(F f)
143 {
144 m_decoder.receive(stream_processor<framed_socket, F>{*this, std::move(f)});
145 }
146
147 void write(const char* data, std::size_t sz)
148 {
149 m_encoder.write(data, sz);
150 }
151
152 encoder m_encoder;
153 decoder m_decoder;
154};
155
156struct tcp_size_prefix_server : framed_server<tcp_server, size_prefix_framing>
157{
158 using framed_server::framed_server;
159};
160struct tcp_slip_server : framed_server<tcp_server, slip_framing>
161{
162 using framed_server::framed_server;
163};
164
165struct tcp_size_prefix_client : framed_client<tcp_client, size_prefix_framing>
166{
167 using framed_client::framed_client;
168};
169struct tcp_slip_client : framed_client<tcp_client, slip_framing>
170{
171 using framed_client::framed_client;
172};
173struct tcp_cobs_client : framed_client<tcp_client, cobs_framing>
174{
175 using framed_client::framed_client;
176};
177struct tcp_cobs_server : framed_server<tcp_server, cobs_framing>
178{
179 using framed_server::framed_server;
180};
181
182#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
183struct unix_stream_size_prefix_server
184 : framed_server<unix_stream_server, size_prefix_framing>
185{
186 using framed_server::framed_server;
187};
188struct unix_stream_slip_server : framed_server<unix_stream_server, slip_framing>
189{
190 using framed_server::framed_server;
191};
192struct unix_stream_cobs_server : framed_server<unix_stream_server, cobs_framing>
193{
194 using framed_server::framed_server;
195};
196
197struct unix_stream_size_prefix_client
198 : framed_socket<unix_stream_client, size_prefix_framing>
199{
200 using framed_socket::framed_socket;
201};
202struct unix_stream_slip_client : framed_socket<unix_stream_client, slip_framing>
203{
204 using framed_socket::framed_socket;
205};
206struct unix_stream_cobs_client : framed_socket<unix_stream_client, cobs_framing>
207{
208 using framed_socket::framed_socket;
209};
210#endif
211
212}