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: 2024-08-19 20:08:54 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          604 : params_iter_impl::
      27              : params_iter_impl(
      28          604 :     query_ref const& ref_) noexcept
      29          604 :     : ref(ref_)
      30          604 :     , index(0)
      31          604 :     , pos(0)
      32              : {
      33          604 :     if(index < ref_.nparam())
      34          555 :         setup();
      35          604 : }
      36              : 
      37          654 : params_iter_impl::
      38              : params_iter_impl(
      39              :     query_ref const& ref_,
      40          654 :     int) noexcept
      41          654 :     : ref(ref_)
      42          654 :     , index(ref_.nparam())
      43          654 :     , pos(ref_.size())
      44              : {
      45          654 : }
      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         2282 : params_iter_impl::
      65              : setup() noexcept
      66              : {
      67         2282 :     dk = 1;
      68         2282 :     dv = 0;
      69         2282 :     auto const end = ref.end();
      70         2282 :     BOOST_ASSERT(pos != ref.size());
      71         2282 :     auto p0 = ref.begin() + pos;
      72         2282 :     auto p = p0;
      73              :     // key
      74              :     for(;;)
      75              :     {
      76         8906 :         if( p == end ||
      77         8847 :             *p == '&')
      78              :         {
      79              :             // no value
      80          333 :             nk = 1 + p - p0;
      81          333 :             dk = nk - dk;
      82          333 :             nv = 0;
      83          333 :             return;
      84              :         }
      85         8573 :         if(*p == '=')
      86         1949 :             break;
      87         6624 :         if(*p == '%')
      88              :         {
      89          228 :             BOOST_ASSERT(
      90              :                 end - p >= 3);
      91          228 :             dk += 2;
      92          228 :             p += 2;
      93              :         }
      94         6624 :         ++p;
      95              :     }
      96         1949 :     nk = 1 + p - p0;
      97         1949 :     dk = nk - dk;
      98         1949 :     p0 = p;
      99              : 
     100              :     // value
     101              :     for(;;)
     102              :     {
     103         7842 :         ++p;
     104         7842 :         if( p == end ||
     105         7274 :             *p == '&')
     106              :             break;
     107         5893 :         if(*p == '%')
     108              :         {
     109          198 :             BOOST_ASSERT(
     110              :                 end - p >= 3);
     111          198 :             dv += 2;
     112          198 :             p += 2;
     113              :         }
     114              :     }
     115         1949 :     nv = p - p0;
     116         1949 :     dv = nv - dv - 1;
     117              : }
     118              : 
     119              : void
     120         2176 : params_iter_impl::
     121              : increment() noexcept
     122              : {
     123         2176 :     BOOST_ASSERT(
     124              :         index < ref.nparam());
     125         2176 :     pos += nk + nv;
     126         2176 :     ++index;
     127         2176 :     if(index < ref.nparam())
     128         1602 :         setup();
     129         2176 : }
     130              : 
     131              : void
     132         1312 : params_iter_impl::
     133              : decrement() noexcept
     134              : {
     135         1312 :     BOOST_ASSERT(index > 0);
     136         1312 :     --index;
     137         1312 :     dk = 1; // for '&' or '?'
     138         1312 :     dv = 1; // for '='
     139         1312 :     auto const begin = ref.begin();
     140         1312 :     BOOST_ASSERT(pos > 0);
     141         1312 :     auto p1 = begin + (pos - 1);
     142         1312 :     auto p = p1;
     143              :     // find key or '='
     144              :     for(;;)
     145              :     {
     146         7566 :         if(p == begin)
     147              :         {
     148              :             // key
     149          216 :             nk = 1 + p1 - p; // with '?'
     150          216 :             dk = nk - dv;
     151          216 :             nv = 0;
     152          216 :             dv = 0;
     153          216 :             pos -= nk;
     154          216 :             return;
     155              :         }
     156         7350 :         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         7256 :         if(*p == '=')
     167              :         {
     168              :             // value
     169         1002 :             nv = p1 - p; // with '='
     170         1002 :             break;
     171              :         }
     172         6254 :         if(*p == '%')
     173          176 :             dv += 2;
     174              :     }
     175              :     // find key and value
     176              :     for(;;)
     177              :     {
     178         5238 :         if(p == begin)
     179              :         {
     180              :             // key and value
     181          248 :             nk = 1 + p1 - p - nv; // with '?'
     182          248 :             dk = nk - dk;
     183          248 :             dv = nv - dv;
     184          248 :             pos -= nk + nv;
     185          248 :             return;
     186              :         }
     187         4990 :         if(*--p == '&')
     188              :         {
     189              :             // key and value
     190          754 :             nk = p1 - p - nv; // with '&'
     191          754 :             dk = nk - dk;
     192          754 :             dv = nv - dv;
     193          754 :             pos -= nk + nv;
     194          754 :             return;
     195              :         }
     196         4236 :         if(*p == '=')
     197              :         {
     198              :             // value
     199            0 :             nv = p1 - p; // with '='
     200            0 :             dv += dk;
     201            0 :             dk = 0;
     202              :         }
     203         4236 :         else if(*p == '%')
     204              :         {
     205           60 :             dk += 2;
     206              :         }
     207              :     }
     208              : }
     209              : 
     210              : param_pct_view
     211         1401 : params_iter_impl::
     212              : dereference() const noexcept
     213              : {
     214         1401 :     BOOST_ASSERT(index < ref.nparam());
     215         1401 :     BOOST_ASSERT(pos < ref.size());
     216         1401 :     auto const p = ref.begin() + pos;
     217         1401 :     if(nv)
     218              :         return {
     219         1082 :             make_pct_string_view_unsafe(
     220         1082 :                 p, nk - 1, dk),
     221              :             make_pct_string_view_unsafe(
     222         1082 :                 p + nk, nv - 1, dv)};
     223              :     return {
     224              :         make_pct_string_view_unsafe(
     225          319 :             p, nk - 1, dk),
     226          319 :         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