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: 2024-03-05 20:06:56 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 :     encoding_opts opt;
     304          12 :     opt.space_as_plus = false;
     305          12 :     n += detail::re_encoded_size_unsafe(
     306             :         s0,
     307             :         detail::param_key_chars,
     308             :         opt);
     309          12 :     if(has_value_)
     310          12 :         n += detail::re_encoded_size_unsafe(
     311             :             s1,
     312             :             detail::param_value_chars,
     313          12 :             opt) + 1; // for '='
     314          12 :     at_end_ = true;
     315          12 :     return true;
     316             : }
     317             : 
     318             : void
     319          12 : param_encoded_iter::
     320             : copy(
     321             :     char*& dest,
     322             :     char const* end) noexcept
     323             : {
     324          12 :     encoding_opts opt;
     325          12 :     opt.space_as_plus = false;
     326          12 :     detail::re_encode_unsafe(
     327             :         dest,
     328             :         end,
     329             :         s0,
     330             :         detail::param_key_chars,
     331             :         opt);
     332          12 :     if(has_value_)
     333             :     {
     334          12 :         *dest++ = '=';
     335          12 :         detail::re_encode_unsafe(
     336             :             dest,
     337             :             end,
     338             :             s1,
     339             :             detail::param_value_chars,
     340             :             opt);
     341             :     }
     342          12 : }
     343             : 
     344             : 
     345             : //------------------------------------------------
     346             : //
     347             : // params_encoded_iter_base
     348             : //
     349             : //------------------------------------------------
     350             : 
     351             : void
     352          51 : params_encoded_iter_base::
     353             : measure_impl(
     354             :     std::size_t& n,
     355             :     param_view const& p) noexcept
     356             : {
     357          51 :     encoding_opts opt;
     358          51 :     opt.space_as_plus = false;
     359          51 :     n += detail::re_encoded_size_unsafe(
     360             :         p.key,
     361             :         detail::param_key_chars,
     362             :         opt);
     363          51 :     if(p.has_value)
     364          42 :         n += detail::re_encoded_size_unsafe(
     365             :             p.value,
     366             :             detail::param_value_chars,
     367          42 :             opt) + 1; // for '='
     368          51 : }
     369             : 
     370             : void
     371          51 : params_encoded_iter_base::
     372             : copy_impl(
     373             :     char*& dest,
     374             :     char const* end,
     375             :     param_view const& p) noexcept
     376             : {
     377          51 :     encoding_opts opt;
     378          51 :     opt.space_as_plus = false;
     379          51 :     detail::re_encode_unsafe(
     380             :         dest,
     381             :         end,
     382             :         p.key,
     383             :         detail::param_key_chars,
     384             :         opt);
     385          51 :     if(p.has_value)
     386             :     {
     387          42 :         *dest++ = '=';
     388          42 :         detail::re_encode_unsafe(
     389             :             dest,
     390             :             end,
     391             :             p.value,
     392             :             detail::param_value_chars,
     393             :             opt);
     394             :     }
     395          51 : }
     396             : 
     397             : //------------------------------------------------
     398             : //
     399             : // param_value_iter
     400             : //
     401             : //------------------------------------------------
     402             : 
     403             : void
     404           9 : param_value_iter::
     405             : rewind() noexcept
     406             : {
     407           9 :     at_end_ = false;
     408           9 : }
     409             : 
     410             : bool
     411          18 : param_value_iter::
     412             : measure(
     413             :     std::size_t& n) noexcept
     414             : {
     415          18 :     if(at_end_)
     416           9 :         return false;
     417           9 :     n += nk_; // skip key
     418           9 :     if(has_value_)
     419             :     {
     420           5 :         encoding_opts opt;
     421           5 :         opt.space_as_plus = false;
     422           5 :         n += encoded_size(
     423             :             s0,
     424             :             detail::param_value_chars,
     425           5 :             opt) + 1; // for '='
     426             :     }
     427           9 :     at_end_ = true;
     428           9 :     return true;
     429             : }
     430             : 
     431             : void
     432           9 : param_value_iter::
     433             : copy(char*& it, char const* end) noexcept
     434             : {
     435           9 :     it += nk_; // skip key
     436           9 :     if(! has_value_)
     437           4 :         return;
     438           5 :     *it++ = '=';
     439           5 :     encoding_opts opt;
     440           5 :     opt.space_as_plus = false;
     441           5 :     it += encode(
     442             :         it,
     443           5 :         end - it,
     444             :         s0,
     445             :         detail::param_value_chars,
     446             :         opt);
     447             : }
     448             : 
     449             : //------------------------------------------------
     450             : //
     451             : // param_encoded_value_iter
     452             : //
     453             : //------------------------------------------------
     454             : 
     455             : void
     456           8 : param_encoded_value_iter::
     457             : rewind() noexcept
     458             : {
     459           8 :     at_end_ = false;
     460           8 : }
     461             : 
     462             : bool
     463          16 : param_encoded_value_iter::
     464             : measure(
     465             :     std::size_t& n) noexcept
     466             : {
     467          16 :     if(at_end_)
     468           8 :         return false;
     469           8 :     n += nk_; // skip key
     470           8 :     if(has_value_)
     471             :     {
     472           4 :         encoding_opts opt;
     473           4 :         opt.space_as_plus = false;
     474           4 :         n += detail::re_encoded_size_unsafe(
     475             :             s0,
     476             :             detail::param_value_chars,
     477           4 :             opt) + 1; // for '='
     478             :     }
     479           8 :     at_end_ = true;
     480           8 :     return true;
     481             : }
     482             : 
     483             : void
     484           8 : param_encoded_value_iter::
     485             : copy(
     486             :     char*& dest,
     487             :     char const* end) noexcept
     488             : {
     489           8 :     dest += nk_; // skip key
     490           8 :     if(! has_value_)
     491           4 :         return;
     492           4 :     *dest++ = '=';
     493           4 :     encoding_opts opt;
     494           4 :     opt.space_as_plus = false;
     495           4 :     detail::re_encode_unsafe(
     496             :         dest,
     497             :         end,
     498             :         s0,
     499             :         detail::param_value_chars,
     500             :         opt);
     501             : }
     502             : 
     503             : } // detail
     504             : } // urls
     505             : } // boost
     506             : 

Generated by: LCOV version 1.15