2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
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)
7 // Official repository: https://github.com/boostorg/beast
10 // Test that header file is self-contained.
11 #include <boost/beast/core/multi_buffer.hpp>
13 #include "test_buffer.hpp"
15 #include <boost/beast/core/buffer_traits.hpp>
16 #include <boost/beast/core/ostream.hpp>
17 #include <boost/beast/core/read_size.hpp>
18 #include <boost/beast/core/string.hpp>
19 #include <boost/beast/test/test_allocator.hpp>
20 #include <boost/beast/_experimental/unit_test/suite.hpp>
21 #include <boost/asio/buffer.hpp>
22 #include <boost/asio/buffers_iterator.hpp>
32 class multi_buffer_test
: public beast::unit_test::suite
36 is_mutable_dynamic_buffer
<multi_buffer
>::value
);
38 #if ! BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000) && \
39 ! BOOST_WORKAROUND(BOOST_MSVC, < 1910)
40 BOOST_STATIC_ASSERT(std::is_trivially_copyable
<
41 multi_buffer::const_buffers_type
>::value
);
42 BOOST_STATIC_ASSERT(std::is_trivially_copyable
<
43 multi_buffer::mutable_data_type
>::value
);
46 template<class Alloc1
, class Alloc2
>
49 eq( basic_multi_buffer
<Alloc1
> const& mb1
,
50 basic_multi_buffer
<Alloc2
> const& mb2
)
52 return buffers_to_string(mb1
.data()) ==
53 buffers_to_string(mb2
.data());
63 BEAST_EXPECT(b
.size() == 0);
64 BEAST_EXPECT(b
.capacity() == 0);
66 BEAST_EXPECT(b
.size() == 0);
67 BEAST_EXPECT(b
.capacity() == 0);
70 // zero readable bytes
76 BEAST_EXPECT(b
.size() == 0);
77 BEAST_EXPECT(b
.capacity() == 0);
86 BEAST_EXPECT(b
.size() == 0);
87 BEAST_EXPECT(b
.capacity() == 0);
97 BEAST_EXPECT(b
.size() == 0);
98 BEAST_EXPECT(b
.capacity() == 0);
109 BEAST_EXPECT(b
.size() == 512);
110 BEAST_EXPECT(b
.capacity() == 512);
120 BEAST_EXPECT(b
.size() == 512);
121 BEAST_EXPECT(b
.capacity() == 512);
124 // partial last buffer
133 BEAST_EXPECT(b
.size() == 600);
134 BEAST_EXPECT(b
.capacity() == 600);
137 // shrink front of first buffer
145 BEAST_EXPECT(b
.size() == 500);
146 BEAST_EXPECT(b
.capacity() == 500);
149 // shrink ends of first buffer
157 BEAST_EXPECT(b
.size() == 400);
158 BEAST_EXPECT(b
.capacity() == 400);
166 BEAST_EXPECT(b
.max_size() == 30);
167 test_dynamic_buffer(b
);
173 using namespace test
;
176 using equal_t
= test::test_allocator
<char,
177 true, true, true, true, true>;
180 using unequal_t
= test::test_allocator
<char,
181 false, true, true, true, true>;
187 BEAST_EXPECT(b
.capacity() == 0);
191 BEAST_EXPECT(b
.capacity() == 0);
192 BEAST_EXPECT(b
.max_size() == 500);
196 basic_multi_buffer
<unequal_t
> b
{a1
};
197 BEAST_EXPECT(b
.get_allocator() == a1
);
198 BEAST_EXPECT(b
.get_allocator() != unequal_t
{});
202 basic_multi_buffer
<unequal_t
> b
{500, a1
};
203 BEAST_EXPECT(b
.capacity() == 0);
204 BEAST_EXPECT(b
.max_size() == 500);
205 BEAST_EXPECT(b
.get_allocator() == a1
);
206 BEAST_EXPECT(b
.get_allocator() != unequal_t
{});
213 basic_multi_buffer
<equal_t
> b1
{30};
214 BEAST_EXPECT(b1
.get_allocator()->nmove
== 0);
215 ostream(b1
) << "Hello";
216 basic_multi_buffer
<equal_t
> b2
{std::move(b1
)};
217 BEAST_EXPECT(b2
.get_allocator()->nmove
== 1);
218 BEAST_EXPECT(b1
.size() == 0);
219 BEAST_EXPECT(b1
.capacity() == 0);
220 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
221 BEAST_EXPECT(b1
.max_size() == b2
.max_size());
225 basic_multi_buffer
<equal_t
> b1
{30};
226 ostream(b1
) << "Hello";
228 basic_multi_buffer
<equal_t
> b2
{std::move(b1
), a
};
229 BEAST_EXPECT(b1
.size() == 0);
230 BEAST_EXPECT(b1
.capacity() == 0);
231 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
232 BEAST_EXPECT(b1
.max_size() == b2
.max_size());
235 // allocators unequal
236 basic_multi_buffer
<unequal_t
> b1
{30};
237 ostream(b1
) << "Hello";
239 basic_multi_buffer
<unequal_t
> b2
{std::move(b1
), a
};
240 BEAST_EXPECT(b1
.size() == 0);
241 BEAST_EXPECT(b1
.capacity() == 0);
242 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
243 BEAST_EXPECT(b1
.max_size() == b2
.max_size());
250 basic_multi_buffer
<equal_t
> b1
;
251 ostream(b1
) << "Hello";
252 basic_multi_buffer
<equal_t
> b2
{b1
};
253 BEAST_EXPECT(b1
.get_allocator() == b2
.get_allocator());
254 BEAST_EXPECT(buffers_to_string(b1
.data()) == "Hello");
255 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
258 basic_multi_buffer
<unequal_t
> b1
;
259 ostream(b1
) << "Hello";
261 basic_multi_buffer
<unequal_t
> b2(b1
, a
);
262 BEAST_EXPECT(b1
.get_allocator() != b2
.get_allocator());
263 BEAST_EXPECT(buffers_to_string(b1
.data()) == "Hello");
264 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
267 basic_multi_buffer
<equal_t
> b1
;
268 ostream(b1
) << "Hello";
269 basic_multi_buffer
<unequal_t
> b2(b1
);
270 BEAST_EXPECT(buffers_to_string(b1
.data()) == "Hello");
271 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
274 basic_multi_buffer
<unequal_t
> b1
;
275 ostream(b1
) << "Hello";
277 basic_multi_buffer
<equal_t
> b2(b1
, a
);
278 BEAST_EXPECT(b2
.get_allocator() == a
);
279 BEAST_EXPECT(buffers_to_string(b1
.data()) == "Hello");
280 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
288 ostream(b1
) << "Hello";
291 BEAST_EXPECT(b1
.size() == 0);
292 BEAST_EXPECT(b1
.capacity() == 0);
293 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
296 using na_t
= test::test_allocator
<char,
297 false, true, false, true, true>;
298 basic_multi_buffer
<na_t
> b1
;
299 ostream(b1
) << "Hello";
300 basic_multi_buffer
<na_t
> b2
;
302 BEAST_EXPECT(b1
.get_allocator() != b2
.get_allocator());
303 BEAST_EXPECT(b1
.size() == 0);
304 BEAST_EXPECT(b1
.capacity() == 0);
305 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
308 // propagate_on_container_move_assignment : true
309 using pocma_t
= test::test_allocator
<char,
310 true, true, true, true, true>;
311 basic_multi_buffer
<pocma_t
> b1
;
312 ostream(b1
) << "Hello";
313 basic_multi_buffer
<pocma_t
> b2
;
315 BEAST_EXPECT(b1
.size() == 0);
316 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
319 // propagate_on_container_move_assignment : false
320 using pocma_t
= test::test_allocator
<char,
321 true, true, false, true, true>;
322 basic_multi_buffer
<pocma_t
> b1
;
323 ostream(b1
) << "Hello";
324 basic_multi_buffer
<pocma_t
> b2
;
326 BEAST_EXPECT(b1
.size() == 0);
327 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
335 ostream(b1
) << "Hello";
338 BEAST_EXPECT(buffers_to_string(b1
.data()) == "Hello");
339 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
340 basic_multi_buffer
<equal_t
> b3
;
342 BEAST_EXPECT(buffers_to_string(b3
.data()) == "Hello");
345 // propagate_on_container_copy_assignment : true
346 using pocca_t
= test::test_allocator
<char,
347 true, true, true, true, true>;
348 basic_multi_buffer
<pocca_t
> b1
;
349 ostream(b1
) << "Hello";
350 basic_multi_buffer
<pocca_t
> b2
;
352 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
355 // propagate_on_container_copy_assignment : false
356 using pocca_t
= test::test_allocator
<char,
357 true, false, true, true, true>;
358 basic_multi_buffer
<pocca_t
> b1
;
359 ostream(b1
) << "Hello";
360 basic_multi_buffer
<pocca_t
> b2
;
362 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
369 BEAST_EXPECT(b
.max_size() == 10);
371 BEAST_EXPECT(b
.max_size() == 32);
374 // allocator max_size
376 basic_multi_buffer
<equal_t
> b
;
377 auto a
= b
.get_allocator();
379 ! std::is_const
<decltype(a
)>::value
);
384 fail("", __FILE__
, __LINE__
);
386 catch(std::length_error
const&)
393 fail("", __FILE__
, __LINE__
);
395 catch(std::length_error
const&)
408 b
.prepare(b
.max_size() + 1);
409 fail("", __FILE__
, __LINE__
);
411 catch(std::length_error
const&)
417 string_view
const s
= "Hello, world!";
419 BEAST_EXPECT(b1
.size() == 0);
420 BEAST_EXPECT(b1
.max_size() == 64);
421 BEAST_EXPECT(b1
.capacity() == 0);
423 BEAST_EXPECT(buffers_to_string(b1
.data()) == s
);
426 BEAST_EXPECT(buffers_to_string(b2
.data()) == s
);
428 BEAST_EXPECT(buffers_to_string(b2
.data()) == s
.substr(7));
433 BEAST_EXPECT(buffers_to_string(b2
.data()) == s
);
435 BEAST_EXPECT(buffers_to_string(b2
.data()) == s
.substr(7));
441 BEAST_EXPECT(b
.capacity() >= 1000);
443 BEAST_EXPECT(b
.size() == 1);
444 BEAST_EXPECT(b
.capacity() >= 1000);
446 BEAST_EXPECT(b
.size() == 1);
447 BEAST_EXPECT(b
.capacity() >= 1000);
449 BEAST_EXPECT(b
.capacity() >= 1000);
454 BEAST_EXPECT(b
.capacity() >= 1000);
456 BEAST_EXPECT(b
.capacity() >= 1000);
458 BEAST_EXPECT(b
.capacity() >= 1000);
460 BEAST_EXPECT(b
.capacity() >= 2000);
466 BEAST_EXPECT(b
.capacity() >= 1000);
468 BEAST_EXPECT(b
.capacity() >= 2000);
470 BEAST_EXPECT(b
.capacity() >= 4000);
472 BEAST_EXPECT(b
.capacity() >= 50);
483 b
.capacity() - b
.size();
488 auto const capacity
=
491 BEAST_EXPECT(b
.size() == size
);
492 BEAST_EXPECT(b
.capacity() == capacity
);
497 BEAST_EXPECT(b
.capacity() >= 1000);
499 BEAST_EXPECT(b
.size() == 1000);
500 BEAST_EXPECT(b
.capacity() >= 1000);
502 BEAST_EXPECT(b
.size() == 0);
503 BEAST_EXPECT(b
.capacity() == 0);
506 BEAST_EXPECT(b
.size() == 650);
507 BEAST_EXPECT(b
.capacity() >= 1000);
509 BEAST_EXPECT(b
.capacity() >= 1650);
511 BEAST_EXPECT(b
.size() == 750);
512 BEAST_EXPECT(b
.capacity() >= 1000);
514 BEAST_EXPECT(b
.capacity() >= 2000);
522 BEAST_EXPECT(b
.capacity() >= 1000);
524 BEAST_EXPECT(b
.size() == 1000);
525 BEAST_EXPECT(b
.capacity() >= 1000);
527 BEAST_EXPECT(b
.capacity() >= 2000);
529 BEAST_EXPECT(b
.size() == 1750);
531 BEAST_EXPECT(b
.size() == 1250);
533 BEAST_EXPECT(b
.size() == 750);
536 BEAST_EXPECT(b
.size() == 0);
539 BEAST_EXPECT(b
.size() == 800);
542 BEAST_EXPECT(b
.size() == 1400);
544 BEAST_EXPECT(b
.size() == 0);
550 BEAST_EXPECT(b
.capacity() == 0);
552 BEAST_EXPECT(b
.capacity() >= 50);
556 BEAST_EXPECT(b
.capacity() >= 50);
557 BEAST_EXPECT(b
.size() > 1);
558 auto capacity
= b
.capacity();
559 b
.reserve(b
.size() - 1);
560 BEAST_EXPECT(b
.capacity() == capacity
);
561 b
.reserve(b
.capacity() + 1);
562 BEAST_EXPECT(b
.capacity() > capacity
);
563 capacity
= b
.capacity();
564 BEAST_EXPECT(buffers_length(
565 b
.prepare(b
.capacity() + 200)) > 1);
566 BEAST_EXPECT(b
.capacity() > capacity
);
567 b
.reserve(b
.capacity() + 2);
568 BEAST_EXPECT(b
.capacity() > capacity
);
569 capacity
= b
.capacity();
570 b
.reserve(b
.capacity());
571 BEAST_EXPECT(b
.capacity() == capacity
);
578 BEAST_EXPECT(b
.capacity() == 0);
580 BEAST_EXPECT(b
.capacity() >= 50);
582 BEAST_EXPECT(b
.capacity() >= 50);
584 BEAST_EXPECT(b
.capacity() >= 125);
586 BEAST_EXPECT(b
.capacity() >= b
.size());
591 BEAST_EXPECT(b
.capacity() == 2000);
593 BEAST_EXPECT(b
.size() == 1800);
594 BEAST_EXPECT(b
.capacity() == 2000);
596 BEAST_EXPECT(b
.capacity() == 6800);
598 BEAST_EXPECT(b
.capacity() == 2000);
605 BEAST_EXPECT(b
.capacity() == 0);
608 BEAST_EXPECT(b
.size() == 50);
609 BEAST_EXPECT(b
.capacity() == 512);
611 BEAST_EXPECT(b
.size() == 0);
612 BEAST_EXPECT(b
.capacity() == 512);
618 // propagate_on_container_swap : true
619 using pocs_t
= test::test_allocator
<char,
620 false, true, true, true, true>;
622 BEAST_EXPECT(a1
!= a2
);
623 basic_multi_buffer
<pocs_t
> b1
{a1
};
624 ostream(b1
) << "Hello";
625 basic_multi_buffer
<pocs_t
> b2
{a2
};
626 BEAST_EXPECT(b1
.get_allocator() == a1
);
627 BEAST_EXPECT(b2
.get_allocator() == a2
);
629 BEAST_EXPECT(b1
.get_allocator() == a2
);
630 BEAST_EXPECT(b2
.get_allocator() == a1
);
631 BEAST_EXPECT(b1
.size() == 0);
632 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
634 BEAST_EXPECT(b1
.get_allocator() == a1
);
635 BEAST_EXPECT(b2
.get_allocator() == a2
);
636 BEAST_EXPECT(buffers_to_string(b1
.data()) == "Hello");
637 BEAST_EXPECT(b2
.size() == 0);
640 // propagate_on_container_swap : false
641 using pocs_t
= test::test_allocator
<char,
642 true, true, true, false, true>;
644 BEAST_EXPECT(a1
== a2
);
645 BEAST_EXPECT(a1
.id() != a2
.id());
646 basic_multi_buffer
<pocs_t
> b1
{a1
};
647 ostream(b1
) << "Hello";
648 basic_multi_buffer
<pocs_t
> b2
{a2
};
649 BEAST_EXPECT(b1
.get_allocator() == a1
);
650 BEAST_EXPECT(b2
.get_allocator() == a2
);
652 BEAST_EXPECT(b1
.get_allocator().id() == a1
.id());
653 BEAST_EXPECT(b2
.get_allocator().id() == a2
.id());
654 BEAST_EXPECT(b1
.size() == 0);
655 BEAST_EXPECT(buffers_to_string(b2
.data()) == "Hello");
657 BEAST_EXPECT(b1
.get_allocator().id() == a1
.id());
658 BEAST_EXPECT(b2
.get_allocator().id() == a2
.id());
659 BEAST_EXPECT(buffers_to_string(b1
.data()) == "Hello");
660 BEAST_EXPECT(b2
.size() == 0);
667 BEAST_EXPECT(read_size(b
, 512) == 10);
670 BEAST_EXPECT(read_size(b
, 512) == 6);
672 BEAST_EXPECT(read_size(b
, 512) == 8);
675 BEAST_EXPECT(read_size(b
, 512) == 0);
682 string_view s
= "Hello, world";
683 BEAST_EXPECT(s
.size() == 12);
684 for(std::size_t i
= 1; i
< 12; ++i
) {
685 for(std::size_t x
= 1; x
< 4; ++x
) {
686 for(std::size_t y
= 1; y
< 4; ++y
) {
687 std::size_t z
= s
.size() - (x
+ y
);
690 b
.commit(net::buffer_copy(
691 b
.prepare(x
), net::buffer(s
.data(), x
)));
692 b
.commit(net::buffer_copy(
693 b
.prepare(y
), net::buffer(s
.data()+x
, y
)));
694 b
.commit(net::buffer_copy(
695 b
.prepare(z
), net::buffer(s
.data()+x
+y
, z
)));
696 BEAST_EXPECT(buffers_to_string(b
.data()) == s
);
699 BEAST_EXPECT(eq(b
, mb2
));
704 BEAST_EXPECT(eq(b
, mb2
));
707 multi_buffer mb2
{std::move(b
)};
708 BEAST_EXPECT(buffers_to_string(mb2
.data()) == s
);
709 BEAST_EXPECT(b
.size() == 0);
710 BEAST_EXPECT(buffer_bytes(b
.data()) == 0);
712 BEAST_EXPECT(buffers_to_string(b
.data()) == s
);
713 BEAST_EXPECT(mb2
.size() == 0);
714 BEAST_EXPECT(buffer_bytes(mb2
.data()) == 0);
723 using namespace test
;
724 std::string
const s
= "Hello, world";
725 BEAST_EXPECT(s
.size() == 12);
726 for(std::size_t i
= 1; i
< 12; ++i
) {
727 for(std::size_t x
= 1; x
< 4; ++x
) {
728 for(std::size_t y
= 1; y
< 4; ++y
) {
729 for(std::size_t t
= 1; t
< 4; ++ t
) {
730 for(std::size_t u
= 1; u
< 4; ++ u
) {
731 std::size_t z
= s
.size() - (x
+ y
);
732 std::size_t v
= s
.size() - (t
+ u
);
736 auto d
= b
.prepare(z
);
737 BEAST_EXPECT(buffer_bytes(d
) == z
);
740 auto d
= b
.prepare(0);
741 BEAST_EXPECT(buffer_bytes(d
) == 0);
744 auto d
= b
.prepare(y
);
745 BEAST_EXPECT(buffer_bytes(d
) == y
);
748 auto d
= b
.prepare(x
);
749 BEAST_EXPECT(buffer_bytes(d
) == x
);
750 b
.commit(buffer_copy(d
, net::buffer(s
.data(), x
)));
752 BEAST_EXPECT(b
.size() == x
);
753 BEAST_EXPECT(buffer_bytes(b
.data()) == b
.size());
755 auto d
= b
.prepare(x
);
756 BEAST_EXPECT(buffer_bytes(d
) == x
);
759 auto d
= b
.prepare(0);
760 BEAST_EXPECT(buffer_bytes(d
) == 0);
763 auto d
= b
.prepare(z
);
764 BEAST_EXPECT(buffer_bytes(d
) == z
);
767 auto d
= b
.prepare(y
);
768 BEAST_EXPECT(buffer_bytes(d
) == y
);
769 b
.commit(buffer_copy(d
, net::buffer(s
.data()+x
, y
)));
772 BEAST_EXPECT(b
.size() == x
+ y
);
773 BEAST_EXPECT(buffer_bytes(b
.data()) == b
.size());
775 auto d
= b
.prepare(x
);
776 BEAST_EXPECT(buffer_bytes(d
) == x
);
779 auto d
= b
.prepare(y
);
780 BEAST_EXPECT(buffer_bytes(d
) == y
);
783 auto d
= b
.prepare(0);
784 BEAST_EXPECT(buffer_bytes(d
) == 0);
787 auto d
= b
.prepare(z
);
788 BEAST_EXPECT(buffer_bytes(d
) == z
);
789 b
.commit(buffer_copy(d
, net::buffer(s
.data()+x
+y
, z
)));
792 BEAST_EXPECT(b
.size() == x
+ y
+ z
);
793 BEAST_EXPECT(buffer_bytes(b
.data()) == b
.size());
794 BEAST_EXPECT(buffers_to_string(b
.data()) == s
);
797 auto d
= b
.prepare(0);
798 BEAST_EXPECT(buffer_bytes(d
) == 0);
800 BEAST_EXPECT(buffers_to_string(b
.data()) ==
801 s
.substr(t
, std::string::npos
));
803 BEAST_EXPECT(buffers_to_string(b
.data()) ==
804 s
.substr(t
+ u
, std::string::npos
));
806 BEAST_EXPECT(buffers_to_string(b
.data()).empty());
809 auto d
= b
.prepare(0);
810 BEAST_EXPECT(buffer_bytes(d
) == 0);
829 BEAST_DEFINE_TESTSUITE(beast
,core
,multi_buffer
);