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_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
|