GCC Code Coverage Report


Directory: src/gate/
File: src/gate/net/cxx_sockettools.cpp
Date: 2025-09-22 22:57:09
Exec Total Coverage
Lines: 12 169 7.1%
Functions: 2 41 4.9%
Branches: 8 94 8.5%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/net/sockettools.hpp"
30 #include "gate/exceptions.hpp"
31
32 namespace gate
33 {
34 namespace net
35 {
36
37 /////////////////////////////////////
38 // SocketSelector implementation //
39 /////////////////////////////////////
40
41 ✗ SocketSelector::SocketSelector()
42 {
43 ✗ result_t result = gate_socketselector_create(&this->impl);
44 ✗ GATEXX_CHECK_ERROR(result);
45 ✗ }
46 ✗ SocketSelector::~SocketSelector() noexcept
47 {
48 ✗ gate_socketselector_destroy(&this->impl);
49 ✗ }
50 ✗ bool SocketSelector::select(gate_socket_t const* sockets, size_t socketsCount, uint8_t* statusFlags, uint32_t timeoutMS)
51 {
52 ✗ result_t result = gate_socketselector_select(&this->impl, sockets, socketsCount, statusFlags, timeoutMS);
53 ✗ if (GATE_RESULT_TIMEOUT == result)
54 {
55 ✗ return false;
56 }
57 ✗ GATEXX_CHECK_EXCEPTION(result);
58 ✗ return true;
59 }
60 ✗ void SocketSelector::intercept()
61 {
62 ✗ result_t result = gate_socketselector_interrupt(&this->impl);
63 ✗ GATEXX_CHECK_EXCEPTION(result);
64 ✗ }
65
66
67 //////////////////////////////////////
68 // SocketGroupSink implementation //
69 //////////////////////////////////////
70
71 ✗ SocketGroupSink::~SocketGroupSink() noexcept
72 {
73 ✗ }
74
75 ✗ void SocketGroupSink::onPrepare(gate_socket_t sock, result_t result, void* userParam)
76 {
77 GATE_UNUSED_ARG(sock);
78 GATE_UNUSED_ARG(result);
79 GATE_UNUSED_ARG(userParam);
80 ✗ }
81 ✗ void SocketGroupSink::onConnect(gate_socket_t sock, result_t result, void* userParam)
82 {
83 GATE_UNUSED_ARG(sock);
84 GATE_UNUSED_ARG(result);
85 GATE_UNUSED_ARG(userParam);
86 ✗ }
87 ✗ void SocketGroupSink::onAccept(gate_socket_t sock, result_t result, void* userParam)
88 {
89 GATE_UNUSED_ARG(sock);
90 GATE_UNUSED_ARG(result);
91 GATE_UNUSED_ARG(userParam);
92 ✗ }
93 ✗ void SocketGroupSink::onRead(gate_socket_t sock, result_t result, char const* data, size_t dataLength, void* userParam)
94 {
95 GATE_UNUSED_ARG(sock);
96 GATE_UNUSED_ARG(result);
97 GATE_UNUSED_ARG(data);
98 GATE_UNUSED_ARG(dataLength);
99 GATE_UNUSED_ARG(userParam);
100 ✗ }
101 ✗ void SocketGroupSink::onWrite(gate_socket_t sock, result_t result, char const* data, size_t dataLength, void* userParam)
102 {
103 GATE_UNUSED_ARG(sock);
104 GATE_UNUSED_ARG(result);
105 GATE_UNUSED_ARG(data);
106 GATE_UNUSED_ARG(dataLength);
107 GATE_UNUSED_ARG(userParam);
108 ✗ }
109 ✗ void SocketGroupSink::onShutdown(gate_socket_t sock, result_t result, void* userParam)
110 {
111 GATE_UNUSED_ARG(sock);
112 GATE_UNUSED_ARG(result);
113 GATE_UNUSED_ARG(userParam);
114 ✗ }
115 ✗ void SocketGroupSink::onError(gate_socket_t sock, result_t result, void* userParam)
116 {
117 GATE_UNUSED_ARG(sock);
118 GATE_UNUSED_ARG(result);
119 GATE_UNUSED_ARG(userParam);
120 ✗ }
121
122
123 //////////////////////////////////
124 // SocketGroup implementation //
125 //////////////////////////////////
126
127 ✗ SocketGroup::SocketGroup()
128 ✗ : eventSink(NULL)
129 {
130 ✗ result_t result = gate_socketgroup_create(&this->impl, this);
131 ✗ GATEXX_CHECK_ERROR(result);
132 ✗ }
133 ✗ SocketGroup::~SocketGroup()
134 {
135 ✗ gate_socketgroup_destroy(&this->impl);
136 ✗ }
137
138 ✗ void SocketGroup::remove(gate_socket_t sock)
139 {
140 ✗ result_t result = gate_socketgroup_remove(&this->impl, sock);
141 ✗ GATEXX_CHECK_ERROR(result);
142 ✗ }
143 ✗ void SocketGroup::remove(Socket& sock)
144 {
145 ✗ this->remove(*sock.c_impl());
146 ✗ }
147 ✗ void SocketGroup::clear()
148 {
149 ✗ result_t result = gate_socketgroup_clear(&this->impl);
150 ✗ GATEXX_CHECK_ERROR(result);
151 ✗ }
152 ✗ void SocketGroup::connect(gate_socket_t sock, Socket::Endpoint const& endpoint, void* userParam)
153 {
154 ✗ result_t result = gate_socketgroup_connect(&this->impl, sock, &endpoint, userParam);
155 ✗ GATEXX_CHECK_EXCEPTION(result);
156 ✗ }
157 ✗ void SocketGroup::connect(Socket& sock, Socket::Endpoint const& endpoint, void* userParam)
158 {
159 ✗ this->connect(*sock.c_impl(), endpoint, userParam);
160 ✗ }
161 ✗ void SocketGroup::accept(gate_socket_t sock, void* userParam)
162 {
163 ✗ result_t result = gate_socketgroup_accept(&this->impl, sock, userParam);
164 ✗ GATEXX_CHECK_EXCEPTION(result);
165 ✗ }
166 ✗ void SocketGroup::accept(Socket& sock, void* userParam)
167 {
168 ✗ this->accept(*sock.c_impl(), userParam);
169 ✗ }
170 ✗ void SocketGroup::read(gate_socket_t sock, size_t length, void* userParam)
171 {
172 ✗ result_t result = gate_socketgroup_read(&this->impl, sock, length, userParam);
173 ✗ GATEXX_CHECK_EXCEPTION(result);
174 ✗ }
175 ✗ void SocketGroup::read(Socket& sock, size_t length, void* userParam)
176 {
177 ✗ this->read(*sock.c_impl(), length, userParam);
178 ✗ }
179 ✗ void SocketGroup::write(gate_socket_t sock, char const* data, size_t length, void* userParam)
180 {
181 ✗ result_t result = gate_socketgroup_write(&this->impl, sock, data, length, userParam);
182 ✗ GATEXX_CHECK_EXCEPTION(result);
183 ✗ }
184 ✗ void SocketGroup::write(Socket& sock, char const* data, size_t length, void* userParam)
185 {
186 ✗ this->write(*sock.c_impl(), data, length, userParam);
187 ✗ }
188 ✗ void SocketGroup::shutdown(gate_socket_t sock, void* userParam)
189 {
190 ✗ result_t result = gate_socketgroup_shutdown_write(&this->impl, sock, userParam);
191 ✗ GATEXX_CHECK_EXCEPTION(result);
192 ✗ }
193 ✗ void SocketGroup::shutdown(Socket& sock, void* userParam)
194 {
195 ✗ this->shutdown(*sock.c_impl(), userParam);
196 ✗ }
197
198
199 ✗ void SocketGroup::eventDispatcher(gate_socketgroup_t* group, gate_uint32_t operation,
200 gate_socket_t sock, gate_result_t result, void* userParam,
201 char const* data, gate_size_t dataLength)
202 {
203 ✗ SocketGroup* parent = static_cast<SocketGroup*>(group->user_tag);
204 ✗ if (!parent) return;
205
206 ✗ SocketGroupSink* sink = parent->eventSink;
207 ✗ if (!sink) return;
208
209 try
210 {
211 ✗ switch (operation)
212 {
213 ✗ case GATE_SOCKETGROUP_OPERATION_PREPARE:
214 ✗ sink->onPrepare(sock, result, userParam);
215 ✗ break;
216 ✗ case GATE_SOCKETGROUP_OPERATION_CONNECT:
217 ✗ sink->onConnect(sock, result, userParam);
218 ✗ break;
219 ✗ case GATE_SOCKETGROUP_OPERATION_ACCEPT:
220 ✗ sink->onAccept(sock, result, userParam);
221 ✗ break;
222 ✗ case GATE_SOCKETGROUP_OPERATION_READ:
223 ✗ sink->onRead(sock, result, data, dataLength, userParam);
224 ✗ break;
225 ✗ case GATE_SOCKETGROUP_OPERATION_WRITE:
226 ✗ sink->onWrite(sock, result, data, dataLength, userParam);
227 ✗ break;
228 ✗ case GATE_SOCKETGROUP_OPERATION_SHUTDOWN_WRITE:
229 ✗ sink->onShutdown(sock, result, userParam);
230 ✗ break;
231 ✗ case GATE_SOCKETGROUP_OPERATION_ERROR:
232 ✗ sink->onError(sock, result, userParam);
233 ✗ break;
234 }
235 }
236 ✗ catch (...) {}
237 }
238
239 ✗ void SocketGroup::run(SocketGroupSink* eventHandler)
240 {
241 ✗ SocketGroupSink* sink = this->eventSink;
242 ✗ this->eventSink = eventHandler;
243 ✗ result_t result = gate_socketgroup_run(&this->impl, &SocketGroup::eventDispatcher);
244 ✗ this->eventSink = sink;
245 ✗ GATEXX_CHECK_EXCEPTION(result);
246 ✗ }
247 ✗ void SocketGroup::quit()
248 {
249 ✗ result_t result = gate_socketgroup_quit(&this->impl);
250 ✗ GATEXX_CHECK_EXCEPTION(result);
251 ✗ }
252
253
254 //////////////////////////////////
255 // SocketQueue implementation //
256 //////////////////////////////////
257
258 ✗ SocketQueue::SocketQueue(gate_socketqueue_t* queue)
259 : DataQueue((gate_dataqueue_t*)queue),
260 ✗ ptr_socketqueue(queue)
261 {
262 ✗ }
263 ✗ SocketQueue::SocketQueue(SocketQueue const& src)
264 : DataQueue(src),
265 ✗ ptr_socketqueue(src.ptr_socketqueue)
266 {
267 ✗ }
268 ✗ SocketQueue& SocketQueue::operator=(SocketQueue const& src)
269 {
270 ✗ if (this != &src)
271 {
272 ✗ DataQueue::operator=(src);
273 ✗ this->ptr_socketqueue = src.ptr_socketqueue;
274 }
275 ✗ return *this;
276 }
277 ✗ SocketQueue::~SocketQueue()
278 {
279 ✗ ptr_socketqueue = NULL;
280 ✗ }
281
282 ✗ void SocketQueue::closeAll()
283 {
284 ✗ gate_socketqueue_close_all(this->ptr_socketqueue);
285 ✗ }
286
287 ✗ gate_socketqueue_t* SocketQueue::c_impl()
288 {
289 ✗ return this->ptr_socketqueue;
290 }
291
292 ✗ gate_socketqueue_t const* SocketQueue::c_impl() const
293 {
294 ✗ return this->ptr_socketqueue;
295 }
296
297
298
299 ✗ ControlStream SocketStream::createClient(Socket::Endpoint const& ep, bool_t delayConnect)
300 {
301 ✗ gate_controlstream_t* ptr_strm = NULL;
302 ✗ gate_result_t result = gate_socketstream_create_endpoint(&ep, &ptr_strm, delayConnect);
303 ✗ GATEXX_CHECK_EXCEPTION(result);
304 ✗ return ControlStream(ptr_strm);
305 }
306
307
308 1 ControlStream SocketStream::createClient(String const& address, bool_t delayConnect)
309 {
310 1 gate_controlstream_t* ptr_strm = NULL;
311
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 gate_result_t result = gate_socketstream_create_address(address.c_impl(), &ptr_strm, delayConnect);
312
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 GATEXX_CHECK_EXCEPTION(result);
313
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 return ControlStream(ptr_strm);
314 }
315
316 ✗ ControlStream SocketStream::createServer(Socket::Endpoint const& ep)
317 {
318 ✗ gate_controlstream_t* ptr_strm = NULL;
319 ✗ gate_result_t result = gate_socketstream_create_server(&ep, &ptr_strm);
320 ✗ GATEXX_CHECK_EXCEPTION(result);
321 ✗ return ControlStream(ptr_strm);
322 }
323
324 1 ControlStream SocketStream::createServer(String const& address)
325 {
326 gate_socket_endpoint_t ep;
327
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 result_t result = gate_socket_parse_endpoint(address.c_impl(), &ep);
328
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 GATEXX_CHECK_EXCEPTION(result);
329
330 1 gate_controlstream_t* ptr_strm = NULL;
331
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 result = gate_socketstream_create_server(&ep, &ptr_strm);
332
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 GATEXX_CHECK_EXCEPTION(result);
333
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 return ControlStream(ptr_strm);
334 }
335
336
337 } // end of namespace net
338 } // end of namespace gate
339