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-03-13 19:32:03 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             : 
      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             :     : ref(ref_)
      30             :     , 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             :     : 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             :     : ref(ref_)
      53             :     , 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             :             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             :     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 1.15