Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:30

0001 //
0002 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
0003 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // Official repository: https://github.com/boostorg/url
0009 //
0010 
0011 #ifndef BOOST_URL_URL_HPP
0012 #define BOOST_URL_URL_HPP
0013 
0014 #include <boost/url/detail/config.hpp>
0015 #include <boost/url/url_base.hpp>
0016 #include <boost/assert.hpp>
0017 #include <utility>
0018 
0019 namespace boost {
0020 namespace urls {
0021 
0022 /** A modifiable container for a URL.
0023 
0024     This container owns a url, represented
0025     by a null-terminated character buffer
0026     which is managed by performing dymamic
0027     memory allocations as needed.
0028     The contents may be inspected and modified,
0029     and the implementation maintains a useful
0030     invariant: changes to the url always
0031     leave it in a valid state.
0032 
0033     @par Exception Safety
0034 
0035     @li Functions marked `noexcept` provide the
0036     no-throw guarantee, otherwise:
0037 
0038     @li Functions which throw offer the strong
0039     exception safety guarantee.
0040 
0041     @par BNF
0042     @code
0043     URI-reference = URI / relative-ref
0044 
0045     URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
0046 
0047     relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
0048 
0049     absolute-URI  = scheme ":" hier-part [ "?" query ]
0050     @endcode
0051 
0052     @par Specification
0053     @li <a href="https://tools.ietf.org/html/rfc3986"
0054         >Uniform Resource Identifier (URI): Generic Syntax (rfc3986)</a>
0055 
0056     @see
0057         @ref parse_absolute_uri,
0058         @ref parse_relative_ref,
0059         @ref parse_uri,
0060         @ref parse_uri_reference,
0061         @ref resolve.
0062 */
0063 class BOOST_URL_DECL url
0064     : public url_base
0065 {
0066     friend std::hash<url>;
0067 
0068     using url_view_base::digest;
0069 
0070 public:
0071     //--------------------------------------------
0072     //
0073     // Special Members
0074     //
0075     //--------------------------------------------
0076 
0077     /** Destructor
0078 
0079         Any params, segments, iterators, or
0080         views which reference this object are
0081         invalidated. The underlying character
0082         buffer is destroyed, invalidating all
0083         references to it.
0084     */
0085     virtual ~url();
0086 
0087     /** Constructor
0088 
0089         Default constructed urls contain
0090         a zero-length string. This matches
0091         the grammar for a relative-ref with
0092         an empty path and no query or
0093         fragment.
0094 
0095         @par Example
0096         @code
0097         url u;
0098         @endcode
0099 
0100         @par Postconditions
0101         @code
0102         this->empty() == true
0103         @endcode
0104 
0105         @par Complexity
0106         Constant.
0107 
0108         @par Exception Safety
0109         Throws nothing.
0110 
0111         @par BNF
0112         @code
0113         relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
0114         @endcode
0115 
0116         @par Specification
0117         <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2"
0118             >4.2. Relative Reference (rfc3986)</a>
0119     */
0120     url() noexcept;
0121 
0122     /** Constructor
0123 
0124         This function constructs a URL from
0125         the string `s`, which must contain a
0126         valid <em>URI</em> or <em>relative-ref</em>
0127         or else an exception is thrown.
0128         The new url retains ownership by
0129         allocating a copy of the passed string.
0130 
0131         @par Example
0132         @code
0133         url u( "https://www.example.com" );
0134         @endcode
0135 
0136         @par Effects
0137         @code
0138         return url( parse_uri_reference( s ).value() );
0139         @endcode
0140 
0141         @par Postconditions
0142         @code
0143         this->buffer().data() != s.data()
0144         @endcode
0145 
0146         @par Complexity
0147         Linear in `s.size()`.
0148 
0149         @par Exception Safety
0150         Calls to allocate may throw.
0151         Exceptions thrown on invalid input.
0152 
0153         @throw system_error
0154         The input does not contain a valid url.
0155 
0156         @param s The string to parse.
0157 
0158         @par BNF
0159         @code
0160         URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
0161 
0162         relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
0163         @endcode
0164 
0165         @par Specification
0166         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.1"
0167             >4.1. URI Reference</a>
0168     */
0169     explicit
0170     url(core::string_view s);
0171 
0172     /** Constructor
0173 
0174         The contents of `u` are transferred
0175         to the newly constructed object,
0176         which includes the underlying
0177         character buffer.
0178         After construction, the moved-from
0179         object is as if default constructed.
0180 
0181         @par Postconditions
0182         @code
0183         u.empty() == true
0184         @endcode
0185 
0186         @par Complexity
0187         Constant.
0188 
0189         @par Exception Safety
0190         Throws nothing.
0191 
0192         @param u The url to move from.
0193     */
0194     url(url&& u) noexcept;
0195 
0196     /** Constructor
0197 
0198         The newly constructed object
0199         contains a copy of `u`.
0200 
0201         @par Postconditions
0202         @code
0203         this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
0204         @endcode
0205 
0206         @par Complexity
0207         Linear in `u.size()`.
0208 
0209         @par Exception Safety
0210         Strong guarantee.
0211         Calls to allocate may throw.
0212 
0213         @throw std::length_error `u.size() > max_size()`.
0214 
0215         @param u The url to copy.
0216     */
0217     url(url_view_base const& u)
0218     {
0219         copy(u);
0220     }
0221 
0222     /** Constructor
0223 
0224         The newly constructed object
0225         contains a copy of `u`.
0226 
0227         @par Postconditions
0228         @code
0229         this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
0230         @endcode
0231 
0232         @par Complexity
0233         Linear in `u.size()`.
0234 
0235         @par Exception Safety
0236         Strong guarantee.
0237         Calls to allocate may throw.
0238 
0239         @throw std::length_error `u.size() > max_size()`.
0240 
0241         @param u The url to copy.
0242     */
0243     url(url const& u)
0244         : url(static_cast<
0245             url_view_base const&>(u))
0246     {
0247     }
0248 
0249     /** Assignment
0250 
0251         The contents of `u` are transferred to
0252         `this`, including the underlying
0253         character buffer. The previous contents
0254         of `this` are destroyed.
0255         After assignment, the moved-from
0256         object is as if default constructed.
0257 
0258         @par Postconditions
0259         @code
0260         u.empty() == true
0261         @endcode
0262 
0263         @par Complexity
0264         Constant.
0265 
0266         @par Exception Safety
0267         Throws nothing.
0268 
0269         @param u The url to assign from.
0270     */
0271     url&
0272     operator=(url&& u) noexcept;
0273 
0274     /** Assignment
0275 
0276         The contents of `u` are copied and
0277         the previous contents of `this` are
0278         destroyed.
0279         Capacity is preserved, or increases.
0280 
0281         @par Postconditions
0282         @code
0283         this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
0284         @endcode
0285 
0286         @par Complexity
0287         Linear in `u.size()`.
0288 
0289         @par Exception Safety
0290         Strong guarantee.
0291         Calls to allocate may throw.
0292 
0293         @throw std::length_error `u.size() > max_size()`.
0294 
0295         @param u The url to copy.
0296     */
0297     url&
0298     operator=(
0299         url_view_base const& u)
0300     {
0301         copy(u);
0302         return *this;
0303     }
0304 
0305     /** Assignment
0306 
0307         The contents of `u` are copied and
0308         the previous contents of `this` are
0309         destroyed.
0310         Capacity is preserved, or increases.
0311 
0312         @par Postconditions
0313         @code
0314         this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
0315         @endcode
0316 
0317         @par Complexity
0318         Linear in `u.size()`.
0319 
0320         @par Exception Safety
0321         Strong guarantee.
0322         Calls to allocate may throw.
0323 
0324         @param u The url to copy.
0325     */
0326     url&
0327     operator=(url const& u)
0328     {
0329         return (*this)=static_cast<
0330             url_view_base const&>(u);
0331     }
0332 
0333     //--------------------------------------------
0334 
0335     /** Swap the contents.
0336 
0337         Exchanges the contents of this url with another
0338         url. All views, iterators and references remain valid.
0339 
0340         If `this == &other`, this function call has no effect.
0341 
0342         @par Example
0343         @code
0344         url u1( "https://www.example.com" );
0345         url u2( "https://www.boost.org" );
0346         u1.swap(u2);
0347         assert(u1 == "https://www.boost.org" );
0348         assert(u2 == "https://www.example.com" );
0349         @endcode
0350 
0351         @par Complexity
0352         Constant
0353 
0354         @par Exception Safety
0355         Throws nothing.
0356 
0357         @param other The object to swap with
0358 
0359     */
0360     void
0361     swap(url& other) noexcept;
0362 
0363     /** Swap
0364 
0365         Exchanges the contents of `v0` with another `v1`.
0366         All views, iterators and references remain
0367         valid.
0368 
0369         If `&v0 == &v1`, this function call has no effect.
0370 
0371         @par Example
0372         @code
0373         url u1( "https://www.example.com" );
0374         url u2( "https://www.boost.org" );
0375         std::swap(u1, u2);
0376         assert(u1 == "https://www.boost.org" );
0377         assert(u2 == "https://www.example.com" );
0378         @endcode
0379 
0380         @par Effects
0381         @code
0382         v0.swap( v1 );
0383         @endcode
0384 
0385         @par Complexity
0386         Constant
0387 
0388         @par Exception Safety
0389         Throws nothing
0390 
0391         @param v0, v1 The objects to swap
0392 
0393         @see
0394             @ref url::swap
0395     */
0396     friend
0397     void
0398     swap(url& v0, url& v1) noexcept
0399     {
0400         v0.swap(v1);
0401     }
0402 
0403     //--------------------------------------------
0404     //
0405     // fluent api
0406     //
0407 
0408     /// @copydoc url_base::set_scheme
0409     url& set_scheme(core::string_view s) { url_base::set_scheme(s); return *this; }
0410     /// @copydoc url_base::set_scheme_id
0411     url& set_scheme_id(urls::scheme id) { url_base::set_scheme_id(id); return *this; }
0412     /// @copydoc url_base::remove_scheme
0413     url& remove_scheme() { url_base::remove_scheme(); return *this; }
0414 
0415     /// @copydoc url_base::set_encoded_authority
0416     url& set_encoded_authority(pct_string_view s) { url_base::set_encoded_authority(s); return *this; }
0417     /// @copydoc url_base::remove_authority
0418     url& remove_authority() { url_base::remove_authority(); return *this; }
0419 
0420     /// @copydoc url_base::set_userinfo
0421     url& set_userinfo(core::string_view s) { url_base::set_userinfo(s); return *this; }
0422     /// @copydoc url_base::set_encoded_userinfo
0423     url& set_encoded_userinfo(pct_string_view s) { url_base::set_encoded_userinfo(s); return *this; }
0424     /// @copydoc url_base::remove_userinfo
0425     url& remove_userinfo() noexcept { url_base::remove_userinfo(); return *this; }
0426     /// @copydoc url_base::set_user
0427     url& set_user(core::string_view s) { url_base::set_user(s); return *this; }
0428     /// @copydoc url_base::set_encoded_user
0429     url& set_encoded_user(pct_string_view s) { url_base::set_encoded_user(s); return *this; }
0430     /// @copydoc url_base::set_password
0431     url& set_password(core::string_view s) { url_base::set_password(s); return *this; }
0432     /// @copydoc url_base::set_encoded_password
0433     url& set_encoded_password(pct_string_view s) { url_base::set_encoded_password(s); return *this; }
0434     /// @copydoc url_base::remove_password
0435     url& remove_password() noexcept { url_base::remove_password(); return *this; }
0436 
0437     /// @copydoc url_base::set_host
0438     url& set_host(core::string_view s) { url_base::set_host(s); return *this; }
0439     /// @copydoc url_base::set_encoded_host
0440     url& set_encoded_host(pct_string_view s) { url_base::set_encoded_host(s); return *this; }
0441     /// @copydoc url_base::set_host_address
0442     url& set_host_address(core::string_view s) { url_base::set_host_address(s); return *this; }
0443     /// @copydoc url_base::set_encoded_host_address
0444     url& set_encoded_host_address(pct_string_view s) { url_base::set_encoded_host_address(s); return *this; }
0445     /// @copydoc url_base::set_host_ipv4
0446     url& set_host_ipv4(ipv4_address const& addr) { url_base::set_host_ipv4(addr); return *this; }
0447     /// @copydoc url_base::set_host_ipv6
0448     url& set_host_ipv6(ipv6_address const& addr) { url_base::set_host_ipv6(addr); return *this; }
0449     /// @copydoc url_base::set_host_ipvfuture
0450     url& set_host_ipvfuture(core::string_view s) { url_base::set_host_ipvfuture(s); return *this; }
0451     /// @copydoc url_base::set_host_name
0452     url& set_host_name(core::string_view s) { url_base::set_host_name(s); return *this; }
0453     /// @copydoc url_base::set_encoded_host_name
0454     url& set_encoded_host_name(pct_string_view s) { url_base::set_encoded_host_name(s); return *this; }
0455     /// @copydoc url_base::set_port_number
0456     url& set_port_number(std::uint16_t n) { url_base::set_port_number(n); return *this; }
0457     /// @copydoc url_base::set_port
0458     url& set_port(core::string_view s) { url_base::set_port(s); return *this; }
0459     /// @copydoc url_base::remove_port
0460     url& remove_port() noexcept { url_base::remove_port(); return *this; }
0461 
0462     /// @copydoc url_base::set_path_absolute
0463     //bool set_path_absolute(bool absolute);
0464     /// @copydoc url_base::set_path
0465     url& set_path(core::string_view s) { url_base::set_path(s); return *this; }
0466     /// @copydoc url_base::set_encoded_path
0467     url& set_encoded_path(pct_string_view s) { url_base::set_encoded_path(s); return *this; }
0468 
0469     /// @copydoc url_base::set_query
0470     url& set_query(core::string_view s) { url_base::set_query(s); return *this; }
0471     /// @copydoc url_base::set_encoded_query
0472     url& set_encoded_query(pct_string_view s) { url_base::set_encoded_query(s); return *this; }
0473     /// @copydoc url_base::set_params
0474     url& set_params(std::initializer_list<param_view> ps) { url_base::set_params(ps); return *this; }
0475     /// @copydoc url_base::set_encoded_params
0476     url& set_encoded_params(std::initializer_list< param_pct_view > ps) { url_base::set_encoded_params(ps); return *this; }
0477     /// @copydoc url_base::remove_query
0478     url& remove_query() noexcept { url_base::remove_query(); return *this; }
0479 
0480     /// @copydoc url_base::remove_fragment
0481     url& remove_fragment() noexcept { url_base::remove_fragment(); return *this; }
0482     /// @copydoc url_base::set_fragment
0483     url& set_fragment(core::string_view s) { url_base::set_fragment(s); return *this; }
0484     /// @copydoc url_base::set_encoded_fragment
0485     url& set_encoded_fragment(pct_string_view s) { url_base::set_encoded_fragment(s); return *this; }
0486 
0487     /// @copydoc url_base::remove_origin
0488     url& remove_origin() { url_base::remove_origin(); return *this; }
0489 
0490     /// @copydoc url_base::normalize
0491     url& normalize() { url_base::normalize(); return *this; }
0492     /// @copydoc url_base::normalize_scheme
0493     url& normalize_scheme() { url_base::normalize_scheme(); return *this; }
0494     /// @copydoc url_base::normalize_authority
0495     url& normalize_authority() { url_base::normalize_authority(); return *this; }
0496     /// @copydoc url_base::normalize_path
0497     url& normalize_path() { url_base::normalize_path(); return *this; }
0498     /// @copydoc url_base::normalize_query
0499     url& normalize_query() { url_base::normalize_query(); return *this; }
0500     /// @copydoc url_base::normalize_fragment
0501     url& normalize_fragment() { url_base::normalize_fragment(); return *this; }
0502 
0503     //--------------------------------------------
0504 
0505 private:
0506     char* allocate(std::size_t);
0507     void deallocate(char* s);
0508 
0509     void clear_impl() noexcept override;
0510     void reserve_impl(std::size_t, op_t&) override;
0511     void cleanup(op_t&) override;
0512 };
0513 
0514 } // urls
0515 } // boost
0516 
0517 //------------------------------------------------
0518 
0519 // std::hash specialization
0520 #ifndef BOOST_URL_DOCS
0521 namespace std {
0522 template<>
0523 struct hash< ::boost::urls::url >
0524 {
0525     hash() = default;
0526     hash(hash const&) = default;
0527     hash& operator=(hash const&) = default;
0528 
0529     explicit
0530     hash(std::size_t salt) noexcept
0531         : salt_(salt)
0532     {
0533     }
0534 
0535     std::size_t
0536     operator()(::boost::urls::url const& u) const noexcept
0537     {
0538         return u.digest(salt_);
0539     }
0540 
0541 private:
0542     std::size_t salt_ = 0;
0543 };
0544 } // std
0545 #endif
0546 
0547 #endif