LCOV - code coverage report
Current view: top level - libs/url/src/detail/any_params_iter.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 99.4 % 168 167
Test Date: 2025-11-10 19:06:20 Functions: 96.0 % 25 24

            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          143 : any_params_iter::
      39              : ~any_params_iter() noexcept = default;
      40              : 
      41              : //------------------------------------------------
      42              : //
      43              : // query_iter
      44              : //
      45              : //------------------------------------------------
      46              : 
      47           32 : query_string_iter::
      48              : query_string_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_string_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_string_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_string_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_string_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           21 : single_param_iter::
     150              : single_param_iter(
     151              :     param_view const& p,
     152           21 :     bool space_as_plus) noexcept
     153              :     : any_params_iter(
     154              :         false,
     155              :         p.key,
     156              :         p.value)
     157           21 :     , has_value_(p.has_value)
     158           21 :     , space_as_plus_(space_as_plus)
     159              : {
     160           21 : }
     161              : 
     162              : void
     163           21 : single_param_iter::
     164              : rewind() noexcept
     165              : {
     166           21 :     at_end_ = false;
     167           21 : }
     168              : 
     169              : bool
     170           42 : single_param_iter::
     171              : measure(std::size_t& n) noexcept
     172              : {
     173           42 :     if(at_end_)
     174           21 :         return false;
     175           21 :     encoding_opts opt;
     176           21 :     opt.space_as_plus = space_as_plus_;
     177           21 :     n += encoded_size(
     178              :         s0,
     179              :         detail::param_key_chars,
     180              :         opt);
     181           21 :     if(has_value_)
     182              :     {
     183           21 :         ++n; // '='
     184           21 :         n += encoded_size(
     185              :             s1,
     186              :             detail::param_value_chars,
     187              :             opt);
     188              :     }
     189           21 :     at_end_ = true;
     190           21 :     return true;
     191              : }
     192              : 
     193              : void
     194           21 : single_param_iter::
     195              : copy(
     196              :     char*& dest,
     197              :     char const* end) noexcept
     198              : {
     199           21 :     BOOST_ASSERT(! at_end_);
     200           21 :     encoding_opts opt;
     201           21 :     opt.space_as_plus = space_as_plus_;
     202           42 :     dest += encode(
     203              :         dest,
     204           21 :         end - dest,
     205              :         s0,
     206              :         detail::param_key_chars,
     207              :         opt);
     208           21 :     if (has_value_)
     209              :     {
     210           21 :         *dest++ = '=';
     211           21 :         dest += encode(
     212              :             dest,
     213           21 :             end - dest,
     214              :             s1,
     215              :             detail::param_value_chars,
     216              :             opt);
     217              :     }
     218           21 : }
     219              : 
     220              : //------------------------------------------------
     221              : //
     222              : // params_iter_base
     223              : //
     224              : //------------------------------------------------
     225              : 
     226              : void
     227           70 : params_iter_base::
     228              : measure_impl(
     229              :     std::size_t& n,
     230              :     param_view const& p) noexcept
     231              : {
     232           70 :     encoding_opts opt;
     233           70 :     opt.space_as_plus = space_as_plus_;
     234           70 :     n += encoded_size(
     235              :         p.key,
     236              :         detail::param_key_chars,
     237              :         opt);
     238           70 :     if(p.has_value)
     239              :     {
     240           58 :         ++n; // '='
     241           58 :         n += encoded_size(
     242              :             p.value,
     243              :             detail::param_value_chars,
     244              :             opt);
     245              :     }
     246           70 : }
     247              : 
     248              : void
     249           70 : params_iter_base::
     250              : copy_impl(
     251              :     char*& dest,
     252              :     char const* end,
     253              :     param_view const& p) noexcept
     254              : {
     255           70 :     encoding_opts opt;
     256           70 :     opt.space_as_plus = space_as_plus_;
     257          140 :     dest += encode(
     258              :         dest,
     259           70 :         end - dest,
     260              :         p.key,
     261              :         detail::param_key_chars,
     262              :         opt);
     263           70 :     if(p.has_value)
     264              :     {
     265           58 :         *dest++ = '=';
     266           58 :         dest += encode(
     267              :             dest,
     268           58 :             end - dest,
     269              :             p.value,
     270              :             detail::param_value_chars,
     271              :             opt);
     272              :     }
     273           70 : }
     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 :     n += detail::re_encoded_size_unsafe(
     306              :         s0,
     307              :         detail::param_key_chars);
     308           12 :     if(has_value_)
     309           12 :         n += detail::re_encoded_size_unsafe(
     310              :             s1,
     311           12 :             detail::param_value_chars) + 1; // for '='
     312           12 :     at_end_ = true;
     313           12 :     return true;
     314              : }
     315              : 
     316              : void
     317           12 : param_encoded_iter::
     318              : copy(
     319              :     char*& dest,
     320              :     char const* end) noexcept
     321              : {
     322           12 :     detail::re_encode_unsafe(
     323              :         dest,
     324              :         end,
     325              :         s0,
     326              :         detail::param_key_chars);
     327           12 :     if(has_value_)
     328              :     {
     329           12 :         *dest++ = '=';
     330           12 :         detail::re_encode_unsafe(
     331              :             dest,
     332              :             end,
     333              :             s1,
     334              :             detail::param_value_chars);
     335              :     }
     336           12 : }
     337              : 
     338              : 
     339              : //------------------------------------------------
     340              : //
     341              : // params_encoded_iter_base
     342              : //
     343              : //------------------------------------------------
     344              : 
     345              : void
     346           51 : params_encoded_iter_base::
     347              : measure_impl(
     348              :     std::size_t& n,
     349              :     param_view const& p) noexcept
     350              : {
     351           51 :     n += detail::re_encoded_size_unsafe(
     352              :         p.key,
     353              :         detail::param_key_chars);
     354           51 :     if(p.has_value)
     355           42 :         n += detail::re_encoded_size_unsafe(
     356              :             p.value,
     357           42 :             detail::param_value_chars) + 1; // for '='
     358           51 : }
     359              : 
     360              : void
     361           51 : params_encoded_iter_base::
     362              : copy_impl(
     363              :     char*& dest,
     364              :     char const* end,
     365              :     param_view const& p) noexcept
     366              : {
     367           51 :     detail::re_encode_unsafe(
     368              :         dest,
     369              :         end,
     370              :         p.key,
     371              :         detail::param_key_chars);
     372           51 :     if(p.has_value)
     373              :     {
     374           42 :         *dest++ = '=';
     375           42 :         detail::re_encode_unsafe(
     376              :             dest,
     377              :             end,
     378              :             p.value,
     379              :             detail::param_value_chars);
     380              :     }
     381           51 : }
     382              : 
     383              : //------------------------------------------------
     384              : //
     385              : // param_value_iter
     386              : //
     387              : //------------------------------------------------
     388              : 
     389              : void
     390            9 : param_value_iter::
     391              : rewind() noexcept
     392              : {
     393            9 :     at_end_ = false;
     394            9 : }
     395              : 
     396              : bool
     397           18 : param_value_iter::
     398              : measure(
     399              :     std::size_t& n) noexcept
     400              : {
     401           18 :     if(at_end_)
     402            9 :         return false;
     403            9 :     n += nk_; // skip key
     404            9 :     if(has_value_)
     405              :     {
     406            5 :         encoding_opts opt;
     407            5 :         opt.space_as_plus = false;
     408            5 :         n += encoded_size(
     409              :             s0,
     410              :             detail::param_value_chars,
     411            5 :             opt) + 1; // for '='
     412              :     }
     413            9 :     at_end_ = true;
     414            9 :     return true;
     415              : }
     416              : 
     417              : void
     418            9 : param_value_iter::
     419              : copy(char*& it, char const* end) noexcept
     420              : {
     421            9 :     it += nk_; // skip key
     422            9 :     if(! has_value_)
     423            4 :         return;
     424            5 :     *it++ = '=';
     425            5 :     encoding_opts opt;
     426            5 :     opt.space_as_plus = false;
     427            5 :     it += encode(
     428              :         it,
     429            5 :         end - it,
     430              :         s0,
     431              :         detail::param_value_chars,
     432              :         opt);
     433              : }
     434              : 
     435              : //------------------------------------------------
     436              : //
     437              : // param_encoded_value_iter
     438              : //
     439              : //------------------------------------------------
     440              : 
     441              : void
     442            8 : param_encoded_value_iter::
     443              : rewind() noexcept
     444              : {
     445            8 :     at_end_ = false;
     446            8 : }
     447              : 
     448              : bool
     449           16 : param_encoded_value_iter::
     450              : measure(
     451              :     std::size_t& n) noexcept
     452              : {
     453           16 :     if(at_end_)
     454            8 :         return false;
     455            8 :     n += nk_; // skip key
     456            8 :     if(has_value_)
     457              :     {
     458            4 :         n += detail::re_encoded_size_unsafe(
     459              :             s0,
     460            4 :             detail::param_value_chars) + 1; // for '='
     461              :     }
     462            8 :     at_end_ = true;
     463            8 :     return true;
     464              : }
     465              : 
     466              : void
     467            8 : param_encoded_value_iter::
     468              : copy(
     469              :     char*& dest,
     470              :     char const* end) noexcept
     471              : {
     472            8 :     dest += nk_; // skip key
     473            8 :     if(! has_value_)
     474            4 :         return;
     475            4 :     *dest++ = '=';
     476            4 :     detail::re_encode_unsafe(
     477              :         dest,
     478              :         end,
     479              :         s0,
     480              :         detail::param_value_chars);
     481              : }
     482              : 
     483              : } // detail
     484              : } // urls
     485              : } // boost
     486              : 
        

Generated by: LCOV version 2.1