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_BUFFERS_SUFFIX_HPP
11 #define BOOST_BEAST_BUFFERS_SUFFIX_HPP
12 
13 #include <boost/beast/core/detail/config.hpp>
14 #include <boost/beast/core/buffer_traits.hpp>
15 #include <boost/optional.hpp>
16 #include <cstdint>
17 #include <iterator>
18 #include <utility>
19 
20 namespace boost {
21 namespace beast {
22 
23 /** Adaptor to progressively trim the front of a <em>BufferSequence</em>.
24 
25     This adaptor wraps a buffer sequence to create a new sequence
26     which may be incrementally consumed. Bytes consumed are removed
27     from the front of the buffer. The underlying memory is not changed,
28     instead the adaptor efficiently iterates through a subset of
29     the buffers wrapped.
30 
31     The wrapped buffer is not modified, a copy is made instead.
32     Ownership of the underlying memory is not transferred, the application
33     is still responsible for managing its lifetime.
34 
35     @tparam BufferSequence The buffer sequence to wrap.
36 
37     @par Example
38 
39     This function writes the entire contents of a buffer sequence
40     to the specified stream.
41 
42     @code
43     template<class SyncWriteStream, class ConstBufferSequence>
44     void send(SyncWriteStream& stream, ConstBufferSequence const& buffers)
45     {
46         buffers_suffix<ConstBufferSequence> bs{buffers};
47         while(buffer_bytes(bs) > 0)
48             bs.consume(stream.write_some(bs));
49     }
50     @endcode
51 */
52 template<class BufferSequence>
53 class buffers_suffix
54 {
55     using iter_type =
56         buffers_iterator_type<BufferSequence>;
57 
58     BufferSequence bs_;
59     iter_type begin_{};
60     std::size_t skip_ = 0;
61 
62     template<class Deduced>
buffers_suffix(Deduced && other,std::size_t dist)63     buffers_suffix(Deduced&& other, std::size_t dist)
64         : bs_(std::forward<Deduced>(other).bs_)
65         , begin_(std::next(
66             net::buffer_sequence_begin(bs_),
67                 dist))
68         , skip_(other.skip_)
69     {
70     }
71 
72 public:
73     /** The type for each element in the list of buffers.
74 
75         If <em>BufferSequence</em> meets the requirements of
76         <em>MutableBufferSequence</em>, then this type will be
77         `net::mutable_buffer`, otherwise this type will be
78         `net::const_buffer`.
79     */
80 #if BOOST_BEAST_DOXYGEN
81     using value_type = __see_below__;
82 #else
83     using value_type = buffers_type<BufferSequence>;
84 #endif
85 
86 #if BOOST_BEAST_DOXYGEN
87     /// A bidirectional iterator type that may be used to read elements.
88     using const_iterator = __implementation_defined__;
89 
90 #else
91     class const_iterator;
92 
93 #endif
94 
95     /// Constructor
96     buffers_suffix();
97 
98     /// Copy Constructor
99     buffers_suffix(buffers_suffix const&);
100 
101     /** Constructor
102 
103         A copy of the buffer sequence is made. Ownership of the
104         underlying memory is not transferred or copied.
105     */
106     explicit
107     buffers_suffix(BufferSequence const& buffers);
108 
109     /** Constructor
110 
111         This constructs the buffer sequence in-place from
112         a list of arguments.
113 
114         @param args Arguments forwarded to the buffers constructor.
115     */
116     template<class... Args>
117     explicit
118     buffers_suffix(boost::in_place_init_t, Args&&... args);
119 
120     /// Copy Assignment
121     buffers_suffix& operator=(buffers_suffix const&);
122 
123     /// Get a bidirectional iterator to the first element.
124     const_iterator
125     begin() const;
126 
127     /// Get a bidirectional iterator to one past the last element.
128     const_iterator
129     end() const;
130 
131     /** Remove bytes from the beginning of the sequence.
132 
133         @param amount The number of bytes to remove. If this is
134         larger than the number of bytes remaining, all the
135         bytes remaining are removed.
136     */
137     void
138     consume(std::size_t amount);
139 };
140 
141 } // beast
142 } // boost
143 
144 #include <boost/beast/core/impl/buffers_suffix.hpp>
145 
146 #endif
147