Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
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/boostorg/url
9 : //
10 :
11 : #ifndef BOOST_URL_PARAMS_VIEW_HPP
12 : #define BOOST_URL_PARAMS_VIEW_HPP
13 :
14 : #include <boost/url/detail/config.hpp>
15 : #include <boost/url/params_base.hpp>
16 :
17 : namespace boost {
18 : namespace urls {
19 :
20 : /** Non-owning decoded query parameter view
21 :
22 : This read-only range interprets the query
23 : string of a URL as bidirectional key/value
24 : pairs with percent-decoding applied on
25 : access. It merely references the original
26 : character buffer; callers must keep that
27 : buffer alive while the view is used.
28 :
29 : @par Example
30 : @code
31 : url_view u( "?first=John&last=Doe" );
32 :
33 : params_view p = u.params();
34 : @endcode
35 :
36 : Strings retrieved from the iterators are
37 : automatically percent-decoded.
38 :
39 : @par Iterator Invalidation
40 : Changes to the underlying character buffer
41 : can invalidate iterators which reference it.
42 : */
43 : class BOOST_URL_DECL params_view
44 : : public params_base
45 : {
46 : friend class url_view_base;
47 : friend class params_encoded_view;
48 : friend class params_ref;
49 :
50 : params_view(
51 : detail::query_ref const& ref,
52 : encoding_opts opt) noexcept;
53 :
54 : public:
55 : /** Constructor
56 :
57 : Default-constructed params have
58 : zero elements.
59 :
60 : @par Example
61 : @code
62 : params_view qp;
63 : @endcode
64 :
65 : @par Effects
66 : @code
67 : return params_view( "" );
68 : @endcode
69 :
70 : @par Complexity
71 : Constant.
72 :
73 : @par Exception Safety
74 : Throws nothing.
75 : */
76 1 : params_view() = default;
77 :
78 : /** Constructor
79 :
80 : After construction both views reference
81 : the same character buffer.
82 :
83 : Ownership is not transferred; the caller
84 : is responsible for ensuring the lifetime
85 : of the buffer extends until it is no
86 : longer referenced.
87 :
88 : @par Postconditions
89 : @code
90 : this->buffer().data() == other.buffer().data()
91 : @endcode
92 :
93 : @par Complexity
94 : Constant.
95 :
96 : @par Exception Safety
97 : Throws nothing
98 :
99 : @param other The object to copy
100 : */
101 : params_view(
102 : params_view const& other) = default;
103 :
104 : /** Constructor
105 :
106 : After construction both views will
107 : reference the same character buffer
108 : but this instance will use the specified
109 : @ref encoding_opts when the values
110 : are decoded.
111 :
112 : Ownership is not transferred; the caller
113 : is responsible for ensuring the lifetime
114 : of the buffer extends until it is no
115 : longer referenced.
116 :
117 : @par Postconditions
118 : @code
119 : this->buffer().data() == other.buffer().data()
120 : @endcode
121 :
122 : @par Complexity
123 : Constant.
124 :
125 : @par Exception Safety
126 : Throws nothing
127 :
128 : @param other The object to copy
129 : @param opt The options for decoding
130 : */
131 : params_view(
132 : params_view const& other,
133 : encoding_opts opt) noexcept;
134 :
135 : /** Constructor
136 :
137 : This function constructs params from
138 : a valid query parameter string, which
139 : can contain percent escapes. Unlike
140 : the parameters in URLs, the string
141 : passed here should not start with "?".
142 : Upon construction, the view references
143 : the character buffer pointed to by `s`.
144 : The caller is responsible for ensuring
145 : that the lifetime of the buffer extends
146 : until it is no longer referenced.
147 :
148 : @par Example
149 : @code
150 : params_view qp( "first=John&last=Doe" );
151 : @endcode
152 :
153 : @par Effects
154 : @code
155 : return parse_query( s ).value();
156 : @endcode
157 :
158 : @par Postconditions
159 : @code
160 : this->buffer().data() == s.data()
161 : @endcode
162 :
163 : @par Complexity
164 : Linear in `s`.
165 :
166 : @par Exception Safety
167 : Exceptions thrown on invalid input.
168 :
169 : @throw system_error
170 : `s` contains an invalid query parameter
171 : string.
172 :
173 : @param s The string to parse.
174 :
175 : @par BNF
176 : @code
177 : query-params = [ query-param ] *( "&" query-param )
178 :
179 : query-param = key [ "=" value ]
180 : @endcode
181 :
182 : @par Specification
183 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
184 : >3.4. Query</a>
185 : */
186 : params_view(
187 : core::string_view s);
188 :
189 : /** Constructor
190 :
191 : This function constructs params from
192 : a valid query parameter string, which
193 : can contain percent escapes.
194 :
195 : This instance will use the specified
196 : @ref encoding_opts when the values
197 : are decoded.
198 :
199 : Unlike the parameters in URLs, the string
200 : passed here should not start with "?".
201 : Upon construction, the view will
202 : reference the character buffer pointed
203 : to by `s`. The caller is responsible
204 : for ensuring that the lifetime of the
205 : buffer extends until it is no longer
206 : referenced.
207 :
208 : @par Example
209 : @code
210 : encoding_opts opt;
211 : opt.space_as_plus = true;
212 : params_view qp( "name=John+Doe", opt );
213 : @endcode
214 :
215 : @par Effects
216 : @code
217 : return params_view(parse_query( s ).value(), opt);
218 : @endcode
219 :
220 : @par Postconditions
221 : @code
222 : this->buffer().data() == s.data()
223 : @endcode
224 :
225 : @par Complexity
226 : Linear in `s`.
227 :
228 : @par Exception Safety
229 : Exceptions thrown on invalid input.
230 :
231 : @throw system_error
232 : `s` contains an invalid query parameter
233 : string.
234 :
235 : @param s The string to parse.
236 :
237 : @param opt The options for decoding. If
238 : this parameter is omitted, `space_as_plus`
239 : is used.
240 :
241 : @par BNF
242 : @code
243 : query-params = [ query-param ] *( "&" query-param )
244 :
245 : query-param = key [ "=" value ]
246 : @endcode
247 :
248 : @par Specification
249 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.4"
250 : >3.4. Query</a>
251 : */
252 : params_view(
253 : core::string_view s,
254 : encoding_opts opt);
255 :
256 : /** Assignment
257 :
258 : After assignment, both views reference
259 : the same underlying character buffer.
260 :
261 : Ownership is not transferred; the caller
262 : is responsible for ensuring the lifetime
263 : of the buffer extends until it is no
264 : longer referenced.
265 :
266 : @par Postconditions
267 : @code
268 : this->buffer().data() == other.buffer().data()
269 : @endcode
270 :
271 : @par Complexity
272 : Constant
273 :
274 : @par Exception Safety
275 : Throws nothing
276 :
277 : @param other The object to assign
278 : @return A reference to this object
279 : */
280 : params_view&
281 : operator=(
282 : params_view const& other) = default;
283 : };
284 :
285 : } // urls
286 : } // boost
287 :
288 : //------------------------------------------------
289 : //
290 : // std::ranges::enable_borrowed_range
291 : //
292 : //------------------------------------------------
293 :
294 : #ifdef BOOST_URL_HAS_CONCEPTS
295 : #include <ranges>
296 : namespace std::ranges {
297 : template<>
298 : inline constexpr bool
299 : enable_borrowed_range<
300 : boost::urls::params_view> = true;
301 : } // std::ranges
302 : #endif
303 :
304 : #endif
|