LCOV - code coverage report
Current view: top level - libs/url/src/detail/params_iter_impl.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 97.6 % 124 121
Test Date: 2025-01-10 18:07:09 Functions: 100.0 % 8 8

            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/params_iter_impl.hpp>
      13              : #include <boost/assert.hpp>
      14              : 
      15              : namespace boost {
      16              : namespace urls {
      17              : namespace detail {
      18              : 
      19              : /*  index   zero-based index of param
      20              :     pos     offset from start   0 = '?'
      21              :     nk      size of key         with '?' or '&'
      22              :     nv      size of value       with '='
      23              :     dk      decoded key size    no '?' or '&'
      24              :     dv      decoded value size  no '='
      25              : */
      26          612 : params_iter_impl::
      27              : params_iter_impl(
      28          612 :     query_ref const& ref_) noexcept
      29          612 :     : ref(ref_)
      30          612 :     , index(0)
      31          612 :     , pos(0)
      32              : {
      33          612 :     if(index < ref_.nparam())
      34          561 :         setup();
      35          612 : }
      36              : 
      37          660 : params_iter_impl::
      38              : params_iter_impl(
      39              :     query_ref const& ref_,
      40          660 :     int) noexcept
      41          660 :     : ref(ref_)
      42          660 :     , index(ref_.nparam())
      43          660 :     , pos(ref_.size())
      44              : {
      45          660 : }
      46              : 
      47          133 : params_iter_impl::
      48              : params_iter_impl(
      49              :     query_ref const& ref_,
      50              :     std::size_t pos_,
      51          133 :     std::size_t index_) noexcept
      52          133 :     : ref(ref_)
      53          133 :     , index(index_)
      54          133 :     , pos(pos_)
      55              : {
      56          133 :     BOOST_ASSERT(
      57              :         pos <= ref.size());
      58          133 :     if(index < ref_.nparam())
      59          125 :         setup();
      60          133 : }
      61              : 
      62              : // set up state for key/value at pos
      63              : void
      64         2290 : params_iter_impl::
      65              : setup() noexcept
      66              : {
      67         2290 :     dk = 1;
      68         2290 :     dv = 0;
      69         2290 :     auto const end = ref.end();
      70         2290 :     BOOST_ASSERT(pos != ref.size());
      71         2290 :     auto p0 = ref.begin() + pos;
      72         2290 :     auto p = p0;
      73              :     // key
      74              :     for(;;)
      75              :     {
      76         8929 :         if( p == end ||
      77         8868 :             *p == '&')
      78              :         {
      79              :             // no value
      80          335 :             nk = 1 + p - p0;
      81          335 :             dk = nk - dk;
      82          335 :             nv = 0;
      83          335 :             return;
      84              :         }
      85         8594 :         if(*p == '=')
      86         1955 :             break;
      87         6639 :         if(*p == '%')
      88              :         {
      89          228 :             BOOST_ASSERT(
      90              :                 end - p >= 3);
      91          228 :             dk += 2;
      92          228 :             p += 2;
      93              :         }
      94         6639 :         ++p;
      95              :     }
      96         1955 :     nk = 1 + p - p0;
      97         1955 :     dk = nk - dk;
      98         1955 :     p0 = p;
      99              : 
     100              :     // value
     101              :     for(;;)
     102              :     {
     103         7871 :         ++p;
     104         7871 :         if( p == end ||
     105         7298 :             *p == '&')
     106              :             break;
     107         5916 :         if(*p == '%')
     108              :         {
     109          198 :             BOOST_ASSERT(
     110              :                 end - p >= 3);
     111          198 :             dv += 2;
     112          198 :             p += 2;
     113              :         }
     114              :     }
     115         1955 :     nv = p - p0;
     116         1955 :     dv = nv - dv - 1;
     117              : }
     118              : 
     119              : void
     120         2190 : params_iter_impl::
     121              : increment() noexcept
     122              : {
     123         2190 :     BOOST_ASSERT(
     124              :         index < ref.nparam());
     125         2190 :     pos += nk + nv;
     126         2190 :     ++index;
     127         2190 :     if(index < ref.nparam())
     128         1604 :         setup();
     129         2190 : }
     130              : 
     131              : void
     132         1326 : params_iter_impl::
     133              : decrement() noexcept
     134              : {
     135         1326 :     BOOST_ASSERT(index > 0);
     136         1326 :     --index;
     137         1326 :     dk = 1; // for '&' or '?'
     138         1326 :     dv = 1; // for '='
     139         1326 :     auto const begin = ref.begin();
     140         1326 :     BOOST_ASSERT(pos > 0);
     141         1326 :     auto p1 = begin + (pos - 1);
     142         1326 :     auto p = p1;
     143              :     // find key or '='
     144              :     for(;;)
     145              :     {
     146         7614 :         if(p == begin)
     147              :         {
     148              :             // key
     149          220 :             nk = 1 + p1 - p; // with '?'
     150          220 :             dk = nk - dv;
     151          220 :             nv = 0;
     152          220 :             dv = 0;
     153          220 :             pos -= nk;
     154          220 :             return;
     155              :         }
     156         7394 :         else if(*--p == '&')
     157              :         {
     158              :             // key
     159           94 :             nk = p1 - p; // with '&'
     160           94 :             dk = nk - dv;
     161           94 :             nv = 0;
     162           94 :             dv = 0;
     163           94 :             pos -= nk;
     164           94 :             return;
     165              :         }
     166         7300 :         if(*p == '=')
     167              :         {
     168              :             // value
     169         1012 :             nv = p1 - p; // with '='
     170         1012 :             break;
     171              :         }
     172         6288 :         if(*p == '%')
     173          176 :             dv += 2;
     174              :     }
     175              :     // find key and value
     176              :     for(;;)
     177              :     {
     178         5270 :         if(p == begin)
     179              :         {
     180              :             // key and value
     181          256 :             nk = 1 + p1 - p - nv; // with '?'
     182          256 :             dk = nk - dk;
     183          256 :             dv = nv - dv;
     184          256 :             pos -= nk + nv;
     185          256 :             return;
     186              :         }
     187         5014 :         if(*--p == '&')
     188              :         {
     189              :             // key and value
     190          756 :             nk = p1 - p - nv; // with '&'
     191          756 :             dk = nk - dk;
     192          756 :             dv = nv - dv;
     193          756 :             pos -= nk + nv;
     194          756 :             return;
     195              :         }
     196         4258 :         if(*p == '=')
     197              :         {
     198              :             // value
     199            0 :             nv = p1 - p; // with '='
     200            0 :             dv += dk;
     201            0 :             dk = 0;
     202              :         }
     203         4258 :         else if(*p == '%')
     204              :         {
     205           60 :             dk += 2;
     206              :         }
     207              :     }
     208              : }
     209              : 
     210              : param_pct_view
     211         1415 : params_iter_impl::
     212              : dereference() const noexcept
     213              : {
     214         1415 :     BOOST_ASSERT(index < ref.nparam());
     215         1415 :     BOOST_ASSERT(pos < ref.size());
     216         1415 :     auto const p = ref.begin() + pos;
     217         1415 :     if(nv)
     218              :         return {
     219         1092 :             make_pct_string_view_unsafe(
     220         1092 :                 p, nk - 1, dk),
     221              :             make_pct_string_view_unsafe(
     222         1092 :                 p + nk, nv - 1, dv)};
     223              :     return {
     224              :         make_pct_string_view_unsafe(
     225          323 :             p, nk - 1, dk),
     226          323 :         no_value};
     227              : }
     228              : 
     229              : pct_string_view
     230          812 : params_iter_impl::
     231              : key() const noexcept
     232              : {
     233          812 :     BOOST_ASSERT(index < ref.nparam());
     234          812 :     BOOST_ASSERT(pos < ref.size());
     235          812 :     auto const p = ref.begin() + pos;
     236          812 :     return make_pct_string_view_unsafe(
     237          812 :         p, nk - 1, dk);
     238              : }
     239              : 
     240              : } // detail
     241              : } // url
     242              : } // boost
     243              : 
        

Generated by: LCOV version 2.1