LCOV - code coverage report
Current view: top level - libs/url/src/detail - any_params_iter.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 177 178 99.4 %
Date: 2023-12-15 15:31:48 Functions: 23 23 100.0 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2019 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_DETAIL_IMPL_ANY_PARAMS_ITER_IPP
      11             : #define BOOST_URL_DETAIL_IMPL_ANY_PARAMS_ITER_IPP
      12             : 
      13             : #include <boost/url/detail/config.hpp>
      14             : #include <boost/url/detail/any_params_iter.hpp>
      15             : #include <boost/url/encode.hpp>
      16             : #include <boost/core/detail/string_view.hpp>
      17             : #include <boost/url/rfc/detail/charsets.hpp>
      18             : 
      19             : namespace boost {
      20             : namespace urls {
      21             : namespace detail {
      22             : 
      23             : /*
      24             :     When a string is transformed into a range of
      25             :     params, the empty string becomes ambiguous:
      26             :     it can be an empty range, or a range with
      27             :     one param. The value `not_empty` is used on
      28             :     construction to inform the transformation
      29             :     that the empty string should be treated as
      30             :     a one-element range. This simplifies
      31             :     edit_params().
      32             : */
      33             : 
      34             : //------------------------------------------------
      35             : //
      36             : // any_params_iter
      37             : //
      38             : //------------------------------------------------
      39             : 
      40             : any_params_iter::
      41             : ~any_params_iter() noexcept = default;
      42             : 
      43             : //------------------------------------------------
      44             : //
      45             : // query_iter
      46             : //
      47             : //------------------------------------------------
      48             : 
      49          32 : query_iter::
      50             : query_iter(
      51             :     core::string_view s,
      52          32 :     bool ne) noexcept
      53             :     : any_params_iter(
      54          32 :         s.empty() && ! ne, s)
      55             : {
      56          32 :     rewind();
      57          32 : }
      58             : 
      59             : void
      60          42 : query_iter::
      61             : rewind() noexcept
      62             : {
      63          42 :     if(empty)
      64             :     {
      65          22 :         at_end_ = true;
      66          22 :         return;
      67             :     }
      68          20 :     p_ = s0.begin();
      69          20 :     if(! s0.empty())
      70             :     {
      71             :         auto pos =
      72          14 :             s0.find_first_of('&');
      73          14 :         if(pos != core::string_view::npos)
      74           2 :             n_ = pos;
      75             :         else
      76          12 :             n_ = s0.size();
      77             :     }
      78             :     else
      79             :     {
      80           6 :         n_ = 0;
      81             :     }
      82          20 :     at_end_ = false;
      83             : }
      84             : 
      85             : bool
      86          43 : query_iter::
      87             : measure(
      88             :     std::size_t& n) noexcept
      89             : {
      90          43 :     if(at_end_)
      91          32 :         return false;
      92             :     // When interacting with the query as
      93             :     // an intact string, we do not treat
      94             :     // the plus sign as an encoded space.
      95          11 :     encoding_opts opt;
      96          11 :     opt.space_as_plus = false;
      97          11 :     n += encoded_size(
      98             :         core::string_view(p_, n_),
      99             :         query_chars,
     100             :         opt);
     101          11 :     increment();
     102          11 :     return true;
     103             : }
     104             : 
     105             : void
     106          11 : query_iter::
     107             : copy(
     108             :     char*& dest,
     109             :     char const* end) noexcept
     110             : {
     111          11 :     BOOST_ASSERT(! at_end_);
     112             :     // When interacting with the query as
     113             :     // an intact string, we do not treat
     114             :     // the plus sign as an encoded space.
     115          11 :     encoding_opts opt;
     116          11 :     opt.space_as_plus = false;
     117          11 :     dest += encode_unsafe(
     118             :         dest,
     119          11 :         end - dest,
     120             :         core::string_view(p_, n_),
     121             :         query_chars,
     122             :         opt);
     123          11 :     increment();
     124          11 : }
     125             : 
     126             : void
     127          22 : query_iter::
     128             : increment() noexcept
     129             : {
     130          22 :     p_ += n_;
     131          22 :     if(p_ == s0.end())
     132             :     {
     133          20 :         at_end_ = true;
     134          20 :         return;
     135             :     }
     136           2 :     ++p_;
     137           2 :     core::string_view s(p_, s0.end() - p_);
     138           2 :     auto pos = s.find_first_of('&');
     139           2 :     if(pos != core::string_view::npos)
     140           0 :         n_ = pos;
     141             :     else
     142           2 :         n_ = s.size();
     143             : }
     144             : 
     145             : //------------------------------------------------
     146             : //
     147             : // param_iter
     148             : //
     149             : //------------------------------------------------
     150             : 
     151          17 : param_iter::
     152             : param_iter(
     153          17 :     param_view const& p) noexcept
     154             :     : any_params_iter(
     155             :         false,
     156             :         p.key,
     157             :         p.value)
     158          17 :     , has_value_(p.has_value)
     159             : {
     160          17 : }
     161             : 
     162             : void
     163          17 : param_iter::
     164             : rewind() noexcept
     165             : {
     166          17 :     at_end_ = false;
     167          17 : }
     168             : 
     169             : bool
     170          34 : param_iter::
     171             : measure(std::size_t& n) noexcept
     172             : {
     173          34 :     if(at_end_)
     174          17 :         return false;
     175          17 :     encoding_opts opt;
     176          17 :     opt.space_as_plus = false;
     177          17 :     n += encoded_size(
     178             :         s0,
     179             :         detail::param_key_chars,
     180             :         opt);
     181          17 :     if(has_value_)
     182             :     {
     183          17 :         ++n; // '='
     184          17 :         n += encoded_size(
     185             :             s1,
     186             :             detail::param_value_chars,
     187             :             opt);
     188             :     }
     189          17 :     at_end_ = true;
     190          17 :     return true;
     191             : }
     192             : 
     193             : void
     194          17 : param_iter::
     195             : copy(
     196             :     char*& dest,
     197             :     char const* end) noexcept
     198             : {
     199          17 :     BOOST_ASSERT(! at_end_);
     200          17 :     encoding_opts opt;
     201          17 :     opt.space_as_plus = false;
     202          34 :     dest += encode(
     203             :         dest,
     204          17 :         end - dest,
     205             :         s0,
     206             :         detail::param_key_chars,
     207             :         opt);
     208          17 :     if(has_value_)
     209             :     {
     210          17 :         *dest++ = '=';
     211          17 :         dest += encode(
     212             :             dest,
     213          17 :             end - dest,
     214             :             s1,
     215             :             detail::param_value_chars,
     216             :             opt);
     217             :     }
     218          17 : }
     219             : 
     220             : //------------------------------------------------
     221             : //
     222             : // params_iter_base
     223             : //
     224             : //------------------------------------------------
     225             : 
     226             : void
     227          68 : params_iter_base::
     228             : measure_impl(
     229             :     std::size_t& n,
     230             :     param_view const& p) noexcept
     231             : {
     232          68 :     encoding_opts opt;
     233          68 :     opt.space_as_plus = false;
     234          68 :     n += encoded_size(
     235             :         p.key,
     236             :         detail::param_key_chars,
     237             :         opt);
     238          68 :     if(p.has_value)
     239             :     {
     240          56 :         ++n; // '='
     241          56 :         n += encoded_size(
     242             :             p.value,
     243             :             detail::param_value_chars,
     244             :             opt);
     245             :     }
     246          68 : }
     247             : 
     248             : void
     249          68 : params_iter_base::
     250             : copy_impl(
     251             :     char*& dest,
     252             :     char const* end,
     253             :     param_view const& p) noexcept
     254             : {
     255          68 :     encoding_opts opt;
     256          68 :     opt.space_as_plus = false;
     257         136 :     dest += encode(
     258             :         dest,
     259          68 :         end - dest,
     260             :         p.key,
     261             :         detail::param_key_chars,
     262             :         opt);
     263          68 :     if(p.has_value)
     264             :     {
     265          56 :         *dest++ = '=';
     266          56 :         dest += encode(
     267             :             dest,
     268          56 :             end - dest,
     269             :             p.value,
     270             :             detail::param_value_chars,
     271             :             opt);
     272             :     }
     273          68 : }
     274             : 
     275             : //------------------------------------------------
     276             : //
     277             : // param_encoded_iter
     278             : //
     279             : //------------------------------------------------
     280             : 
     281          12 : param_encoded_iter::
     282             : param_encoded_iter(
     283          12 :     param_pct_view const& p) noexcept
     284             :     : any_params_iter(
     285             :         false,
     286             :         p.key,
     287             :         p.value)
     288          12 :     , has_value_(p.has_value)
     289             : {
     290          12 : }
     291             : 
     292             : void
     293          12 : param_encoded_iter::
     294             : rewind() noexcept
     295             : {
     296          12 :     at_end_ = false;
     297          12 : }
     298             : 
     299             : bool
     300          24 : param_encoded_iter::
     301             : measure(std::size_t& n) noexcept
     302             : {
     303          24 :     if(at_end_)
     304          12 :         return false;
     305          12 :     encoding_opts opt;
     306          12 :     opt.space_as_plus = false;
     307          12 :     n += detail::re_encoded_size_unsafe(
     308             :         s0,
     309             :         detail::param_key_chars,
     310             :         opt);
     311          12 :     if(has_value_)
     312          12 :         n += detail::re_encoded_size_unsafe(
     313             :             s1,
     314             :             detail::param_value_chars,
     315          12 :             opt) + 1; // for '='
     316          12 :     at_end_ = true;
     317          12 :     return true;
     318             : }
     319             : 
     320             : void
     321          12 : param_encoded_iter::
     322             : copy(
     323             :     char*& dest,
     324             :     char const* end) noexcept
     325             : {
     326          12 :     encoding_opts opt;
     327          12 :     opt.space_as_plus = false;
     328          12 :     detail::re_encode_unsafe(
     329             :         dest,
     330             :         end,
     331             :         s0,
     332             :         detail::param_key_chars,
     333             :         opt);
     334          12 :     if(has_value_)
     335             :     {
     336          12 :         *dest++ = '=';
     337          12 :         detail::re_encode_unsafe(
     338             :             dest,
     339             :             end,
     340             :             s1,
     341             :             detail::param_value_chars,
     342             :             opt);
     343             :     }
     344          12 : }
     345             : 
     346             : 
     347             : //------------------------------------------------
     348             : //
     349             : // params_encoded_iter_base
     350             : //
     351             : //------------------------------------------------
     352             : 
     353             : void
     354          51 : params_encoded_iter_base::
     355             : measure_impl(
     356             :     std::size_t& n,
     357             :     param_view const& p) noexcept
     358             : {
     359          51 :     encoding_opts opt;
     360          51 :     opt.space_as_plus = false;
     361          51 :     n += detail::re_encoded_size_unsafe(
     362             :         p.key,
     363             :         detail::param_key_chars,
     364             :         opt);
     365          51 :     if(p.has_value)
     366          42 :         n += detail::re_encoded_size_unsafe(
     367             :             p.value,
     368             :             detail::param_value_chars,
     369          42 :             opt) + 1; // for '='
     370          51 : }
     371             : 
     372             : void
     373          51 : params_encoded_iter_base::
     374             : copy_impl(
     375             :     char*& dest,
     376             :     char const* end,
     377             :     param_view const& p) noexcept
     378             : {
     379          51 :     encoding_opts opt;
     380          51 :     opt.space_as_plus = false;
     381          51 :     detail::re_encode_unsafe(
     382             :         dest,
     383             :         end,
     384             :         p.key,
     385             :         detail::param_key_chars,
     386             :         opt);
     387          51 :     if(p.has_value)
     388             :     {
     389          42 :         *dest++ = '=';
     390          42 :         detail::re_encode_unsafe(
     391             :             dest,
     392             :             end,
     393             :             p.value,
     394             :             detail::param_value_chars,
     395             :             opt);
     396             :     }
     397          51 : }
     398             : 
     399             : //------------------------------------------------
     400             : //
     401             : // param_value_iter
     402             : //
     403             : //------------------------------------------------
     404             : 
     405             : void
     406           9 : param_value_iter::
     407             : rewind() noexcept
     408             : {
     409           9 :     at_end_ = false;
     410           9 : }
     411             : 
     412             : bool
     413          18 : param_value_iter::
     414             : measure(
     415             :     std::size_t& n) noexcept
     416             : {
     417          18 :     if(at_end_)
     418           9 :         return false;
     419           9 :     n += nk_; // skip key
     420           9 :     if(has_value_)
     421             :     {
     422           5 :         encoding_opts opt;
     423           5 :         opt.space_as_plus = false;
     424           5 :         n += encoded_size(
     425             :             s0,
     426             :             detail::param_value_chars,
     427           5 :             opt) + 1; // for '='
     428             :     }
     429           9 :     at_end_ = true;
     430           9 :     return true;
     431             : }
     432             : 
     433             : void
     434           9 : param_value_iter::
     435             : copy(char*& it, char const* end) noexcept
     436             : {
     437           9 :     it += nk_; // skip key
     438           9 :     if(! has_value_)
     439           4 :         return;
     440           5 :     *it++ = '=';
     441           5 :     encoding_opts opt;
     442           5 :     opt.space_as_plus = false;
     443           5 :     it += encode(
     444             :         it,
     445           5 :         end - it,
     446             :         s0,
     447             :         detail::param_value_chars,
     448             :         opt);
     449             : }
     450             : 
     451             : //------------------------------------------------
     452             : //
     453             : // param_encoded_value_iter
     454             : //
     455             : //------------------------------------------------
     456             : 
     457             : void
     458           8 : param_encoded_value_iter::
     459             : rewind() noexcept
     460             : {
     461           8 :     at_end_ = false;
     462           8 : }
     463             : 
     464             : bool
     465          16 : param_encoded_value_iter::
     466             : measure(
     467             :     std::size_t& n) noexcept
     468             : {
     469          16 :     if(at_end_)
     470           8 :         return false;
     471           8 :     n += nk_; // skip key
     472           8 :     if(has_value_)
     473             :     {
     474           4 :         encoding_opts opt;
     475           4 :         opt.space_as_plus = false;
     476           4 :         n += detail::re_encoded_size_unsafe(
     477             :             s0,
     478             :             detail::param_value_chars,
     479           4 :             opt) + 1; // for '='
     480             :     }
     481           8 :     at_end_ = true;
     482           8 :     return true;
     483             : }
     484             : 
     485             : void
     486           8 : param_encoded_value_iter::
     487             : copy(
     488             :     char*& dest,
     489             :     char const* end) noexcept
     490             : {
     491           8 :     dest += nk_; // skip key
     492           8 :     if(! has_value_)
     493           4 :         return;
     494           4 :     *dest++ = '=';
     495           4 :     encoding_opts opt;
     496           4 :     opt.space_as_plus = false;
     497           4 :     detail::re_encode_unsafe(
     498             :         dest,
     499             :         end,
     500             :         s0,
     501             :         detail::param_value_chars,
     502             :         opt);
     503             : }
     504             : 
     505             : } // detail
     506             : } // urls
     507             : } // boost
     508             : 
     509             : #endif

Generated by: LCOV version 1.15