LCOV - code coverage report
Current view: top level - boost/url - pct_string_view.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 25 25 100.0 %
Date: 2024-04-08 19:38:36 Functions: 37 41 90.2 %

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

Generated by: LCOV version 1.15