LCOV - code coverage report
Current view: top level - boost/url/pct_string_view.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 25 25
Test Date: 2024-07-10 02:48:26 Functions: 92.9 % 42 39

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2022 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_PCT_STRING_VIEW_HPP
      11              : #define BOOST_URL_PCT_STRING_VIEW_HPP
      12              : 
      13              : #include <boost/url/detail/config.hpp>
      14              : #include <boost/url/encoding_opts.hpp>
      15              : #include <boost/url/error_types.hpp>
      16              : #include <boost/core/detail/string_view.hpp>
      17              : #include <boost/url/grammar/string_token.hpp>
      18              : #include <boost/url/grammar/string_view_base.hpp>
      19              : #include <cstddef>
      20              : #include <iterator>
      21              : #include <string>
      22              : #include <type_traits>
      23              : #include <utility>
      24              : 
      25              : namespace boost {
      26              : namespace urls {
      27              : 
      28              : //------------------------------------------------
      29              : 
      30              : #ifndef BOOST_URL_DOCS
      31              : class decode_view;
      32              : class pct_string_view;
      33              : 
      34              : pct_string_view
      35              : make_pct_string_view_unsafe(
      36              :     char const*, std::size_t,
      37              :         std::size_t) noexcept;
      38              : 
      39              : namespace detail {
      40              : core::string_view&
      41              : ref(pct_string_view& s) noexcept;
      42              : } // detail
      43              : #endif
      44              : 
      45              : //------------------------------------------------
      46              : 
      47              : /** A reference to a valid percent-encoded string
      48              : 
      49              :     Objects of this type behave like a
      50              :     `core::string_view` and have the same interface,
      51              :     but offer an additional invariant: they can
      52              :     only be constructed from strings containing
      53              :     valid percent-escapes.
      54              : 
      55              :     Attempting construction from a string
      56              :     containing invalid or malformed percent
      57              :     escapes results in an exception.
      58              : 
      59              :     @par Operators
      60              :     The following operators are supported between
      61              :     @ref pct_string_view and any object that is
      62              :     convertible to `core::string_view`
      63              : 
      64              :     @code
      65              :     bool operator==( pct_string_view, pct_string_view ) noexcept;
      66              :     bool operator!=( pct_string_view, pct_string_view ) noexcept;
      67              :     bool operator<=( pct_string_view, pct_string_view ) noexcept;
      68              :     bool operator< ( pct_string_view, pct_string_view ) noexcept;
      69              :     bool operator> ( pct_string_view, pct_string_view ) noexcept;
      70              :     bool operator>=( pct_string_view, pct_string_view ) noexcept;
      71              :     @endcode
      72              : */
      73              : class pct_string_view final
      74              :     : public grammar::string_view_base
      75              : {
      76              :     std::size_t dn_ = 0;
      77              : 
      78              : #ifndef BOOST_URL_DOCS
      79              :     friend
      80              :     pct_string_view
      81              :     make_pct_string_view_unsafe(
      82              :         char const*, std::size_t,
      83              :             std::size_t) noexcept;
      84              : 
      85              :     friend
      86              :     core::string_view&
      87              :     detail::ref(pct_string_view&) noexcept;
      88              : #endif
      89              : 
      90              :     // unsafe
      91        34583 :     pct_string_view(
      92              :         char const* data,
      93              :         std::size_t size,
      94              :         std::size_t dn) noexcept
      95        34583 :         : string_view_base(data, size)
      96        34583 :         , dn_(dn)
      97              :     {
      98        34583 :     }
      99              : 
     100              :     BOOST_URL_DECL
     101              :     void
     102              :     decode_impl(
     103              :         string_token::arg& dest,
     104              :         encoding_opts opt) const;
     105              : 
     106              : public:
     107              :     /** Constructor
     108              : 
     109              :         Default constructed string are empty.
     110              : 
     111              :         @par Complexity
     112              :         Constant.
     113              : 
     114              :         @par Exception Safety
     115              :         Throws nothing.
     116              :     */
     117        16491 :     constexpr pct_string_view() = default;
     118              : 
     119              :     /** Constructor
     120              : 
     121              :         The copy references the same
     122              :         underlying character buffer.
     123              :         Ownership is not transferred.
     124              : 
     125              :         @par Postconditions
     126              :         @code
     127              :         this->data() == other.data()
     128              :         @endcode
     129              : 
     130              :         @par Complexity
     131              :         Constant.
     132              : 
     133              :         @par Exception Safety
     134              :         Throws nothing.
     135              : 
     136              :         @par other The string to copy.
     137              :     */
     138              :     constexpr
     139              :     pct_string_view(
     140              :         pct_string_view const& other) = default;
     141              : 
     142              :     /** Constructor
     143              : 
     144              :         The newly constructed string references
     145              :         the specified character buffer.
     146              :         Ownership is not transferred.
     147              : 
     148              :         @par Postconditions
     149              :         @code
     150              :         this->data() == core::string_view(s).data()
     151              :         @endcode
     152              : 
     153              :         @par Complexity
     154              :         Linear in `core::string_view(s).size()`.
     155              : 
     156              :         @par Exception Safety
     157              :         Exceptions thrown on invalid input.
     158              : 
     159              :         @throw system_error
     160              :         The string contains an invalid percent encoding.
     161              : 
     162              :         @tparam String A type convertible to `core::string_view`
     163              : 
     164              :         @param s The string to construct from.
     165              :     */
     166              :     template<
     167              :         class String
     168              : #ifndef BOOST_URL_DOCS
     169              :         , class = typename std::enable_if<
     170              :             std::is_convertible<
     171              :                 String,
     172              :                 core::string_view
     173              :                     >::value>::type
     174              : #endif
     175              :     >
     176          931 :     pct_string_view(
     177              :         String const& s)
     178              :         : pct_string_view(
     179          931 :             detail::to_sv(s))
     180              :     {
     181          876 :     }
     182              : 
     183              :     /** Constructor (deleted)
     184              :     */
     185              :     pct_string_view(
     186              :         std::nullptr_t) = delete;
     187              : 
     188              :     /** Constructor
     189              : 
     190              :         The newly constructed string references
     191              :         the specified character buffer. Ownership
     192              :         is not transferred.
     193              : 
     194              :         @par Postconditions
     195              :         @code
     196              :         this->data() == s && this->size() == len
     197              :         @endcode
     198              : 
     199              :         @par Complexity
     200              :         Linear in `len`.
     201              : 
     202              :         @par Exception Safety
     203              :         Exceptions thrown on invalid input.
     204              : 
     205              :         @throw system_error
     206              :          The string contains an invalid percent encoding.
     207              : 
     208              :         @param s, len The string to construct from.
     209              :     */
     210          182 :     pct_string_view(
     211              :         char const* s,
     212              :         std::size_t len)
     213          182 :         : pct_string_view(
     214          182 :             core::string_view(s, len))
     215              :     {
     216          182 :     }
     217              : 
     218              :     /** Constructor
     219              : 
     220              :         The newly constructed string references
     221              :         the specified character buffer. Ownership
     222              :         is not transferred.
     223              : 
     224              :         @par Postconditions
     225              :         @code
     226              :         this->data() == s.data() && this->size() == s.size()
     227              :         @endcode
     228              : 
     229              :         @par Complexity
     230              :         Linear in `s.size()`.
     231              : 
     232              :         @par Exception Safety
     233              :         Exceptions thrown on invalid input.
     234              : 
     235              :         @throw system_error
     236              :         The string contains an invalid percent encoding.
     237              : 
     238              :         @param s The string to construct from.
     239              :     */
     240              :     BOOST_URL_DECL
     241              :     pct_string_view(
     242              :         core::string_view s);
     243              : 
     244              :     /** Assignment
     245              : 
     246              :         The copy references the same
     247              :         underlying character buffer.
     248              :         Ownership is not transferred.
     249              : 
     250              :         @par Postconditions
     251              :         @code
     252              :         this->data() == other.data()
     253              :         @endcode
     254              : 
     255              :         @par Complexity
     256              :         Constant.
     257              : 
     258              :         @par Exception Safety
     259              :         Throws nothing.
     260              : 
     261              :         @par other The string to copy.
     262              :     */
     263              :     pct_string_view& operator=(
     264              :         pct_string_view const& other) = default;
     265              : 
     266              :     friend
     267              :     BOOST_URL_DECL
     268              :     system::result<pct_string_view>
     269              :     make_pct_string_view(
     270              :         core::string_view s) noexcept;
     271              : 
     272              :     //--------------------------------------------
     273              : 
     274              :     /** Return the decoded size
     275              : 
     276              :         This function returns the number of
     277              :         characters in the resulting string if
     278              :         percent escapes were converted into
     279              :         ordinary characters.
     280              : 
     281              :         @par Complexity
     282              :         Constant.
     283              : 
     284              :         @par Exception Safety
     285              :         Throws nothing.
     286              :     */
     287              :     std::size_t
     288        14698 :     decoded_size() const noexcept
     289              :     {
     290        14698 :         return dn_;
     291              :     }
     292              : 
     293              :     /** Return the string as a range of decoded characters
     294              : 
     295              :         @par Complexity
     296              :         Constant.
     297              : 
     298              :         @par Exception Safety
     299              :         Throws nothing.
     300              : 
     301              :         @see
     302              :             @ref decode_view.
     303              :     */
     304              :     decode_view
     305              :     operator*() const noexcept;
     306              : 
     307              :     /** Return the string with percent-decoding
     308              : 
     309              :         This function converts percent escapes
     310              :         in the string into ordinary characters
     311              :         and returns the result.
     312              :         When called with no arguments, the
     313              :         return type is `std::string`.
     314              :         Otherwise, the return type and style
     315              :         of output is determined by which string
     316              :         token is passed.
     317              : 
     318              :         @par Example
     319              :         @code
     320              :         assert( pct_string_view( "Program%20Files" ).decode() == "Program Files" );
     321              :         @endcode
     322              : 
     323              :         @par Complexity
     324              :         Linear in `this->size()`.
     325              : 
     326              :         @par Exception Safety
     327              :         Calls to allocate may throw.
     328              :         String tokens may throw exceptions.
     329              : 
     330              :         @param opt The options for encoding. If
     331              :         this parameter is omitted, the default
     332              :         options are used.
     333              : 
     334              :         @param token An optional string token.
     335              :         If this parameter is omitted, then
     336              :         a new `std::string` is returned.
     337              :         Otherwise, the function return type
     338              :         is the result type of the token.
     339              : 
     340              :         @see
     341              :             @ref encoding_opts,
     342              :             @ref string_token::return_string.
     343              :     */
     344              :     template<BOOST_URL_STRTOK_TPARAM>
     345              :     BOOST_URL_STRTOK_RETURN
     346         3302 :     decode(
     347              :         encoding_opts opt = {},
     348              :         BOOST_URL_STRTOK_ARG(token)) const
     349              :     {
     350              : /*      If you get a compile error here, it
     351              :         means that the token you passed does
     352              :         not meet the requirements stated
     353              :         in the documentation.
     354              : */
     355              :         static_assert(
     356              :             string_token::is_token<
     357              :                 StringToken>::value,
     358              :             "Type requirements not met");
     359              : 
     360         3302 :         decode_impl(token, opt);
     361         3302 :         return token.result();
     362              :     }
     363              : 
     364              : #ifndef BOOST_URL_DOCS
     365              :     // arrow support
     366              :     pct_string_view const*
     367           93 :     operator->() const noexcept
     368              :     {
     369           93 :         return this;
     370              :     }
     371              : #endif
     372              : 
     373              :     //--------------------------------------------
     374              : 
     375              :     // VFALCO No idea why this fails in msvc
     376              :     /** Swap
     377              :     */
     378              :     /*BOOST_CXX14_CONSTEXPR*/ void swap(
     379              :         pct_string_view& s ) noexcept
     380              :     {
     381              :         string_view_base::swap(s);
     382              :         std::swap(dn_, s.dn_);
     383              :     }
     384              : };
     385              : 
     386              : //------------------------------------------------
     387              : 
     388              : #ifndef BOOST_URL_DOCS
     389              : namespace detail {
     390              : // obtain modifiable reference to
     391              : // underlying string, to handle
     392              : // self-intersection on modifiers.
     393              : inline
     394              : core::string_view&
     395          578 : ref(pct_string_view& s) noexcept
     396              : {
     397          578 :     return s.s_;
     398              : }
     399              : 
     400              : } // detail
     401              : #endif
     402              : 
     403              : //------------------------------------------------
     404              : 
     405              : /** Return a valid percent-encoded string
     406              : 
     407              :     If `s` is a valid percent-encoded string,
     408              :     the function returns the buffer as a valid
     409              :     view which may be used to perform decoding
     410              :     or measurements.
     411              :     Otherwise the result contains an error code.
     412              :     Upon success, the returned view references
     413              :     the original character buffer;
     414              :     Ownership is not transferred.
     415              : 
     416              :     @par Complexity
     417              :     Linear in `s.size()`.
     418              : 
     419              :     @par Exception Safety
     420              :     Throws nothing.
     421              : 
     422              :     @param s The string to validate.
     423              : */
     424              : BOOST_URL_DECL
     425              : system::result<pct_string_view>
     426              : make_pct_string_view(
     427              :     core::string_view s) noexcept;
     428              : 
     429              : #ifndef BOOST_URL_DOCS
     430              : // VFALCO semi-private for now
     431              : inline
     432              : pct_string_view
     433        34583 : make_pct_string_view_unsafe(
     434              :     char const* data,
     435              :     std::size_t size,
     436              :     std::size_t decoded_size) noexcept
     437              : {
     438              : #if 0
     439              :     BOOST_ASSERT(! make_pct_string_view(
     440              :         core::string_view(data, size)).has_error());
     441              : #endif
     442              :     return pct_string_view(
     443        34583 :         data, size, decoded_size);
     444              : }
     445              : #endif
     446              : 
     447              : #ifndef BOOST_URL_DOCS
     448              : namespace detail {
     449              : template <>
     450              : inline
     451              : core::string_view
     452         9865 : to_sv(pct_string_view const& s) noexcept
     453              : {
     454         9865 :     return s.substr();
     455              : }
     456              : } // detail
     457              : #endif
     458              : 
     459              : } // urls
     460              : } // boost
     461              : 
     462              : #endif
        

Generated by: LCOV version 2.1