1//
2// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot 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/boostorg/beast
8//
9
10// Test that header file is self-contained.
11#include <boost/beast/core/buffers_adaptor.hpp>
12
13#include "test_buffer.hpp"
14
15#include <boost/beast/core/buffer_traits.hpp>
16#include <boost/beast/core/multi_buffer.hpp>
17#include <boost/beast/core/ostream.hpp>
18#include <boost/beast/core/read_size.hpp>
19#include <boost/beast/_experimental/unit_test/suite.hpp>
20#include <boost/asio/buffer.hpp>
21#include <boost/asio/buffers_iterator.hpp>
22#include <boost/asio/streambuf.hpp>
23#include <iterator>
24
25namespace boost {
26namespace beast {
27
28template class buffers_adaptor<net::mutable_buffer>;
29
30struct buffers_adaptor_test_hook
31{
32 template<class MutableBufferSequence>
33 static
34 auto
35 make_subrange(
36 buffers_adaptor <MutableBufferSequence> &adaptor,
37 std::size_t pos = 0,
38 std::size_t n = (std::numeric_limits<std::size_t>::max)())
39 -> typename buffers_adaptor<MutableBufferSequence>::mutable_buffers_type
40 {
41 return adaptor.make_subrange(pos, n);
42 }
43
44 template<class MutableBufferSequence>
45 static
46 auto
47 make_subrange(
48 buffers_adaptor<MutableBufferSequence> const& adaptor,
49 std::size_t pos = 0,
50 std::size_t n = (std::numeric_limits<std::size_t>::max)())
51 -> typename buffers_adaptor<MutableBufferSequence>::const_buffers_type
52 {
53 return adaptor.make_subrange(pos, n);
54 }
55};
56
57class buffers_adaptor_test : public unit_test::suite
58{
59public:
60 BOOST_STATIC_ASSERT(
61 is_mutable_dynamic_buffer<
62 buffers_adaptor<buffers_triple>>::value);
63
64 void
65 testDynamicBuffer()
66 {
67 char s[13];
68 buffers_triple tb(s, sizeof(s));
69 buffers_adaptor<buffers_triple> b(tb);
70 test_dynamic_buffer(b0: b);
71 }
72
73 void
74 testSpecial()
75 {
76 char s1[13];
77 buffers_triple tb1(s1, sizeof(s1));
78 BEAST_EXPECT(buffer_bytes(tb1) == sizeof(s1));
79
80 char s2[15];
81 buffers_triple tb2(s2, sizeof(s2));
82 BEAST_EXPECT(buffer_bytes(tb2) == sizeof(s2));
83
84 {
85 // construction
86
87 buffers_adaptor<buffers_triple> b1(tb1);
88 BEAST_EXPECT(b1.value() == tb1);
89
90 buffers_adaptor<buffers_triple> b2(tb2);
91 BEAST_EXPECT(b2.value() == tb2);
92
93 buffers_adaptor<buffers_triple> b3(b2);
94 BEAST_EXPECT(b3.value() == tb2);
95
96 char s3[15];
97 buffers_adaptor<buffers_triple> b4(
98 boost::in_place_init, s3, sizeof(s3));
99 BEAST_EXPECT(b4.value() == buffers_triple(s3, sizeof(s3)));
100
101 // assignment
102
103 b3 = b1;
104 BEAST_EXPECT(b3.value() == tb1);
105 }
106 }
107
108 void
109 testIssue386()
110 {
111 using type = net::streambuf;
112 type buffer;
113 buffers_adaptor<
114 type::mutable_buffers_type> ba{buffer.prepare(n: 512)};
115 read_size(buffer&: ba, max_size: 1024);
116 }
117
118 void
119 testIssue2459()
120 {
121 char s[13];
122 buffers_triple tb(s, sizeof(s));
123 buffers_adaptor<buffers_triple> b(tb);
124 ignore_unused(net::buffers_begin(buffers: b.data()));
125 }
126
127 template<bool isMutable>
128 void
129 testSubrange()
130 {
131 std::string s =
132 "the quick brown fox jumps over the lazy dog";
133
134 auto iterate_test = [&](
135 std::size_t a,
136 std::size_t b,
137 std::size_t c)
138 {
139 auto buffers = std::vector<net::mutable_buffer>();
140 if (a)
141 buffers.push_back(x: net::buffer(data: &s[0], size_in_bytes: a));
142 if (b - a)
143 buffers.push_back(x: net::buffer(data: &s[a], size_in_bytes: (b - a)));
144 if (c - b)
145 buffers.push_back(x: net::buffer(data: &s[b], size_in_bytes: (c - b)));
146 auto adapter = buffers_adaptor<std::vector<net::mutable_buffer>>(buffers);
147
148 using maybe_mutable =
149 typename std::conditional<
150 isMutable,
151 buffers_adaptor<std::vector<net::mutable_buffer>>&,
152 buffers_adaptor<std::vector<net::mutable_buffer>> const&>::type;
153
154 auto sub = buffers_adaptor_test_hook::make_subrange(static_cast<maybe_mutable>(adapter));
155 /*
156 using value_type = typename std::conditional<
157 isMutable, net::mutable_buffer, net::const_buffer>::type;
158 BEAST_EXPECTS(typeid(typename decltype(sub)::value_type) == typeid(value_type), "iterate_test");
159 */
160 BEAST_EXPECT(buffers_to_string(sub) == s.substr(0, c));
161 };
162
163 iterate_test(0, 0, 1);
164
165 for (std::size_t a = 0; a <= s.size(); ++a)
166 for (std::size_t b = a; b <= s.size(); ++b)
167 for (std::size_t c = b; c <= s.size(); ++c)
168 iterate_test(a, b, c);
169 }
170
171
172 void
173 run() override
174 {
175 testDynamicBuffer();
176 testSpecial();
177 testIssue386();
178 testIssue2459();
179 testSubrange<true>();
180 testSubrange<false>();
181 }
182};
183
184BEAST_DEFINE_TESTSUITE(beast,core,buffers_adaptor);
185
186} // beast
187} // boost
188

source code of boost/libs/beast/test/beast/core/buffers_adaptor.cpp