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

Generated by: LCOV version 1.15