Line |
Branch |
Exec |
Source |
1 |
|
|
// |
2 |
|
|
// Copyright (c) 2025 Mohammad Nejati |
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_STATIC_FIELDS_HPP |
11 |
|
|
#define BOOST_HTTP_PROTO_STATIC_FIELDS_HPP |
12 |
|
|
|
13 |
|
|
#include <boost/http_proto/detail/config.hpp> |
14 |
|
|
#include <boost/http_proto/fields_base.hpp> |
15 |
|
|
#include <boost/http_proto/fields_view.hpp> |
16 |
|
|
#include <boost/core/detail/string_view.hpp> |
17 |
|
|
|
18 |
|
|
namespace boost { |
19 |
|
|
namespace http_proto { |
20 |
|
|
|
21 |
|
|
/** A modifiable static container of HTTP fields. |
22 |
|
|
|
23 |
|
|
This container owns a collection of HTTP fields, |
24 |
|
|
represented by an inline buffer with fixed capacity. |
25 |
|
|
The contents may be inspected and modified, |
26 |
|
|
and the implementation maintains a useful |
27 |
|
|
invariant: changes to the fields always |
28 |
|
|
leave it in a valid state. |
29 |
|
|
|
30 |
|
|
@par Example |
31 |
|
|
@code |
32 |
|
|
static_fields<1024> fs; |
33 |
|
|
|
34 |
|
|
fs.set(field::host, "example.com"); |
35 |
|
|
fs.set(field::accept_encoding, "gzip, deflate, br"); |
36 |
|
|
fs.set(field::cache_control, "no-cache"); |
37 |
|
|
|
38 |
|
|
assert(fs.buffer() == |
39 |
|
|
"Host: example.com\r\n" |
40 |
|
|
"Accept-Encoding: gzip, deflate, br\r\n" |
41 |
|
|
"Cache-Control: no-cache\r\n" |
42 |
|
|
"\r\n"); |
43 |
|
|
@endcode |
44 |
|
|
|
45 |
|
|
@par Invariants |
46 |
|
|
@code |
47 |
|
|
this->capacity_in_bytes() == Capacity && this->max_capacity_in_bytes() == Capacity |
48 |
|
|
@endcode |
49 |
|
|
|
50 |
|
|
@tparam Capacity The maximum capacity in bytes. |
51 |
|
|
|
52 |
|
|
@see |
53 |
|
|
@ref fields, |
54 |
|
|
@ref fields_view. |
55 |
|
|
*/ |
56 |
|
|
template<std::size_t Capacity> |
57 |
|
|
class static_fields final |
58 |
|
|
: public fields_base |
59 |
|
|
{ |
60 |
|
|
alignas(entry) |
61 |
|
|
char buf_[Capacity]; |
62 |
|
|
|
63 |
|
|
public: |
64 |
|
|
|
65 |
|
|
//-------------------------------------------- |
66 |
|
|
// |
67 |
|
|
// Special Members |
68 |
|
|
// |
69 |
|
|
//-------------------------------------------- |
70 |
|
|
|
71 |
|
|
/** Constructor. |
72 |
|
|
|
73 |
|
|
A default-constructed fields container |
74 |
|
|
contains no name-value pairs. |
75 |
|
|
|
76 |
|
|
@par Example |
77 |
|
|
@code |
78 |
|
|
static_fields<1024> fs; |
79 |
|
|
@endcode |
80 |
|
|
|
81 |
|
|
@par Postconditions |
82 |
|
|
@code |
83 |
|
|
this->buffer() == "\r\n" |
84 |
|
|
@endcode |
85 |
|
|
|
86 |
|
|
@par Complexity |
87 |
|
|
Constant. |
88 |
|
|
*/ |
89 |
|
18 |
static_fields() noexcept |
90 |
|
|
: fields_view_base( |
91 |
|
18 |
&this->fields_base::h_) |
92 |
|
|
, fields_base( |
93 |
|
|
detail::kind::fields, |
94 |
|
18 |
buf_, |
95 |
|
18 |
Capacity) |
96 |
|
|
{ |
97 |
|
18 |
} |
98 |
|
|
|
99 |
|
|
|
100 |
|
|
/** Constructor. |
101 |
|
|
|
102 |
|
|
Constructs a fields container from the |
103 |
|
|
string `s`, which must contain valid |
104 |
|
|
HTTP fields or else an exception is thrown. |
105 |
|
|
The new fields container retains ownership |
106 |
|
|
by making a copy of the passed string. |
107 |
|
|
|
108 |
|
|
@par Example |
109 |
|
|
@code |
110 |
|
|
static_fields<1024> fs( |
111 |
|
|
"Server: Boost.HttpProto\r\n" |
112 |
|
|
"Content-Type: text/plain\r\n" |
113 |
|
|
"\r\n"); |
114 |
|
|
@endcode |
115 |
|
|
|
116 |
|
|
@par Postconditions |
117 |
|
|
@code |
118 |
|
|
this->buffer.data() != s.data() |
119 |
|
|
@endcode |
120 |
|
|
|
121 |
|
|
@par Complexity |
122 |
|
|
Linear in `s.size()`. |
123 |
|
|
|
124 |
|
|
@par Exception Safety |
125 |
|
|
Exception thrown on invalid input. |
126 |
|
|
Exception thrown if max capacity exceeded. |
127 |
|
|
|
128 |
|
|
@throw system_error |
129 |
|
|
The input does not contain a valid HTTP fields. |
130 |
|
|
|
131 |
|
|
@throw std::length_error |
132 |
|
|
Max capacity would be exceeded. |
133 |
|
|
|
134 |
|
|
@param s The string to parse. |
135 |
|
|
*/ |
136 |
|
12 |
explicit static_fields( |
137 |
|
|
core::string_view s) |
138 |
|
|
: fields_view_base( |
139 |
|
12 |
&this->fields_base::h_) |
140 |
|
|
, fields_base( |
141 |
|
|
detail::kind::fields, |
142 |
|
12 |
buf_, |
143 |
|
|
Capacity, |
144 |
|
12 |
s) |
145 |
|
|
{ |
146 |
|
12 |
} |
147 |
|
|
|
148 |
|
|
/** Constructor. |
149 |
|
|
|
150 |
|
|
The newly constructed object contains |
151 |
|
|
a copy of `f`. |
152 |
|
|
|
153 |
|
|
@par Postconditions |
154 |
|
|
@code |
155 |
|
|
this->buffer() == f.buffer() && this->buffer.data() != f.buffer().data() |
156 |
|
|
@endcode |
157 |
|
|
|
158 |
|
|
@par Complexity |
159 |
|
|
Linear in `f.size()`. |
160 |
|
|
|
161 |
|
|
@param f The fields container to copy. |
162 |
|
|
*/ |
163 |
|
1 |
static_fields( |
164 |
|
|
static_fields const& f) noexcept |
165 |
|
|
: fields_view_base( |
166 |
|
1 |
&this->fields_base::h_) |
167 |
|
|
, fields_base( |
168 |
|
1 |
*f.ph_, |
169 |
|
1 |
buf_, |
170 |
|
1 |
Capacity) |
171 |
|
|
{ |
172 |
|
1 |
} |
173 |
|
|
|
174 |
|
|
/** Constructor. |
175 |
|
|
|
176 |
|
|
The newly constructed object contains |
177 |
|
|
a copy of `f`. |
178 |
|
|
|
179 |
|
|
@par Postconditions |
180 |
|
|
@code |
181 |
|
|
this->buffer() == f.buffer() && this->buffer.data() != f.buffer().data() |
182 |
|
|
@endcode |
183 |
|
|
|
184 |
|
|
@par Complexity |
185 |
|
|
Linear in `f.size()`. |
186 |
|
|
|
187 |
|
|
@par Exception Safety |
188 |
|
|
Exception thrown if max capacity exceeded. |
189 |
|
|
|
190 |
|
|
@throw std::length_error |
191 |
|
|
Max capacity would be exceeded. |
192 |
|
|
|
193 |
|
|
@param f The fields container to copy. |
194 |
|
|
*/ |
195 |
|
|
/** Constructor |
196 |
|
|
*/ |
197 |
|
1 |
static_fields( |
198 |
|
|
fields_view const& f) |
199 |
|
|
: fields_view_base( |
200 |
|
1 |
&this->fields_base::h_) |
201 |
|
|
, fields_base( |
202 |
|
1 |
*f.ph_, |
203 |
|
1 |
buf_, |
204 |
|
1 |
Capacity) |
205 |
|
|
{ |
206 |
|
1 |
} |
207 |
|
|
|
208 |
|
|
/** Assignment. |
209 |
|
|
|
210 |
|
|
The contents of `f` are copied and |
211 |
|
|
the previous contents of `this` are |
212 |
|
|
discarded. |
213 |
|
|
|
214 |
|
|
@par Postconditions |
215 |
|
|
@code |
216 |
|
|
this->buffer() == f.buffer() && this->buffer().data() != f.buffer().data() |
217 |
|
|
@endcode |
218 |
|
|
|
219 |
|
|
@par Complexity |
220 |
|
|
Linear in `f.size()`. |
221 |
|
|
|
222 |
|
|
@param f The fields container to copy. |
223 |
|
|
|
224 |
|
|
@return A reference to this object. |
225 |
|
|
*/ |
226 |
|
|
static_fields& |
227 |
|
3 |
operator=(static_fields const& f) noexcept |
228 |
|
|
{ |
229 |
|
3 |
copy_impl(*f.ph_); |
230 |
|
3 |
return *this; |
231 |
|
|
} |
232 |
|
|
|
233 |
|
|
/** Assignment. |
234 |
|
|
|
235 |
|
|
The contents of `f` are copied and |
236 |
|
|
the previous contents of `this` are |
237 |
|
|
discarded. |
238 |
|
|
|
239 |
|
|
@par Postconditions |
240 |
|
|
@code |
241 |
|
|
this->buffer() == f.buffer() && this->buffer().data() != f.buffer().data() |
242 |
|
|
@endcode |
243 |
|
|
|
244 |
|
|
@par Complexity |
245 |
|
|
Linear in `f.size()`. |
246 |
|
|
|
247 |
|
|
@par Exception Safety |
248 |
|
|
Strong guarantee. |
249 |
|
|
Exception thrown if max capacity exceeded. |
250 |
|
|
|
251 |
|
|
@throw std::length_error |
252 |
|
|
Max capacity would be exceeded. |
253 |
|
|
|
254 |
|
|
@param f The fields container to copy. |
255 |
|
|
|
256 |
|
|
@return A reference to this object. |
257 |
|
|
*/ |
258 |
|
|
static_fields& |
259 |
|
8 |
operator=(fields_view const& f) |
260 |
|
|
{ |
261 |
|
8 |
copy_impl(*f.ph_); |
262 |
|
8 |
return *this; |
263 |
|
|
} |
264 |
|
|
|
265 |
|
|
/** Conversion. |
266 |
|
|
|
267 |
|
|
@see |
268 |
|
|
@ref fields_view. |
269 |
|
|
|
270 |
|
|
@return A view of the fields. |
271 |
|
|
*/ |
272 |
|
4 |
operator fields_view() const noexcept |
273 |
|
|
{ |
274 |
|
4 |
return fields_view(ph_); |
275 |
|
|
} |
276 |
|
|
}; |
277 |
|
|
|
278 |
|
|
} // http_proto |
279 |
|
|
} // boost |
280 |
|
|
|
281 |
|
|
#endif |
282 |
|
|
|