Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.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/CPPAlliance/http_proto | ||
8 | // | ||
9 | |||
10 | #ifndef BOOST_HTTP_PROTO_BUFFERED_BASE_HPP | ||
11 | #define BOOST_HTTP_PROTO_BUFFERED_BASE_HPP | ||
12 | |||
13 | #include <boost/http_proto/detail/config.hpp> | ||
14 | #include <cstddef> | ||
15 | |||
16 | namespace boost { | ||
17 | namespace http_proto { | ||
18 | |||
19 | /** Base class for buffered algorithms | ||
20 | |||
21 | Algorithms implementing @ref filter, | ||
22 | @ref source, or @ref sink inherit from | ||
23 | this common interface. | ||
24 | */ | ||
25 | struct BOOST_SYMBOL_VISIBLE | ||
26 | 92 | buffered_base | |
27 | { | ||
28 | /** Allocator for buffered algorithms. | ||
29 | */ | ||
30 | class allocator; | ||
31 | |||
32 | /** Destructor. | ||
33 | */ | ||
34 | BOOST_HTTP_PROTO_DECL | ||
35 | virtual | ||
36 | ~buffered_base(); | ||
37 | |||
38 | /** Initialize the algorithm. | ||
39 | |||
40 | The derived class must be initialized | ||
41 | before invoking any other members, | ||
42 | except destruction. | ||
43 | The default implementation does nothing. | ||
44 | The purpose of this function is to | ||
45 | allow the derived class to optionally | ||
46 | allocate temporary storage using the | ||
47 | specified allocator, which could offer | ||
48 | advantages. | ||
49 | <br> | ||
50 | Subclasses are still required to operate | ||
51 | correctly even when insufficient storage | ||
52 | is available from the allocator. In this | ||
53 | case they should simply allocate normally. | ||
54 | |||
55 | @par Preconditions | ||
56 | Initialization has not already occurred. | ||
57 | |||
58 | @param a The allocator to use. | ||
59 | */ | ||
60 | void | ||
61 | 23 | init(allocator& a) | |
62 | { | ||
63 | 23 | on_init(a); | |
64 | 20 | } | |
65 | |||
66 | /** Initialize the algorithm. | ||
67 | |||
68 | The derived class must be initialized | ||
69 | before invoking any other members, | ||
70 | except destruction. | ||
71 | The default implementation does nothing. | ||
72 | The purpose of this function is to | ||
73 | allow the derived class to optionally | ||
74 | allocate temporary storage using the | ||
75 | specified allocator, which could offer | ||
76 | advantages. | ||
77 | <br> | ||
78 | Subclasses are still required to operate | ||
79 | correctly even when insufficient storage | ||
80 | is available from the allocator. In this | ||
81 | case they should simply allocate normally. | ||
82 | |||
83 | @par Preconditions | ||
84 | Initialization has not already occurred. | ||
85 | |||
86 | @throws std::invalid_argument `max_size > a.max_size()` | ||
87 | |||
88 | @param a The allocator to use. | ||
89 | |||
90 | @param max_size The largest allowed | ||
91 | total amount of bytes for the | ||
92 | allocator. | ||
93 | */ | ||
94 | BOOST_HTTP_PROTO_DECL | ||
95 | void | ||
96 | init( | ||
97 | allocator& a, | ||
98 | std::size_t max_size); | ||
99 | |||
100 | protected: | ||
101 | /** Initialize the algorithm. | ||
102 | |||
103 | The default implementation does nothing. | ||
104 | The purpose of this function is to | ||
105 | allow the derived class to optionally | ||
106 | allocate temporary storage using the | ||
107 | specified allocator, which could offer | ||
108 | advantages. | ||
109 | <br> | ||
110 | Subclasses are still required to operate | ||
111 | correctly even when insufficient storage | ||
112 | is available from the allocator. In this | ||
113 | case they should simply allocate normally. | ||
114 | |||
115 | @par Preconditions | ||
116 | Initialization has not already occurred. | ||
117 | |||
118 | @param a The allocator to use. | ||
119 | */ | ||
120 | BOOST_HTTP_PROTO_DECL | ||
121 | virtual | ||
122 | void | ||
123 | on_init(allocator& a); | ||
124 | }; | ||
125 | |||
126 | //------------------------------------------------ | ||
127 | |||
128 | /** Provides memory to buffered algorithms. | ||
129 | */ | ||
130 | class buffered_base::allocator | ||
131 | { | ||
132 | public: | ||
133 | /** Constructor | ||
134 | |||
135 | Default constructed objects return | ||
136 | zero from @ref max_size. | ||
137 | */ | ||
138 | allocator() = default; | ||
139 | |||
140 | /** Constructor | ||
141 | |||
142 | This function constructs an allocator | ||
143 | which uses the specified contiguous | ||
144 | buffer. Calls to allocate will return | ||
145 | parcels of the buffer from either the | ||
146 | beginning or the end depending on the | ||
147 | value of `downwards`. | ||
148 | |||
149 | @par Preconditions | ||
150 | @code | ||
151 | p != nullptr || n == 0 | ||
152 | @endcode | ||
153 | |||
154 | @par Exception Safety | ||
155 | Throws nothing. | ||
156 | |||
157 | @param p A pointer to contiguous storage. | ||
158 | This may be `nullptr` if `n == 0`. | ||
159 | |||
160 | @param n The number of valid bytes of | ||
161 | storage pointed to by p. This may | ||
162 | be zero. | ||
163 | |||
164 | @param downwards When true, calls to | ||
165 | allocate will return storage from | ||
166 | the end of the memory pointed to | ||
167 | by `p` rather than the beginning. | ||
168 | */ | ||
169 | 18 | allocator( | |
170 | void* p, | ||
171 | std::size_t n, | ||
172 | bool downwards) noexcept | ||
173 | 18 | : base_(static_cast< | |
174 | unsigned char*>(p)) | ||
175 | , size_(n) | ||
176 | 18 | , down_(downwards) | |
177 | { | ||
178 | 18 | } | |
179 | |||
180 | /** The maximum amount that can be successfully returned from reserve | ||
181 | */ | ||
182 | std::size_t | ||
183 | 38 | max_size() const noexcept | |
184 | { | ||
185 | 38 | return size_; | |
186 | } | ||
187 | |||
188 | /** Return the total number of bytes allocated | ||
189 | */ | ||
190 | std::size_t | ||
191 | 24 | size_used() const noexcept | |
192 | { | ||
193 | 24 | return size_used_; | |
194 | } | ||
195 | |||
196 | /** Return a pointer to at least n bytes of contiguous storage | ||
197 | |||
198 | Allocated storage will be automatically | ||
199 | deallocated when the @ref filter, | ||
200 | @ref sink, or @ref source is destroyed. | ||
201 | |||
202 | @throws std::invalid_argument `n > max_size()` | ||
203 | |||
204 | @return A pointer to uninitialized storage. | ||
205 | |||
206 | @param n The number of bytes. | ||
207 | */ | ||
208 | BOOST_HTTP_PROTO_DECL | ||
209 | void* | ||
210 | allocate(std::size_t n); | ||
211 | |||
212 | private: | ||
213 | void | ||
214 | 7 | remove( | |
215 | std::size_t n) noexcept | ||
216 | { | ||
217 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
|
7 | if(down_) |
218 | 2 | base_ += n; | |
219 | 7 | size_ -= n; | |
220 | 7 | } | |
221 | |||
222 | void | ||
223 | 7 | restore( | |
224 | std::size_t n) noexcept | ||
225 | { | ||
226 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
|
7 | if(down_) |
227 | 2 | base_ -= n; | |
228 | 7 | size_ += n; | |
229 | 7 | } | |
230 | |||
231 | friend struct buffered_base; | ||
232 | |||
233 | unsigned char* base_ = nullptr; | ||
234 | std::size_t size_ = 0; | ||
235 | std::size_t size_used_ = 0; | ||
236 | bool down_ = false; | ||
237 | }; | ||
238 | |||
239 | } // http_proto | ||
240 | } // boost | ||
241 | |||
242 | #endif | ||
243 |