LCOV - code coverage report
Current view: top level - boost/url - static_url.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 18 22 81.8 %
Date: 2024-01-19 15:42:53 Functions: 33 48 68.8 %

          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          29 :     ~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          24 :     copy(url_view_base const& u)
      70             :     {
      71          24 :         this->url_base::copy(u);
      72          21 :     }
      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
      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          27 :     ~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          14 :     static_url() noexcept
     166             :         : static_url_base(
     167          14 :             buf_, sizeof(buf_))
     168             :     {
     169          14 :     }
     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          15 :     static_url(
     219             :         core::string_view s)
     220             :         : static_url_base(
     221          15 :             buf_, sizeof(buf_), s)
     222             :     {
     223          13 :     }
     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           0 :     static_url(
     244             :         static_url const& u) noexcept
     245           0 :         : static_url()
     246             :     {
     247           0 :         copy(u);
     248           0 :     }
     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           6 :         : static_url()
     274             :     {
     275           5 :         copy(u);
     276           4 :     }
     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::remove_query
     410             :     static_url& remove_query() noexcept { url_base::remove_query(); return *this; }
     411             : 
     412             :     /// @copydoc url_base::remove_fragment
     413             :     static_url& remove_fragment() noexcept { url_base::remove_fragment(); return *this; }
     414             :     /// @copydoc url_base::set_fragment
     415             :     static_url& set_fragment(core::string_view s) { url_base::set_fragment(s); return *this; }
     416             :     /// @copydoc url_base::set_encoded_fragment
     417             :     static_url& set_encoded_fragment(pct_string_view s) { url_base::set_encoded_fragment(s); return *this; }
     418             : 
     419             :     /// @copydoc url_base::remove_origin
     420             :     static_url& remove_origin() { url_base::remove_origin(); return *this; }
     421             : 
     422             :     /// @copydoc url_base::normalize
     423             :     static_url& normalize() { url_base::normalize(); return *this; }
     424             :     /// @copydoc url_base::normalize_scheme
     425             :     static_url& normalize_scheme() { url_base::normalize_scheme(); return *this; }
     426             :     /// @copydoc url_base::normalize_authority
     427             :     static_url& normalize_authority() { url_base::normalize_authority(); return *this; }
     428             :     /// @copydoc url_base::normalize_path
     429             :     static_url& normalize_path() { url_base::normalize_path(); return *this; }
     430             :     /// @copydoc url_base::normalize_query
     431             :     static_url& normalize_query() { url_base::normalize_query(); return *this; }
     432             :     /// @copydoc url_base::normalize_fragment
     433             :     static_url& normalize_fragment() { url_base::normalize_fragment(); return *this; }
     434             : 
     435             :     //--------------------------------------------
     436             : };
     437             : 
     438             : } // urls
     439             : } // boost
     440             : 
     441             : //------------------------------------------------
     442             : 
     443             : // std::hash specialization
     444             : #ifndef BOOST_URL_DOCS
     445             : namespace std {
     446             : template<std::size_t N>
     447             : struct hash< ::boost::urls::static_url<N> >
     448             : {
     449             :     hash() = default;
     450             :     hash(hash const&) = default;
     451             :     hash& operator=(hash const&) = default;
     452             : 
     453             :     explicit
     454             :     hash(std::size_t salt) noexcept
     455             :         : salt_(salt)
     456             :     {
     457             :     }
     458             : 
     459             :     std::size_t
     460             :     operator()(::boost::urls::static_url<N> const& u) const noexcept
     461             :     {
     462             :         return u.digest(salt_);
     463             :     }
     464             : 
     465             : private:
     466             :     std::size_t salt_ = 0;
     467             : };
     468             : } // std
     469             : #endif
     470             : 
     471             : #endif

Generated by: LCOV version 1.15