LCOV - code coverage report
Current view: top level - libs/url/src/detail/segments_iter_impl.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 97 97
Test Date: 2025-10-23 13:40:31 Functions: 100.0 % 6 6

            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              : 
      12              : #include <boost/url/detail/config.hpp>
      13              : #include "path.hpp"
      14              : #include <boost/url/detail/segments_iter_impl.hpp>
      15              : #include "boost/url/rfc/detail/path_rules.hpp"
      16              : #include <boost/assert.hpp>
      17              : 
      18              : namespace boost {
      19              : namespace urls {
      20              : namespace detail {
      21              : 
      22              : // begin
      23         2280 : segments_iter_impl::
      24              : segments_iter_impl(
      25         2280 :     detail::path_ref const& ref_) noexcept
      26         2280 :     : ref(ref_)
      27              : {
      28         2280 :     pos = path_prefix(ref.buffer());
      29         2280 :     update();
      30         2280 : }
      31              : 
      32              : // end
      33         1852 : segments_iter_impl::
      34              : segments_iter_impl(
      35              :     detail::path_ref const& ref_,
      36         1852 :     int) noexcept
      37         1852 :     : ref(ref_)
      38         1852 :     , pos(ref.size())
      39         1852 :     , next(ref.size())
      40         1852 :     , index(ref.nseg())
      41              : {
      42         1852 : }
      43              : 
      44          595 : segments_iter_impl::
      45              : segments_iter_impl(
      46              :     url_impl const& u_,
      47              :     std::size_t pos_,
      48          595 :     std::size_t index_) noexcept
      49          595 :     : ref(u_)
      50          595 :     , pos(pos_)
      51          595 :     , index(index_)
      52              : {
      53          595 :     if(index == 0)
      54              :     {
      55          272 :         pos = path_prefix(ref.buffer());
      56              :     }
      57          323 :     else if(pos != ref.size())
      58              :     {
      59          199 :         BOOST_ASSERT(
      60              :             ref.data()[pos] == '/');
      61          199 :         ++pos; // skip '/'
      62              :     }
      63          595 :     update();
      64          595 : }
      65              : 
      66              : void
      67         2875 : segments_iter_impl::
      68              : update() noexcept
      69              : {
      70         2875 :     auto const end = ref.end();
      71              :     char const* const p0 =
      72         2875 :         ref.data() + pos;
      73         2875 :     dn = 0;
      74         2875 :     auto p = p0;
      75        10601 :     while(p != end)
      76              :     {
      77         9310 :         if(*p == '/')
      78         1584 :             break;
      79         7726 :         if(*p != '%')
      80              :         {
      81         7358 :             ++p;
      82         7358 :             continue;
      83              :         }
      84          368 :         p += 3;
      85          368 :         dn += 2;
      86              :     }
      87         2875 :     next = p - ref.data();
      88         2875 :     dn = p - p0 - dn;
      89         2875 :     s_ = make_pct_string_view_unsafe(
      90         2875 :         p0, p - p0, dn);
      91         2875 : }
      92              : 
      93              : void
      94         2795 : segments_iter_impl::
      95              : increment() noexcept
      96              : {
      97         2795 :     BOOST_ASSERT(
      98              :         index != ref.nseg());
      99         2795 :     ++index;
     100         2795 :     pos = next;
     101         2795 :     if(index == ref.nseg())
     102         1142 :         return;
     103              :     // "/" segment
     104         1653 :     auto const end = ref.end();
     105         1653 :     auto p = ref.data() + pos;
     106         1653 :     BOOST_ASSERT(p != end);
     107         1653 :     BOOST_ASSERT(*p == '/');
     108         1653 :     dn = 0;
     109         1653 :     ++p; // skip '/'
     110         1653 :     auto const p0 = p;
     111         7211 :     while(p != end)
     112              :     {
     113         6507 :         if(*p == '/')
     114          949 :             break;
     115         5558 :         if(*p != '%')
     116              :         {
     117         5446 :             ++p;
     118         5446 :             continue;
     119              :         }
     120          112 :         p += 3;
     121          112 :         dn += 2;
     122              :     }
     123         1653 :     next = p - ref.data();
     124         1653 :     dn = p - p0 - dn;
     125         1653 :     s_ = make_pct_string_view_unsafe(
     126         1653 :         p0, p - p0, dn);
     127              : }
     128              : 
     129              : void
     130         1584 : segments_iter_impl::
     131              : decrement() noexcept
     132              : {
     133         1584 :     BOOST_ASSERT(index != 0);
     134         1584 :     --index;
     135         1584 :     if(index == 0)
     136              :     {
     137          549 :         next = pos;
     138          549 :         pos = path_prefix(ref.buffer());
     139          549 :         s_ = core::string_view(
     140          549 :             ref.data() + pos,
     141          549 :             next - pos);
     142          549 :         BOOST_ASSERT(! s_.ends_with('/'));
     143          549 :         return;
     144              :     }
     145         1035 :     auto const begin = ref.data() +
     146         1035 :         path_prefix(ref.buffer());
     147         1035 :     next = pos;
     148         1035 :     auto p = ref.data() + next;
     149         1035 :     auto const p1 = p;
     150         1035 :     BOOST_ASSERT(p != begin);
     151         1035 :     dn = 0;
     152         3188 :     while(p != begin)
     153              :     {
     154         3188 :         --p;
     155         3188 :         if(*p == '/')
     156              :         {
     157         1035 :             ++dn;
     158         1035 :             break;
     159              :         }
     160         2153 :         if(*p == '%')
     161           28 :             dn += 2;
     162              :     }
     163         1035 :     dn = p1 - p - dn;
     164         1035 :     pos = p - ref.data();
     165         1035 :     s_ = make_pct_string_view_unsafe(
     166         1035 :         p + 1, p1 - p - 1, dn);
     167              : }
     168              : 
     169              : } // detail
     170              : } // url
     171              : } // boost
     172              : 
        

Generated by: LCOV version 2.1