LCOV - code coverage report
Current view: top level - libs/url/src/detail - params_iter_impl.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 114 117 97.4 %
Date: 2024-02-29 20:02:55 Functions: 8 8 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             : #ifndef BOOST_URL_DETAIL_IMPL_PARAMS_ITER_IMPL_IPP
      11             : #define BOOST_URL_DETAIL_IMPL_PARAMS_ITER_IMPL_IPP
      12             : 
      13             : #include <boost/url/detail/config.hpp>
      14             : #include <boost/url/detail/params_iter_impl.hpp>
      15             : #include <boost/assert.hpp>
      16             : 
      17             : namespace boost {
      18             : namespace urls {
      19             : namespace detail {
      20             : 
      21             : /*  index   zero-based index of param
      22             :     pos     offset from start   0 = '?'
      23             :     nk      size of key         with '?' or '&'
      24             :     nv      size of value       with '='
      25             :     dk      decoded key size    no '?' or '&'
      26             :     dv      decoded value size  no '='
      27             : */
      28         604 : params_iter_impl::
      29             : params_iter_impl(
      30         604 :     query_ref const& ref_) noexcept
      31             :     : ref(ref_)
      32             :     , index(0)
      33         604 :     , pos(0)
      34             : {
      35         604 :     if(index < ref_.nparam())
      36         555 :         setup();
      37         604 : }
      38             : 
      39         654 : params_iter_impl::
      40             : params_iter_impl(
      41             :     query_ref const& ref_,
      42         654 :     int) noexcept
      43             :     : ref(ref_)
      44         654 :     , index(ref_.nparam())
      45         654 :     , pos(ref_.size())
      46             : {
      47         654 : }
      48             : 
      49         133 : params_iter_impl::
      50             : params_iter_impl(
      51             :     query_ref const& ref_,
      52             :     std::size_t pos_,
      53         133 :     std::size_t index_) noexcept
      54             :     : ref(ref_)
      55             :     , index(index_)
      56         133 :     , pos(pos_)
      57             : {
      58         133 :     BOOST_ASSERT(
      59             :         pos <= ref.size());
      60         133 :     if(index < ref_.nparam())
      61         125 :         setup();
      62         133 : }
      63             : 
      64             : // set up state for key/value at pos
      65             : void
      66        2282 : params_iter_impl::
      67             : setup() noexcept
      68             : {
      69        2282 :     dk = 1;
      70        2282 :     dv = 0;
      71        2282 :     auto const end = ref.end();
      72        2282 :     BOOST_ASSERT(pos != ref.size());
      73        2282 :     auto p0 = ref.begin() + pos;
      74        2282 :     auto p = p0;
      75             :     // key
      76             :     for(;;)
      77             :     {
      78        8906 :         if( p == end ||
      79        8847 :             *p == '&')
      80             :         {
      81             :             // no value
      82         333 :             nk = 1 + p - p0;
      83         333 :             dk = nk - dk;
      84         333 :             nv = 0;
      85         333 :             return;
      86             :         }
      87        8573 :         if(*p == '=')
      88        1949 :             break;
      89        6624 :         if(*p == '%')
      90             :         {
      91         228 :             BOOST_ASSERT(
      92             :                 end - p >= 3);
      93         228 :             dk += 2;
      94         228 :             p += 2;
      95             :         }
      96        6624 :         ++p;
      97             :     }
      98        1949 :     nk = 1 + p - p0;
      99        1949 :     dk = nk - dk;
     100        1949 :     p0 = p;
     101             : 
     102             :     // value
     103             :     for(;;)
     104             :     {
     105        7842 :         ++p;
     106        7842 :         if( p == end ||
     107        7274 :             *p == '&')
     108             :             break;
     109        5893 :         if(*p == '%')
     110             :         {
     111         198 :             BOOST_ASSERT(
     112             :                 end - p >= 3);
     113         198 :             dv += 2;
     114         198 :             p += 2;
     115             :         }
     116             :     }
     117        1949 :     nv = p - p0;
     118        1949 :     dv = nv - dv - 1;
     119             : }
     120             : 
     121             : void
     122        2176 : params_iter_impl::
     123             : increment() noexcept
     124             : {
     125        2176 :     BOOST_ASSERT(
     126             :         index < ref.nparam());
     127        2176 :     pos += nk + nv;
     128        2176 :     ++index;
     129        2176 :     if(index < ref.nparam())
     130        1602 :         setup();
     131        2176 : }
     132             : 
     133             : void
     134        1312 : params_iter_impl::
     135             : decrement() noexcept
     136             : {
     137        1312 :     BOOST_ASSERT(index > 0);
     138        1312 :     --index;
     139        1312 :     dk = 1; // for '&' or '?'
     140        1312 :     dv = 1; // for '='
     141        1312 :     auto const begin = ref.begin();
     142        1312 :     BOOST_ASSERT(pos > 0);
     143        1312 :     auto p1 = begin + (pos - 1);
     144        1312 :     auto p = p1;
     145             :     // find key or '='
     146             :     for(;;)
     147             :     {
     148        7566 :         if(p == begin)
     149             :         {
     150             :             // key
     151         216 :             nk = 1 + p1 - p; // with '?'
     152         216 :             dk = nk - dv;
     153         216 :             nv = 0;
     154         216 :             dv = 0;
     155         216 :             pos -= nk;
     156         216 :             return;
     157             :         }
     158        7350 :         else if(*--p == '&')
     159             :         {
     160             :             // key
     161          94 :             nk = p1 - p; // with '&'
     162          94 :             dk = nk - dv;
     163          94 :             nv = 0;
     164          94 :             dv = 0;
     165          94 :             pos -= nk;
     166          94 :             return;
     167             :         }
     168        7256 :         if(*p == '=')
     169             :         {
     170             :             // value
     171        1002 :             nv = p1 - p; // with '='
     172        1002 :             break;
     173             :         }
     174        6254 :         if(*p == '%')
     175         176 :             dv += 2;
     176             :     }
     177             :     // find key and value
     178             :     for(;;)
     179             :     {
     180        5238 :         if(p == begin)
     181             :         {
     182             :             // key and value
     183         248 :             nk = 1 + p1 - p - nv; // with '?'
     184         248 :             dk = nk - dk;
     185         248 :             dv = nv - dv;
     186         248 :             pos -= nk + nv;
     187         248 :             return;
     188             :         }
     189        4990 :         if(*--p == '&')
     190             :         {
     191             :             // key and value
     192         754 :             nk = p1 - p - nv; // with '&'
     193         754 :             dk = nk - dk;
     194         754 :             dv = nv - dv;
     195         754 :             pos -= nk + nv;
     196         754 :             return;
     197             :         }
     198        4236 :         if(*p == '=')
     199             :         {
     200             :             // value
     201           0 :             nv = p1 - p; // with '='
     202           0 :             dv += dk;
     203           0 :             dk = 0;
     204             :         }
     205        4236 :         else if(*p == '%')
     206             :         {
     207          60 :             dk += 2;
     208             :         }
     209             :     }
     210             : }
     211             : 
     212             : param_pct_view
     213        1401 : params_iter_impl::
     214             : dereference() const noexcept
     215             : {
     216        1401 :     BOOST_ASSERT(index < ref.nparam());
     217        1401 :     BOOST_ASSERT(pos < ref.size());
     218        1401 :     auto const p = ref.begin() + pos;
     219        1401 :     if(nv)
     220             :         return {
     221             :             make_pct_string_view_unsafe(
     222        1082 :                 p, nk - 1, dk),
     223             :             make_pct_string_view_unsafe(
     224        1082 :                 p + nk, nv - 1, dv)};
     225             :     return {
     226             :         make_pct_string_view_unsafe(
     227         319 :             p, nk - 1, dk),
     228         319 :         no_value};
     229             : }
     230             : 
     231             : pct_string_view
     232         812 : params_iter_impl::
     233             : key() const noexcept
     234             : {
     235         812 :     BOOST_ASSERT(index < ref.nparam());
     236         812 :     BOOST_ASSERT(pos < ref.size());
     237         812 :     auto const p = ref.begin() + pos;
     238             :     return make_pct_string_view_unsafe(
     239         812 :         p, nk - 1, dk);
     240             : }
     241             : 
     242             : } // detail
     243             : } // url
     244             : } // boost
     245             : 
     246             : #endif

Generated by: LCOV version 1.15