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: 2024-09-08 09:46:47 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         2203 : segments_iter_impl::
      24              : segments_iter_impl(
      25         2203 :     detail::path_ref const& ref_) noexcept
      26         2203 :     : ref(ref_)
      27              : {
      28         2203 :     pos = path_prefix(ref.buffer());
      29         2203 :     update();
      30         2203 : }
      31              : 
      32              : // end
      33         1802 : segments_iter_impl::
      34              : segments_iter_impl(
      35              :     detail::path_ref const& ref_,
      36         1802 :     int) noexcept
      37         1802 :     : ref(ref_)
      38         1802 :     , pos(ref.size())
      39         1802 :     , next(ref.size())
      40         1802 :     , index(ref.nseg())
      41              : {
      42         1802 : }
      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         2798 : segments_iter_impl::
      68              : update() noexcept
      69              : {
      70         2798 :     auto const end = ref.end();
      71              :     char const* const p0 =
      72         2798 :         ref.data() + pos;
      73         2798 :     dn = 0;
      74         2798 :     auto p = p0;
      75        10449 :     while(p != end)
      76              :     {
      77         9213 :         if(*p == '/')
      78         1562 :             break;
      79         7651 :         if(*p != '%')
      80              :         {
      81         7286 :             ++p;
      82         7286 :             continue;
      83              :         }
      84          365 :         p += 3;
      85          365 :         dn += 2;
      86              :     }
      87         2798 :     next = p - ref.data();
      88         2798 :     dn = p - p0 - dn;
      89         2798 :     s_ = make_pct_string_view_unsafe(
      90         2798 :         p0, p - p0, dn);
      91         2798 : }
      92              : 
      93              : void
      94         2753 : segments_iter_impl::
      95              : increment() noexcept
      96              : {
      97         2753 :     BOOST_ASSERT(
      98              :         index != ref.nseg());
      99         2753 :     ++index;
     100         2753 :     pos = next;
     101         2753 :     if(index == ref.nseg())
     102         1130 :         return;
     103              :     // "/" segment
     104         1623 :     auto const end = ref.end();
     105         1623 :     auto p = ref.data() + pos;
     106         1623 :     BOOST_ASSERT(p != end);
     107         1623 :     BOOST_ASSERT(*p == '/');
     108         1623 :     dn = 0;
     109         1623 :     ++p; // skip '/'
     110         1623 :     auto const p0 = p;
     111         7151 :     while(p != end)
     112              :     {
     113         6465 :         if(*p == '/')
     114          937 :             break;
     115         5528 :         if(*p != '%')
     116              :         {
     117         5416 :             ++p;
     118         5416 :             continue;
     119              :         }
     120          112 :         p += 3;
     121          112 :         dn += 2;
     122              :     }
     123         1623 :     next = p - ref.data();
     124         1623 :     dn = p - p0 - dn;
     125         1623 :     s_ = make_pct_string_view_unsafe(
     126         1623 :         p0, p - p0, dn);
     127              : }
     128              : 
     129              : void
     130         1553 : segments_iter_impl::
     131              : decrement() noexcept
     132              : {
     133         1553 :     BOOST_ASSERT(index != 0);
     134         1553 :     --index;
     135         1553 :     if(index == 0)
     136              :     {
     137          521 :         next = pos;
     138          521 :         pos = path_prefix(ref.buffer());
     139          521 :         s_ = core::string_view(
     140          521 :             ref.data() + pos,
     141          521 :             next - pos);
     142          521 :         BOOST_ASSERT(! s_.ends_with('/'));
     143          521 :         return;
     144              :     }
     145         1032 :     auto const begin = ref.data() +
     146         1032 :         path_prefix(ref.buffer());
     147         1032 :     next = pos;
     148         1032 :     auto p = ref.data() + next;
     149         1032 :     auto const p1 = p;
     150         1032 :     BOOST_ASSERT(p != begin);
     151         1032 :     dn = 0;
     152         3182 :     while(p != begin)
     153              :     {
     154         3182 :         --p;
     155         3182 :         if(*p == '/')
     156              :         {
     157         1032 :             ++dn;
     158         1032 :             break;
     159              :         }
     160         2150 :         if(*p == '%')
     161           28 :             dn += 2;
     162              :     }
     163         1032 :     dn = p1 - p - dn;
     164         1032 :     pos = p - ref.data();
     165         1032 :     s_ = make_pct_string_view_unsafe(
     166         1032 :         p + 1, p1 - p - 1, dn);
     167              : }
     168              : 
     169              : } // detail
     170              : } // url
     171              : } // boost
     172              : 
        

Generated by: LCOV version 2.1