LCOV - code coverage report
Current view: top level - boost/url/static_url.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 22 22
Test Date: 2024-08-20 16:05:53 Functions: 70.0 % 50 35

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

Generated by: LCOV version 2.1