TLA 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 : 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 HIT 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
|