]> git.proxmox.com Git - ceph.git/blob - 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
1 //
2 // Copyright (c) 2016-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 // Official repository: https://github.com/boostorg/beast
8 //
9
10 #ifndef BOOST_BEAST_IMPL_BUFFERS_ADAPTER_IPP
11 #define BOOST_BEAST_IMPL_BUFFERS_ADAPTER_IPP
12
13 #include <boost/beast/core/detail/type_traits.hpp>
14 #include <boost/asio/buffer.hpp>
15 #include <boost/throw_exception.hpp>
16 #include <algorithm>
17 #include <cstring>
18 #include <iterator>
19 #include <stdexcept>
20
21 namespace boost {
22 namespace beast {
23
24 template<class MutableBufferSequence>
25 class buffers_adapter<MutableBufferSequence>::
26 const_buffers_type
27 {
28 buffers_adapter const* ba_;
29
30 public:
31 using value_type = boost::asio::mutable_buffer;
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
47 private:
48 friend class buffers_adapter;
49
50 const_buffers_type(buffers_adapter const& ba)
51 : ba_(&ba)
52 {
53 }
54 };
55
56 template<class MutableBufferSequence>
57 class buffers_adapter<MutableBufferSequence>::
58 const_buffers_type::const_iterator
59 {
60 iter_type it_;
61 buffers_adapter const* ba_ = nullptr;
62
63 public:
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 {
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_} +
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
133 private:
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
144 template<class MutableBufferSequence>
145 inline
146 auto
147 buffers_adapter<MutableBufferSequence>::const_buffers_type::begin() const ->
148 const_iterator
149 {
150 return const_iterator{*ba_, ba_->begin_};
151 }
152
153 template<class MutableBufferSequence>
154 inline
155 auto
156 buffers_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
165 template<class MutableBufferSequence>
166 class buffers_adapter<MutableBufferSequence>::
167 mutable_buffers_type
168 {
169 buffers_adapter const* ba_;
170
171 public:
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
188 private:
189 friend class buffers_adapter;
190
191 mutable_buffers_type(
192 buffers_adapter const& ba)
193 : ba_(&ba)
194 {
195 }
196 };
197
198 template<class MutableBufferSequence>
199 class buffers_adapter<MutableBufferSequence>::
200 mutable_buffers_type::const_iterator
201 {
202 iter_type it_;
203 buffers_adapter const* ba_ = nullptr;
204
205 public:
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 {
235 value_type const b = *it_;
236 return value_type{b.data(),
237 it_ == std::prev(ba_->end_) ?
238 ba_->out_end_ : b.size()} +
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
275 private:
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
286 template<class MutableBufferSequence>
287 inline
288 auto
289 buffers_adapter<MutableBufferSequence>::
290 mutable_buffers_type::
291 begin() const ->
292 const_iterator
293 {
294 return const_iterator{*ba_, ba_->out_};
295 }
296
297 template<class MutableBufferSequence>
298 inline
299 auto
300 buffers_adapter<MutableBufferSequence>::
301 mutable_buffers_type::
302 end() const ->
303 const_iterator
304 {
305 return const_iterator{*ba_, ba_->end_};
306 }
307
308 //------------------------------------------------------------------------------
309
310 template<class MutableBufferSequence>
311 buffers_adapter<MutableBufferSequence>::buffers_adapter(
312 buffers_adapter&& other)
313 : buffers_adapter(std::move(other),
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_))
317 {
318 }
319
320 template<class MutableBufferSequence>
321 buffers_adapter<MutableBufferSequence>::buffers_adapter(
322 buffers_adapter const& other)
323 : buffers_adapter(other,
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_))
327 {
328 }
329
330 template<class MutableBufferSequence>
331 auto
332 buffers_adapter<MutableBufferSequence>::operator=(
333 buffers_adapter&& other) -> buffers_adapter&
334 {
335 auto const nbegin = std::distance<iter_type>(
336 boost::asio::buffer_sequence_begin(other.bs_),
337 other.begin_);
338 auto const nout = std::distance<iter_type>(
339 boost::asio::buffer_sequence_begin(other.bs_),
340 other.out_);
341 auto const nend = std::distance<iter_type>(
342 boost::asio::buffer_sequence_begin(other.bs_),
343 other.end_);
344 bs_ = std::move(other.bs_);
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);
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
356 template<class MutableBufferSequence>
357 auto
358 buffers_adapter<MutableBufferSequence>::operator=(
359 buffers_adapter const& other) -> buffers_adapter&
360 {
361 auto const nbegin = std::distance<iter_type>(
362 boost::asio::buffer_sequence_begin(other.bs_),
363 other.begin_);
364 auto const nout = std::distance<iter_type>(
365 boost::asio::buffer_sequence_begin(other.bs_),
366 other.out_);
367 auto const nend = std::distance<iter_type>(
368 boost::asio::buffer_sequence_begin(other.bs_),
369 other.end_);
370 bs_ = other.bs_;
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);
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
382 template<class MutableBufferSequence>
383 buffers_adapter<MutableBufferSequence>::buffers_adapter(
384 MutableBufferSequence const& bs)
385 : bs_(bs)
386 , begin_(boost::asio::buffer_sequence_begin(bs_))
387 , out_ (boost::asio::buffer_sequence_begin(bs_))
388 , end_ (boost::asio::buffer_sequence_begin(bs_))
389 , max_size_(boost::asio::buffer_size(bs_))
390 {
391 }
392
393 template<class MutableBufferSequence>
394 auto
395 buffers_adapter<MutableBufferSequence>::prepare(std::size_t n) ->
396 mutable_buffers_type
397 {
398 using boost::asio::buffer_size;
399 end_ = out_;
400 if(end_ != boost::asio::buffer_sequence_end(bs_))
401 {
402 auto size = buffer_size(*end_) - out_pos_;
403 if(n > size)
404 {
405 n -= size;
406 while(++end_ !=
407 boost::asio::buffer_sequence_end(bs_))
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)
429 BOOST_THROW_EXCEPTION(std::length_error{
430 "buffer overflow"});
431 return mutable_buffers_type{*this};
432 }
433
434 template<class MutableBufferSequence>
435 void
436 buffers_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
472 template<class MutableBufferSequence>
473 inline
474 auto
475 buffers_adapter<MutableBufferSequence>::data() const ->
476 const_buffers_type
477 {
478 return const_buffers_type{*this};
479 }
480
481 template<class MutableBufferSequence>
482 void
483 buffers_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
515 } // boost
516
517 #endif