]> git.proxmox.com Git - ceph.git/blame - ceph/src/Beast/include/beast/core/impl/dynabuf_readstream.ipp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / Beast / include / beast / core / impl / dynabuf_readstream.ipp
CommitLineData
7c673cae
FG
1//
2// Copyright (c) 2013-2017 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
8#ifndef BEAST_IMPL_DYNABUF_READSTREAM_HPP
9#define BEAST_IMPL_DYNABUF_READSTREAM_HPP
10
11#include <beast/core/bind_handler.hpp>
12#include <beast/core/error.hpp>
13#include <beast/core/handler_concepts.hpp>
14#include <beast/core/handler_helpers.hpp>
15#include <beast/core/handler_ptr.hpp>
16
17namespace beast {
18
19template<class Stream, class DynamicBuffer>
20template<class MutableBufferSequence, class Handler>
21class dynabuf_readstream<
22 Stream, DynamicBuffer>::read_some_op
23{
24 // VFALCO What about bool cont for is_continuation?
25 struct data
26 {
27 dynabuf_readstream& srs;
28 MutableBufferSequence bs;
29 int state = 0;
30
31 data(Handler&, dynabuf_readstream& srs_,
32 MutableBufferSequence const& bs_)
33 : srs(srs_)
34 , bs(bs_)
35 {
36 }
37 };
38
39 handler_ptr<data, Handler> d_;
40
41public:
42 read_some_op(read_some_op&&) = default;
43 read_some_op(read_some_op const&) = default;
44
45 template<class DeducedHandler, class... Args>
46 read_some_op(DeducedHandler&& h,
47 dynabuf_readstream& srs, Args&&... args)
48 : d_(std::forward<DeducedHandler>(h),
49 srs, std::forward<Args>(args)...)
50 {
51 (*this)(error_code{}, 0);
52 }
53
54 void
55 operator()(error_code const& ec,
56 std::size_t bytes_transferred);
57
58 friend
59 void* asio_handler_allocate(
60 std::size_t size, read_some_op* op)
61 {
62 return beast_asio_helpers::
63 allocate(size, op->d_.handler());
64 }
65
66 friend
67 void asio_handler_deallocate(
68 void* p, std::size_t size, read_some_op* op)
69 {
70 return beast_asio_helpers::
71 deallocate(p, size, op->d_.handler());
72 }
73
74 friend
75 bool asio_handler_is_continuation(read_some_op* op)
76 {
77 return beast_asio_helpers::
78 is_continuation(op->d_.handler());
79 }
80
81 template<class Function>
82 friend
83 void asio_handler_invoke(Function&& f, read_some_op* op)
84 {
85 return beast_asio_helpers::
86 invoke(f, op->d_.handler());
87 }
88};
89
90template<class Stream, class DynamicBuffer>
91template<class MutableBufferSequence, class Handler>
92void
93dynabuf_readstream<Stream, DynamicBuffer>::
94read_some_op<MutableBufferSequence, Handler>::operator()(
95 error_code const& ec, std::size_t bytes_transferred)
96{
97 auto& d = *d_;
98 while(! ec && d.state != 99)
99 {
100 switch(d.state)
101 {
102 case 0:
103 if(d.srs.sb_.size() == 0)
104 {
105 d.state =
106 d.srs.capacity_ > 0 ? 2 : 1;
107 break;
108 }
109 d.state = 4;
110 d.srs.get_io_service().post(
111 bind_handler(std::move(*this), ec, 0));
112 return;
113
114 case 1:
115 // read (unbuffered)
116 d.state = 99;
117 d.srs.next_layer_.async_read_some(
118 d.bs, std::move(*this));
119 return;
120
121 case 2:
122 // read
123 d.state = 3;
124 d.srs.next_layer_.async_read_some(
125 d.srs.sb_.prepare(d.srs.capacity_),
126 std::move(*this));
127 return;
128
129 // got data
130 case 3:
131 d.state = 4;
132 d.srs.sb_.commit(bytes_transferred);
133 break;
134
135 // copy
136 case 4:
137 bytes_transferred =
138 boost::asio::buffer_copy(
139 d.bs, d.srs.sb_.data());
140 d.srs.sb_.consume(bytes_transferred);
141 // call handler
142 d.state = 99;
143 break;
144 }
145 }
146 d_.invoke(ec, bytes_transferred);
147}
148
149//------------------------------------------------------------------------------
150
151template<class Stream, class DynamicBuffer>
152template<class... Args>
153dynabuf_readstream<Stream, DynamicBuffer>::
154dynabuf_readstream(Args&&... args)
155 : next_layer_(std::forward<Args>(args)...)
156{
157}
158
159template<class Stream, class DynamicBuffer>
160template<class ConstBufferSequence, class WriteHandler>
161auto
162dynabuf_readstream<Stream, DynamicBuffer>::
163async_write_some(ConstBufferSequence const& buffers,
164 WriteHandler&& handler) ->
165 typename async_completion<
166 WriteHandler, void(error_code)>::result_type
167{
168 static_assert(is_AsyncWriteStream<next_layer_type>::value,
169 "AsyncWriteStream requirements not met");
170 static_assert(is_ConstBufferSequence<
171 ConstBufferSequence>::value,
172 "ConstBufferSequence requirements not met");
173 static_assert(is_CompletionHandler<WriteHandler,
174 void(error_code, std::size_t)>::value,
175 "WriteHandler requirements not met");
176 return next_layer_.async_write_some(buffers,
177 std::forward<WriteHandler>(handler));
178}
179
180template<class Stream, class DynamicBuffer>
181template<class MutableBufferSequence>
182std::size_t
183dynabuf_readstream<Stream, DynamicBuffer>::
184read_some(
185 MutableBufferSequence const& buffers)
186{
187 static_assert(is_SyncReadStream<next_layer_type>::value,
188 "SyncReadStream requirements not met");
189 static_assert(is_MutableBufferSequence<
190 MutableBufferSequence>::value,
191 "MutableBufferSequence requirements not met");
192 error_code ec;
193 auto n = read_some(buffers, ec);
194 if(ec)
195 throw system_error{ec};
196 return n;
197}
198
199template<class Stream, class DynamicBuffer>
200template<class MutableBufferSequence>
201std::size_t
202dynabuf_readstream<Stream, DynamicBuffer>::
203read_some(MutableBufferSequence const& buffers,
204 error_code& ec)
205{
206 static_assert(is_SyncReadStream<next_layer_type>::value,
207 "SyncReadStream requirements not met");
208 static_assert(is_MutableBufferSequence<
209 MutableBufferSequence>::value,
210 "MutableBufferSequence requirements not met");
211 using boost::asio::buffer_size;
212 using boost::asio::buffer_copy;
213 if(sb_.size() == 0)
214 {
215 if(capacity_ == 0)
216 return next_layer_.read_some(buffers, ec);
217 sb_.commit(next_layer_.read_some(
218 sb_.prepare(capacity_), ec));
219 if(ec)
220 return 0;
221 }
222 auto bytes_transferred =
223 buffer_copy(buffers, sb_.data());
224 sb_.consume(bytes_transferred);
225 return bytes_transferred;
226}
227
228template<class Stream, class DynamicBuffer>
229template<class MutableBufferSequence, class ReadHandler>
230auto
231dynabuf_readstream<Stream, DynamicBuffer>::
232async_read_some(
233 MutableBufferSequence const& buffers,
234 ReadHandler&& handler) ->
235 typename async_completion<
236 ReadHandler, void(error_code)>::result_type
237{
238 static_assert(is_AsyncReadStream<next_layer_type>::value,
239 "Stream requirements not met");
240 static_assert(is_MutableBufferSequence<
241 MutableBufferSequence>::value,
242 "MutableBufferSequence requirements not met");
243 beast::async_completion<
244 ReadHandler, void(error_code, std::size_t)
245 > completion{handler};
246 read_some_op<MutableBufferSequence,
247 decltype(completion.handler)>{
248 completion.handler, *this, buffers};
249 return completion.result.get();
250}
251
252} // beast
253
254#endif