include/boost/url/url_view.hpp

100.0% Lines (24/24) 100.0% Functions (65/65)
include/boost/url/url_view.hpp
Line TLA Hits 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_URL_VIEW_HPP
12 #define BOOST_URL_URL_VIEW_HPP
13
14 #include <boost/url/detail/config.hpp>
15 #include <boost/url/url_view_base.hpp>
16 #include <utility>
17
18 namespace boost {
19 namespace urls {
20
21 namespace implementation_defined {
22 struct origin_form_rule_t;
23 struct uri_rule_t;
24 struct relative_ref_rule_t;
25 struct absolute_uri_rule_t;
26 } // implementation_defined
27
28 /** A non-owning reference to a valid URL
29
30 Objects of this type represent valid URL
31 strings constructed from a parsed, external
32 character buffer whose storage is managed
33 by the caller. That is, it acts like a
34 `core::string_view` in terms of ownership.
35 The caller is responsible for ensuring
36 that the lifetime of the underlying
37 character buffer extends until it is no
38 longer referenced.
39
40 @par Example 1
41 Construction from a string parses the input
42 as a <em>URI-reference</em> and throws an
43 exception on error. Upon success, the
44 constructed object points to the passed
45 character buffer; ownership is not
46 transferred.
47 @code
48 url_view u( "https://www.example.com/index.htm?text=none#a1" );
49 @endcode
50
51 @par Example 2
52 Parsing functions like @ref parse_uri_reference
53 return a `boost::system::result` containing either a valid
54 @ref url_view upon success, otherwise they
55 contain an error. The error can be converted to
56 an exception by the caller if desired:
57 @code
58 system::result< url_view > rv = parse_uri_reference( "https://www.example.com/index.htm?text=none#a1" );
59 @endcode
60
61 @par BNF
62 @code
63 URI-reference = URI / relative-ref
64
65 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
66
67 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
68 @endcode
69
70 @par Specification
71 @li <a href="https://tools.ietf.org/html/rfc3986"
72 >Uniform Resource Identifier (URI): Generic Syntax (rfc3986)</a>
73
74 @see
75 @ref parse_absolute_uri,
76 @ref parse_origin_form,
77 @ref parse_relative_ref,
78 @ref parse_uri,
79 @ref parse_uri_reference.
80 */
81 class BOOST_SYMBOL_VISIBLE url_view
82 : public url_view_base
83 {
84 friend std::hash<url_view>;
85 friend class url_view_base;
86 friend class params_base;
87 friend class params_encoded_base;
88 friend struct implementation_defined::origin_form_rule_t;
89 friend struct implementation_defined::uri_rule_t;
90 friend struct implementation_defined::relative_ref_rule_t;
91 friend struct implementation_defined::absolute_uri_rule_t;
92
93 using url_view_base::digest;
94
95 BOOST_URL_CXX14_CONSTEXPR
96 explicit
97 3749 url_view(
98 detail::url_impl const& impl) noexcept
99 3749 : url_view_base(impl)
100 {
101 3749 }
102
103 public:
104 //--------------------------------------------
105 //
106 // Special Members
107 //
108 //--------------------------------------------
109
110 /** Destructor
111
112 Any params, segments, iterators, or
113 other views which reference the same
114 underlying character buffer remain
115 valid.
116 */
117 ~url_view() = default;
118
119 /** Constructor
120
121 Default constructed views refer to
122 a string with zero length, which
123 always remains valid. This matches
124 the grammar for a relative-ref with
125 an empty path and no query or
126 fragment.
127
128 @par Example
129 @code
130 url_view u;
131 @endcode
132
133 @par Postconditions
134 @code
135 this->empty() == true
136 @endcode
137
138 @par Complexity
139 Constant.
140
141 @par Exception Safety
142 Throws nothing.
143
144 @par BNF
145 @code
146 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
147 @endcode
148
149 @par Specification
150 <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2"
151 >4.2. Relative Reference (rfc3986)</a>
152 */
153 BOOST_URL_CXX14_CONSTEXPR
154 34 url_view() noexcept = default;
155
156 /** Constructor
157
158 This function constructs a URL from
159 the string `s`, which must contain a
160 valid <em>URI</em> or <em>relative-ref</em>
161 or else an exception is thrown. Upon
162 successful construction, the view
163 refers to the characters in the
164 buffer pointed to by `s`.
165 Ownership is not transferred; The caller
166 is responsible for ensuring that the
167 lifetime of the buffer extends until
168 it is no longer referenced.
169
170 @par Example
171 @code
172 url_view u( "http://www.example.com/index.htm" );
173 @endcode
174
175 @par Effects
176 @code
177 return parse_uri_reference( s ).value();
178 @endcode
179
180 @par Complexity
181 Linear in `s.size()`.
182
183 @par Exception Safety
184 Exceptions thrown on invalid input.
185
186 @throw system_error
187 The input failed to parse correctly.
188
189 @param s The string to parse.
190
191 @par BNF
192 @code
193 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
194
195 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
196 @endcode
197
198 @par Specification
199 @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.1"
200 >4.1. URI Reference</a>
201
202 @see
203 @ref parse_uri_reference.
204 */
205 url_view(core::string_view s);
206
207 /// @copydoc url_view(core::string_view)
208 template<
209 class String
210 #ifndef BOOST_URL_DOCS
211 , class = typename std::enable_if<
212 std::is_convertible<
213 String,
214 core::string_view
215 >::value &&
216 !std::is_convertible<
217 String*,
218 url_view_base*
219 >::value
220 >::type
221 #endif
222 >
223 310 url_view(
224 String const& s)
225 : url_view(
226 310 detail::to_sv(s))
227 {
228 309 }
229
230 /** Constructor
231
232 After construction, both views
233 reference the same underlying character
234 buffer. Ownership is not transferred.
235
236 @par Postconditions
237 @code
238 this->buffer().data() == other.buffer().data()
239 @endcode
240
241 @par Complexity
242 Constant.
243
244 @par Exception Safety
245 Throws nothing.
246
247 @param other The other view.
248 */
249 BOOST_URL_CXX14_CONSTEXPR
250 url_view(
251 url_view const& other) noexcept = default;
252
253 /** Move constructor
254 */
255 BOOST_URL_CXX14_CONSTEXPR
256 url_view(
257 url_view&& other) noexcept = default;
258
259 /** Constructor
260
261 After construction, both views
262 reference the same underlying character
263 buffer. Ownership is not transferred.
264
265 @par Postconditions
266 @code
267 this->buffer().data() == other.buffer().data()
268 @endcode
269
270 @par Complexity
271 Constant.
272
273 @par Exception Safety
274 Throws nothing.
275
276 @param other The other view.
277 */
278 BOOST_URL_CXX14_CONSTEXPR
279 146 url_view(
280 url_view_base const& other) noexcept
281 146 : url_view_base(other.impl_)
282 {
283 146 external_impl_ = other.external_impl_;
284 146 }
285
286 /** Assignment
287
288 After assignment, both views
289 reference the same underlying character
290 buffer. Ownership is not transferred.
291
292 @par Postconditions
293 @code
294 this->buffer().data() == other.buffer().data()
295 @endcode
296
297 @par Complexity
298 Constant.
299
300 @par Exception Safety
301 Throws nothing.
302
303 @param other The other view.
304 @return A reference to this object.
305 */
306 BOOST_URL_CXX14_CONSTEXPR
307 url_view&
308 13 operator=(
309 url_view const& other) noexcept
310 {
311 13 impl_ = other.impl_;
312 13 external_impl_ = other.external_impl_;
313 13 return *this;
314 }
315
316 /** Assignment
317
318 After assignment, both views
319 reference the same underlying character
320 buffer. Ownership is not transferred.
321
322 @par Postconditions
323 @code
324 this->buffer().data() == other.buffer().data()
325 @endcode
326
327 @par Complexity
328 Constant.
329
330 @par Exception Safety
331 Throws nothing.
332
333 @param other The other view.
334 @return A reference to this object.
335 */
336 BOOST_URL_CXX14_CONSTEXPR
337 2 url_view& operator=(
338 url_view_base const& other) noexcept
339 {
340 2 impl_ = other.impl_;
341 2 external_impl_ = other.external_impl_;
342 2 return *this;
343 }
344
345 //--------------------------------------------
346 //
347 // Observers
348 //
349 //--------------------------------------------
350
351 /** Return the maximum number of characters possible
352
353 This represents the largest number of
354 characters that are possible in a url,
355 not including any null terminator.
356
357 @par Complexity
358 Constant.
359
360 @par Exception Safety
361 Throws nothing.
362
363 @return The maximum number of characters possible.
364 */
365 static
366 constexpr
367 std::size_t
368 max_size() noexcept
369 {
370 return BOOST_URL_MAX_SIZE;
371 }
372 };
373
374 } // urls
375 } // boost
376
377 //------------------------------------------------
378
379 // std::hash specialization
380 #ifndef BOOST_URL_DOCS
381 namespace std {
382 template<>
383 struct hash< ::boost::urls::url_view >
384 {
385 hash() = default;
386 hash(hash const&) = default;
387 hash& operator=(hash const&) = default;
388
389 explicit
390 76 hash(std::size_t salt) noexcept
391 76 : salt_(salt)
392 {
393 76 }
394
395 std::size_t
396 304 operator()(::boost::urls::url_view const& u) const noexcept
397 {
398 304 return u.digest(salt_);
399 }
400
401 private:
402 std::size_t salt_ = 0;
403 };
404 } // std
405 #endif
406
407 // When parse.hpp is being processed,
408 // it will include impl/url_view.hpp itself
409 // after declaring parse_uri_reference.
410 #if !defined(BOOST_URL_PARSE_HPP)
411 #include <boost/url/impl/url_view.hpp>
412 #endif
413
414 #endif
415