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

Generated by: LCOV version 2.1