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 :
11 : #include <boost/url/detail/config.hpp>
12 : #include "hier_part_rule.hpp"
13 : #include "boost/url/rfc/detail/path_rules.hpp"
14 : #include <boost/url/grammar/parse.hpp>
15 : #include <boost/url/grammar/parse.hpp>
16 :
17 : namespace boost {
18 : namespace urls {
19 : namespace detail {
20 :
21 : auto
22 2269 : hier_part_rule_t::
23 : parse(
24 : char const*& it,
25 : char const* const end
26 : ) const noexcept ->
27 : system::result<value_type>
28 : {
29 2269 : value_type t;
30 2269 : if(it == end)
31 : {
32 : // path-empty
33 44 : return t;
34 : }
35 2225 : if(end - it == 1)
36 : {
37 36 : if(*it == '/')
38 : {
39 : // path-absolute
40 26 : t.path = make_pct_string_view_unsafe(
41 : it, 1, 1);
42 26 : t.segment_count = 1;
43 26 : ++it;
44 26 : return t;
45 : }
46 : // path-rootless
47 10 : auto rv = grammar::parse(
48 : it, end, segment_rule);
49 10 : if(! rv)
50 0 : return rv.error();
51 10 : t.path = *rv;
52 10 : t.segment_count = !t.path.empty();
53 10 : return t;
54 : }
55 2189 : if( it[0] == '/' &&
56 1588 : it[1] == '/')
57 : {
58 : // "//" authority
59 1492 : it += 2;
60 : auto rv = grammar::parse(
61 1492 : it, end, authority_rule);
62 1492 : if(! rv)
63 30 : return rv.error();
64 1462 : t.authority = *rv;
65 1462 : t.has_authority = true;
66 1492 : }
67 : // the authority requires an absolute path
68 : // or an empty path
69 2159 : if(it == end || (
70 1739 : t.has_authority && (
71 1042 : *it != '/' &&
72 146 : *it != '?' &&
73 103 : *it != '#')))
74 : {
75 : // path-empty
76 509 : return t;
77 : }
78 1650 : auto const it0 = it;
79 1650 : std::size_t dn = 0;
80 1650 : if(*it != '/')
81 : {
82 658 : auto rv = grammar::parse(
83 : it, end, segment_rule);
84 658 : if(! rv)
85 2 : return rv.error();
86 656 : if(rv->empty())
87 75 : return t;
88 581 : dn += rv->decoded_size();
89 581 : ++t.segment_count;
90 : }
91 4371 : while(it != end)
92 : {
93 2990 : if(*it == '/')
94 : {
95 1671 : ++dn;
96 1671 : ++it;
97 1671 : ++t.segment_count;
98 1671 : continue;
99 : }
100 1319 : auto rv = grammar::parse(
101 : it, end, segment_rule);
102 1319 : if(! rv)
103 4 : return rv.error();
104 1315 : if(rv->empty())
105 188 : break;
106 1127 : dn += rv->decoded_size();
107 : }
108 1569 : t.path = make_pct_string_view_unsafe(
109 1569 : it0, it - it0, dn);
110 1569 : return t;
111 2269 : }
112 :
113 : } // detail
114 : } // urls
115 : } // boost
116 :
|