LCOV - code coverage report
Current view: top level - url - static_url.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 100.0 % 22 22
Test Date: 2026-02-25 21:00:01 Functions: 74.0 % 50 37 13

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3                 : //
       4                 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5                 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6                 : //
       7                 : // Official repository: https://github.com/boostorg/url
       8                 : //
       9                 : 
      10                 : #ifndef BOOST_URL_STATIC_URL_HPP
      11                 : #define BOOST_URL_STATIC_URL_HPP
      12                 : 
      13                 : #include <boost/url/detail/config.hpp>
      14                 : #include <boost/url/url_base.hpp>
      15                 : #include <boost/align/align_up.hpp>
      16                 : #include <boost/core/detail/static_assert.hpp>
      17                 : #include <cstddef>
      18                 : 
      19                 : namespace boost {
      20                 : namespace urls {
      21                 : 
      22                 : #ifndef BOOST_URL_DOCS
      23                 : template<std::size_t Capacity>
      24                 : class static_url;
      25                 : #endif
      26                 : 
      27                 : // VFALCO This class is for reducing
      28                 : // the number of template instantiations,
      29                 : // and keep definitions in the library
      30                 : 
      31                 : /** Common implementation for all static URLs
      32                 : 
      33                 :     This base class is used by the library
      34                 :     to provide common functionality for
      35                 :     static URLs. Users should not use this
      36                 :     class directly. Instead, construct an
      37                 :     instance of one of the containers
      38                 :     or call a parsing function.
      39                 : 
      40                 :     @par Containers
      41                 :         @li @ref url
      42                 :         @li @ref url_view
      43                 :         @li @ref static_url
      44                 : 
      45                 :     @par Parsing Functions
      46                 :         @li @ref parse_absolute_uri
      47                 :         @li @ref parse_origin_form
      48                 :         @li @ref parse_relative_ref
      49                 :         @li @ref parse_uri
      50                 :         @li @ref parse_uri_reference
      51                 : */
      52                 : class BOOST_SYMBOL_VISIBLE static_url_base
      53                 :     : public url_base
      54                 : {
      55                 :     template<std::size_t>
      56                 :     friend class static_url;
      57                 : 
      58 HIT          39 :     ~static_url_base() = default;
      59                 :     static_url_base(
      60                 :         char* buf, std::size_t cap) noexcept;
      61                 :     static_url_base(
      62                 :         char* buf, std::size_t cap, core::string_view s);
      63                 :     void clear_impl() noexcept override;
      64                 :     void reserve_impl(std::size_t, op_t&) override;
      65                 :     void cleanup(op_t&) override;
      66                 : 
      67                 :     void
      68              32 :     copy(url_view_base const& u)
      69                 :     {
      70              32 :         this->url_base::copy(u);
      71              29 :     }
      72                 : 
      73                 : };
      74                 : 
      75                 : //------------------------------------------------
      76                 : 
      77                 : /** A modifiable container for a URL.
      78                 : 
      79                 :     This container owns a url, represented
      80                 :     by an inline, null-terminated character
      81                 :     buffer with fixed capacity.
      82                 :     The contents may be inspected and modified,
      83                 :     and the implementation maintains a useful
      84                 :     invariant: changes to the url always
      85                 :     leave it in a valid state.
      86                 : 
      87                 :     @par Example
      88                 :     @code
      89                 :     static_url< 1024 > u( "https://www.example.com" );
      90                 :     @endcode
      91                 : 
      92                 :     @par Invariants
      93                 :     @code
      94                 :     this->capacity() == Capacity + 1
      95                 :     @endcode
      96                 : 
      97                 :     @tparam Capacity The maximum capacity
      98                 :     in characters, not including the
      99                 :     null terminator.
     100                 : 
     101                 :     @see
     102                 :         @ref url,
     103                 :         @ref url_view.
     104                 : */
     105                 : template<std::size_t Capacity>
     106                 : class static_url
     107                 :     : public static_url_base
     108                 : {
     109                 :     char buf_[Capacity + 1];
     110                 : 
     111                 :     friend std::hash<static_url>;
     112                 :     using url_view_base::digest;
     113                 : 
     114                 : public:
     115                 :     //--------------------------------------------
     116                 :     //
     117                 :     // Special Members
     118                 :     //
     119                 :     //--------------------------------------------
     120                 : 
     121                 :     /** Destructor
     122                 : 
     123                 :         Any params, segments, iterators, or
     124                 :         views which reference this object are
     125                 :         invalidated. The underlying character
     126                 :         buffer is destroyed, invalidating all
     127                 :         references to it.
     128                 :     */
     129              37 :     ~static_url() = default;
     130                 : 
     131                 :     /** Constructor
     132                 : 
     133                 :         Default constructed urls contain
     134                 :         a zero-length string. This matches
     135                 :         the grammar for a relative-ref with
     136                 :         an empty path and no query or
     137                 :         fragment.
     138                 : 
     139                 :         @par Example
     140                 :         @code
     141                 :         static_url< 1024 > u;
     142                 :         @endcode
     143                 : 
     144                 :         @par Postconditions
     145                 :         @code
     146                 :         this->empty() == true
     147                 :         @endcode
     148                 : 
     149                 :         @par Complexity
     150                 :         Constant.
     151                 : 
     152                 :         @par Exception Safety
     153                 :         Throws nothing.
     154                 : 
     155                 :         @par BNF
     156                 :         @code
     157                 :         relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
     158                 :         @endcode
     159                 : 
     160                 :         @par Specification
     161                 :         <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.2"
     162                 :             >4.2. Relative Reference (rfc3986)</a>
     163                 :     */
     164              21 :     static_url() noexcept
     165                 :         : static_url_base(
     166              21 :             buf_, sizeof(buf_))
     167                 :     {
     168              21 :     }
     169                 : 
     170                 :     /** Constructor
     171                 : 
     172                 :         This function constructs a url from
     173                 :         the string `s`, which must contain a
     174                 :         valid <em>URI</em> or <em>relative-ref</em>
     175                 :         or else an exception is thrown.
     176                 :         The new url retains ownership by
     177                 :         making a copy of the passed string.
     178                 : 
     179                 :         @par Example
     180                 :         @code
     181                 :         static_url< 1024 > u( "https://www.example.com" );
     182                 :         @endcode
     183                 : 
     184                 :         @par Effects
     185                 :         @code
     186                 :         return static_url( parse_uri_reference( s ).value() );
     187                 :         @endcode
     188                 : 
     189                 :         @par Postconditions
     190                 :         @code
     191                 :         this->buffer().data() != s.data()
     192                 :         @endcode
     193                 : 
     194                 :         @par Complexity
     195                 :         Linear in `s.size()`.
     196                 : 
     197                 :         @par Exception Safety
     198                 :         Exceptions thrown on invalid input.
     199                 : 
     200                 :         @throw system_error
     201                 :         The input does not contain a valid url.
     202                 : 
     203                 :         @param s The string to parse.
     204                 : 
     205                 :         @par BNF
     206                 :         @code
     207                 :         URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
     208                 : 
     209                 :         relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
     210                 :         @endcode
     211                 : 
     212                 :         @par Specification
     213                 :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-4.1"
     214                 :             >4.1. URI Reference</a>
     215                 :     */
     216                 :     explicit
     217              18 :     static_url(
     218                 :         core::string_view s)
     219                 :         : static_url_base(
     220              18 :             buf_, sizeof(buf_), s)
     221                 :     {
     222              16 :     }
     223                 : 
     224                 :     /** Constructor
     225                 : 
     226                 :         The newly constructed object contains
     227                 :         a copy of `u`.
     228                 : 
     229                 :         @par Postconditions
     230                 :         @code
     231                 :         this->buffer() == u.buffer() && this->buffer.data() != u.buffer().data()
     232                 :         @endcode
     233                 : 
     234                 :         @par Complexity
     235                 :         Linear in `u.size()`.
     236                 : 
     237                 :         @par Exception Safety
     238                 :         Throws nothing.
     239                 : 
     240                 :         @param u The url to copy.
     241                 :     */
     242               2 :     static_url(
     243                 :         static_url const& u) noexcept
     244               2 :         : static_url()
     245                 :     {
     246               2 :         copy(u);
     247               2 :     }
     248                 : 
     249                 :     /** Constructor
     250                 : 
     251                 :         The newly constructed object contains
     252                 :         a copy of `u`.
     253                 : 
     254                 :         @par Postconditions
     255                 :         @code
     256                 :         this->buffer() == u.buffer() && this->buffer.data() != u.buffer().data()
     257                 :         @endcode
     258                 : 
     259                 :         @par Complexity
     260                 :         Linear in `u.size()`.
     261                 : 
     262                 :         @par Exception Safety
     263                 :         Exception thrown if capacity exceeded.
     264                 : 
     265                 :         @throw system_error
     266                 :         Capacity would be exceeded.
     267                 : 
     268                 :         @param u The url to copy.
     269                 :     */
     270               8 :     static_url(
     271                 :         url_view_base const& u)
     272               8 :         : static_url()
     273                 :     {
     274               8 :         copy(u);
     275               8 :     }
     276                 : 
     277                 :     /** Assignment
     278                 : 
     279                 :         The contents of `u` are copied and
     280                 :         the previous contents of `this` are
     281                 :         discarded.
     282                 :         Capacity remains unchanged.
     283                 : 
     284                 :         @par Postconditions
     285                 :         @code
     286                 :         this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
     287                 :         @endcode
     288                 : 
     289                 :         @par Complexity
     290                 :         Linear in `u.size()`.
     291                 : 
     292                 :         @par Exception Safety
     293                 :         Throws nothing.
     294                 : 
     295                 :         @param u The url to copy.
     296                 :         @return A reference to this object.
     297                 :     */
     298                 :     static_url&
     299                 :     operator=(
     300                 :         static_url const& u) noexcept
     301                 :     {
     302                 :         if (this != &u)
     303                 :             copy(u);
     304                 :         return *this;
     305                 :     }
     306                 : 
     307                 :     /** Assignment
     308                 : 
     309                 :         The contents of `u` are copied and
     310                 :         the previous contents of `this` are
     311                 :         discarded.
     312                 : 
     313                 :         @par Postconditions
     314                 :         @code
     315                 :         this->buffer() == u.buffer() && this->buffer().data() != u.buffer().data()
     316                 :         @endcode
     317                 : 
     318                 :         @par Complexity
     319                 :         Linear in `u.size()`.
     320                 : 
     321                 :         @par Exception Safety
     322                 :         Strong guarantee.
     323                 :         Exception thrown if capacity exceeded.
     324                 : 
     325                 :         @throw system_error
     326                 :         Capacity would be exceeded.
     327                 : 
     328                 :         @param u The url to copy.
     329                 :         @return A reference to this object.
     330                 :     */
     331                 :     static_url&
     332               5 :     operator=(
     333                 :         url_view_base const& u)
     334                 :     {
     335               5 :         copy(u);
     336               4 :         return *this;
     337                 :     }
     338                 : 
     339                 : 
     340                 :     //--------------------------------------------
     341                 :     //
     342                 :     // fluent api
     343                 :     //
     344                 : 
     345                 :     /// @copydoc url_base::set_scheme
     346                 :     static_url& set_scheme(core::string_view s) { url_base::set_scheme(s); return *this; }
     347                 :     /// @copydoc url_base::set_scheme_id
     348                 :     static_url& set_scheme_id(urls::scheme id) { url_base::set_scheme_id(id); return *this; }
     349                 :     /// @copydoc url_base::remove_scheme
     350                 :     static_url& remove_scheme() { url_base::remove_scheme(); return *this; }
     351                 : 
     352                 :     /// @copydoc url_base::set_encoded_authority
     353                 :     static_url& set_encoded_authority(pct_string_view s) { url_base::set_encoded_authority(s); return *this; }
     354                 :     /// @copydoc url_base::remove_authority
     355                 :     static_url& remove_authority() { url_base::remove_authority(); return *this; }
     356                 : 
     357                 :     /// @copydoc url_base::set_userinfo
     358                 :     static_url& set_userinfo(core::string_view s) { url_base::set_userinfo(s); return *this; }
     359                 :     /// @copydoc url_base::set_encoded_userinfo
     360                 :     static_url& set_encoded_userinfo(pct_string_view s) { url_base::set_encoded_userinfo(s); return *this; }
     361                 :     /// @copydoc url_base::remove_userinfo
     362                 :     static_url& remove_userinfo() noexcept { url_base::remove_userinfo(); return *this; }
     363                 :     /// @copydoc url_base::set_user
     364                 :     static_url& set_user(core::string_view s) { url_base::set_user(s); return *this; }
     365                 :     /// @copydoc url_base::set_encoded_user
     366                 :     static_url& set_encoded_user(pct_string_view s) { url_base::set_encoded_user(s); return *this; }
     367                 :     /// @copydoc url_base::set_password
     368                 :     static_url& set_password(core::string_view s) { url_base::set_password(s); return *this; }
     369                 :     /// @copydoc url_base::set_encoded_password
     370                 :     static_url& set_encoded_password(pct_string_view s) { url_base::set_encoded_password(s); return *this; }
     371                 :     /// @copydoc url_base::remove_password
     372                 :     static_url& remove_password() noexcept { url_base::remove_password(); return *this; }
     373                 : 
     374                 :     /// @copydoc url_base::set_host
     375                 :     static_url& set_host(core::string_view s) { url_base::set_host(s); return *this; }
     376                 :     /// @copydoc url_base::set_encoded_host
     377                 :     static_url& set_encoded_host(pct_string_view s) { url_base::set_encoded_host(s); return *this; }
     378                 :     /// @copydoc url_base::set_host_address
     379                 :     static_url& set_host_address(core::string_view s) { url_base::set_host_address(s); return *this; }
     380                 :     /// @copydoc url_base::set_encoded_host_address
     381                 :     static_url& set_encoded_host_address(pct_string_view s) { url_base::set_encoded_host_address(s); return *this; }
     382                 :     /// @copydoc url_base::set_host_ipv4
     383                 :     static_url& set_host_ipv4(ipv4_address const& addr) { url_base::set_host_ipv4(addr); return *this; }
     384                 :     /// @copydoc url_base::set_host_ipv6
     385                 :     static_url& set_host_ipv6(ipv6_address const& addr) { url_base::set_host_ipv6(addr); return *this; }
     386                 :     /// @copydoc url_base::set_zone_id
     387                 :     static_url& set_zone_id(core::string_view s) { url_base::set_zone_id(s); return *this; }
     388                 :     /// @copydoc url_base::set_encoded_zone_id
     389                 :     static_url& set_encoded_zone_id(pct_string_view const& s) { url_base::set_encoded_zone_id(s); return *this; }
     390                 :     /// @copydoc url_base::set_host_ipvfuture
     391                 :     static_url& set_host_ipvfuture(core::string_view s) { url_base::set_host_ipvfuture(s); return *this; }
     392                 :     /// @copydoc url_base::set_host_name
     393                 :     static_url& set_host_name(core::string_view s) { url_base::set_host_name(s); return *this; }
     394                 :     /// @copydoc url_base::set_encoded_host_name
     395                 :     static_url& set_encoded_host_name(pct_string_view s) { url_base::set_encoded_host_name(s); return *this; }
     396                 :     /// @copydoc url_base::set_port_number
     397                 :     static_url& set_port_number(std::uint16_t n) { url_base::set_port_number(n); return *this; }
     398                 :     /// @copydoc url_base::set_port
     399                 :     static_url& set_port(core::string_view s) { url_base::set_port(s); return *this; }
     400                 :     /// @copydoc url_base::remove_port
     401                 :     static_url& remove_port() noexcept { url_base::remove_port(); return *this; }
     402                 : 
     403                 :     /// @copydoc url_base::set_path_absolute
     404                 :     //bool set_path_absolute(bool absolute);
     405                 :     /// @copydoc url_base::set_path
     406                 :     static_url& set_path(core::string_view s) { url_base::set_path(s); return *this; }
     407                 :     /// @copydoc url_base::set_encoded_path
     408                 :     static_url& set_encoded_path(pct_string_view s) { url_base::set_encoded_path(s); return *this; }
     409                 : 
     410                 :     /// @copydoc url_base::set_query
     411                 :     static_url& set_query(core::string_view s) { url_base::set_query(s); return *this; }
     412                 :     /// @copydoc url_base::set_encoded_query
     413                 :     static_url& set_encoded_query(pct_string_view s) { url_base::set_encoded_query(s); return *this; }
     414                 :     /// @copydoc url_base::set_params
     415                 :     static_url& set_params(std::initializer_list<param_view> ps, encoding_opts opts = {}) { url_base::set_params(ps, opts); return *this; }
     416                 :     /// @copydoc url_base::remove_query
     417                 :     static_url& remove_query() noexcept { url_base::remove_query(); return *this; }
     418                 : 
     419                 :     /// @copydoc url_base::remove_fragment
     420                 :     static_url& remove_fragment() noexcept { url_base::remove_fragment(); return *this; }
     421                 :     /// @copydoc url_base::set_fragment
     422                 :     static_url& set_fragment(core::string_view s) { url_base::set_fragment(s); return *this; }
     423                 :     /// @copydoc url_base::set_encoded_fragment
     424                 :     static_url& set_encoded_fragment(pct_string_view s) { url_base::set_encoded_fragment(s); return *this; }
     425                 : 
     426                 :     /// @copydoc url_base::remove_origin
     427                 :     static_url& remove_origin() { url_base::remove_origin(); return *this; }
     428                 : 
     429                 :     /// @copydoc url_base::normalize
     430                 :     static_url& normalize() { url_base::normalize(); return *this; }
     431                 :     /// @copydoc url_base::normalize_scheme
     432                 :     static_url& normalize_scheme() { url_base::normalize_scheme(); return *this; }
     433                 :     /// @copydoc url_base::normalize_authority
     434                 :     static_url& normalize_authority() { url_base::normalize_authority(); return *this; }
     435                 :     /// @copydoc url_base::normalize_path
     436                 :     static_url& normalize_path() { url_base::normalize_path(); return *this; }
     437                 :     /// @copydoc url_base::normalize_query
     438                 :     static_url& normalize_query() { url_base::normalize_query(); return *this; }
     439                 :     /// @copydoc url_base::normalize_fragment
     440                 :     static_url& normalize_fragment() { url_base::normalize_fragment(); return *this; }
     441                 : 
     442                 :     //--------------------------------------------
     443                 : };
     444                 : 
     445                 : } // urls
     446                 : } // boost
     447                 : 
     448                 : //------------------------------------------------
     449                 : 
     450                 : // std::hash specialization
     451                 : #ifndef BOOST_URL_DOCS
     452                 : namespace std {
     453                 : template<std::size_t N>
     454                 : struct hash< ::boost::urls::static_url<N> >
     455                 : {
     456                 :     hash() = default;
     457                 :     hash(hash const&) = default;
     458                 :     hash& operator=(hash const&) = default;
     459                 : 
     460                 :     explicit
     461                 :     hash(std::size_t salt) noexcept
     462                 :         : salt_(salt)
     463                 :     {
     464                 :     }
     465                 : 
     466                 :     std::size_t
     467                 :     operator()(::boost::urls::static_url<N> const& u) const noexcept
     468                 :     {
     469                 :         return u.digest(salt_);
     470                 :     }
     471                 : 
     472                 : private:
     473                 :     std::size_t salt_ = 0;
     474                 : };
     475                 : } // std
     476                 : #endif
     477                 : 
     478                 : #include <boost/url/parse.hpp>
     479                 : #include <boost/url/impl/static_url.hpp>
     480                 : 
     481                 : #endif
        

Generated by: LCOV version 2.3