1//
2// buffered_read_stream.cpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11// Disable autolinking for unit tests.
12#if !defined(BOOST_ALL_NO_LIB)
13#define BOOST_ALL_NO_LIB 1
14#endif // !defined(BOOST_ALL_NO_LIB)
15
16// Test that header file is self-contained.
17#include <boost/asio/buffered_read_stream.hpp>
18
19#include <cstring>
20#include <functional>
21#include "archetypes/async_result.hpp"
22#include <boost/asio/buffer.hpp>
23#include <boost/asio/io_context.hpp>
24#include <boost/asio/ip/tcp.hpp>
25#include <boost/system/system_error.hpp>
26#include "unit_test.hpp"
27
28#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
29# include <boost/array.hpp>
30#else // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
31# include <array>
32#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
33
34typedef boost::asio::buffered_read_stream<
35 boost::asio::ip::tcp::socket> stream_type;
36
37void write_some_handler(const boost::system::error_code&, std::size_t)
38{
39}
40
41void fill_handler(const boost::system::error_code&, std::size_t)
42{
43}
44
45void read_some_handler(const boost::system::error_code&, std::size_t)
46{
47}
48
49void test_compile()
50{
51#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
52 using boost::array;
53#else // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
54 using std::array;
55#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
56
57 using namespace boost::asio;
58
59 try
60 {
61 io_context ioc;
62 char mutable_char_buffer[128] = "";
63 const char const_char_buffer[128] = "";
64 array<boost::asio::mutable_buffer, 2> mutable_buffers = {.elems: {
65 boost::asio::buffer(data&: mutable_char_buffer, max_size_in_bytes: 10),
66 boost::asio::buffer(data: mutable_char_buffer + 10, size_in_bytes: 10) }};
67 array<boost::asio::const_buffer, 2> const_buffers = {.elems: {
68 boost::asio::buffer(data: const_char_buffer, max_size_in_bytes: 10),
69 boost::asio::buffer(data: const_char_buffer + 10, size_in_bytes: 10) }};
70 archetypes::lazy_handler lazy;
71 boost::system::error_code ec;
72
73 stream_type stream1(ioc);
74 stream_type stream2(ioc, 1024);
75
76 stream_type::executor_type ex = stream1.get_executor();
77 (void)ex;
78
79 stream_type::lowest_layer_type& lowest_layer = stream1.lowest_layer();
80 (void)lowest_layer;
81
82 stream1.write_some(buffers: buffer(data&: mutable_char_buffer));
83 stream1.write_some(buffers: buffer(data: const_char_buffer));
84 stream1.write_some(buffers: mutable_buffers);
85 stream1.write_some(buffers: const_buffers);
86 stream1.write_some(buffers: null_buffers());
87 stream1.write_some(buffers: buffer(data&: mutable_char_buffer), ec);
88 stream1.write_some(buffers: buffer(data: const_char_buffer), ec);
89 stream1.write_some(buffers: mutable_buffers, ec);
90 stream1.write_some(buffers: const_buffers, ec);
91 stream1.write_some(buffers: null_buffers(), ec);
92
93 stream1.async_write_some(buffers: buffer(data&: mutable_char_buffer), handler: &write_some_handler);
94 stream1.async_write_some(buffers: buffer(data: const_char_buffer), handler: &write_some_handler);
95 stream1.async_write_some(buffers: mutable_buffers, handler: &write_some_handler);
96 stream1.async_write_some(buffers: const_buffers, handler: &write_some_handler);
97 stream1.async_write_some(buffers: null_buffers(), handler: &write_some_handler);
98 int i1 = stream1.async_write_some(buffers: buffer(data&: mutable_char_buffer), handler&: lazy);
99 (void)i1;
100 int i2 = stream1.async_write_some(buffers: buffer(data: const_char_buffer), handler&: lazy);
101 (void)i2;
102 int i3 = stream1.async_write_some(buffers: mutable_buffers, handler&: lazy);
103 (void)i3;
104 int i4 = stream1.async_write_some(buffers: const_buffers, handler&: lazy);
105 (void)i4;
106 int i5 = stream1.async_write_some(buffers: null_buffers(), handler&: lazy);
107 (void)i5;
108
109 stream1.fill();
110 stream1.fill(ec);
111
112 stream1.async_fill(handler: &fill_handler);
113 int i6 = stream1.async_fill(handler&: lazy);
114 (void)i6;
115
116 stream1.read_some(buffers: buffer(data&: mutable_char_buffer));
117 stream1.read_some(buffers: mutable_buffers);
118 stream1.read_some(buffers: null_buffers());
119 stream1.read_some(buffers: buffer(data&: mutable_char_buffer), ec);
120 stream1.read_some(buffers: mutable_buffers, ec);
121 stream1.read_some(buffers: null_buffers(), ec);
122
123 stream1.async_read_some(buffers: buffer(data&: mutable_char_buffer), handler: &read_some_handler);
124 stream1.async_read_some(buffers: mutable_buffers, handler: &read_some_handler);
125 stream1.async_read_some(buffers: null_buffers(), handler: &read_some_handler);
126 int i7 = stream1.async_read_some(buffers: buffer(data&: mutable_char_buffer), handler&: lazy);
127 (void)i7;
128 int i8 = stream1.async_read_some(buffers: mutable_buffers, handler&: lazy);
129 (void)i8;
130 int i9 = stream1.async_read_some(buffers: null_buffers(), handler&: lazy);
131 (void)i9;
132 }
133 catch (std::exception&)
134 {
135 }
136}
137
138void test_sync_operations()
139{
140 using namespace std; // For memcmp.
141
142 boost::asio::io_context io_context;
143
144 boost::asio::ip::tcp::acceptor acceptor(io_context,
145 boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 0));
146 boost::asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
147 server_endpoint.address(addr: boost::asio::ip::address_v4::loopback());
148
149 stream_type client_socket(io_context);
150 client_socket.lowest_layer().connect(peer_endpoint: server_endpoint);
151
152 stream_type server_socket(io_context);
153 acceptor.accept(peer&: server_socket.lowest_layer());
154
155 const char write_data[]
156 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
157 const boost::asio::const_buffer write_buf = boost::asio::buffer(data: write_data);
158
159 std::size_t bytes_written = 0;
160 while (bytes_written < sizeof(write_data))
161 {
162 bytes_written += client_socket.write_some(
163 buffers: boost::asio::buffer(b: write_buf + bytes_written));
164 }
165
166 char read_data[sizeof(write_data)];
167 const boost::asio::mutable_buffer read_buf = boost::asio::buffer(data&: read_data);
168
169 std::size_t bytes_read = 0;
170 while (bytes_read < sizeof(read_data))
171 {
172 bytes_read += server_socket.read_some(
173 buffers: boost::asio::buffer(b: read_buf + bytes_read));
174 }
175
176 BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
177 BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
178 BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
179
180 bytes_written = 0;
181 while (bytes_written < sizeof(write_data))
182 {
183 bytes_written += server_socket.write_some(
184 buffers: boost::asio::buffer(b: write_buf + bytes_written));
185 }
186
187 bytes_read = 0;
188 while (bytes_read < sizeof(read_data))
189 {
190 bytes_read += client_socket.read_some(
191 buffers: boost::asio::buffer(b: read_buf + bytes_read));
192 }
193
194 BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
195 BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
196 BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
197
198 server_socket.close();
199 boost::system::error_code error;
200 bytes_read = client_socket.read_some(
201 buffers: boost::asio::buffer(b: read_buf), ec&: error);
202
203 BOOST_ASIO_CHECK(bytes_read == 0);
204 BOOST_ASIO_CHECK(error == boost::asio::error::eof);
205
206 client_socket.close(ec&: error);
207}
208
209void handle_accept(const boost::system::error_code& e)
210{
211 BOOST_ASIO_CHECK(!e);
212}
213
214void handle_write(const boost::system::error_code& e,
215 std::size_t bytes_transferred,
216 std::size_t* total_bytes_written)
217{
218 BOOST_ASIO_CHECK(!e);
219 if (e)
220 throw boost::system::system_error(e); // Terminate test.
221 *total_bytes_written += bytes_transferred;
222}
223
224void handle_read(const boost::system::error_code& e,
225 std::size_t bytes_transferred,
226 std::size_t* total_bytes_read)
227{
228 BOOST_ASIO_CHECK(!e);
229 if (e)
230 throw boost::system::system_error(e); // Terminate test.
231 *total_bytes_read += bytes_transferred;
232}
233
234void handle_read_eof(const boost::system::error_code& e,
235 std::size_t bytes_transferred)
236{
237 BOOST_ASIO_CHECK(e == boost::asio::error::eof);
238 BOOST_ASIO_CHECK(bytes_transferred == 0);
239}
240
241void test_async_operations()
242{
243 using namespace std; // For memcmp.
244
245 namespace bindns = std;
246 using bindns::placeholders::_1;
247 using bindns::placeholders::_2;
248
249 boost::asio::io_context io_context;
250
251 boost::asio::ip::tcp::acceptor acceptor(io_context,
252 boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 0));
253 boost::asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
254 server_endpoint.address(addr: boost::asio::ip::address_v4::loopback());
255
256 stream_type client_socket(io_context);
257 client_socket.lowest_layer().connect(peer_endpoint: server_endpoint);
258
259 stream_type server_socket(io_context);
260 acceptor.async_accept(peer&: server_socket.lowest_layer(), token: &handle_accept);
261 io_context.run();
262 io_context.restart();
263
264 const char write_data[]
265 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
266 const boost::asio::const_buffer write_buf = boost::asio::buffer(data: write_data);
267
268 std::size_t bytes_written = 0;
269 while (bytes_written < sizeof(write_data))
270 {
271 client_socket.async_write_some(
272 buffers: boost::asio::buffer(b: write_buf + bytes_written),
273 handler: bindns::bind(f&: handle_write, args: _1, args: _2, args: &bytes_written));
274 io_context.run();
275 io_context.restart();
276 }
277
278 char read_data[sizeof(write_data)];
279 const boost::asio::mutable_buffer read_buf = boost::asio::buffer(data&: read_data);
280
281 std::size_t bytes_read = 0;
282 while (bytes_read < sizeof(read_data))
283 {
284 server_socket.async_read_some(
285 buffers: boost::asio::buffer(b: read_buf + bytes_read),
286 handler: bindns::bind(f&: handle_read, args: _1, args: _2, args: &bytes_read));
287 io_context.run();
288 io_context.restart();
289 }
290
291 BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
292 BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
293 BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
294
295 bytes_written = 0;
296 while (bytes_written < sizeof(write_data))
297 {
298 server_socket.async_write_some(
299 buffers: boost::asio::buffer(b: write_buf + bytes_written),
300 handler: bindns::bind(f&: handle_write, args: _1, args: _2, args: &bytes_written));
301 io_context.run();
302 io_context.restart();
303 }
304
305 bytes_read = 0;
306 while (bytes_read < sizeof(read_data))
307 {
308 client_socket.async_read_some(
309 buffers: boost::asio::buffer(b: read_buf + bytes_read),
310 handler: bindns::bind(f&: handle_read, args: _1, args: _2, args: &bytes_read));
311 io_context.run();
312 io_context.restart();
313 }
314
315 BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
316 BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
317 BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
318
319 server_socket.close();
320 client_socket.async_read_some(buffers: boost::asio::buffer(b: read_buf), handler&: handle_read_eof);
321}
322
323BOOST_ASIO_TEST_SUITE
324(
325 "buffered_read_stream",
326 BOOST_ASIO_COMPILE_TEST_CASE(test_compile)
327 BOOST_ASIO_TEST_CASE(test_sync_operations)
328 BOOST_ASIO_TEST_CASE(test_async_operations)
329)
330

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of boost/libs/asio/test/buffered_read_stream.cpp