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

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

Generated by: LCOV version 2.3