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