]> git.proxmox.com Git - ceph.git/blame - ceph/src/Beast/include/beast/core/streambuf.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / Beast / include / beast / core / streambuf.hpp
CommitLineData
7c673cae
FG
1//
2// Copyright (c) 2013-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
8#ifndef BEAST_STREAMBUF_HPP
9#define BEAST_STREAMBUF_HPP
10
11#include <beast/config.hpp>
12#include <beast/core/detail/empty_base_optimization.hpp>
13#include <boost/asio/buffer.hpp>
14#include <boost/intrusive/list.hpp>
15#include <iterator>
16#include <limits>
17#include <memory>
18#include <type_traits>
19
20namespace beast {
21
22/** A @b `DynamicBuffer` that uses multiple buffers internally.
23
24 The implementation uses a sequence of one or more character arrays
25 of varying sizes. Additional character array objects are appended to
26 the sequence to accommodate changes in the size of the character
27 sequence.
28
29 @note Meets the requirements of @b DynamicBuffer.
30
31 @tparam Allocator The allocator to use for managing memory.
32*/
33template<class Allocator>
34class basic_streambuf
35#if ! BEAST_DOXYGEN
36 : private detail::empty_base_optimization<
37 typename std::allocator_traits<Allocator>::
38 template rebind_alloc<char>>
39#endif
40{
41public:
42#if BEAST_DOXYGEN
43 /// The type of allocator used.
44 using allocator_type = Allocator;
45#else
46 using allocator_type = typename
47 std::allocator_traits<Allocator>::
48 template rebind_alloc<char>;
49#endif
50
51private:
52 // Storage for the list of buffers representing the input
53 // and output sequences. The allocation for each element
54 // contains `element` followed by raw storage bytes.
55 class element;
56
57 using alloc_traits = std::allocator_traits<allocator_type>;
58 using list_type = typename boost::intrusive::make_list<element,
59 boost::intrusive::constant_time_size<true>>::type;
60 using iterator = typename list_type::iterator;
61 using const_iterator = typename list_type::const_iterator;
62
63 using size_type = typename std::allocator_traits<Allocator>::size_type;
64 using const_buffer = boost::asio::const_buffer;
65 using mutable_buffer = boost::asio::mutable_buffer;
66
67 static_assert(std::is_base_of<std::bidirectional_iterator_tag,
68 typename std::iterator_traits<iterator>::iterator_category>::value,
69 "BidirectionalIterator requirements not met");
70
71 static_assert(std::is_base_of<std::bidirectional_iterator_tag,
72 typename std::iterator_traits<const_iterator>::iterator_category>::value,
73 "BidirectionalIterator requirements not met");
74
75 list_type list_; // list of allocated buffers
76 iterator out_; // element that contains out_pos_
77 size_type alloc_size_; // min amount to allocate
78 size_type in_size_ = 0; // size of the input sequence
79 size_type in_pos_ = 0; // input offset in list_.front()
80 size_type out_pos_ = 0; // output offset in *out_
81 size_type out_end_ = 0; // output end offset in list_.back()
82
83public:
84#if BEAST_DOXYGEN
85 /// The type used to represent the input sequence as a list of buffers.
86 using const_buffers_type = implementation_defined;
87
88 /// The type used to represent the output sequence as a list of buffers.
89 using mutable_buffers_type = implementation_defined;
90
91#else
92 class const_buffers_type;
93
94 class mutable_buffers_type;
95
96#endif
97
98 /// Destructor.
99 ~basic_streambuf();
100
101 /** Move constructor.
102
103 The new object will have the input sequence of
104 the other stream buffer, and an empty output sequence.
105
106 @note After the move, the moved-from object will have
107 an empty input and output sequence, with no internal
108 buffers allocated.
109 */
110 basic_streambuf(basic_streambuf&&);
111
112 /** Move constructor.
113
114 The new object will have the input sequence of
115 the other stream buffer, and an empty output sequence.
116
117 @note After the move, the moved-from object will have
118 an empty input and output sequence, with no internal
119 buffers allocated.
120
121 @param alloc The allocator to associate with the
122 stream buffer.
123 */
124 basic_streambuf(basic_streambuf&&,
125 allocator_type const& alloc);
126
127 /** Move assignment.
128
129 This object will have the input sequence of
130 the other stream buffer, and an empty output sequence.
131
132 @note After the move, the moved-from object will have
133 an empty input and output sequence, with no internal
134 buffers allocated.
135 */
136 basic_streambuf&
137 operator=(basic_streambuf&&);
138
139 /** Copy constructor.
140
141 This object will have a copy of the other stream
142 buffer's input sequence, and an empty output sequence.
143 */
144 basic_streambuf(basic_streambuf const&);
145
146 /** Copy constructor.
147
148 This object will have a copy of the other stream
149 buffer's input sequence, and an empty output sequence.
150
151 @param alloc The allocator to associate with the
152 stream buffer.
153 */
154 basic_streambuf(basic_streambuf const&,
155 allocator_type const& alloc);
156
157 /** Copy assignment.
158
159 This object will have a copy of the other stream
160 buffer's input sequence, and an empty output sequence.
161 */
162 basic_streambuf& operator=(basic_streambuf const&);
163
164 /** Copy constructor.
165
166 This object will have a copy of the other stream
167 buffer's input sequence, and an empty output sequence.
168 */
169 template<class OtherAlloc>
170 basic_streambuf(basic_streambuf<OtherAlloc> const&);
171
172 /** Copy constructor.
173
174 This object will have a copy of the other stream
175 buffer's input sequence, and an empty output sequence.
176
177 @param alloc The allocator to associate with the
178 stream buffer.
179 */
180 template<class OtherAlloc>
181 basic_streambuf(basic_streambuf<OtherAlloc> const&,
182 allocator_type const& alloc);
183
184 /** Copy assignment.
185
186 This object will have a copy of the other stream
187 buffer's input sequence, and an empty output sequence.
188 */
189 template<class OtherAlloc>
190 basic_streambuf& operator=(basic_streambuf<OtherAlloc> const&);
191
192 /** Construct a stream buffer.
193
194 @param alloc_size The size of buffer to allocate. This is a
195 soft limit, calls to prepare for buffers exceeding this size
196 will allocate the larger size. The default allocation size
197 is 1KB (1024 bytes).
198
199 @param alloc The allocator to use. If this parameter is
200 unspecified, a default constructed allocator will be used.
201 */
202 explicit
203 basic_streambuf(std::size_t alloc_size = 1024,
204 Allocator const& alloc = allocator_type{});
205
206 /// Returns a copy of the associated allocator.
207 allocator_type
208 get_allocator() const
209 {
210 return this->member();
211 }
212
213 /** Returns the default allocation size.
214
215 This is the smallest size that the stream buffer will allocate.
216 The size of the allocation can influence capacity, which will
217 affect algorithms that use capacity to efficiently read from
218 streams.
219 */
220 std::size_t
221 alloc_size() const
222 {
223 return alloc_size_;
224 }
225
226 /** Set the default allocation size.
227
228 This is the smallest size that the stream buffer will allocate.
229 The size of the allocation can influence capacity, which will
230 affect algorithms that use capacity to efficiently read from
231 streams.
232
233 @note This will not affect any already-existing allocations.
234
235 @param n The number of bytes.
236 */
237 void
238 alloc_size(std::size_t n)
239 {
240 alloc_size_ = n;
241 }
242
243 /// Returns the size of the input sequence.
244 size_type
245 size() const
246 {
247 return in_size_;
248 }
249
250 /// Returns the permitted maximum sum of the sizes of the input and output sequence.
251 size_type
252 max_size() const
253 {
254 return (std::numeric_limits<std::size_t>::max)();
255 }
256
257 /// Returns the maximum sum of the sizes of the input sequence and output sequence the buffer can hold without requiring reallocation.
258 std::size_t
259 capacity() const;
260
261 /** Get a list of buffers that represents the input sequence.
262
263 @note These buffers remain valid across subsequent calls to `prepare`.
264 */
265 const_buffers_type
266 data() const;
267
268 /** Get a list of buffers that represents the output sequence, with the given size.
269
270 @note Buffers representing the input sequence acquired prior to
271 this call remain valid.
272 */
273 mutable_buffers_type
274 prepare(size_type n);
275
276 /** Move bytes from the output sequence to the input sequence.
277
278 @note Buffers representing the input sequence acquired prior to
279 this call remain valid.
280 */
281 void
282 commit(size_type n);
283
284 /// Remove bytes from the input sequence.
285 void
286 consume(size_type n);
287
288 // Helper for boost::asio::read_until
289 template<class OtherAllocator>
290 friend
291 std::size_t
292 read_size_helper(basic_streambuf<
293 OtherAllocator> const& streambuf, std::size_t max_size);
294
295private:
296 void
297 clear();
298
299 void
300 move_assign(basic_streambuf& other, std::false_type);
301
302 void
303 move_assign(basic_streambuf& other, std::true_type);
304
305 void
306 copy_assign(basic_streambuf const& other, std::false_type);
307
308 void
309 copy_assign(basic_streambuf const& other, std::true_type);
310
311 void
312 delete_list();
313
314 void
315 debug_check() const;
316};
317
318/** A @b `DynamicBuffer` that uses multiple buffers internally.
319
320 The implementation uses a sequence of one or more character arrays
321 of varying sizes. Additional character array objects are appended to
322 the sequence to accommodate changes in the size of the character
323 sequence.
324
325 @note Meets the requirements of @b `DynamicBuffer`.
326*/
327using streambuf = basic_streambuf<std::allocator<char>>;
328
329/** Format output to a @ref basic_streambuf.
330
331 @param streambuf The @ref basic_streambuf to write to.
332
333 @param t The object to write.
334
335 @return A reference to the @ref basic_streambuf.
336*/
337template<class Allocator, class T>
338basic_streambuf<Allocator>&
339operator<<(basic_streambuf<Allocator>& streambuf, T const& t);
340
341} // beast
342
343#include <beast/core/impl/streambuf.ipp>
344
345#endif