]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // |
92f5a8d4 | 2 | // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) |
7c673cae FG |
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 | // | |
b32b8144 FG |
7 | // Official repository: https://github.com/boostorg/beast |
8 | // | |
7c673cae FG |
9 | |
10 | // Test that header file is self-contained. | |
b32b8144 | 11 | #include <boost/beast/core/buffers_cat.hpp> |
7c673cae | 12 | |
92f5a8d4 TL |
13 | #include "test_buffer.hpp" |
14 | ||
15 | #include <boost/beast/_experimental/unit_test/suite.hpp> | |
16 | #include <boost/beast/core/buffer_traits.hpp> | |
17 | #include <boost/beast/core/buffers_prefix.hpp> | |
18 | #include <boost/beast/core/buffers_suffix.hpp> | |
7c673cae FG |
19 | #include <boost/asio/buffer.hpp> |
20 | #include <boost/asio/streambuf.hpp> | |
21 | #include <iterator> | |
22 | #include <list> | |
23 | #include <type_traits> | |
24 | #include <vector> | |
25 | ||
b32b8144 | 26 | namespace boost { |
7c673cae FG |
27 | namespace beast { |
28 | ||
b32b8144 | 29 | class buffers_cat_test : public unit_test::suite |
7c673cae FG |
30 | { |
31 | public: | |
92f5a8d4 TL |
32 | void |
33 | testDefaultIterators() | |
7c673cae | 34 | { |
92f5a8d4 TL |
35 | // default ctor is one past the end |
36 | char c[2] = {}; | |
37 | auto bs = buffers_cat( | |
38 | net::const_buffer(&c[0], 1), | |
39 | net::const_buffer(&c[1], 1)); | |
40 | decltype(bs)::const_iterator it; | |
41 | decltype(bs)::const_iterator it2; | |
42 | BEAST_EXPECT(it == it2); | |
43 | BEAST_EXPECT(it2 == it); | |
44 | it = bs.end(); | |
45 | it2 = bs.end(); | |
46 | BEAST_EXPECT(it == it2); | |
47 | BEAST_EXPECT(it2 == it); | |
48 | decltype(bs)::const_iterator it3(it2); | |
49 | BEAST_EXPECT(it3 == it2); | |
50 | it = bs.begin(); | |
51 | BEAST_EXPECT(it != it3); | |
52 | it = it3; | |
53 | BEAST_EXPECT(it == it3); | |
7c673cae | 54 | |
92f5a8d4 TL |
55 | // dereferencing default iterator should throw |
56 | try | |
7c673cae | 57 | { |
92f5a8d4 TL |
58 | it = {}; |
59 | (void)*it; | |
60 | fail(); | |
7c673cae | 61 | } |
92f5a8d4 | 62 | catch(std::logic_error const&) |
7c673cae | 63 | { |
92f5a8d4 | 64 | pass(); |
7c673cae | 65 | } |
92f5a8d4 | 66 | catch(...) |
7c673cae | 67 | { |
92f5a8d4 | 68 | fail(); |
7c673cae FG |
69 | } |
70 | } | |
71 | ||
92f5a8d4 TL |
72 | void |
73 | testBufferSequence() | |
74 | { | |
75 | string_view s = "Hello, world!"; | |
76 | net::const_buffer b1(s.data(), 6); | |
77 | net::const_buffer b2( | |
78 | s.data() + b1.size(), s.size() - b1.size()); | |
79 | test_buffer_sequence(buffers_cat(b1, b2)); | |
80 | } | |
81 | ||
82 | template<class F> | |
83 | void | |
84 | checkException(F&& f) | |
7c673cae | 85 | { |
7c673cae FG |
86 | try |
87 | { | |
92f5a8d4 TL |
88 | f(); |
89 | fail("missing exception", __FILE__, __LINE__); | |
7c673cae | 90 | } |
92f5a8d4 | 91 | catch(std::logic_error const&) |
7c673cae FG |
92 | { |
93 | pass(); | |
94 | } | |
92f5a8d4 | 95 | catch(...) |
7c673cae | 96 | { |
92f5a8d4 | 97 | fail("wrong exception", __FILE__, __LINE__); |
7c673cae | 98 | } |
92f5a8d4 | 99 | } |
7c673cae | 100 | |
92f5a8d4 TL |
101 | void |
102 | testExceptions() | |
103 | { | |
104 | net::const_buffer b1{"He", 2}; | |
105 | net::const_buffer b2{"llo,", 4}; | |
106 | net::const_buffer b3{" world!", 7}; | |
107 | ||
108 | auto const b = beast::buffers_cat(b1, b2, b3); | |
109 | using type = decltype(b); | |
110 | ||
111 | // Dereferencing a default-constructed iterator | |
112 | checkException( | |
113 | [] | |
114 | { | |
115 | (void)*(type::const_iterator{}); | |
116 | }); | |
117 | ||
118 | // Incrementing a default-constructed iterator | |
119 | checkException( | |
120 | [] | |
121 | { | |
122 | ++(type::const_iterator{}); | |
123 | }); | |
124 | ||
125 | // Decrementing a default-constructed iterator | |
126 | checkException( | |
127 | [] | |
128 | { | |
129 | --(type::const_iterator{}); | |
130 | }); | |
131 | ||
132 | // Decrementing an iterator to the beginning | |
133 | checkException( | |
134 | [&b] | |
135 | { | |
136 | --b.begin(); | |
137 | }); | |
138 | ||
139 | // Dereferencing an iterator to the end | |
140 | checkException( | |
141 | [&b] | |
142 | { | |
143 | *b.end(); | |
144 | }); | |
145 | ||
146 | // Incrementing an iterator to the end | |
147 | checkException( | |
148 | [&b] | |
149 | { | |
150 | ++b.end(); | |
151 | }); | |
152 | } | |
153 | ||
154 | void | |
155 | testEmpty() | |
156 | { | |
157 | struct empty_sequence | |
7c673cae | 158 | { |
92f5a8d4 TL |
159 | using value_type = net::const_buffer; |
160 | using const_iterator = value_type const*; | |
161 | ||
162 | const_iterator | |
163 | begin() const noexcept | |
164 | { | |
165 | return &v_; | |
166 | } | |
167 | ||
168 | const_iterator | |
169 | end() const noexcept | |
170 | { | |
171 | return begin(); | |
172 | } | |
173 | ||
174 | private: | |
175 | value_type v_; | |
176 | }; | |
177 | ||
7c673cae | 178 | { |
92f5a8d4 TL |
179 | net::const_buffer b0{}; |
180 | net::const_buffer b1{"He", 2}; | |
181 | net::const_buffer b2{"llo,", 4}; | |
182 | net::const_buffer b3{" world!", 7}; | |
183 | ||
184 | { | |
185 | auto const b = beast::buffers_cat(b0, b0); | |
186 | BEAST_EXPECT(buffer_bytes(b) == 0); | |
187 | BEAST_EXPECT(buffers_length(b) == 0); | |
188 | } | |
189 | { | |
190 | auto const b = beast::buffers_cat(b0, b0, b0, b0); | |
191 | BEAST_EXPECT(buffer_bytes(b) == 0); | |
192 | BEAST_EXPECT(buffers_length(b) == 0); | |
193 | } | |
194 | { | |
195 | auto const b = beast::buffers_cat(b1, b2, b3); | |
196 | BEAST_EXPECT(beast::buffers_to_string(b) == "Hello, world!"); | |
197 | BEAST_EXPECT(buffers_length(b) == 3); | |
198 | test_buffer_sequence(b); | |
199 | } | |
200 | { | |
201 | auto const b = beast::buffers_cat(b0, b1, b2, b3); | |
202 | BEAST_EXPECT(beast::buffers_to_string(b) == "Hello, world!"); | |
203 | BEAST_EXPECT(buffers_length(b) == 3); | |
204 | test_buffer_sequence(b); | |
205 | } | |
206 | { | |
207 | auto const b = beast::buffers_cat(b1, b0, b2, b3); | |
208 | BEAST_EXPECT(beast::buffers_to_string(b) == "Hello, world!"); | |
209 | BEAST_EXPECT(buffers_length(b) == 3); | |
210 | test_buffer_sequence(b); | |
211 | } | |
212 | { | |
213 | auto const b = beast::buffers_cat(b1, b2, b0, b3); | |
214 | BEAST_EXPECT(beast::buffers_to_string(b) == "Hello, world!"); | |
215 | BEAST_EXPECT(buffers_length(b) == 3); | |
216 | test_buffer_sequence(b); | |
217 | } | |
218 | { | |
219 | auto const b = beast::buffers_cat(b1, b2, b3, b0); | |
220 | BEAST_EXPECT(beast::buffers_to_string(b) == "Hello, world!"); | |
221 | BEAST_EXPECT(buffers_length(b) == 3); | |
222 | test_buffer_sequence(b); | |
223 | } | |
7c673cae FG |
224 | } |
225 | ||
7c673cae | 226 | { |
92f5a8d4 TL |
227 | auto e1 = net::const_buffer{}; |
228 | auto b1 = std::array<net::const_buffer, 3>{{ | |
229 | e1, | |
230 | net::const_buffer{"He", 2}, | |
231 | net::const_buffer{"l", 1} }}; | |
232 | auto b2 = std::array<net::const_buffer, 3>{{ | |
233 | net::const_buffer{"lo", 2}, | |
234 | e1, | |
235 | net::const_buffer{", ", 2} }}; | |
236 | auto b3 = std::array<net::const_buffer, 3>{{ | |
237 | net::const_buffer{"w", 1}, | |
238 | net::const_buffer{"orld!", 5}, | |
239 | e1 }}; | |
240 | { | |
241 | auto const b = beast::buffers_cat( | |
242 | e1, b1, e1, b2, e1, b3, e1); | |
243 | BEAST_EXPECT(beast::buffers_to_string(b) == "Hello, world!"); | |
244 | BEAST_EXPECT(buffers_length(b) == 6); | |
245 | } | |
7c673cae | 246 | } |
92f5a8d4 | 247 | |
7c673cae | 248 | { |
92f5a8d4 TL |
249 | auto e1 = net::const_buffer{}; |
250 | auto e2 = empty_sequence{}; | |
251 | auto b1 = std::array<net::const_buffer, 3>{{ | |
252 | e1, | |
253 | net::const_buffer{"He", 2}, | |
254 | net::const_buffer{"l", 1} }}; | |
255 | auto b2 = std::array<net::const_buffer, 3>{{ | |
256 | net::const_buffer{"lo", 2}, | |
257 | e1, | |
258 | net::const_buffer{", ", 2} }}; | |
259 | auto b3 = std::array<net::const_buffer, 3>{{ | |
260 | net::const_buffer{"w", 1}, | |
261 | net::const_buffer{"orld!", 5}, | |
262 | e1 }}; | |
263 | { | |
264 | auto const b = beast::buffers_cat( | |
265 | e2, b1, e2, b2, e2, b3, e2); | |
266 | BEAST_EXPECT(beast::buffers_to_string(b) == "Hello, world!"); | |
267 | BEAST_EXPECT(buffers_length(b) == 6); | |
268 | } | |
7c673cae | 269 | } |
7c673cae FG |
270 | } |
271 | ||
92f5a8d4 TL |
272 | void |
273 | testGccWarning1() | |
7c673cae | 274 | { |
92f5a8d4 TL |
275 | char out[64]; |
276 | std::array<net::const_buffer, 2> buffers{ | |
277 | {net::buffer("Hello, "), net::buffer("world!")}}; | |
278 | std::size_t i = 3; | |
279 | buffers_suffix<std::array<net::const_buffer, 2>> cb(buffers); | |
280 | cb.consume(i); | |
281 | net::buffer_copy( | |
282 | net::buffer(out), | |
283 | buffers_cat(cb, cb)); | |
284 | } | |
7c673cae | 285 | |
92f5a8d4 TL |
286 | // VFALCO Some version of g++ incorrectly complain about |
287 | // uninitialized values when buffers_cat and | |
288 | // buffers_prefix and/or buffers_suffix are used | |
289 | // together. | |
290 | void | |
291 | testGccWarning2() | |
292 | { | |
293 | char out[64]; | |
294 | net::const_buffer buffers("Hello, world!", 13); | |
295 | std::size_t i = 3; | |
296 | buffers_suffix<net::const_buffer> cb{buffers}; | |
297 | cb.consume(i); | |
298 | net::buffer_copy( | |
299 | net::buffer(out), | |
300 | buffers_cat(buffers_prefix(i, buffers), cb)); | |
301 | } | |
7c673cae | 302 | |
92f5a8d4 TL |
303 | void |
304 | testSingleBuffer() | |
305 | { | |
306 | char c[1] = {}; | |
307 | auto b = net::const_buffer(c, 1); | |
308 | auto bs = buffers_cat(net::const_buffer(c, 1)); | |
309 | auto first = net::buffer_sequence_begin(bs); | |
310 | auto last = net::buffer_sequence_end(bs); | |
311 | BOOST_ASSERT(first != last); | |
312 | BEAST_EXPECT(std::distance(first, last) == 1); | |
313 | net::const_buffer b2(*first); | |
314 | BEAST_EXPECT(b.data() == b2.data()); | |
315 | BEAST_EXPECT(b.size() == b2.size()); | |
316 | } | |
7c673cae | 317 | |
92f5a8d4 TL |
318 | void run() override |
319 | { | |
320 | testDefaultIterators(); | |
321 | testBufferSequence(); | |
322 | testExceptions(); | |
323 | testEmpty(); | |
324 | testGccWarning1(); | |
325 | testGccWarning2(); | |
326 | testSingleBuffer(); | |
7c673cae FG |
327 | } |
328 | }; | |
329 | ||
b32b8144 | 330 | BEAST_DEFINE_TESTSUITE(beast,core,buffers_cat); |
7c673cae FG |
331 | |
332 | } // beast | |
b32b8144 | 333 | } // boost |