]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/impl/buffered_write_stream.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / asio / impl / buffered_write_stream.hpp
1 //
2 // impl/buffered_write_stream.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #ifndef BOOST_ASIO_IMPL_BUFFERED_WRITE_STREAM_HPP
12 #define BOOST_ASIO_IMPL_BUFFERED_WRITE_STREAM_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include <boost/asio/associated_allocator.hpp>
19 #include <boost/asio/associated_executor.hpp>
20 #include <boost/asio/detail/handler_alloc_helpers.hpp>
21 #include <boost/asio/detail/handler_cont_helpers.hpp>
22 #include <boost/asio/detail/handler_invoke_helpers.hpp>
23 #include <boost/asio/detail/handler_type_requirements.hpp>
24
25 #include <boost/asio/detail/push_options.hpp>
26
27 namespace boost {
28 namespace asio {
29
30 template <typename Stream>
31 std::size_t buffered_write_stream<Stream>::flush()
32 {
33 std::size_t bytes_written = write(next_layer_,
34 buffer(storage_.data(), storage_.size()));
35 storage_.consume(bytes_written);
36 return bytes_written;
37 }
38
39 template <typename Stream>
40 std::size_t buffered_write_stream<Stream>::flush(boost::system::error_code& ec)
41 {
42 std::size_t bytes_written = write(next_layer_,
43 buffer(storage_.data(), storage_.size()),
44 transfer_all(), ec);
45 storage_.consume(bytes_written);
46 return bytes_written;
47 }
48
49 namespace detail
50 {
51 template <typename WriteHandler>
52 class buffered_flush_handler
53 {
54 public:
55 buffered_flush_handler(detail::buffered_stream_storage& storage,
56 WriteHandler& handler)
57 : storage_(storage),
58 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
59 {
60 }
61
62 #if defined(BOOST_ASIO_HAS_MOVE)
63 buffered_flush_handler(const buffered_flush_handler& other)
64 : storage_(other.storage_),
65 handler_(other.handler_)
66 {
67 }
68
69 buffered_flush_handler(buffered_flush_handler&& other)
70 : storage_(other.storage_),
71 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
72 {
73 }
74 #endif // defined(BOOST_ASIO_HAS_MOVE)
75
76 void operator()(const boost::system::error_code& ec,
77 const std::size_t bytes_written)
78 {
79 storage_.consume(bytes_written);
80 handler_(ec, bytes_written);
81 }
82
83 //private:
84 detail::buffered_stream_storage& storage_;
85 WriteHandler handler_;
86 };
87
88 template <typename WriteHandler>
89 inline void* asio_handler_allocate(std::size_t size,
90 buffered_flush_handler<WriteHandler>* this_handler)
91 {
92 return boost_asio_handler_alloc_helpers::allocate(
93 size, this_handler->handler_);
94 }
95
96 template <typename WriteHandler>
97 inline void asio_handler_deallocate(void* pointer, std::size_t size,
98 buffered_flush_handler<WriteHandler>* this_handler)
99 {
100 boost_asio_handler_alloc_helpers::deallocate(
101 pointer, size, this_handler->handler_);
102 }
103
104 template <typename WriteHandler>
105 inline bool asio_handler_is_continuation(
106 buffered_flush_handler<WriteHandler>* this_handler)
107 {
108 return boost_asio_handler_cont_helpers::is_continuation(
109 this_handler->handler_);
110 }
111
112 template <typename Function, typename WriteHandler>
113 inline void asio_handler_invoke(Function& function,
114 buffered_flush_handler<WriteHandler>* this_handler)
115 {
116 boost_asio_handler_invoke_helpers::invoke(
117 function, this_handler->handler_);
118 }
119
120 template <typename Function, typename WriteHandler>
121 inline void asio_handler_invoke(const Function& function,
122 buffered_flush_handler<WriteHandler>* this_handler)
123 {
124 boost_asio_handler_invoke_helpers::invoke(
125 function, this_handler->handler_);
126 }
127 } // namespace detail
128
129 #if !defined(GENERATING_DOCUMENTATION)
130
131 template <typename WriteHandler, typename Allocator>
132 struct associated_allocator<
133 detail::buffered_flush_handler<WriteHandler>, Allocator>
134 {
135 typedef typename associated_allocator<WriteHandler, Allocator>::type type;
136
137 static type get(const detail::buffered_flush_handler<WriteHandler>& h,
138 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
139 {
140 return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
141 }
142 };
143
144 template <typename WriteHandler, typename Executor>
145 struct associated_executor<
146 detail::buffered_flush_handler<WriteHandler>, Executor>
147 {
148 typedef typename associated_executor<WriteHandler, Executor>::type type;
149
150 static type get(const detail::buffered_flush_handler<WriteHandler>& h,
151 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
152 {
153 return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
154 }
155 };
156
157 #endif // !defined(GENERATING_DOCUMENTATION)
158
159 template <typename Stream>
160 template <typename WriteHandler>
161 BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
162 void (boost::system::error_code, std::size_t))
163 buffered_write_stream<Stream>::async_flush(
164 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
165 {
166 // If you get an error on the following line it means that your handler does
167 // not meet the documented type requirements for a WriteHandler.
168 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
169
170 async_completion<WriteHandler,
171 void (boost::system::error_code, std::size_t)> init(handler);
172
173 async_write(next_layer_, buffer(storage_.data(), storage_.size()),
174 detail::buffered_flush_handler<BOOST_ASIO_HANDLER_TYPE(
175 WriteHandler, void (boost::system::error_code, std::size_t))>(
176 storage_, init.completion_handler));
177
178 return init.result.get();
179 }
180
181 template <typename Stream>
182 template <typename ConstBufferSequence>
183 std::size_t buffered_write_stream<Stream>::write_some(
184 const ConstBufferSequence& buffers)
185 {
186 using boost::asio::buffer_size;
187 if (buffer_size(buffers) == 0)
188 return 0;
189
190 if (storage_.size() == storage_.capacity())
191 this->flush();
192
193 return this->copy(buffers);
194 }
195
196 template <typename Stream>
197 template <typename ConstBufferSequence>
198 std::size_t buffered_write_stream<Stream>::write_some(
199 const ConstBufferSequence& buffers, boost::system::error_code& ec)
200 {
201 ec = boost::system::error_code();
202
203 using boost::asio::buffer_size;
204 if (buffer_size(buffers) == 0)
205 return 0;
206
207 if (storage_.size() == storage_.capacity() && !flush(ec))
208 return 0;
209
210 return this->copy(buffers);
211 }
212
213 namespace detail
214 {
215 template <typename ConstBufferSequence, typename WriteHandler>
216 class buffered_write_some_handler
217 {
218 public:
219 buffered_write_some_handler(detail::buffered_stream_storage& storage,
220 const ConstBufferSequence& buffers, WriteHandler& handler)
221 : storage_(storage),
222 buffers_(buffers),
223 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
224 {
225 }
226
227 #if defined(BOOST_ASIO_HAS_MOVE)
228 buffered_write_some_handler(const buffered_write_some_handler& other)
229 : storage_(other.storage_),
230 buffers_(other.buffers_),
231 handler_(other.handler_)
232 {
233 }
234
235 buffered_write_some_handler(buffered_write_some_handler&& other)
236 : storage_(other.storage_),
237 buffers_(other.buffers_),
238 handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
239 {
240 }
241 #endif // defined(BOOST_ASIO_HAS_MOVE)
242
243 void operator()(const boost::system::error_code& ec, std::size_t)
244 {
245 if (ec)
246 {
247 const std::size_t length = 0;
248 handler_(ec, length);
249 }
250 else
251 {
252 using boost::asio::buffer_size;
253 std::size_t orig_size = storage_.size();
254 std::size_t space_avail = storage_.capacity() - orig_size;
255 std::size_t bytes_avail = buffer_size(buffers_);
256 std::size_t length = bytes_avail < space_avail
257 ? bytes_avail : space_avail;
258 storage_.resize(orig_size + length);
259 const std::size_t bytes_copied = boost::asio::buffer_copy(
260 storage_.data() + orig_size, buffers_, length);
261 handler_(ec, bytes_copied);
262 }
263 }
264
265 //private:
266 detail::buffered_stream_storage& storage_;
267 ConstBufferSequence buffers_;
268 WriteHandler handler_;
269 };
270
271 template <typename ConstBufferSequence, typename WriteHandler>
272 inline void* asio_handler_allocate(std::size_t size,
273 buffered_write_some_handler<
274 ConstBufferSequence, WriteHandler>* this_handler)
275 {
276 return boost_asio_handler_alloc_helpers::allocate(
277 size, this_handler->handler_);
278 }
279
280 template <typename ConstBufferSequence, typename WriteHandler>
281 inline void asio_handler_deallocate(void* pointer, std::size_t size,
282 buffered_write_some_handler<
283 ConstBufferSequence, WriteHandler>* this_handler)
284 {
285 boost_asio_handler_alloc_helpers::deallocate(
286 pointer, size, this_handler->handler_);
287 }
288
289 template <typename ConstBufferSequence, typename WriteHandler>
290 inline bool asio_handler_is_continuation(
291 buffered_write_some_handler<
292 ConstBufferSequence, WriteHandler>* this_handler)
293 {
294 return boost_asio_handler_cont_helpers::is_continuation(
295 this_handler->handler_);
296 }
297
298 template <typename Function, typename ConstBufferSequence,
299 typename WriteHandler>
300 inline void asio_handler_invoke(Function& function,
301 buffered_write_some_handler<
302 ConstBufferSequence, WriteHandler>* this_handler)
303 {
304 boost_asio_handler_invoke_helpers::invoke(
305 function, this_handler->handler_);
306 }
307
308 template <typename Function, typename ConstBufferSequence,
309 typename WriteHandler>
310 inline void asio_handler_invoke(const Function& function,
311 buffered_write_some_handler<
312 ConstBufferSequence, WriteHandler>* this_handler)
313 {
314 boost_asio_handler_invoke_helpers::invoke(
315 function, this_handler->handler_);
316 }
317 } // namespace detail
318
319 #if !defined(GENERATING_DOCUMENTATION)
320
321 template <typename ConstBufferSequence,
322 typename WriteHandler, typename Allocator>
323 struct associated_allocator<
324 detail::buffered_write_some_handler<ConstBufferSequence, WriteHandler>,
325 Allocator>
326 {
327 typedef typename associated_allocator<WriteHandler, Allocator>::type type;
328
329 static type get(
330 const detail::buffered_write_some_handler<
331 ConstBufferSequence, WriteHandler>& h,
332 const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
333 {
334 return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
335 }
336 };
337
338 template <typename ConstBufferSequence,
339 typename WriteHandler, typename Executor>
340 struct associated_executor<
341 detail::buffered_write_some_handler<ConstBufferSequence, WriteHandler>,
342 Executor>
343 {
344 typedef typename associated_executor<WriteHandler, Executor>::type type;
345
346 static type get(
347 const detail::buffered_write_some_handler<
348 ConstBufferSequence, WriteHandler>& h,
349 const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
350 {
351 return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
352 }
353 };
354
355 #endif // !defined(GENERATING_DOCUMENTATION)
356
357 template <typename Stream>
358 template <typename ConstBufferSequence, typename WriteHandler>
359 BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
360 void (boost::system::error_code, std::size_t))
361 buffered_write_stream<Stream>::async_write_some(
362 const ConstBufferSequence& buffers,
363 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
364 {
365 // If you get an error on the following line it means that your handler does
366 // not meet the documented type requirements for a WriteHandler.
367 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
368
369 async_completion<WriteHandler,
370 void (boost::system::error_code, std::size_t)> init(handler);
371
372 using boost::asio::buffer_size;
373 if (buffer_size(buffers) == 0
374 || storage_.size() < storage_.capacity())
375 {
376 next_layer_.async_write_some(BOOST_ASIO_CONST_BUFFER(0, 0),
377 detail::buffered_write_some_handler<
378 ConstBufferSequence, BOOST_ASIO_HANDLER_TYPE(
379 WriteHandler, void (boost::system::error_code, std::size_t))>(
380 storage_, buffers, init.completion_handler));
381 }
382 else
383 {
384 this->async_flush(detail::buffered_write_some_handler<
385 ConstBufferSequence, BOOST_ASIO_HANDLER_TYPE(
386 WriteHandler, void (boost::system::error_code, std::size_t))>(
387 storage_, buffers, init.completion_handler));
388 }
389
390 return init.result.get();
391 }
392
393 template <typename Stream>
394 template <typename ConstBufferSequence>
395 std::size_t buffered_write_stream<Stream>::copy(
396 const ConstBufferSequence& buffers)
397 {
398 using boost::asio::buffer_size;
399 std::size_t orig_size = storage_.size();
400 std::size_t space_avail = storage_.capacity() - orig_size;
401 std::size_t bytes_avail = buffer_size(buffers);
402 std::size_t length = bytes_avail < space_avail ? bytes_avail : space_avail;
403 storage_.resize(orig_size + length);
404 return boost::asio::buffer_copy(
405 storage_.data() + orig_size, buffers, length);
406 }
407
408 } // namespace asio
409 } // namespace boost
410
411 #include <boost/asio/detail/pop_options.hpp>
412
413 #endif // BOOST_ASIO_IMPL_BUFFERED_WRITE_STREAM_HPP