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 31 : 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 3521 : url_view( 91 : detail::url_impl const& impl) noexcept 92 3521 : : url_view_base(impl) 93 : { 94 3521 : } 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 217 : url_view( 216 : String const& s) 217 : : url_view( 218 217 : detail::to_sv(s)) 219 : { 220 216 : } 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 15536 : url_view( 240 : url_view const& other) noexcept 241 15536 : : url_view(static_cast< 242 15536 : url_view_base const&>(other)) 243 : { 244 15536 : } 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 69 : hash(std::size_t salt) noexcept 357 69 : : salt_(salt) 358 : { 359 69 : } 360 : 361 : std::size_t 362 276 : operator()(::boost::urls::url_view const& u) const noexcept 363 : { 364 276 : return u.digest(salt_); 365 : } 366 : 367 : private: 368 : std::size_t salt_ = 0; 369 : }; 370 : } // std 371 : #endif 372 : 373 : #endif