Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 08:52:47

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         @return A reference to this object.
0271     */
0272     url&
0273     operator=(url&& u) noexcept;
0274 
0275     /** Assignment
0276 
0277         The contents of `u` are copied and
0278         the previous contents of `this` are
0279         destroyed.
0280         Capacity is preserved, or increases.
0281 
0282         @par Postconditions
0283         @code
0284         this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
0285         @endcode
0286 
0287         @par Complexity
0288         Linear in `u.size()`.
0289 
0290         @par Exception Safety
0291         Strong guarantee.
0292         Calls to allocate may throw.
0293 
0294         @throw std::length_error `u.size() > max_size()`.
0295 
0296         @param u The url to copy.
0297         @return A reference to this object.
0298     */
0299     url&
0300     operator=(
0301         url_view_base const& u)
0302     {
0303         copy(u);
0304         return *this;
0305     }
0306 
0307     /** Assignment
0308 
0309         The contents of `u` are copied and
0310         the previous contents of `this` are
0311         destroyed.
0312         Capacity is preserved, or increases.
0313 
0314         @par Postconditions
0315         @code
0316         this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
0317         @endcode
0318 
0319         @par Complexity
0320         Linear in `u.size()`.
0321 
0322         @par Exception Safety
0323         Strong guarantee.
0324         Calls to allocate may throw.
0325 
0326         @param u The url to copy.
0327         @return A reference to this object.
0328     */
0329     url&
0330     operator=(url const& u)
0331     {
0332         return (*this)=static_cast<
0333             url_view_base const&>(u);
0334     }
0335 
0336     //--------------------------------------------
0337 
0338     /** Swap the contents.
0339 
0340         Exchanges the contents of this url with another
0341         url. All views, iterators and references remain valid.
0342 
0343         If `this == &other`, this function call has no effect.
0344 
0345         @par Example
0346         @code
0347         url u1( "https://www.example.com" );
0348         url u2( "https://www.boost.org" );
0349         u1.swap(u2);
0350         assert(u1 == "https://www.boost.org" );
0351         assert(u2 == "https://www.example.com" );
0352         @endcode
0353 
0354         @par Complexity
0355         Constant
0356 
0357         @par Exception Safety
0358         Throws nothing.
0359 
0360         @param other The object to swap with
0361 
0362     */
0363     void
0364     swap(url& other) noexcept;
0365 
0366     /** Swap
0367 
0368         Exchanges the contents of `v0` with another `v1`.
0369         All views, iterators and references remain
0370         valid.
0371 
0372         If `&v0 == &v1`, this function call has no effect.
0373 
0374         @par Example
0375         @code
0376         url u1( "https://www.example.com" );
0377         url u2( "https://www.boost.org" );
0378         std::swap(u1, u2);
0379         assert(u1 == "https://www.boost.org" );
0380         assert(u2 == "https://www.example.com" );
0381         @endcode
0382 
0383         @par Effects
0384         @code
0385         v0.swap( v1 );
0386         @endcode
0387 
0388         @par Complexity
0389         Constant
0390 
0391         @par Exception Safety
0392         Throws nothing
0393 
0394         @param v0 The first object to swap
0395         @param v1 The second object to swap
0396 
0397         @see
0398             @ref url::swap
0399     */
0400     friend
0401     void
0402     swap(url& v0, url& v1) noexcept
0403     {
0404         v0.swap(v1);
0405     }
0406 
0407     //--------------------------------------------
0408     //
0409     // fluent api
0410     //
0411 
0412     /// @copydoc url_base::set_scheme
0413     url& set_scheme(core::string_view s) { url_base::set_scheme(s); return *this; }
0414     /// @copydoc url_base::set_scheme_id
0415     url& set_scheme_id(urls::scheme id) { url_base::set_scheme_id(id); return *this; }
0416     /// @copydoc url_base::remove_scheme
0417     url& remove_scheme() { url_base::remove_scheme(); return *this; }
0418 
0419     /// @copydoc url_base::set_encoded_authority
0420     url& set_encoded_authority(pct_string_view s) { url_base::set_encoded_authority(s); return *this; }
0421     /// @copydoc url_base::remove_authority
0422     url& remove_authority() { url_base::remove_authority(); return *this; }
0423 
0424     /// @copydoc url_base::set_userinfo
0425     url& set_userinfo(core::string_view s) { url_base::set_userinfo(s); return *this; }
0426     /// @copydoc url_base::set_encoded_userinfo
0427     url& set_encoded_userinfo(pct_string_view s) { url_base::set_encoded_userinfo(s); return *this; }
0428     /// @copydoc url_base::remove_userinfo
0429     url& remove_userinfo() noexcept { url_base::remove_userinfo(); return *this; }
0430     /// @copydoc url_base::set_user
0431     url& set_user(core::string_view s) { url_base::set_user(s); return *this; }
0432     /// @copydoc url_base::set_encoded_user
0433     url& set_encoded_user(pct_string_view s) { url_base::set_encoded_user(s); return *this; }
0434     /// @copydoc url_base::set_password
0435     url& set_password(core::string_view s) { url_base::set_password(s); return *this; }
0436     /// @copydoc url_base::set_encoded_password
0437     url& set_encoded_password(pct_string_view s) { url_base::set_encoded_password(s); return *this; }
0438     /// @copydoc url_base::remove_password
0439     url& remove_password() noexcept { url_base::remove_password(); return *this; }
0440 
0441     /// @copydoc url_base::set_host
0442     url& set_host(core::string_view s) { url_base::set_host(s); return *this; }
0443     /// @copydoc url_base::set_encoded_host
0444     url& set_encoded_host(pct_string_view s) { url_base::set_encoded_host(s); return *this; }
0445     /// @copydoc url_base::set_host_address
0446     url& set_host_address(core::string_view s) { url_base::set_host_address(s); return *this; }
0447     /// @copydoc url_base::set_encoded_host_address
0448     url& set_encoded_host_address(pct_string_view s) { url_base::set_encoded_host_address(s); return *this; }
0449     /// @copydoc url_base::set_host_ipv4
0450     url& set_host_ipv4(ipv4_address const& addr) { url_base::set_host_ipv4(addr); return *this; }
0451     /// @copydoc url_base::set_host_ipv6
0452     url& set_host_ipv6(ipv6_address const& addr) { url_base::set_host_ipv6(addr); return *this; }
0453     /// @copydoc url_base::set_host_ipvfuture
0454     url& set_host_ipvfuture(core::string_view s) { url_base::set_host_ipvfuture(s); return *this; }
0455     /// @copydoc url_base::set_host_name
0456     url& set_host_name(core::string_view s) { url_base::set_host_name(s); return *this; }
0457     /// @copydoc url_base::set_encoded_host_name
0458     url& set_encoded_host_name(pct_string_view s) { url_base::set_encoded_host_name(s); return *this; }
0459     /// @copydoc url_base::set_port_number
0460     url& set_port_number(std::uint16_t n) { url_base::set_port_number(n); return *this; }
0461     /// @copydoc url_base::set_port
0462     url& set_port(core::string_view s) { url_base::set_port(s); return *this; }
0463     /// @copydoc url_base::remove_port
0464     url& remove_port() noexcept { url_base::remove_port(); return *this; }
0465 
0466     /// @copydoc url_base::set_path_absolute
0467     //bool set_path_absolute(bool absolute);
0468     /// @copydoc url_base::set_path
0469     url& set_path(core::string_view s) { url_base::set_path(s); return *this; }
0470     /// @copydoc url_base::set_encoded_path
0471     url& set_encoded_path(pct_string_view s) { url_base::set_encoded_path(s); return *this; }
0472 
0473     /// @copydoc url_base::set_query
0474     url& set_query(core::string_view s) { url_base::set_query(s); return *this; }
0475     /// @copydoc url_base::set_encoded_query
0476     url& set_encoded_query(pct_string_view s) { url_base::set_encoded_query(s); return *this; }
0477     /// @copydoc url_base::set_params
0478     url& set_params(std::initializer_list<param_view> ps, encoding_opts opts = {}) { url_base::set_params(ps, opts); return *this; }
0479     /// @copydoc url_base::set_encoded_params
0480     url& set_encoded_params(std::initializer_list< param_pct_view > ps) { url_base::set_encoded_params(ps); return *this; }
0481     /// @copydoc url_base::remove_query
0482     url& remove_query() noexcept { url_base::remove_query(); return *this; }
0483 
0484     /// @copydoc url_base::remove_fragment
0485     url& remove_fragment() noexcept { url_base::remove_fragment(); return *this; }
0486     /// @copydoc url_base::set_fragment
0487     url& set_fragment(core::string_view s) { url_base::set_fragment(s); return *this; }
0488     /// @copydoc url_base::set_encoded_fragment
0489     url& set_encoded_fragment(pct_string_view s) { url_base::set_encoded_fragment(s); return *this; }
0490 
0491     /// @copydoc url_base::remove_origin
0492     url& remove_origin() { url_base::remove_origin(); return *this; }
0493 
0494     /// @copydoc url_base::normalize
0495     url& normalize() { url_base::normalize(); return *this; }
0496     /// @copydoc url_base::normalize_scheme
0497     url& normalize_scheme() { url_base::normalize_scheme(); return *this; }
0498     /// @copydoc url_base::normalize_authority
0499     url& normalize_authority() { url_base::normalize_authority(); return *this; }
0500     /// @copydoc url_base::normalize_path
0501     url& normalize_path() { url_base::normalize_path(); return *this; }
0502     /// @copydoc url_base::normalize_query
0503     url& normalize_query() { url_base::normalize_query(); return *this; }
0504     /// @copydoc url_base::normalize_fragment
0505     url& normalize_fragment() { url_base::normalize_fragment(); return *this; }
0506 
0507     //--------------------------------------------
0508 
0509 private:
0510     char* allocate(std::size_t);
0511     void deallocate(char* s);
0512 
0513     void clear_impl() noexcept override;
0514     void reserve_impl(std::size_t, op_t&) override;
0515     void cleanup(op_t&) override;
0516 };
0517 
0518 } // urls
0519 } // boost
0520 
0521 //------------------------------------------------
0522 
0523 // std::hash specialization
0524 #ifndef BOOST_URL_DOCS
0525 namespace std {
0526 template<>
0527 struct hash< ::boost::urls::url >
0528 {
0529     hash() = default;
0530     hash(hash const&) = default;
0531     hash& operator=(hash const&) = default;
0532 
0533     explicit
0534     hash(std::size_t salt) noexcept
0535         : salt_(salt)
0536     {
0537     }
0538 
0539     std::size_t
0540     operator()(::boost::urls::url const& u) const noexcept
0541     {
0542         return u.digest(salt_);
0543     }
0544 
0545 private:
0546     std::size_t salt_ = 0;
0547 };
0548 } // std
0549 #endif
0550 
0551 #endif