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