// // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // Official repository: https://github.com/boostorg/url // #ifndef BOOST_URL_RFC_DETAIL_IMPL_HIER_PART_RULE_IPP #define BOOST_URL_RFC_DETAIL_IMPL_HIER_PART_RULE_IPP #include #include #include #include namespace boost { namespace urls { namespace detail { auto hier_part_rule_t:: parse( char const*& it, char const* const end ) const noexcept -> result { value_type t; if(it == end) { // path-empty return t; } if(end - it == 1) { if(*it == '/') { // path-absolute t.path = make_pct_string_view_unsafe( it, 1, 1); t.segment_count = 1; ++it; return t; } // path-rootless auto rv = grammar::parse( it, end, segment_rule); if(! rv) return rv.error(); t.path = *rv; t.segment_count = !t.path.empty(); return t; } if( it[0] == '/' && it[1] == '/') { // "//" authority it += 2; auto rv = grammar::parse( it, end, authority_rule); if(! rv) return rv.error(); t.authority = *rv; t.has_authority = true; } // the authority requires an absolute path // or an empty path if(it == end || ( t.has_authority && ( *it != '/' && *it != '?' && *it != '#'))) { // path-empty return t; } auto const it0 = it; std::size_t dn = 0; if(*it != '/') { auto rv = grammar::parse( it, end, segment_rule); if(! rv) return rv.error(); if(rv->empty()) return t; dn += rv->decoded_size(); ++t.segment_count; } while(it != end) { if(*it == '/') { ++dn; ++it; ++t.segment_count; continue; } auto rv = grammar::parse( it, end, segment_rule); if(! rv) return rv.error(); if(rv->empty()) break; dn += rv->decoded_size(); } t.path = make_pct_string_view_unsafe( it0, it - it0, dn); return t; } } // detail } // urls } // boost #endif