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

Generated by: LCOV version 2.1