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_FLAT_STATIC_BUFFER_HPP
11#define BOOST_BEAST_FLAT_STATIC_BUFFER_HPP
12
13#include <boost/beast/core/detail/config.hpp>
14#include <boost/asio/buffer.hpp>
15#include <algorithm>
16#include <cstddef>
17#include <cstring>
18
19namespace boost {
20namespace beast {
21
22/** A dynamic buffer using a fixed size internal buffer using no memory allocations.
23
24 A dynamic buffer encapsulates memory storage that may be
25 automatically resized as required, where the memory is
26 divided into two regions: readable bytes followed by
27 writable bytes. These memory regions are internal to
28 the dynamic buffer, but direct access to the elements
29 is provided to permit them to be efficiently used with
30 I/O operations.
31
32 Objects of this type meet the requirements of <em>DynamicBuffer</em>
33 and have the following additional properties:
34
35 @li A mutable buffer sequence representing the readable
36 bytes is returned by @ref data when `this` is non-const.
37
38 @li Buffer sequences representing the readable and writable
39 bytes, returned by @ref data and @ref prepare, will have
40 a type of net::const_buffer or net::mutable_buffer.
41
42 @li Ownership of the underlying storage belongs to the
43 derived class.
44
45 @note Variables are usually declared using the template class
46 @ref flat_static_buffer; however, to reduce the number of template
47 instantiations, objects should be passed `flat_static_buffer_base&`.
48
49 @see flat_static_buffer
50*/
51class flat_static_buffer_base
52{
53 char* begin_;
54 char* in_;
55 char* out_;
56 char* last_;
57 char* end_;
58
59 flat_static_buffer_base(
60 flat_static_buffer_base const& other) = delete;
61 flat_static_buffer_base& operator=(
62 flat_static_buffer_base const&) = delete;
63
64public:
65 /** Constructor
66
67 This creates a dynamic buffer using the provided storage area.
68
69 @param p A pointer to valid storage of at least `n` bytes.
70
71 @param n The number of valid bytes pointed to by `p`.
72 */
73 flat_static_buffer_base(
74 void* p, std::size_t n) noexcept
75 {
76 reset(p, n);
77 }
78
79 /** Clear the readable and writable bytes to zero.
80
81 This function causes the readable and writable bytes
82 to become empty. The capacity is not changed.
83
84 Buffer sequences previously obtained using @ref data or
85 @ref prepare become invalid.
86
87 @esafe
88
89 No-throw guarantee.
90 */
91 BOOST_BEAST_DECL
92 void
93 clear() noexcept;
94
95 //--------------------------------------------------------------------------
96
97 /// The ConstBufferSequence used to represent the readable bytes.
98 using const_buffers_type = net::const_buffer;
99
100 /// The MutableBufferSequence used to represent the writable bytes.
101 using mutable_buffers_type = net::mutable_buffer;
102
103 /// Returns the number of readable bytes.
104 std::size_t
105 size() const noexcept
106 {
107 return out_ - in_;
108 }
109
110 /// Return the maximum number of bytes, both readable and writable, that can ever be held.
111 std::size_t
112 max_size() const noexcept
113 {
114 return dist(first: begin_, last: end_);
115 }
116
117 /// Return the maximum number of bytes, both readable and writable, that can be held without requiring an allocation.
118 std::size_t
119 capacity() const noexcept
120 {
121 return max_size();
122 }
123
124 /// Returns a constant buffer sequence representing the readable bytes
125 const_buffers_type
126 data() const noexcept
127 {
128 return {in_, dist(first: in_, last: out_)};
129 }
130
131 /// Returns a constant buffer sequence representing the readable bytes
132 const_buffers_type
133 cdata() const noexcept
134 {
135 return data();
136 }
137
138 /// Returns a mutable buffer sequence representing the readable bytes
139 mutable_buffers_type
140 data() noexcept
141 {
142 return {in_, dist(first: in_, last: out_)};
143 }
144
145 /** Returns a mutable buffer sequence representing writable bytes.
146
147 Returns a mutable buffer sequence representing the writable
148 bytes containing exactly `n` bytes of storage.
149
150 All buffers sequences previously obtained using
151 @ref data or @ref prepare are invalidated.
152
153 @param n The desired number of bytes in the returned buffer
154 sequence.
155
156 @throws std::length_error if `size() + n` exceeds `max_size()`.
157
158 @esafe
159
160 Strong guarantee.
161 */
162 BOOST_BEAST_DECL
163 mutable_buffers_type
164 prepare(std::size_t n);
165
166 /** Append writable bytes to the readable bytes.
167
168 Appends n bytes from the start of the writable bytes to the
169 end of the readable bytes. The remainder of the writable bytes
170 are discarded. If n is greater than the number of writable
171 bytes, all writable bytes are appended to the readable bytes.
172
173 All buffers sequences previously obtained using
174 @ref data or @ref prepare are invalidated.
175
176 @param n The number of bytes to append. If this number
177 is greater than the number of writable bytes, all
178 writable bytes are appended.
179
180 @esafe
181
182 No-throw guarantee.
183 */
184 void
185 commit(std::size_t n) noexcept
186 {
187 out_ += (std::min<std::size_t>)(a: n, b: last_ - out_);
188 }
189
190 /** Remove bytes from beginning of the readable bytes.
191
192 Removes n bytes from the beginning of the readable bytes.
193
194 All buffers sequences previously obtained using
195 @ref data or @ref prepare are invalidated.
196
197 @param n The number of bytes to remove. If this number
198 is greater than the number of readable bytes, all
199 readable bytes are removed.
200
201 @esafe
202
203 No-throw guarantee.
204 */
205 BOOST_BEAST_DECL
206 void
207 consume(std::size_t n) noexcept;
208
209protected:
210 /** Constructor
211
212 The buffer will be in an undefined state. It is necessary
213 for the derived class to call @ref reset with a pointer
214 and size in order to initialize the object.
215 */
216 flat_static_buffer_base() = default;
217
218 /** Reset the pointed-to buffer.
219
220 This function resets the internal state to the buffer provided.
221 All input and output sequences are invalidated. This function
222 allows the derived class to construct its members before
223 initializing the static buffer.
224
225 @param p A pointer to valid storage of at least `n` bytes.
226
227 @param n The number of valid bytes pointed to by `p`.
228
229 @esafe
230
231 No-throw guarantee.
232 */
233 BOOST_BEAST_DECL
234 void
235 reset(void* p, std::size_t n) noexcept;
236
237private:
238 static
239 std::size_t
240 dist(char const* first, char const* last) noexcept
241 {
242 return static_cast<std::size_t>(last - first);
243 }
244};
245
246//------------------------------------------------------------------------------
247
248/** A <em>DynamicBuffer</em> with a fixed size internal buffer using no memory allocations.
249
250 Buffer sequences representing the readable and writable
251 bytes, returned by @ref data and @ref prepare, will have
252 a type of net::const_buffer or net::mutable_buffer.
253
254 @tparam N The number of bytes in the internal buffer.
255
256 @note To reduce the number of template instantiations when passing
257 objects of this type in a deduced context, the signature of the
258 receiving function should use @ref flat_static_buffer_base instead.
259
260 @see flat_static_buffer_base
261*/
262template<std::size_t N>
263class flat_static_buffer : public flat_static_buffer_base
264{
265 char buf_[N];
266
267public:
268 /// Constructor
269 flat_static_buffer(flat_static_buffer const&);
270
271 /// Constructor
272 flat_static_buffer()
273 : flat_static_buffer_base(buf_, N)
274 {
275 }
276
277 /// Assignment
278 flat_static_buffer& operator=(flat_static_buffer const&);
279
280 /// Returns the @ref flat_static_buffer_base portion of this object
281 flat_static_buffer_base&
282 base()
283 {
284 return *this;
285 }
286
287 /// Returns the @ref flat_static_buffer_base portion of this object
288 flat_static_buffer_base const&
289 base() const
290 {
291 return *this;
292 }
293
294 /// Return the maximum sum of the input and output sequence sizes.
295 std::size_t constexpr
296 max_size() const
297 {
298 return N;
299 }
300
301 /// Return the maximum sum of input and output sizes that can be held without an allocation.
302 std::size_t constexpr
303 capacity() const
304 {
305 return N;
306 }
307};
308
309} // beast
310} // boost
311
312#include <boost/beast/core/impl/flat_static_buffer.hpp>
313#ifdef BOOST_BEAST_HEADER_ONLY
314#include <boost/beast/core/impl/flat_static_buffer.ipp>
315#endif
316
317#endif

source code of boost/libs/beast/include/boost/beast/core/flat_static_buffer.hpp