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 @ref result containing either a valid
47 : @ref url_view upon succcess, 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 BOOST_URL_DECL 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 : explicit
90 3542 : url_view(
91 : detail::url_impl const& impl) noexcept
92 3542 : : url_view_base(impl)
93 : {
94 3542 : }
95 :
96 : public:
97 : //--------------------------------------------
98 : //
99 : // Special Members
100 : //
101 : //--------------------------------------------
102 :
103 : /** Destructor
104 :
105 : Any params, segments, iterators, or
106 : other views which reference the same
107 : underlying character buffer remain
108 : valid.
109 : */
110 : ~url_view() = default;
111 :
112 : /** Constructor
113 :
114 : Default constructed views refer to
115 : a string with zero length, which
116 : always remains valid. This matches
117 : the grammar for a relative-ref with
118 : an empty path and no query or
119 : fragment.
120 :
121 : @par Example
122 : @code
123 : url_view u;
124 : @endcode
125 :
126 : @par Postconditions
127 : @code
128 : this->empty() == true
129 : @endcode
130 :
131 : @par Complexity
132 : Constant.
133 :
134 : @par Exception Safety
135 : Throws nothing.
136 :
137 : @par BNF
138 : @code
139 : relative-ref = relative-part [ "?" query ] [ "#" fragment ]
140 : @endcode
141 :
142 : @par Specification
143 : <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2"
144 : >4.2. Relative Reference (rfc3986)</a>
145 : */
146 : url_view() noexcept;
147 :
148 : /** Constructor
149 :
150 : This function constructs a URL from
151 : the string `s`, which must contain a
152 : valid <em>URI</em> or <em>relative-ref</em>
153 : or else an exception is thrown. Upon
154 : successful construction, the view
155 : refers to the characters in the
156 : buffer pointed to by `s`.
157 : Ownership is not transferred; The caller
158 : is responsible for ensuring that the
159 : lifetime of the buffer extends until
160 : it is no longer referenced.
161 :
162 : @par Example
163 : @code
164 : url_view u( "http://www.example.com/index.htm" );
165 : @endcode
166 :
167 : @par Effects
168 : @code
169 : return parse_uri_reference( s ).value();
170 : @endcode
171 :
172 : @par Complexity
173 : Linear in `s.size()`.
174 :
175 : @par Exception Safety
176 : Exceptions thrown on invalid input.
177 :
178 : @throw system_error
179 : The input failed to parse correctly.
180 :
181 : @param s The string to parse.
182 :
183 : @par BNF
184 : @code
185 : URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
186 :
187 : relative-ref = relative-part [ "?" query ] [ "#" fragment ]
188 : @endcode
189 :
190 : @par Specification
191 : @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.1"
192 : >4.1. URI Reference</a>
193 :
194 : @see
195 : @ref parse_uri_reference.
196 : */
197 : url_view(core::string_view s);
198 :
199 : /// @copydoc url_view(core::string_view)
200 : template<
201 : class String
202 : #ifndef BOOST_URL_DOCS
203 : , class = typename std::enable_if<
204 : std::is_convertible<
205 : String,
206 : core::string_view
207 : >::value &&
208 : !std::is_convertible<
209 : String*,
210 : url_view_base*
211 : >::value
212 : >::type
213 : #endif
214 : >
215 221 : url_view(
216 : String const& s)
217 : : url_view(
218 221 : detail::to_sv(s))
219 : {
220 220 : }
221 :
222 : /** Constructor
223 :
224 : After construction, both views
225 : reference the same underlying character
226 : buffer. Ownership is not transferred.
227 :
228 : @par Postconditions
229 : @code
230 : this->buffer().data() == other.buffer().data()
231 : @endcode
232 :
233 : @par Complexity
234 : Constant.
235 :
236 : @par Exception Safety
237 : Throws nothing.
238 : */
239 15626 : url_view(
240 : url_view const& other) noexcept
241 15626 : : url_view(static_cast<
242 15626 : url_view_base const&>(other))
243 : {
244 15626 : }
245 :
246 : /** Constructor
247 :
248 : After construction, both views
249 : reference the same underlying character
250 : buffer. Ownership is not transferred.
251 :
252 : @par Postconditions
253 : @code
254 : this->buffer().data() == other.buffer().data()
255 : @endcode
256 :
257 : @par Complexity
258 : Constant.
259 :
260 : @par Exception Safety
261 : Throws nothing.
262 : */
263 : url_view(
264 : url_view_base const& other) noexcept;
265 :
266 : /** Assignment
267 :
268 : After assignment, both views
269 : reference the same underlying character
270 : buffer. Ownership is not transferred.
271 :
272 : @par Postconditions
273 : @code
274 : this->buffer().data() == other.buffer().data()
275 : @endcode
276 :
277 : @par Complexity
278 : Constant.
279 :
280 : @par Exception Safety
281 : Throws nothing.
282 : */
283 : url_view&
284 13 : operator=(
285 : url_view const& other) noexcept
286 : {
287 13 : if (this != &other)
288 : *this = static_cast<
289 12 : url_view_base const&>(other);
290 13 : return *this;
291 : }
292 :
293 : /** Assignment
294 :
295 : After assignment, both views
296 : reference the same underlying character
297 : buffer. Ownership is not transferred.
298 :
299 : @par Postconditions
300 : @code
301 : this->buffer().data() == other.buffer().data()
302 : @endcode
303 :
304 : @par Complexity
305 : Constant.
306 :
307 : @par Exception Safety
308 : Throws nothing.
309 : */
310 : url_view& operator=(
311 : url_view_base const& other) noexcept;
312 :
313 : //--------------------------------------------
314 : //
315 : // Observers
316 : //
317 : //--------------------------------------------
318 :
319 : /** Return the maximum number of characters possible
320 :
321 : This represents the largest number of
322 : characters that are possible in a url,
323 : not including any null terminator.
324 :
325 : @par Complexity
326 : Constant.
327 :
328 : @par Exception Safety
329 : Throws nothing.
330 : */
331 : static
332 : constexpr
333 : std::size_t
334 : max_size() noexcept
335 : {
336 : return BOOST_URL_MAX_SIZE;
337 : }
338 : };
339 :
340 : } // urls
341 : } // boost
342 :
343 : //------------------------------------------------
344 :
345 : // std::hash specialization
346 : #ifndef BOOST_URL_DOCS
347 : namespace std {
348 : template<>
349 : struct hash< ::boost::urls::url_view >
350 : {
351 : hash() = default;
352 : hash(hash const&) = default;
353 : hash& operator=(hash const&) = default;
354 :
355 : explicit
356 76 : hash(std::size_t salt) noexcept
357 76 : : salt_(salt)
358 : {
359 76 : }
360 :
361 : std::size_t
362 304 : operator()(::boost::urls::url_view const& u) const noexcept
363 : {
364 304 : return u.digest(salt_);
365 : }
366 :
367 : private:
368 : std::size_t salt_ = 0;
369 : };
370 : } // std
371 : #endif
372 :
373 : #endif
|