src/corosio/src/tcp_socket.cpp

77.4% Lines (89/115) 94.7% Functions (18/19) 58.6% Branches (34/58)
src/corosio/src/tcp_socket.cpp
Line Branch Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #include <boost/corosio/tcp_socket.hpp>
11 #include <boost/corosio/detail/except.hpp>
12 #include <boost/corosio/detail/platform.hpp>
13
14 #if BOOST_COROSIO_HAS_IOCP
15 #include "src/detail/iocp/sockets.hpp"
16 #else
17 #include "src/detail/socket_service.hpp"
18 #endif
19
20 namespace boost::corosio {
21
22 16523 tcp_socket::
23 16523 ~tcp_socket()
24 {
25 16523 close();
26 16523 }
27
28 16343 tcp_socket::
29 tcp_socket(
30 16343 capy::execution_context& ctx)
31 #if BOOST_COROSIO_HAS_IOCP
32 : io_stream(create_handle<detail::win_sockets>(ctx))
33 #else
34
1/1
✓ Branch 1 taken 16343 times.
16343 : io_stream(create_handle<detail::socket_service>(ctx))
35 #endif
36 {
37 16343 }
38
39 void
40 8159 tcp_socket::
41 open()
42 {
43
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8159 times.
8159 if (is_open())
44 return;
45 #if BOOST_COROSIO_HAS_IOCP
46 auto& svc = static_cast<detail::win_sockets&>(h_.service());
47 auto& wrapper = static_cast<tcp_socket::implementation&>(*h_.get());
48 std::error_code ec = svc.open_socket(
49 *static_cast<detail::win_socket_impl&>(wrapper).get_internal());
50 #else
51 8159 auto& svc = static_cast<detail::socket_service&>(h_.service());
52
1/1
✓ Branch 1 taken 8159 times.
8159 std::error_code ec = svc.open_socket(
53 8159 static_cast<tcp_socket::implementation&>(*h_.get()));
54 #endif
55
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8159 times.
8159 if (ec)
56 detail::throw_system_error(ec, "tcp_socket::open");
57 }
58
59 void
60 32837 tcp_socket::
61 close()
62 {
63
2/2
✓ Branch 1 taken 16545 times.
✓ Branch 2 taken 16292 times.
32837 if (!is_open())
64 16545 return;
65 16292 h_.service().close(h_);
66 }
67
68 void
69 364 tcp_socket::
70 cancel()
71 {
72
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 364 times.
364 if (!is_open())
73 return;
74 364 get().cancel();
75 }
76
77 void
78 12 tcp_socket::
79 shutdown(shutdown_type what)
80 {
81
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
12 if (is_open())
82 6 get().shutdown(what);
83 12 }
84
85 native_handle_type
86 tcp_socket::
87 native_handle() const noexcept
88 {
89 if (!is_open())
90 {
91 #if BOOST_COROSIO_HAS_IOCP
92 return static_cast<native_handle_type>(~0ull); // INVALID_SOCKET
93 #else
94 return -1;
95 #endif
96 }
97 return get().native_handle();
98 }
99
100 void
101 10 tcp_socket::
102 set_no_delay(bool value)
103 {
104
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if (!is_open())
105 detail::throw_logic_error("set_no_delay: socket not open");
106 10 std::error_code ec = get().set_no_delay(value);
107
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if (ec)
108 detail::throw_system_error(ec, "tcp_socket::set_no_delay");
109 10 }
110
111 bool
112 10 tcp_socket::
113 no_delay() const
114 {
115
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if (!is_open())
116 detail::throw_logic_error("no_delay: socket not open");
117 10 std::error_code ec;
118 10 bool result = get().no_delay(ec);
119
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if (ec)
120 detail::throw_system_error(ec, "tcp_socket::no_delay");
121 10 return result;
122 }
123
124 void
125 8 tcp_socket::
126 set_keep_alive(bool value)
127 {
128
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (!is_open())
129 detail::throw_logic_error("set_keep_alive: socket not open");
130 8 std::error_code ec = get().set_keep_alive(value);
131
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (ec)
132 detail::throw_system_error(ec, "tcp_socket::set_keep_alive");
133 8 }
134
135 bool
136 8 tcp_socket::
137 keep_alive() const
138 {
139
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (!is_open())
140 detail::throw_logic_error("keep_alive: socket not open");
141 8 std::error_code ec;
142 8 bool result = get().keep_alive(ec);
143
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (ec)
144 detail::throw_system_error(ec, "tcp_socket::keep_alive");
145 8 return result;
146 }
147
148 void
149 2 tcp_socket::
150 set_receive_buffer_size(int size)
151 {
152
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!is_open())
153 detail::throw_logic_error("set_receive_buffer_size: socket not open");
154 2 std::error_code ec = get().set_receive_buffer_size(size);
155
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (ec)
156 detail::throw_system_error(ec, "tcp_socket::set_receive_buffer_size");
157 2 }
158
159 int
160 6 tcp_socket::
161 receive_buffer_size() const
162 {
163
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (!is_open())
164 detail::throw_logic_error("receive_buffer_size: socket not open");
165 6 std::error_code ec;
166 6 int result = get().receive_buffer_size(ec);
167
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (ec)
168 detail::throw_system_error(ec, "tcp_socket::receive_buffer_size");
169 6 return result;
170 }
171
172 void
173 2 tcp_socket::
174 set_send_buffer_size(int size)
175 {
176
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!is_open())
177 detail::throw_logic_error("set_send_buffer_size: socket not open");
178 2 std::error_code ec = get().set_send_buffer_size(size);
179
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (ec)
180 detail::throw_system_error(ec, "tcp_socket::set_send_buffer_size");
181 2 }
182
183 int
184 6 tcp_socket::
185 send_buffer_size() const
186 {
187
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (!is_open())
188 detail::throw_logic_error("send_buffer_size: socket not open");
189 6 std::error_code ec;
190 6 int result = get().send_buffer_size(ec);
191
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (ec)
192 detail::throw_system_error(ec, "tcp_socket::send_buffer_size");
193 6 return result;
194 }
195
196 void
197 12 tcp_socket::
198 set_linger(bool enabled, int timeout)
199 {
200
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
12 if (!is_open())
201 detail::throw_logic_error("set_linger: socket not open");
202 12 std::error_code ec = get().set_linger(enabled, timeout);
203
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 10 times.
12 if (ec)
204 2 detail::throw_system_error(ec, "tcp_socket::set_linger");
205 10 }
206
207 tcp_socket::linger_options
208 6 tcp_socket::
209 linger() const
210 {
211
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (!is_open())
212 detail::throw_logic_error("linger: socket not open");
213 6 std::error_code ec;
214 6 linger_options result = get().linger(ec);
215
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (ec)
216 detail::throw_system_error(ec, "tcp_socket::linger");
217 6 return result;
218 }
219
220 endpoint
221 42 tcp_socket::
222 local_endpoint() const noexcept
223 {
224
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 32 times.
42 if (!is_open())
225 10 return endpoint{};
226 32 return get().local_endpoint();
227 }
228
229 endpoint
230 42 tcp_socket::
231 remote_endpoint() const noexcept
232 {
233
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 32 times.
42 if (!is_open())
234 10 return endpoint{};
235 32 return get().remote_endpoint();
236 }
237
238 } // namespace boost::corosio
239