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-08-20 16:05:53 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              :     /** Return a valid percent-encoded string
     267              : 
     268              :         If `s` is a valid percent-encoded string,
     269              :         the function returns the buffer as a valid
     270              :         view which may be used to perform decoding
     271              :         or measurements.
     272              :         Otherwise the result contains an error code.
     273              :         Upon success, the returned view references
     274              :         the original character buffer;
     275              :         Ownership is not transferred.
     276              : 
     277              :         @par Complexity
     278              :         Linear in `s.size()`.
     279              : 
     280              :         @par Exception Safety
     281              :         Throws nothing.
     282              : 
     283              :         @param s The string to validate.
     284              :     */
     285              :     friend
     286              :     BOOST_URL_DECL
     287              :     system::result<pct_string_view>
     288              :     make_pct_string_view(
     289              :         core::string_view s) noexcept;
     290              : 
     291              :     //--------------------------------------------
     292              : 
     293              :     /** Return the decoded size
     294              : 
     295              :         This function returns the number of
     296              :         characters in the resulting string if
     297              :         percent escapes were converted into
     298              :         ordinary characters.
     299              : 
     300              :         @par Complexity
     301              :         Constant.
     302              : 
     303              :         @par Exception Safety
     304              :         Throws nothing.
     305              :     */
     306              :     std::size_t
     307        14698 :     decoded_size() const noexcept
     308              :     {
     309        14698 :         return dn_;
     310              :     }
     311              : 
     312              :     /** Return the string as a range of decoded characters
     313              : 
     314              :         @par Complexity
     315              :         Constant.
     316              : 
     317              :         @par Exception Safety
     318              :         Throws nothing.
     319              : 
     320              :         @see
     321              :             @ref decode_view.
     322              :     */
     323              :     decode_view
     324              :     operator*() const noexcept;
     325              : 
     326              :     /** Return the string with percent-decoding
     327              : 
     328              :         This function converts percent escapes
     329              :         in the string into ordinary characters
     330              :         and returns the result.
     331              :         When called with no arguments, the
     332              :         return type is `std::string`.
     333              :         Otherwise, the return type and style
     334              :         of output is determined by which string
     335              :         token is passed.
     336              : 
     337              :         @par Example
     338              :         @code
     339              :         assert( pct_string_view( "Program%20Files" ).decode() == "Program Files" );
     340              :         @endcode
     341              : 
     342              :         @par Complexity
     343              :         Linear in `this->size()`.
     344              : 
     345              :         @par Exception Safety
     346              :         Calls to allocate may throw.
     347              :         String tokens may throw exceptions.
     348              : 
     349              :         @param opt The options for encoding. If
     350              :         this parameter is omitted, the default
     351              :         options are used.
     352              : 
     353              :         @param token An optional string token.
     354              :         If this parameter is omitted, then
     355              :         a new `std::string` is returned.
     356              :         Otherwise, the function return type
     357              :         is the result type of the token.
     358              : 
     359              :         @see
     360              :             @ref encoding_opts,
     361              :             @ref string_token::return_string.
     362              :     */
     363              :     template<BOOST_URL_STRTOK_TPARAM>
     364              :     BOOST_URL_STRTOK_RETURN
     365         3302 :     decode(
     366              :         encoding_opts opt = {},
     367              :         BOOST_URL_STRTOK_ARG(token)) const
     368              :     {
     369              : /*      If you get a compile error here, it
     370              :         means that the token you passed does
     371              :         not meet the requirements stated
     372              :         in the documentation.
     373              : */
     374              :         static_assert(
     375              :             string_token::is_token<
     376              :                 StringToken>::value,
     377              :             "Type requirements not met");
     378              : 
     379         3302 :         decode_impl(token, opt);
     380         3302 :         return token.result();
     381              :     }
     382              : 
     383              : #ifndef BOOST_URL_DOCS
     384              :     /// Arrow support
     385              :     pct_string_view const*
     386           93 :     operator->() const noexcept
     387              :     {
     388           93 :         return this;
     389              :     }
     390              : #endif
     391              : 
     392              :     //--------------------------------------------
     393              : 
     394              :     // VFALCO No idea why this fails in msvc
     395              :     /** Swap
     396              :     */
     397              :     /*BOOST_CXX14_CONSTEXPR*/ void swap(
     398              :         pct_string_view& s ) noexcept
     399              :     {
     400              :         string_view_base::swap(s);
     401              :         std::swap(dn_, s.dn_);
     402              :     }
     403              : };
     404              : 
     405              : //------------------------------------------------
     406              : 
     407              : #ifndef BOOST_URL_DOCS
     408              : namespace detail {
     409              : // obtain modifiable reference to
     410              : // underlying string, to handle
     411              : // self-intersection on modifiers.
     412              : inline
     413              : core::string_view&
     414          578 : ref(pct_string_view& s) noexcept
     415              : {
     416          578 :     return s.s_;
     417              : }
     418              : 
     419              : } // detail
     420              : #endif
     421              : 
     422              : //------------------------------------------------
     423              : 
     424              : /** Return a valid percent-encoded string
     425              : 
     426              :     If `s` is a valid percent-encoded string,
     427              :     the function returns the buffer as a valid
     428              :     view which may be used to perform decoding
     429              :     or measurements.
     430              :     Otherwise the result contains an error code.
     431              :     Upon success, the returned view references
     432              :     the original character buffer;
     433              :     Ownership is not transferred.
     434              : 
     435              :     @par Complexity
     436              :     Linear in `s.size()`.
     437              : 
     438              :     @par Exception Safety
     439              :     Throws nothing.
     440              : 
     441              :     @param s The string to validate.
     442              : */
     443              : BOOST_URL_DECL
     444              : system::result<pct_string_view>
     445              : make_pct_string_view(
     446              :     core::string_view s) noexcept;
     447              : 
     448              : #ifndef BOOST_URL_DOCS
     449              : // VFALCO semi-private for now
     450              : inline
     451              : pct_string_view
     452        34583 : make_pct_string_view_unsafe(
     453              :     char const* data,
     454              :     std::size_t size,
     455              :     std::size_t decoded_size) noexcept
     456              : {
     457              : #if 0
     458              :     BOOST_ASSERT(! make_pct_string_view(
     459              :         core::string_view(data, size)).has_error());
     460              : #endif
     461              :     return pct_string_view(
     462        34583 :         data, size, decoded_size);
     463              : }
     464              : #endif
     465              : 
     466              : #ifndef BOOST_URL_DOCS
     467              : namespace detail {
     468              : template <>
     469              : inline
     470              : core::string_view
     471         9865 : to_sv(pct_string_view const& s) noexcept
     472              : {
     473         9865 :     return s.substr();
     474              : }
     475              : } // detail
     476              : #endif
     477              : 
     478              : } // urls
     479              : } // boost
     480              : 
     481              : #endif
        

Generated by: LCOV version 2.1