]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/beast/core/impl/buffers_adapter.ipp
Add patch for failing prerm scripts
[ceph.git] / ceph / src / boost / boost / beast / core / impl / buffers_adapter.ipp
CommitLineData
7c673cae 1//
b32b8144 2// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
7c673cae
FG
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//
b32b8144
FG
7// Official repository: https://github.com/boostorg/beast
8//
7c673cae 9
b32b8144
FG
10#ifndef BOOST_BEAST_IMPL_BUFFERS_ADAPTER_IPP
11#define BOOST_BEAST_IMPL_BUFFERS_ADAPTER_IPP
7c673cae 12
b32b8144 13#include <boost/beast/core/detail/type_traits.hpp>
7c673cae 14#include <boost/asio/buffer.hpp>
b32b8144 15#include <boost/throw_exception.hpp>
7c673cae
FG
16#include <algorithm>
17#include <cstring>
18#include <iterator>
19#include <stdexcept>
7c673cae 20
b32b8144 21namespace boost {
7c673cae
FG
22namespace beast {
23
24template<class MutableBufferSequence>
25class buffers_adapter<MutableBufferSequence>::
26 const_buffers_type
27{
28 buffers_adapter const* ba_;
29
30public:
b32b8144 31 using value_type = boost::asio::mutable_buffer;
7c673cae
FG
32
33 class const_iterator;
34
35 const_buffers_type() = delete;
36 const_buffers_type(
37 const_buffers_type const&) = default;
38 const_buffers_type& operator=(
39 const_buffers_type const&) = default;
40
41 const_iterator
42 begin() const;
43
44 const_iterator
45 end() const;
46
47private:
48 friend class buffers_adapter;
49
50 const_buffers_type(buffers_adapter const& ba)
51 : ba_(&ba)
52 {
53 }
54};
55
56template<class MutableBufferSequence>
57class buffers_adapter<MutableBufferSequence>::
58 const_buffers_type::const_iterator
59{
60 iter_type it_;
61 buffers_adapter const* ba_ = nullptr;
62
63public:
64 using value_type = boost::asio::const_buffer;
65 using pointer = value_type const*;
66 using reference = value_type;
67 using difference_type = std::ptrdiff_t;
68 using iterator_category =
69 std::bidirectional_iterator_tag;
70
71 const_iterator() = default;
72 const_iterator(const_iterator&& other) = default;
73 const_iterator(const_iterator const& other) = default;
74 const_iterator& operator=(const_iterator&& other) = default;
75 const_iterator& operator=(const_iterator const& other) = default;
76
77 bool
78 operator==(const_iterator const& other) const
79 {
80 return ba_ == other.ba_ &&
81 it_ == other.it_;
82 }
83
84 bool
85 operator!=(const_iterator const& other) const
86 {
87 return !(*this == other);
88 }
89
90 reference
91 operator*() const
92 {
b32b8144
FG
93 value_type const b = *it_;
94 return value_type{b.data(),
95 (ba_->out_ == boost::asio::buffer_sequence_end(ba_->bs_) ||
96 it_ != ba_->out_) ? b.size() : ba_->out_pos_} +
7c673cae
FG
97 (it_ == ba_->begin_ ? ba_->in_pos_ : 0);
98 }
99
100 pointer
101 operator->() const = delete;
102
103 const_iterator&
104 operator++()
105 {
106 ++it_;
107 return *this;
108 }
109
110 const_iterator
111 operator++(int)
112 {
113 auto temp = *this;
114 ++(*this);
115 return temp;
116 }
117
118 const_iterator&
119 operator--()
120 {
121 --it_;
122 return *this;
123 }
124
125 const_iterator
126 operator--(int)
127 {
128 auto temp = *this;
129 --(*this);
130 return temp;
131 }
132
133private:
134 friend class const_buffers_type;
135
136 const_iterator(buffers_adapter const& ba,
137 iter_type iter)
138 : it_(iter)
139 , ba_(&ba)
140 {
141 }
142};
143
144template<class MutableBufferSequence>
145inline
146auto
147buffers_adapter<MutableBufferSequence>::const_buffers_type::begin() const ->
148 const_iterator
149{
150 return const_iterator{*ba_, ba_->begin_};
151}
152
153template<class MutableBufferSequence>
154inline
155auto
156buffers_adapter<MutableBufferSequence>::const_buffers_type::end() const ->
157 const_iterator
158{
159 return const_iterator{*ba_, ba_->out_ ==
160 ba_->end_ ? ba_->end_ : std::next(ba_->out_)};
161}
162
163//------------------------------------------------------------------------------
164
165template<class MutableBufferSequence>
166class buffers_adapter<MutableBufferSequence>::
167mutable_buffers_type
168{
169 buffers_adapter const* ba_;
170
171public:
172 using value_type = boost::asio::mutable_buffer;
173
174 class const_iterator;
175
176 mutable_buffers_type() = delete;
177 mutable_buffers_type(
178 mutable_buffers_type const&) = default;
179 mutable_buffers_type& operator=(
180 mutable_buffers_type const&) = default;
181
182 const_iterator
183 begin() const;
184
185 const_iterator
186 end() const;
187
188private:
189 friend class buffers_adapter;
190
191 mutable_buffers_type(
192 buffers_adapter const& ba)
193 : ba_(&ba)
194 {
195 }
196};
197
198template<class MutableBufferSequence>
199class buffers_adapter<MutableBufferSequence>::
200mutable_buffers_type::const_iterator
201{
202 iter_type it_;
203 buffers_adapter const* ba_ = nullptr;
204
205public:
206 using value_type = boost::asio::mutable_buffer;
207 using pointer = value_type const*;
208 using reference = value_type;
209 using difference_type = std::ptrdiff_t;
210 using iterator_category =
211 std::bidirectional_iterator_tag;
212
213 const_iterator() = default;
214 const_iterator(const_iterator&& other) = default;
215 const_iterator(const_iterator const& other) = default;
216 const_iterator& operator=(const_iterator&& other) = default;
217 const_iterator& operator=(const_iterator const& other) = default;
218
219 bool
220 operator==(const_iterator const& other) const
221 {
222 return ba_ == other.ba_ &&
223 it_ == other.it_;
224 }
225
226 bool
227 operator!=(const_iterator const& other) const
228 {
229 return !(*this == other);
230 }
231
232 reference
233 operator*() const
234 {
b32b8144
FG
235 value_type const b = *it_;
236 return value_type{b.data(),
7c673cae 237 it_ == std::prev(ba_->end_) ?
b32b8144 238 ba_->out_end_ : b.size()} +
7c673cae
FG
239 (it_ == ba_->out_ ? ba_->out_pos_ : 0);
240 }
241
242 pointer
243 operator->() const = delete;
244
245 const_iterator&
246 operator++()
247 {
248 ++it_;
249 return *this;
250 }
251
252 const_iterator
253 operator++(int)
254 {
255 auto temp = *this;
256 ++(*this);
257 return temp;
258 }
259
260 const_iterator&
261 operator--()
262 {
263 --it_;
264 return *this;
265 }
266
267 const_iterator
268 operator--(int)
269 {
270 auto temp = *this;
271 --(*this);
272 return temp;
273 }
274
275private:
276 friend class mutable_buffers_type;
277
278 const_iterator(buffers_adapter const& ba,
279 iter_type iter)
280 : it_(iter)
281 , ba_(&ba)
282 {
283 }
284};
285
286template<class MutableBufferSequence>
287inline
288auto
b32b8144
FG
289buffers_adapter<MutableBufferSequence>::
290mutable_buffers_type::
291begin() const ->
7c673cae
FG
292 const_iterator
293{
294 return const_iterator{*ba_, ba_->out_};
295}
296
297template<class MutableBufferSequence>
298inline
299auto
b32b8144
FG
300buffers_adapter<MutableBufferSequence>::
301mutable_buffers_type::
302end() const ->
7c673cae
FG
303 const_iterator
304{
305 return const_iterator{*ba_, ba_->end_};
306}
307
308//------------------------------------------------------------------------------
309
310template<class MutableBufferSequence>
311buffers_adapter<MutableBufferSequence>::buffers_adapter(
312 buffers_adapter&& other)
313 : buffers_adapter(std::move(other),
b32b8144
FG
314 std::distance<iter_type>(boost::asio::buffer_sequence_begin(other.bs_), other.begin_),
315 std::distance<iter_type>(boost::asio::buffer_sequence_begin(other.bs_), other.out_),
316 std::distance<iter_type>(boost::asio::buffer_sequence_begin(other.bs_), other.end_))
7c673cae
FG
317{
318}
319
320template<class MutableBufferSequence>
321buffers_adapter<MutableBufferSequence>::buffers_adapter(
322 buffers_adapter const& other)
323 : buffers_adapter(other,
b32b8144
FG
324 std::distance<iter_type>(boost::asio::buffer_sequence_begin(other.bs_), other.begin_),
325 std::distance<iter_type>(boost::asio::buffer_sequence_begin(other.bs_), other.out_),
326 std::distance<iter_type>(boost::asio::buffer_sequence_begin(other.bs_), other.end_))
7c673cae
FG
327{
328}
329
330template<class MutableBufferSequence>
331auto
332buffers_adapter<MutableBufferSequence>::operator=(
333 buffers_adapter&& other) -> buffers_adapter&
334{
335 auto const nbegin = std::distance<iter_type>(
b32b8144
FG
336 boost::asio::buffer_sequence_begin(other.bs_),
337 other.begin_);
7c673cae 338 auto const nout = std::distance<iter_type>(
b32b8144
FG
339 boost::asio::buffer_sequence_begin(other.bs_),
340 other.out_);
7c673cae 341 auto const nend = std::distance<iter_type>(
b32b8144
FG
342 boost::asio::buffer_sequence_begin(other.bs_),
343 other.end_);
7c673cae 344 bs_ = std::move(other.bs_);
b32b8144
FG
345 begin_ = std::next(boost::asio::buffer_sequence_begin(bs_), nbegin);
346 out_ = std::next(boost::asio::buffer_sequence_begin(bs_), nout);
347 end_ = std::next(boost::asio::buffer_sequence_begin(bs_), nend);
7c673cae
FG
348 max_size_ = other.max_size_;
349 in_pos_ = other.in_pos_;
350 in_size_ = other.in_size_;
351 out_pos_ = other.out_pos_;
352 out_end_ = other.out_end_;
353 return *this;
354}
355
356template<class MutableBufferSequence>
357auto
358buffers_adapter<MutableBufferSequence>::operator=(
359 buffers_adapter const& other) -> buffers_adapter&
360{
361 auto const nbegin = std::distance<iter_type>(
b32b8144
FG
362 boost::asio::buffer_sequence_begin(other.bs_),
363 other.begin_);
7c673cae 364 auto const nout = std::distance<iter_type>(
b32b8144
FG
365 boost::asio::buffer_sequence_begin(other.bs_),
366 other.out_);
7c673cae 367 auto const nend = std::distance<iter_type>(
b32b8144
FG
368 boost::asio::buffer_sequence_begin(other.bs_),
369 other.end_);
7c673cae 370 bs_ = other.bs_;
b32b8144
FG
371 begin_ = std::next(boost::asio::buffer_sequence_begin(bs_), nbegin);
372 out_ = std::next(boost::asio::buffer_sequence_begin(bs_), nout);
373 end_ = std::next(boost::asio::buffer_sequence_begin(bs_), nend);
7c673cae
FG
374 max_size_ = other.max_size_;
375 in_pos_ = other.in_pos_;
376 in_size_ = other.in_size_;
377 out_pos_ = other.out_pos_;
378 out_end_ = other.out_end_;
379 return *this;
380}
381
382template<class MutableBufferSequence>
383buffers_adapter<MutableBufferSequence>::buffers_adapter(
384 MutableBufferSequence const& bs)
385 : bs_(bs)
b32b8144
FG
386 , begin_(boost::asio::buffer_sequence_begin(bs_))
387 , out_ (boost::asio::buffer_sequence_begin(bs_))
388 , end_ (boost::asio::buffer_sequence_begin(bs_))
7c673cae
FG
389 , max_size_(boost::asio::buffer_size(bs_))
390{
391}
392
393template<class MutableBufferSequence>
394auto
395buffers_adapter<MutableBufferSequence>::prepare(std::size_t n) ->
396 mutable_buffers_type
397{
398 using boost::asio::buffer_size;
399 end_ = out_;
b32b8144 400 if(end_ != boost::asio::buffer_sequence_end(bs_))
7c673cae
FG
401 {
402 auto size = buffer_size(*end_) - out_pos_;
403 if(n > size)
404 {
405 n -= size;
b32b8144
FG
406 while(++end_ !=
407 boost::asio::buffer_sequence_end(bs_))
7c673cae
FG
408 {
409 size = buffer_size(*end_);
410 if(n < size)
411 {
412 out_end_ = n;
413 n = 0;
414 ++end_;
415 break;
416 }
417 n -= size;
418 out_end_ = size;
419 }
420 }
421 else
422 {
423 ++end_;
424 out_end_ = out_pos_ + n;
425 n = 0;
426 }
427 }
428 if(n > 0)
b32b8144
FG
429 BOOST_THROW_EXCEPTION(std::length_error{
430 "buffer overflow"});
7c673cae
FG
431 return mutable_buffers_type{*this};
432}
433
434template<class MutableBufferSequence>
435void
436buffers_adapter<MutableBufferSequence>::commit(std::size_t n)
437{
438 using boost::asio::buffer_size;
439 if(out_ == end_)
440 return;
441 auto const last = std::prev(end_);
442 while(out_ != last)
443 {
444 auto const avail =
445 buffer_size(*out_) - out_pos_;
446 if(n < avail)
447 {
448 out_pos_ += n;
449 in_size_ += n;
450 max_size_ -= n;
451 return;
452 }
453 ++out_;
454 n -= avail;
455 out_pos_ = 0;
456 in_size_ += avail;
457 max_size_ -= avail;
458 }
459
460 n = (std::min)(n, out_end_ - out_pos_);
461 out_pos_ += n;
462 in_size_ += n;
463 max_size_ -= n;
464 if(out_pos_ == buffer_size(*out_))
465 {
466 ++out_;
467 out_pos_ = 0;
468 out_end_ = 0;
469 }
470}
471
472template<class MutableBufferSequence>
473inline
474auto
475buffers_adapter<MutableBufferSequence>::data() const ->
476 const_buffers_type
477{
478 return const_buffers_type{*this};
479}
480
481template<class MutableBufferSequence>
482void
483buffers_adapter<MutableBufferSequence>::consume(std::size_t n)
484{
485 using boost::asio::buffer_size;
486 while(begin_ != out_)
487 {
488 auto const avail =
489 buffer_size(*begin_) - in_pos_;
490 if(n < avail)
491 {
492 in_size_ -= n;
493 in_pos_ += n;
494 return;
495 }
496 n -= avail;
497 in_size_ -= avail;
498 in_pos_ = 0;
499 ++begin_;
500 }
501 auto const avail = out_pos_ - in_pos_;
502 if(n < avail)
503 {
504 in_size_ -= n;
505 in_pos_ += n;
506 }
507 else
508 {
509 in_size_ -= avail;
510 in_pos_ = out_pos_;
511 }
512}
513
514} // beast
b32b8144 515} // boost
7c673cae
FG
516
517#endif