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-03-05 20:06:56 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             : 
      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        2179 : segments_iter_impl::
      24             : segments_iter_impl(
      25        2179 :     detail::path_ref const& ref_) noexcept
      26        2179 :     : ref(ref_)
      27             : {
      28        2179 :     pos = path_prefix(ref.buffer());
      29        2179 :     update();
      30        2179 : }
      31             : 
      32             : // end
      33        1788 : segments_iter_impl::
      34             : segments_iter_impl(
      35             :     detail::path_ref const& ref_,
      36        1788 :     int) noexcept
      37             :     : ref(ref_)
      38        1788 :     , pos(ref.size())
      39        1788 :     , next(ref.size())
      40        1788 :     , index(ref.nseg())
      41             : {
      42        1788 : }
      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             :     : ref(u_)
      50             :     , 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        2774 : segments_iter_impl::
      68             : update() noexcept
      69             : {
      70        2774 :     auto const end = ref.end();
      71             :     char const* const p0 =
      72        2774 :         ref.data() + pos;
      73        2774 :     dn = 0;
      74        2774 :     auto p = p0;
      75       10413 :     while(p != end)
      76             :     {
      77        9201 :         if(*p == '/')
      78        1562 :             break;
      79        7639 :         if(*p != '%')
      80             :         {
      81        7286 :             ++p;
      82        7286 :             continue;
      83             :         }
      84         353 :         p += 3;
      85         353 :         dn += 2;
      86             :     }
      87        2774 :     next = p - ref.data();
      88        2774 :     dn = p - p0 - dn;
      89             :     s_ = make_pct_string_view_unsafe(
      90        2774 :         p0, p - p0, dn);
      91        2774 : }
      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             :     s_ = make_pct_string_view_unsafe(
     126        1623 :         p0, p - p0, dn);
     127             : }
     128             : 
     129             : void
     130        1545 : segments_iter_impl::
     131             : decrement() noexcept
     132             : {
     133        1545 :     BOOST_ASSERT(index != 0);
     134        1545 :     --index;
     135        1545 :     if(index == 0)
     136             :     {
     137         513 :         next = pos;
     138         513 :         pos = path_prefix(ref.buffer());
     139         513 :         s_ = core::string_view(
     140         513 :             ref.data() + pos,
     141         513 :             next - pos);
     142         513 :         BOOST_ASSERT(! s_.ends_with('/'));
     143         513 :         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             :     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 1.15