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