LCOV - code coverage report
Current view: top level - url - url.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 60 60
Test Date: 2026-02-25 21:00:01 Functions: 100.0 % 49 49

           TLA  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_HPP
      12                 : #define BOOST_URL_URL_HPP
      13                 : 
      14                 : #include <boost/url/detail/config.hpp>
      15                 : #include <boost/url/url_base.hpp>
      16                 : #include <boost/assert.hpp>
      17                 : #include <utility>
      18                 : 
      19                 : namespace boost {
      20                 : namespace urls {
      21                 : 
      22                 : /** A modifiable container for a URL.
      23                 : 
      24                 :     This container owns a url, represented
      25                 :     by a null-terminated character buffer
      26                 :     which is managed by performing dymamic
      27                 :     memory allocations as needed.
      28                 :     The contents may be inspected and modified,
      29                 :     and the implementation maintains a useful
      30                 :     invariant: changes to the url always
      31                 :     leave it in a valid state.
      32                 : 
      33                 :     @par Exception Safety
      34                 : 
      35                 :     @li Functions marked `noexcept` provide the
      36                 :     no-throw guarantee, otherwise:
      37                 : 
      38                 :     @li Functions which throw offer the strong
      39                 :     exception safety guarantee.
      40                 : 
      41                 :     @par BNF
      42                 :     @code
      43                 :     URI-reference = URI / relative-ref
      44                 : 
      45                 :     URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
      46                 : 
      47                 :     relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
      48                 : 
      49                 :     absolute-URI  = scheme ":" hier-part [ "?" query ]
      50                 :     @endcode
      51                 : 
      52                 :     @par Specification
      53                 :     @li <a href="https://tools.ietf.org/html/rfc3986"
      54                 :         >Uniform Resource Identifier (URI): Generic Syntax (rfc3986)</a>
      55                 : 
      56                 :     @see
      57                 :         @ref parse_absolute_uri,
      58                 :         @ref parse_relative_ref,
      59                 :         @ref parse_uri,
      60                 :         @ref parse_uri_reference,
      61                 :         @ref resolve.
      62                 : */
      63                 : class BOOST_SYMBOL_VISIBLE url
      64                 :     : public url_base
      65                 : {
      66                 :     friend std::hash<url>;
      67                 : 
      68                 :     using url_view_base::digest;
      69                 : 
      70                 : public:
      71                 :     //--------------------------------------------
      72                 :     //
      73                 :     // Special Members
      74                 :     //
      75                 :     //--------------------------------------------
      76                 : 
      77                 :     /** Destructor
      78                 : 
      79                 :         Any params, segments, iterators, or
      80                 :         views which reference this object are
      81                 :         invalidated. The underlying character
      82                 :         buffer is destroyed, invalidating all
      83                 :         references to it.
      84                 :     */
      85                 :     virtual ~url();
      86                 : 
      87                 :     /** Constructor
      88                 : 
      89                 :         Default constructed urls contain
      90                 :         a zero-length string. This matches
      91                 :         the grammar for a relative-ref with
      92                 :         an empty path and no query or
      93                 :         fragment.
      94                 : 
      95                 :         @par Example
      96                 :         @code
      97                 :         url u;
      98                 :         @endcode
      99                 : 
     100                 :         @par Postconditions
     101                 :         @code
     102                 :         this->empty() == true
     103                 :         @endcode
     104                 : 
     105                 :         @par Complexity
     106                 :         Constant.
     107                 : 
     108                 :         @par Exception Safety
     109                 :         Throws nothing.
     110                 : 
     111                 :         @par BNF
     112                 :         @code
     113                 :         relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
     114                 :         @endcode
     115                 : 
     116                 :         @par Specification
     117                 :         <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2"
     118                 :             >4.2. Relative Reference (rfc3986)</a>
     119                 :     */
     120                 :     url() noexcept;
     121                 : 
     122                 :     /** Constructor
     123                 : 
     124                 :         This function constructs a URL from
     125                 :         the string `s`, which must contain a
     126                 :         valid <em>URI</em> or <em>relative-ref</em>
     127                 :         or else an exception is thrown.
     128                 :         The new url retains ownership by
     129                 :         allocating a copy of the passed string.
     130                 : 
     131                 :         @par Example
     132                 :         @code
     133                 :         url u( "https://www.example.com" );
     134                 :         @endcode
     135                 : 
     136                 :         @par Effects
     137                 :         @code
     138                 :         return url( parse_uri_reference( s ).value() );
     139                 :         @endcode
     140                 : 
     141                 :         @par Postconditions
     142                 :         @code
     143                 :         this->buffer().data() != s.data()
     144                 :         @endcode
     145                 : 
     146                 :         @par Complexity
     147                 :         Linear in `s.size()`.
     148                 : 
     149                 :         @par Exception Safety
     150                 :         Calls to allocate may throw.
     151                 :         Exceptions thrown on invalid input.
     152                 : 
     153                 :         @throw system_error
     154                 :         The input does not contain a valid url.
     155                 : 
     156                 :         @param s The string to parse.
     157                 : 
     158                 :         @par BNF
     159                 :         @code
     160                 :         URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
     161                 : 
     162                 :         relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
     163                 :         @endcode
     164                 : 
     165                 :         @par Specification
     166                 :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.1"
     167                 :             >4.1. URI Reference</a>
     168                 :     */
     169                 :     explicit
     170                 :     url(core::string_view s);
     171                 : 
     172                 :     /** Constructor
     173                 : 
     174                 :         The contents of `u` are transferred
     175                 :         to the newly constructed object,
     176                 :         which includes the underlying
     177                 :         character buffer.
     178                 :         After construction, the moved-from
     179                 :         object is as if default constructed.
     180                 : 
     181                 :         @par Postconditions
     182                 :         @code
     183                 :         u.empty() == true
     184                 :         @endcode
     185                 : 
     186                 :         @par Complexity
     187                 :         Constant.
     188                 : 
     189                 :         @par Exception Safety
     190                 :         Throws nothing.
     191                 : 
     192                 :         @param u The url to move from.
     193                 :     */
     194                 :     url(url&& u) noexcept;
     195                 : 
     196                 :     /** Constructor
     197                 : 
     198                 :         The newly constructed object
     199                 :         contains a copy of `u`.
     200                 : 
     201                 :         @par Postconditions
     202                 :         @code
     203                 :         this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
     204                 :         @endcode
     205                 : 
     206                 :         @par Complexity
     207                 :         Linear in `u.size()`.
     208                 : 
     209                 :         @par Exception Safety
     210                 :         Strong guarantee.
     211                 :         Calls to allocate may throw.
     212                 : 
     213                 :         @throw std::length_error `u.size() > max_size()`.
     214                 : 
     215                 :         @param u The url to copy.
     216                 :     */
     217 HIT        2998 :     url(url_view_base const& u)
     218            2998 :     {
     219            2998 :         copy(u);
     220            2998 :     }
     221                 : 
     222                 :     /** Constructor
     223                 : 
     224                 :         The newly constructed object
     225                 :         contains a copy of `u`.
     226                 : 
     227                 :         @par Postconditions
     228                 :         @code
     229                 :         this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
     230                 :         @endcode
     231                 : 
     232                 :         @par Complexity
     233                 :         Linear in `u.size()`.
     234                 : 
     235                 :         @par Exception Safety
     236                 :         Strong guarantee.
     237                 :         Calls to allocate may throw.
     238                 : 
     239                 :         @throw std::length_error `u.size() > max_size()`.
     240                 : 
     241                 :         @param u The url to copy.
     242                 :     */
     243             259 :     url(url const& u)
     244             259 :         : url(static_cast<
     245             259 :             url_view_base const&>(u))
     246                 :     {
     247             259 :     }
     248                 : 
     249                 :     /** Assignment
     250                 : 
     251                 :         The contents of `u` are transferred to
     252                 :         `this`, including the underlying
     253                 :         character buffer. The previous contents
     254                 :         of `this` are destroyed.
     255                 :         After assignment, the moved-from
     256                 :         object is as if default constructed.
     257                 : 
     258                 :         @par Postconditions
     259                 :         @code
     260                 :         u.empty() == true
     261                 :         @endcode
     262                 : 
     263                 :         @par Complexity
     264                 :         Constant.
     265                 : 
     266                 :         @par Exception Safety
     267                 :         Throws nothing.
     268                 : 
     269                 :         @param u The url to assign from.
     270                 :         @return A reference to this object.
     271                 :     */
     272                 :     url&
     273                 :     operator=(url&& u) noexcept;
     274                 : 
     275                 :     /** Assignment
     276                 : 
     277                 :         The contents of `u` are copied and
     278                 :         the previous contents of `this` are
     279                 :         destroyed.
     280                 :         Capacity is preserved, or increases.
     281                 : 
     282                 :         @par Postconditions
     283                 :         @code
     284                 :         this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
     285                 :         @endcode
     286                 : 
     287                 :         @par Complexity
     288                 :         Linear in `u.size()`.
     289                 : 
     290                 :         @par Exception Safety
     291                 :         Strong guarantee.
     292                 :         Calls to allocate may throw.
     293                 : 
     294                 :         @throw std::length_error `u.size() > max_size()`.
     295                 : 
     296                 :         @param u The url to copy.
     297                 :         @return A reference to this object.
     298                 :     */
     299                 :     url&
     300             100 :     operator=(
     301                 :         url_view_base const& u)
     302                 :     {
     303             100 :         copy(u);
     304             100 :         return *this;
     305                 :     }
     306                 : 
     307                 :     /** Assignment
     308                 : 
     309                 :         The contents of `u` are copied and
     310                 :         the previous contents of `this` are
     311                 :         destroyed.
     312                 :         Capacity is preserved, or increases.
     313                 : 
     314                 :         @par Postconditions
     315                 :         @code
     316                 :         this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
     317                 :         @endcode
     318                 : 
     319                 :         @par Complexity
     320                 :         Linear in `u.size()`.
     321                 : 
     322                 :         @par Exception Safety
     323                 :         Strong guarantee.
     324                 :         Calls to allocate may throw.
     325                 : 
     326                 :         @param u The url to copy.
     327                 :         @return A reference to this object.
     328                 :     */
     329                 :     url&
     330               1 :     operator=(url const& u)
     331                 :     {
     332                 :         return (*this)=static_cast<
     333               1 :             url_view_base const&>(u);
     334                 :     }
     335                 : 
     336                 :     //--------------------------------------------
     337                 : 
     338                 :     /** Swap the contents.
     339                 : 
     340                 :         Exchanges the contents of this url with another
     341                 :         url. All views, iterators and references remain valid.
     342                 : 
     343                 :         If `this == &other`, this function call has no effect.
     344                 : 
     345                 :         @par Example
     346                 :         @code
     347                 :         url u1( "https://www.example.com" );
     348                 :         url u2( "https://www.boost.org" );
     349                 :         u1.swap(u2);
     350                 :         assert(u1 == "https://www.boost.org" );
     351                 :         assert(u2 == "https://www.example.com" );
     352                 :         @endcode
     353                 : 
     354                 :         @par Complexity
     355                 :         Constant
     356                 : 
     357                 :         @par Exception Safety
     358                 :         Throws nothing.
     359                 : 
     360                 :         @param other The object to swap with
     361                 : 
     362                 :     */
     363                 :     void
     364                 :     swap(url& other) noexcept;
     365                 : 
     366                 :     /** Swap
     367                 : 
     368                 :         Exchanges the contents of `v0` with another `v1`.
     369                 :         All views, iterators and references remain
     370                 :         valid.
     371                 : 
     372                 :         If `&v0 == &v1`, this function call has no effect.
     373                 : 
     374                 :         @par Example
     375                 :         @code
     376                 :         url u1( "https://www.example.com" );
     377                 :         url u2( "https://www.boost.org" );
     378                 :         std::swap(u1, u2);
     379                 :         assert(u1 == "https://www.boost.org" );
     380                 :         assert(u2 == "https://www.example.com" );
     381                 :         @endcode
     382                 : 
     383                 :         @par Effects
     384                 :         @code
     385                 :         v0.swap( v1 );
     386                 :         @endcode
     387                 : 
     388                 :         @par Complexity
     389                 :         Constant
     390                 : 
     391                 :         @par Exception Safety
     392                 :         Throws nothing
     393                 : 
     394                 :         @param v0 The first object to swap
     395                 :         @param v1 The second object to swap
     396                 : 
     397                 :         @see
     398                 :             @ref url::swap
     399                 :     */
     400                 :     friend
     401                 :     void
     402               2 :     swap(url& v0, url& v1) noexcept
     403                 :     {
     404               2 :         v0.swap(v1);
     405               2 :     }
     406                 : 
     407                 :     //--------------------------------------------
     408                 :     //
     409                 :     // fluent api
     410                 :     //
     411                 : 
     412                 :     /// @copydoc url_base::set_scheme
     413              55 :     url& set_scheme(core::string_view s) { url_base::set_scheme(s); return *this; }
     414                 :     /// @copydoc url_base::set_scheme_id
     415              13 :     url& set_scheme_id(urls::scheme id) { url_base::set_scheme_id(id); return *this; }
     416                 :     /// @copydoc url_base::remove_scheme
     417              21 :     url& remove_scheme() { url_base::remove_scheme(); return *this; }
     418                 : 
     419                 :     /// @copydoc url_base::set_encoded_authority
     420              41 :     url& set_encoded_authority(pct_string_view s) { url_base::set_encoded_authority(s); return *this; }
     421                 :     /// @copydoc url_base::remove_authority
     422              43 :     url& remove_authority() { url_base::remove_authority(); return *this; }
     423                 : 
     424                 :     /// @copydoc url_base::set_userinfo
     425              45 :     url& set_userinfo(core::string_view s) { url_base::set_userinfo(s); return *this; }
     426                 :     /// @copydoc url_base::set_encoded_userinfo
     427              51 :     url& set_encoded_userinfo(pct_string_view s) { url_base::set_encoded_userinfo(s); return *this; }
     428                 :     /// @copydoc url_base::remove_userinfo
     429              24 :     url& remove_userinfo() noexcept { url_base::remove_userinfo(); return *this; }
     430                 :     /// @copydoc url_base::set_user
     431               1 :     url& set_user(core::string_view s) { url_base::set_user(s); return *this; }
     432                 :     /// @copydoc url_base::set_encoded_user
     433              17 :     url& set_encoded_user(pct_string_view s) { url_base::set_encoded_user(s); return *this; }
     434                 :     /// @copydoc url_base::set_password
     435              35 :     url& set_password(core::string_view s) { url_base::set_password(s); return *this; }
     436                 :     /// @copydoc url_base::set_encoded_password
     437              38 :     url& set_encoded_password(pct_string_view s) { url_base::set_encoded_password(s); return *this; }
     438                 :     /// @copydoc url_base::remove_password
     439              19 :     url& remove_password() noexcept { url_base::remove_password(); return *this; }
     440                 : 
     441                 :     /// @copydoc url_base::set_host
     442              16 :     url& set_host(core::string_view s) { url_base::set_host(s); return *this; }
     443                 :     /// @copydoc url_base::set_encoded_host
     444             117 :     url& set_encoded_host(pct_string_view s) { url_base::set_encoded_host(s); return *this; }
     445                 :     /// @copydoc url_base::set_host_address
     446              10 :     url& set_host_address(core::string_view s) { url_base::set_host_address(s); return *this; }
     447                 :     /// @copydoc url_base::set_encoded_host_address
     448               8 :     url& set_encoded_host_address(pct_string_view s) { url_base::set_encoded_host_address(s); return *this; }
     449                 :     /// @copydoc url_base::set_host_ipv4
     450               6 :     url& set_host_ipv4(ipv4_address const& addr) { url_base::set_host_ipv4(addr); return *this; }
     451                 :     /// @copydoc url_base::set_host_ipv6
     452               5 :     url& set_host_ipv6(ipv6_address const& addr) { url_base::set_host_ipv6(addr); return *this; }
     453                 :     /// @copydoc url_base::set_zone_id
     454               3 :     url& set_zone_id(core::string_view s) { url_base::set_zone_id(s); return *this; }
     455                 :     /// @copydoc url_base::set_encoded_zone_id
     456               3 :     url& set_encoded_zone_id(pct_string_view const& s) { url_base::set_encoded_zone_id(s); return *this; }
     457                 :     /// @copydoc url_base::set_host_ipvfuture
     458               3 :     url& set_host_ipvfuture(core::string_view s) { url_base::set_host_ipvfuture(s); return *this; }
     459                 :     /// @copydoc url_base::set_host_name
     460               4 :     url& set_host_name(core::string_view s) { url_base::set_host_name(s); return *this; }
     461                 :     /// @copydoc url_base::set_encoded_host_name
     462               4 :     url& set_encoded_host_name(pct_string_view s) { url_base::set_encoded_host_name(s); return *this; }
     463                 :     /// @copydoc url_base::set_port_number
     464              25 :     url& set_port_number(std::uint16_t n) { url_base::set_port_number(n); return *this; }
     465                 :     /// @copydoc url_base::set_port
     466              89 :     url& set_port(core::string_view s) { url_base::set_port(s); return *this; }
     467                 :     /// @copydoc url_base::remove_port
     468              25 :     url& remove_port() noexcept { url_base::remove_port(); return *this; }
     469                 : 
     470                 :     /// @copydoc url_base::set_path_absolute
     471                 :     //bool set_path_absolute(bool absolute);
     472                 :     /// @copydoc url_base::set_path
     473              25 :     url& set_path(core::string_view s) { url_base::set_path(s); return *this; }
     474                 :     /// @copydoc url_base::set_encoded_path
     475              62 :     url& set_encoded_path(pct_string_view s) { url_base::set_encoded_path(s); return *this; }
     476                 : 
     477                 :     /// @copydoc url_base::set_query
     478              10 :     url& set_query(core::string_view s) { url_base::set_query(s); return *this; }
     479                 :     /// @copydoc url_base::set_encoded_query
     480              20 :     url& set_encoded_query(pct_string_view s) { url_base::set_encoded_query(s); return *this; }
     481                 :     /// @copydoc url_base::set_params
     482               1 :     url& set_params(std::initializer_list<param_view> ps, encoding_opts opts = {}) { url_base::set_params(ps, opts); return *this; }
     483                 :     /// @copydoc url_base::set_encoded_params
     484               1 :     url& set_encoded_params(std::initializer_list< param_pct_view > ps) { url_base::set_encoded_params(ps); return *this; }
     485                 :     /// @copydoc url_base::remove_query
     486               7 :     url& remove_query() noexcept { url_base::remove_query(); return *this; }
     487                 : 
     488                 :     /// @copydoc url_base::remove_fragment
     489               5 :     url& remove_fragment() noexcept { url_base::remove_fragment(); return *this; }
     490                 :     /// @copydoc url_base::set_fragment
     491               6 :     url& set_fragment(core::string_view s) { url_base::set_fragment(s); return *this; }
     492                 :     /// @copydoc url_base::set_encoded_fragment
     493              21 :     url& set_encoded_fragment(pct_string_view s) { url_base::set_encoded_fragment(s); return *this; }
     494                 : 
     495                 :     /// @copydoc url_base::remove_origin
     496              14 :     url& remove_origin() { url_base::remove_origin(); return *this; }
     497                 : 
     498                 :     /// @copydoc url_base::normalize
     499              47 :     url& normalize() { url_base::normalize(); return *this; }
     500                 :     /// @copydoc url_base::normalize_scheme
     501               3 :     url& normalize_scheme() { url_base::normalize_scheme(); return *this; }
     502                 :     /// @copydoc url_base::normalize_authority
     503             349 :     url& normalize_authority() { url_base::normalize_authority(); return *this; }
     504                 :     /// @copydoc url_base::normalize_path
     505             370 :     url& normalize_path() { url_base::normalize_path(); return *this; }
     506                 :     /// @copydoc url_base::normalize_query
     507               4 :     url& normalize_query() { url_base::normalize_query(); return *this; }
     508                 :     /// @copydoc url_base::normalize_fragment
     509               1 :     url& normalize_fragment() { url_base::normalize_fragment(); return *this; }
     510                 : 
     511                 :     //--------------------------------------------
     512                 : 
     513                 : private:
     514                 :     char* allocate(std::size_t);
     515                 :     void deallocate(char* s);
     516                 : 
     517                 :     void clear_impl() noexcept override;
     518                 :     void reserve_impl(std::size_t, op_t&) override;
     519                 :     void cleanup(op_t&) override;
     520                 : };
     521                 : 
     522                 : } // urls
     523                 : } // boost
     524                 : 
     525                 : //------------------------------------------------
     526                 : 
     527                 : // std::hash specialization
     528                 : #ifndef BOOST_URL_DOCS
     529                 : namespace std {
     530                 : template<>
     531                 : struct hash< ::boost::urls::url >
     532                 : {
     533                 :     hash() = default;
     534                 :     hash(hash const&) = default;
     535                 :     hash& operator=(hash const&) = default;
     536                 : 
     537                 :     explicit
     538                 :     hash(std::size_t salt) noexcept
     539                 :         : salt_(salt)
     540                 :     {
     541                 :     }
     542                 : 
     543                 :     std::size_t
     544                 :     operator()(::boost::urls::url const& u) const noexcept
     545                 :     {
     546                 :         return u.digest(salt_);
     547                 :     }
     548                 : 
     549                 : private:
     550                 :     std::size_t salt_ = 0;
     551                 : };
     552                 : } // std
     553                 : #endif
     554                 : 
     555                 : #include <boost/url/parse.hpp>
     556                 : #include <boost/url/impl/url.hpp>
     557                 : 
     558                 : #endif
        

Generated by: LCOV version 2.3