Line data Source code
1 : //
2 : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2024 Christian Mazakas
4 : //
5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 : //
8 : // Official repository: https://github.com/cppalliance/http_proto
9 : //
10 :
11 : #ifndef BOOST_HTTP_PROTO_FIELDS_HPP
12 : #define BOOST_HTTP_PROTO_FIELDS_HPP
13 :
14 : #include <boost/http_proto/detail/config.hpp>
15 : #include <boost/http_proto/fields_base.hpp>
16 : #include <boost/http_proto/fields_view.hpp>
17 : #include <boost/core/detail/string_view.hpp>
18 : #include <initializer_list>
19 :
20 : namespace boost {
21 : namespace http_proto {
22 :
23 : /** A modifiable container of HTTP fields
24 : */
25 : class fields final
26 : : public fields_base
27 : {
28 : public:
29 :
30 : //--------------------------------------------
31 : //
32 : // Special Members
33 : //
34 : //--------------------------------------------
35 :
36 : /** Constructor
37 :
38 : Default-constructed fields have no
39 : name-value pairs.
40 : */
41 : BOOST_HTTP_PROTO_DECL
42 : fields() noexcept;
43 :
44 : /** Constructor
45 : */
46 : BOOST_HTTP_PROTO_DECL
47 : explicit
48 : fields(
49 : core::string_view s);
50 :
51 : /** Constructor
52 :
53 : Construct a fields container which allocates
54 : `storage_size` bytes for storing the header.
55 : Attempting to grow the container beyond
56 : this amount will result in an exception.
57 : The storage is also used internally to store
58 : instances of an implementation-defined type.
59 : The requested number of bytes will be aligned
60 : accordingly (currently the alignment requirement is 4).
61 :
62 : <br/>
63 :
64 : This constructor is useful when an upper-bound size
65 : of the fields is known ahead of time and we want
66 : to prevent reallocations.
67 :
68 : <br/>
69 :
70 : Passing an initial storage size of `0` does not
71 : throw and the maximum capacity is set to an
72 : implementation-defined limit observable via
73 : @ref max_capacity_in_bytes().
74 :
75 : @param storage_size The initial and final size of
76 : the storage.
77 :
78 : @code
79 : boost::http_proto::fields
80 : make_fields(std::string_view server)
81 : {
82 : std::size_t size = 4096;
83 : // flds.buffer() is now stable
84 : boost::http_proto::fields flds(size);
85 : BOOST_ASSERT(
86 : flds.max_capacity_in_bytes(), 4096);
87 :
88 : // uses spare capacity so that reallocations
89 : // are avoided
90 : flds.append(
91 : boost::http_proto::field::server, server);
92 : flds.append(
93 : boost::http_proto::field::connection, "close");
94 : return flds;
95 : }
96 : @endcode
97 : */
98 : BOOST_HTTP_PROTO_DECL
99 : explicit
100 : fields(
101 : std::size_t storage_size);
102 :
103 : /** Constructor
104 :
105 : Construct a fields container which allocates
106 : `storage_size` bytes for storing the header, with an
107 : upper limit of `max_storage_size`. Attempting to
108 : grow the container beyond its maximum will result in
109 : an exception. The storage is also used internally to
110 : store instances of an implementation-defined type.
111 : Both values will be aligned accordingly (currently
112 : the alignment requirement is 4).
113 :
114 : <br/>
115 :
116 : This constructor is useful when there's a best-fit
117 : guess for an initial header size but we still wish
118 : to permit reallocating and growing the container to
119 : some upper limit.
120 :
121 : <br/>
122 :
123 : Passing an initial size of `0` does not throw.
124 :
125 : @param storage_size The initial size of the storage.
126 :
127 : @param max_storage_size The maximum size of the
128 : allocated storage. Any operation that attempts to
129 : grow the container beyond this value throws
130 : `std::length_error`.
131 :
132 : @throws std::length_error Thrown if `size > max_size`
133 :
134 : @code
135 : boost::http_proto::fields
136 : make_fields(std::string_view host)
137 : {
138 : std::size_t size = 4096;
139 : boost::http_proto::fields flds(size, 2 * size);
140 : BOOST_ASSERT(
141 : flds.max_capacity_in_bytes(), 2 * 4096);
142 :
143 : // uses spare capacity so that reallocations
144 : // are avoided
145 : flds.append(
146 : boost::http_proto::field::host, host);
147 : flds.append(
148 : boost::http_proto::field::connection, "close");
149 : return flds;
150 : }
151 : @endcode
152 : */
153 : BOOST_HTTP_PROTO_DECL
154 : explicit
155 : fields(
156 : std::size_t storage_size,
157 : std::size_t max_storage_size);
158 :
159 : /** Constructor
160 : */
161 : BOOST_HTTP_PROTO_DECL
162 : fields(fields&& other) noexcept;
163 :
164 : /** Constructor
165 : */
166 : BOOST_HTTP_PROTO_DECL
167 : fields(fields const& other);
168 :
169 : /** Constructor
170 : */
171 : BOOST_HTTP_PROTO_DECL
172 : fields(fields_view const& other);
173 :
174 : /** Assignment
175 : */
176 : BOOST_HTTP_PROTO_DECL
177 : fields&
178 : operator=(fields&& f) noexcept;
179 :
180 : /** Assignment
181 : */
182 : fields&
183 5 : operator=(fields const& f) noexcept
184 : {
185 5 : copy_impl(*f.ph_);
186 5 : return *this;
187 : }
188 :
189 : /** Assignment
190 : */
191 : fields&
192 4 : operator=(fields_view const& f)
193 : {
194 4 : copy_impl(*f.ph_);
195 4 : return *this;
196 : }
197 :
198 : /** Conversion
199 : */
200 4 : operator fields_view() const noexcept
201 : {
202 4 : return fields_view(ph_);
203 : }
204 :
205 : //--------------------------------------------
206 : //
207 : // Modifiers
208 : //
209 : //--------------------------------------------
210 :
211 : /** Swap this with another instance
212 : */
213 : void
214 10 : swap(fields& other) noexcept
215 : {
216 10 : h_.swap(other.h_);
217 10 : }
218 :
219 : /** Swap two instances
220 : */
221 : // hidden friend
222 : friend
223 : void
224 : swap(
225 : fields& t0,
226 : fields& t1) noexcept
227 : {
228 : t0.swap(t1);
229 : }
230 : };
231 :
232 : } // http_proto
233 : } // boost
234 :
235 : #endif
|