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 -
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 -
    value_type t;
 
30 -
    if(it == end)
 
31 -
    {
 
32 -
        // path-empty
 
33 -
        return t;
 
34 -
    }
 
35 -
    if(end - it == 1)
 
36 -
    {
 
37 -
        if(*it == '/')
 
38 -
        {
 
39 -
            // path-absolute
 
40 -
            t.path = make_pct_string_view_unsafe(
 
41 -
                it, 1, 1);
 
42 -
            t.segment_count = 1;
 
43 -
            ++it;
 
44 -
            return t;
 
45 -
        }
 
46 -
        // path-rootless
 
47 -
        auto rv = grammar::parse(
 
48 -
            it, end, segment_rule);
 
49 -
        if(! rv)
 
50 -
            return rv.error();
 
51 -
        t.path = *rv;
 
52 -
        t.segment_count = !t.path.empty();
 
53 -
        return t;
 
54 -
    }
 
55 -
    if( it[0] == '/' &&
 
56 -
        it[1] == '/')
 
57 -
    {
 
58 -
        // "//" authority
 
59 -
        it += 2;
 
60 -
        auto rv = grammar::parse(
 
61 -
            it, end, authority_rule);
 
62 -
        if(! rv)
 
63 -
            return rv.error();
 
64 -
        t.authority = *rv;
 
65 -
        t.has_authority = true;
 
66 -
    }
 
67 -
    // the authority requires an absolute path
 
68 -
    // or an empty path
 
69 -
    if(it == end || (
 
70 -
        t.has_authority && (
 
71 -
            *it != '/' &&
 
72 -
            *it != '?' &&
 
73 -
            *it != '#')))
 
74 -
    {
 
75 -
        // path-empty
 
76 -
        return t;
 
77 -
    }
 
78 -
    auto const it0 = it;
 
79 -
    std::size_t dn = 0;
 
80 -
    if(*it != '/')
 
81 -
    {
 
82 -
        auto rv = grammar::parse(
 
83 -
            it, end, segment_rule);
 
84 -
        if(! rv)
 
85 -
            return rv.error();
 
86 -
        if(rv->empty())
 
87 -
            return t;
 
88 -
        dn += rv->decoded_size();
 
89 -
        ++t.segment_count;
 
90 -
    }
 
91 -
    while(it != end)
 
92 -
    {
 
93 -
        if(*it == '/')
 
94 -
        {
 
95 -
            ++dn;
 
96 -
            ++it;
 
97 -
            ++t.segment_count;
 
98 -
            continue;
 
99 -
        }
 
100 -
        auto rv = grammar::parse(
 
101 -
            it, end, segment_rule);
 
102 -
        if(! rv)
 
103 -
            return rv.error();
 
104 -
        if(rv->empty())
 
105 -
            break;
 
106 -
        dn += rv->decoded_size();
 
107 -
    }
 
108 -
    t.path = make_pct_string_view_unsafe(
 
109 -
        it0, it - it0, dn);
 
110 -
    return t;
 
111 -
}
 
112 -

 
113 -
} // detail
 
114 -
} // urls
 
115 -
} // boost
 
116 -