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