Line data Source code
1 : // 2 : // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) 3 : // 4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 : // 7 : // Official repository: https://github.com/boostorg/url 8 : // 9 : 10 : #ifndef BOOST_URL_RFC_DETAIL_IMPL_RELATIVE_PART_RULE_IPP 11 : #define BOOST_URL_RFC_DETAIL_IMPL_RELATIVE_PART_RULE_IPP 12 : 13 : #include <boost/url/detail/config.hpp> 14 : #include "relative_part_rule.hpp" 15 : #include "boost/url/rfc/detail/path_rules.hpp" 16 : #include <boost/url/grammar/parse.hpp> 17 : 18 : namespace boost { 19 : namespace urls { 20 : namespace detail { 21 : 22 : constexpr auto pchars_nc = pchars - ':'; 23 : 24 : auto 25 1339 : relative_part_rule_t:: 26 : parse( 27 : char const*& it, 28 : char const* const end 29 : ) const noexcept -> 30 : system::result<value_type> 31 : { 32 2678 : value_type t; 33 1339 : if(it == end) 34 : { 35 : // path-empty 36 125 : return t; 37 : } 38 1214 : if(end - it == 1) 39 : { 40 142 : if(*it == '/') 41 : { 42 : // path-absolute 43 : t.path = make_pct_string_view_unsafe( 44 78 : it, 1, 1); 45 78 : t.segment_count = 1; 46 78 : ++it; 47 78 : return t; 48 : } 49 64 : if(*it != ':') 50 : { 51 : // path-noscheme or 52 : // path-empty 53 : auto rv = grammar::parse( 54 63 : it, end, segment_rule); 55 63 : if(! rv) 56 0 : return rv.error(); 57 63 : if(! rv->empty()) 58 : { 59 29 : t.path = *rv; 60 29 : t.segment_count = 1; 61 : } 62 : } 63 : // path-empty 64 64 : return t; 65 : } 66 1072 : if( it[0] == '/' && 67 523 : it[1] == '/') 68 : { 69 : // "//" authority 70 244 : it += 2; 71 : auto rv = grammar::parse( 72 244 : it, end, authority_rule); 73 244 : if(! rv) 74 0 : return rv.error(); 75 244 : t.authority = *rv; 76 244 : t.has_authority = true; 77 : } 78 1072 : if(it == end) 79 : { 80 : // path-empty 81 123 : return t; 82 : } 83 949 : auto const it0 = it; 84 949 : std::size_t dn = 0; 85 949 : if(*it != '/') 86 : { 87 : // segment_nc 88 : auto rv = grammar::parse(it, end, 89 552 : pct_encoded_rule(pchars_nc)); 90 552 : if(! rv) 91 1 : return rv.error(); 92 551 : if(rv->empty()) 93 207 : return t; 94 344 : dn += rv->decoded_size(); 95 344 : ++t.segment_count; 96 344 : if( it != end && 97 269 : *it == ':') 98 : { 99 41 : BOOST_URL_RETURN_EC( 100 : grammar::error::mismatch); 101 : } 102 : } 103 3137 : while(it != end) 104 : { 105 2490 : if(*it == '/') 106 : { 107 1319 : ++dn; 108 1319 : ++it; 109 1319 : ++t.segment_count; 110 1319 : continue; 111 : } 112 : auto rv = grammar::parse( 113 1171 : it, end, segment_rule); 114 1171 : if(! rv) 115 0 : return rv.error(); 116 1171 : if(rv->empty()) 117 53 : break; 118 1118 : dn += rv->decoded_size(); 119 : } 120 : t.path = make_pct_string_view_unsafe( 121 700 : it0, it - it0, dn); 122 700 : return t; 123 : } 124 : 125 : } // detail 126 : } // urls 127 : } // boost 128 : 129 : #endif