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-25 21:00:01 Functions: 100.0 % 42 42

           TLA  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 HIT       34885 :     pct_string_view(
      82                 :         char const* data,
      83                 :         std::size_t size,
      84                 :         std::size_t dn) noexcept
      85           34885 :         : string_view_base(data, size)
      86           34885 :         , dn_(dn)
      87                 :     {
      88           34885 :     }
      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           17351 :     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             989 :     pct_string_view(
     169                 :         String const& s)
     170                 :         : pct_string_view(
     171             989 :             detail::to_sv(s))
     172                 :     {
     173             934 :     }
     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           15711 :     decoded_size() const noexcept
     286                 :     {
     287           15711 :         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            3607 :     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            3607 :         decode_impl(token, opt);
     362            3607 :         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           34885 : 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           34885 :         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           10188 : to_sv(pct_string_view const& s) noexcept
     462                 : {
     463           10188 :     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