LCOV - code coverage report
Current view: top level - libs/url/src/detail - segments_iter_impl.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 91 91 100.0 %
Date: 2023-12-15 15:31:48 Functions: 6 6 100.0 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3             : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
       4             : //
       5             : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6             : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7             : //
       8             : // Official repository: https://github.com/boostorg/url
       9             : //
      10             : 
      11             : #ifndef BOOST_URL_DETAIL_IMPL_SEGMENTS_ITER_IMPL_IPP
      12             : #define BOOST_URL_DETAIL_IMPL_SEGMENTS_ITER_IMPL_IPP
      13             : 
      14             : #include <boost/url/detail/config.hpp>
      15             : #include <boost/url/detail/path.hpp>
      16             : #include <boost/url/detail/segments_iter_impl.hpp>
      17             : #include <boost/url/rfc/detail/path_rules.hpp>
      18             : #include <boost/assert.hpp>
      19             : 
      20             : namespace boost {
      21             : namespace urls {
      22             : namespace detail {
      23             : 
      24             : // begin
      25        2163 : segments_iter_impl::
      26             : segments_iter_impl(
      27        2163 :     detail::path_ref const& ref_) noexcept
      28        2163 :     : ref(ref_)
      29             : {
      30        2163 :     pos = path_prefix(ref.buffer());
      31        2163 :     update();
      32        2163 : }
      33             : 
      34             : // end
      35        1740 : segments_iter_impl::
      36             : segments_iter_impl(
      37             :     detail::path_ref const& ref_,
      38        1740 :     int) noexcept
      39             :     : ref(ref_)
      40        1740 :     , pos(ref.size())
      41        1740 :     , next(ref.size())
      42        1740 :     , index(ref.nseg())
      43             : {
      44        1740 : }
      45             : 
      46         563 : segments_iter_impl::
      47             : segments_iter_impl(
      48             :     url_impl const& u_,
      49             :     std::size_t pos_,
      50         563 :     std::size_t index_) noexcept
      51             :     : ref(u_)
      52             :     , pos(pos_)
      53         563 :     , index(index_)
      54             : {
      55         563 :     if(index == 0)
      56             :     {
      57         272 :         pos = path_prefix(ref.buffer());
      58             :     }
      59         291 :     else if(pos != ref.size())
      60             :     {
      61         183 :         BOOST_ASSERT(
      62             :             ref.data()[pos] == '/');
      63         183 :         ++pos; // skip '/'
      64             :     }
      65         563 :     update();
      66         563 : }
      67             : 
      68             : void
      69        2726 : segments_iter_impl::
      70             : update() noexcept
      71             : {
      72        2726 :     auto const end = ref.end();
      73             :     char const* const p0 =
      74        2726 :         ref.data() + pos;
      75        2726 :     dn = 0;
      76        2726 :     auto p = p0;
      77       10301 :     while(p != end)
      78             :     {
      79        9105 :         if(*p == '/')
      80        1530 :             break;
      81        7575 :         if(*p != '%')
      82             :         {
      83        7222 :             ++p;
      84        7222 :             continue;
      85             :         }
      86         353 :         p += 3;
      87         353 :         dn += 2;
      88             :     }
      89        2726 :     next = p - ref.data();
      90        2726 :     dn = p - p0 - dn;
      91             :     s_ = make_pct_string_view_unsafe(
      92        2726 :         p0, p - p0, dn);
      93        2726 : }
      94             : 
      95             : void
      96        2577 : segments_iter_impl::
      97             : increment() noexcept
      98             : {
      99        2577 :     BOOST_ASSERT(
     100             :         index != ref.nseg());
     101        2577 :     ++index;
     102        2577 :     pos = next;
     103        2577 :     if(index == ref.nseg())
     104        1082 :         return;
     105             :     // "/" segment
     106        1495 :     auto const end = ref.end();
     107        1495 :     auto p = ref.data() + pos;
     108        1495 :     BOOST_ASSERT(p != end);
     109        1495 :     BOOST_ASSERT(*p == '/');
     110        1495 :     dn = 0;
     111        1495 :     ++p; // skip '/'
     112        1495 :     auto const p0 = p;
     113        6799 :     while(p != end)
     114             :     {
     115        6145 :         if(*p == '/')
     116         841 :             break;
     117        5304 :         if(*p != '%')
     118             :         {
     119        5192 :             ++p;
     120        5192 :             continue;
     121             :         }
     122         112 :         p += 3;
     123         112 :         dn += 2;
     124             :     }
     125        1495 :     next = p - ref.data();
     126        1495 :     dn = p - p0 - dn;
     127             :     s_ = make_pct_string_view_unsafe(
     128        1495 :         p0, p - p0, dn);
     129             : }
     130             : 
     131             : void
     132        1529 : segments_iter_impl::
     133             : decrement() noexcept
     134             : {
     135        1529 :     BOOST_ASSERT(index != 0);
     136        1529 :     --index;
     137        1529 :     if(index == 0)
     138             :     {
     139         513 :         next = pos;
     140         513 :         pos = path_prefix(ref.buffer());
     141         513 :         s_ = core::string_view(
     142         513 :             ref.data() + pos,
     143         513 :             next - pos);
     144         513 :         BOOST_ASSERT(! s_.ends_with('/'));
     145         513 :         return;
     146             :     }
     147        1016 :     auto const begin = ref.data() +
     148        1016 :         path_prefix(ref.buffer());
     149        1016 :     next = pos;
     150        1016 :     auto p = ref.data() + next;
     151        1016 :     auto const p1 = p;
     152        1016 :     BOOST_ASSERT(p != begin);
     153        1016 :     dn = 0;
     154        3158 :     while(p != begin)
     155             :     {
     156        3158 :         --p;
     157        3158 :         if(*p == '/')
     158             :         {
     159        1016 :             ++dn;
     160        1016 :             break;
     161             :         }
     162        2142 :         if(*p == '%')
     163          28 :             dn += 2;
     164             :     }
     165        1016 :     dn = p1 - p - dn;
     166        1016 :     pos = p - ref.data();
     167             :     s_ = make_pct_string_view_unsafe(
     168        1016 :         p + 1, p1 - p - 1, dn);
     169             : }
     170             : 
     171             : } // detail
     172             : } // url
     173             : } // boost
     174             : 
     175             : #endif

Generated by: LCOV version 1.15