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

            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 static_url_base
      53              :     : public url_base
      54              : {
      55              :     template<std::size_t>
      56              :     friend class static_url;
      57              : 
      58           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