include/boost/url/url_view.hpp

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