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: 2024-02-29 20:02:55 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 "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        2179 : segments_iter_impl::
      26             : segments_iter_impl(
      27        2179 :     detail::path_ref const& ref_) noexcept
      28        2179 :     : ref(ref_)
      29             : {
      30        2179 :     pos = path_prefix(ref.buffer());
      31        2179 :     update();
      32        2179 : }
      33             : 
      34             : // end
      35        1788 : segments_iter_impl::
      36             : segments_iter_impl(
      37             :     detail::path_ref const& ref_,
      38        1788 :     int) noexcept
      39             :     : ref(ref_)
      40        1788 :     , pos(ref.size())
      41        1788 :     , next(ref.size())
      42        1788 :     , index(ref.nseg())
      43             : {
      44        1788 : }
      45             : 
      46         595 : segments_iter_impl::
      47             : segments_iter_impl(
      48             :     url_impl const& u_,
      49             :     std::size_t pos_,
      50         595 :     std::size_t index_) noexcept
      51             :     : ref(u_)
      52             :     , pos(pos_)
      53         595 :     , index(index_)
      54             : {
      55         595 :     if(index == 0)
      56             :     {
      57         272 :         pos = path_prefix(ref.buffer());
      58             :     }
      59         323 :     else if(pos != ref.size())
      60             :     {
      61         199 :         BOOST_ASSERT(
      62             :             ref.data()[pos] == '/');
      63         199 :         ++pos; // skip '/'
      64             :     }
      65         595 :     update();
      66         595 : }
      67             : 
      68             : void
      69        2774 : segments_iter_impl::
      70             : update() noexcept
      71             : {
      72        2774 :     auto const end = ref.end();
      73             :     char const* const p0 =
      74        2774 :         ref.data() + pos;
      75        2774 :     dn = 0;
      76        2774 :     auto p = p0;
      77       10413 :     while(p != end)
      78             :     {
      79        9201 :         if(*p == '/')
      80        1562 :             break;
      81        7639 :         if(*p != '%')
      82             :         {
      83        7286 :             ++p;
      84        7286 :             continue;
      85             :         }
      86         353 :         p += 3;
      87         353 :         dn += 2;
      88             :     }
      89        2774 :     next = p - ref.data();
      90        2774 :     dn = p - p0 - dn;
      91             :     s_ = make_pct_string_view_unsafe(
      92        2774 :         p0, p - p0, dn);
      93        2774 : }
      94             : 
      95             : void
      96        2753 : segments_iter_impl::
      97             : increment() noexcept
      98             : {
      99        2753 :     BOOST_ASSERT(
     100             :         index != ref.nseg());
     101        2753 :     ++index;
     102        2753 :     pos = next;
     103        2753 :     if(index == ref.nseg())
     104        1130 :         return;
     105             :     // "/" segment
     106        1623 :     auto const end = ref.end();
     107        1623 :     auto p = ref.data() + pos;
     108        1623 :     BOOST_ASSERT(p != end);
     109        1623 :     BOOST_ASSERT(*p == '/');
     110        1623 :     dn = 0;
     111        1623 :     ++p; // skip '/'
     112        1623 :     auto const p0 = p;
     113        7151 :     while(p != end)
     114             :     {
     115        6465 :         if(*p == '/')
     116         937 :             break;
     117        5528 :         if(*p != '%')
     118             :         {
     119        5416 :             ++p;
     120        5416 :             continue;
     121             :         }
     122         112 :         p += 3;
     123         112 :         dn += 2;
     124             :     }
     125        1623 :     next = p - ref.data();
     126        1623 :     dn = p - p0 - dn;
     127             :     s_ = make_pct_string_view_unsafe(
     128        1623 :         p0, p - p0, dn);
     129             : }
     130             : 
     131             : void
     132        1545 : segments_iter_impl::
     133             : decrement() noexcept
     134             : {
     135        1545 :     BOOST_ASSERT(index != 0);
     136        1545 :     --index;
     137        1545 :     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        1032 :     auto const begin = ref.data() +
     148        1032 :         path_prefix(ref.buffer());
     149        1032 :     next = pos;
     150        1032 :     auto p = ref.data() + next;
     151        1032 :     auto const p1 = p;
     152        1032 :     BOOST_ASSERT(p != begin);
     153        1032 :     dn = 0;
     154        3182 :     while(p != begin)
     155             :     {
     156        3182 :         --p;
     157        3182 :         if(*p == '/')
     158             :         {
     159        1032 :             ++dn;
     160        1032 :             break;
     161             :         }
     162        2150 :         if(*p == '%')
     163          28 :             dn += 2;
     164             :     }
     165        1032 :     dn = p1 - p - dn;
     166        1032 :     pos = p - ref.data();
     167             :     s_ = make_pct_string_view_unsafe(
     168        1032 :         p + 1, p1 - p - 1, dn);
     169             : }
     170             : 
     171             : } // detail
     172             : } // url
     173             : } // boost
     174             : 
     175             : #endif

Generated by: LCOV version 1.15