]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/beast/core/impl/flat_stream.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / beast / core / impl / flat_stream.hpp
CommitLineData
92f5a8d4
TL
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#ifndef BOOST_BEAST_CORE_IMPL_FLAT_STREAM_HPP
11#define BOOST_BEAST_CORE_IMPL_FLAT_STREAM_HPP
12
13#include <boost/beast/core/async_base.hpp>
14#include <boost/beast/core/buffers_prefix.hpp>
15#include <boost/beast/core/static_buffer.hpp>
16#include <boost/beast/core/stream_traits.hpp>
17#include <boost/beast/websocket/teardown.hpp>
18#include <boost/asio/buffer.hpp>
19#include <memory>
20
21namespace boost {
22namespace beast {
23
24template<class NextLayer>
25struct flat_stream<NextLayer>::ops
26{
27
28template<class Handler>
29class write_op
30 : public async_base<Handler,
31 beast::executor_type<flat_stream>>
32{
33public:
34 template<
35 class ConstBufferSequence,
36 class Handler_>
37 write_op(
38 Handler_&& h,
39 flat_stream<NextLayer>& s,
40 ConstBufferSequence const& b)
41 : async_base<Handler,
42 beast::executor_type<flat_stream>>(
43 std::forward<Handler_>(h),
44 s.get_executor())
45 {
46 auto const result =
47 flatten(b, max_size);
48 if(result.flatten)
49 {
50 s.buffer_.clear();
51 s.buffer_.commit(net::buffer_copy(
52 s.buffer_.prepare(result.size),
53 b, result.size));
20effc67
TL
54
55 BOOST_ASIO_HANDLER_LOCATION((
56 __FILE__, __LINE__,
57 "flat_stream::async_write_some"));
58
92f5a8d4
TL
59 s.stream_.async_write_some(
60 s.buffer_.data(), std::move(*this));
61 }
62 else
63 {
64 s.buffer_.clear();
65 s.buffer_.shrink_to_fit();
20effc67
TL
66
67 BOOST_ASIO_HANDLER_LOCATION((
68 __FILE__, __LINE__,
69 "flat_stream::async_write_some"));
70
92f5a8d4
TL
71 s.stream_.async_write_some(
72 beast::buffers_prefix(
73 result.size, b), std::move(*this));
74 }
75 }
76
77 void
78 operator()(
79 boost::system::error_code ec,
80 std::size_t bytes_transferred)
81 {
82 this->complete_now(ec, bytes_transferred);
83 }
84};
85
86struct run_write_op
87{
88 template<class WriteHandler, class Buffers>
89 void
90 operator()(
91 WriteHandler&& h,
92 flat_stream* s,
93 Buffers const& b)
94 {
95 // If you get an error on the following line it means
96 // that your handler does not meet the documented type
97 // requirements for the handler.
98
99 static_assert(
100 beast::detail::is_invocable<WriteHandler,
101 void(error_code, std::size_t)>::value,
102 "WriteHandler type requirements not met");
103
104 write_op<
105 typename std::decay<WriteHandler>::type>(
106 std::forward<WriteHandler>(h), *s, b);
107 }
108};
109
110};
111
112//------------------------------------------------------------------------------
113
114template<class NextLayer>
115template<class... Args>
116flat_stream<NextLayer>::
117flat_stream(Args&&... args)
118 : stream_(std::forward<Args>(args)...)
119{
120}
121
122template<class NextLayer>
123template<class MutableBufferSequence>
124std::size_t
125flat_stream<NextLayer>::
126read_some(MutableBufferSequence const& buffers)
127{
128 static_assert(boost::beast::is_sync_read_stream<next_layer_type>::value,
129 "SyncReadStream type requirements not met");
130 static_assert(net::is_mutable_buffer_sequence<
131 MutableBufferSequence>::value,
132 "MutableBufferSequence type requirements not met");
133 error_code ec;
134 auto n = read_some(buffers, ec);
135 if(ec)
136 BOOST_THROW_EXCEPTION(boost::system::system_error{ec});
137 return n;
138}
139
140template<class NextLayer>
141template<class MutableBufferSequence>
142std::size_t
143flat_stream<NextLayer>::
144read_some(MutableBufferSequence const& buffers, error_code& ec)
145{
146 static_assert(boost::beast::is_sync_read_stream<next_layer_type>::value,
147 "SyncReadStream type requirements not met");
148 static_assert(net::is_mutable_buffer_sequence<
149 MutableBufferSequence>::value,
150 "MutableBufferSequence type requirements not met");
151 return stream_.read_some(buffers, ec);
152}
153
154template<class NextLayer>
155template<
156 class MutableBufferSequence,
20effc67 157 BOOST_BEAST_ASYNC_TPARAM2 ReadHandler>
92f5a8d4
TL
158BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
159flat_stream<NextLayer>::
160async_read_some(
161 MutableBufferSequence const& buffers,
162 ReadHandler&& handler)
163{
164 static_assert(boost::beast::is_async_read_stream<next_layer_type>::value,
165 "AsyncReadStream type requirements not met");
166 static_assert(net::is_mutable_buffer_sequence<
167 MutableBufferSequence >::value,
168 "MutableBufferSequence type requirements not met");
169 return stream_.async_read_some(
170 buffers, std::forward<ReadHandler>(handler));
171}
172
173template<class NextLayer>
174template<class ConstBufferSequence>
175std::size_t
176flat_stream<NextLayer>::
177write_some(ConstBufferSequence const& buffers)
178{
179 static_assert(boost::beast::is_sync_write_stream<next_layer_type>::value,
180 "SyncWriteStream type requirements not met");
181 static_assert(net::is_const_buffer_sequence<
182 ConstBufferSequence>::value,
183 "ConstBufferSequence type requirements not met");
184 error_code ec;
185 auto n = write_some(buffers, ec);
186 if(ec)
187 BOOST_THROW_EXCEPTION(boost::system::system_error{ec});
188 return n;
189}
190
191template<class NextLayer>
192template<class ConstBufferSequence>
193std::size_t
194flat_stream<NextLayer>::
195stack_write_some(
196 std::size_t size,
197 ConstBufferSequence const& buffers,
198 error_code& ec)
199{
200 static_buffer<max_stack> b;
201 b.commit(net::buffer_copy(
202 b.prepare(size), buffers));
203 return stream_.write_some(b.data(), ec);
204}
205
206template<class NextLayer>
207template<class ConstBufferSequence>
208std::size_t
209flat_stream<NextLayer>::
210write_some(ConstBufferSequence const& buffers, error_code& ec)
211{
212 static_assert(boost::beast::is_sync_write_stream<next_layer_type>::value,
213 "SyncWriteStream type requirements not met");
214 static_assert(net::is_const_buffer_sequence<
215 ConstBufferSequence>::value,
216 "ConstBufferSequence type requirements not met");
217 auto const result = flatten(buffers, max_size);
218 if(result.flatten)
219 {
220 if(result.size <= max_stack)
221 return stack_write_some(result.size, buffers, ec);
222
223 buffer_.clear();
224 buffer_.commit(net::buffer_copy(
225 buffer_.prepare(result.size),
226 buffers));
227 return stream_.write_some(buffer_.data(), ec);
228 }
229 buffer_.clear();
230 buffer_.shrink_to_fit();
231 return stream_.write_some(
232 boost::beast::buffers_prefix(result.size, buffers), ec);
233}
234
235template<class NextLayer>
236template<
237 class ConstBufferSequence,
20effc67 238 BOOST_BEAST_ASYNC_TPARAM2 WriteHandler>
92f5a8d4
TL
239BOOST_BEAST_ASYNC_RESULT2(WriteHandler)
240flat_stream<NextLayer>::
241async_write_some(
242 ConstBufferSequence const& buffers,
243 WriteHandler&& handler)
244{
245 static_assert(boost::beast::is_async_write_stream<next_layer_type>::value,
246 "AsyncWriteStream type requirements not met");
247 static_assert(net::is_const_buffer_sequence<
248 ConstBufferSequence>::value,
249 "ConstBufferSequence type requirements not met");
250 return net::async_initiate<
251 WriteHandler,
252 void(error_code, std::size_t)>(
253 typename ops::run_write_op{},
254 handler,
255 this,
256 buffers);
257}
258
259template<class NextLayer>
260void
261teardown(
262 boost::beast::role_type role,
263 flat_stream<NextLayer>& s,
264 error_code& ec)
265{
266 using boost::beast::websocket::teardown;
267 teardown(role, s.next_layer(), ec);
268}
269
270template<class NextLayer, class TeardownHandler>
271void
272async_teardown(
273 boost::beast::role_type role,
274 flat_stream<NextLayer>& s,
275 TeardownHandler&& handler)
276{
277 using boost::beast::websocket::async_teardown;
278 async_teardown(role, s.next_layer(), std::move(handler));
279}
280
281} // beast
282} // boost
283
284#endif