7
7
// http://www.boost.org/LICENSE_1_0.txt)
8
8
9
9
#include < boost/fusion/tuple.hpp>
10
- #include < boost/network/uri/detail/uri_parts .hpp>
11
-
10
+ #include < boost/spirit/include/phoenix_operator .hpp>
11
+ # include < boost/spirit/include/qi_char_.hpp >
12
12
#include < boost/spirit/include/qi_core.hpp>
13
- #include < boost/spirit/include/qi_sequence.hpp>
13
+ #include < boost/spirit/include/qi_eps.hpp>
14
+ #include < boost/spirit/include/qi_omit.hpp>
14
15
#include < boost/spirit/include/qi_parse.hpp>
15
- #include < boost/spirit/include/qi_char_.hpp>
16
- #include < boost/spirit/include/qi_lexeme.hpp>
16
+ #include < boost/spirit/include/qi_raw.hpp>
17
+ #include < boost/spirit/include/qi_rule.hpp>
18
+ #include < boost/spirit/include/qi_sequence.hpp>
19
+
20
+ #include < boost/network/uri/detail/uri_parts.hpp>
17
21
18
22
namespace boost { namespace network { namespace uri {
19
23
@@ -29,30 +33,122 @@ namespace boost { namespace network { namespace uri {
29
33
namespace qi = boost::spirit::qi;
30
34
31
35
typedef typename range_iterator<Range>::type iterator;
32
- typedef typename string<Tag>::type string_type;
36
+
37
+ typedef typename string<Tag>::type string_type;
38
+ typedef typename string<Tag>::type::value_type char_type;
33
39
34
40
iterator start_ = begin (range);
35
41
iterator end_ = end (range);
36
- fusion::tuple<string_type&,string_type&> result =
37
- fusion::tie (parts.scheme ,parts.scheme_specific_part );
42
+ fusion::tuple<
43
+ string_type &,
44
+ string_type &,
45
+ boost::optional<string_type> &,
46
+ boost::optional<string_type> &
47
+ > result =
48
+ fusion::tie (
49
+ parts.scheme ,
50
+ parts.path ,
51
+ parts.query ,
52
+ parts.fragment
53
+ );
54
+
55
+ // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
56
+ qi::rule<iterator, char_type ()> gen_delims, sub_delims;
57
+ gen_delims = qi::char_ (" :/?#[]@" );
58
+ // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
59
+ sub_delims = qi::char_ (" !$&'()*+,;=" );
60
+ // reserved = gen-delims / sub-delims
61
+ qi::rule<iterator, char_type ()> reserved;
62
+ reserved = gen_delims | sub_delims;
63
+ // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
64
+ qi::rule<iterator, char_type ()> unreserved;
65
+ unreserved = qi::alnum | qi::char_ (" -._~" );
66
+ // pct-encoded = "%" HEXDIG HEXDIG
67
+ qi::rule<iterator, string_type ()> pct_encoded;
68
+ pct_encoded = qi::char_ (" %" ) >> qi::repeat (2 )[qi::xdigit];
69
+
70
+ // pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
71
+ qi::rule<iterator, string_type ()> pchar;
72
+ pchar = qi::raw[
73
+ unreserved | pct_encoded | sub_delims | qi::char_ (" :@" )
74
+ ];
75
+
76
+ // segment = *pchar
77
+ qi::rule<iterator, string_type ()> segment = qi::raw[*pchar];
78
+ // segment-nz = 1*pchar
79
+ qi::rule<iterator, string_type ()> segment_nz = qi::raw[+pchar];
80
+ // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
81
+ qi::rule<iterator, string_type ()> segment_nz_nc;
82
+ segment_nz_nc = qi::raw[
83
+ +(unreserved | pct_encoded | sub_delims | qi::char_ (" @" ))
84
+ ];
85
+ // path-abempty = *( "/" segment )
86
+ qi::rule<iterator, string_type ()> path_abempty;
87
+ path_abempty = qi::raw[*(qi::char_ (" /" ) >> segment)];
88
+ // path-absolute = "/" [ segment-nz *( "/" segment ) ]
89
+ qi::rule<iterator, string_type ()> path_absolute;
90
+ path_absolute = qi::raw[
91
+ qi::char_ (" /" )
92
+ >> -(segment_nz >> *(qi::char_ (" /" ) >> segment))
93
+ ];
94
+ // path-rootless = segment-nz *( "/" segment )
95
+ qi::rule<iterator, string_type ()> path_rootless;
96
+ path_rootless = qi::raw[
97
+ segment_nz >> *(qi::char_ (" /" ) >> segment)
98
+ ];
99
+ // path-empty = 0<pchar>
100
+ qi::rule<iterator, string_type ()> path_empty = qi::eps;
101
+
102
+ // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
103
+ qi::rule<iterator, string_type ()> scheme;
104
+ scheme = qi::alpha >> *(qi::alnum | qi::char_ (" +.-" ));
105
+
106
+ // user_info = *( unreserved / pct-encoded / sub-delims / ":" )
107
+ qi::rule<iterator, string_type ()> user_info;
108
+ user_info = qi::raw[
109
+ *(unreserved | pct_encoded | sub_delims | qi::char_ (" :" ))
110
+ ];
111
+
112
+ // reg-name = *( unreserved / pct-encoded / sub-delims )
113
+ qi::rule<iterator, string_type ()> reg_name;
114
+ reg_name = qi::raw[*(unreserved | pct_encoded | sub_delims)];
115
+ // FIXME, host = IP-literal / IPv4address / reg-name
116
+ qi::rule<iterator, string_type ()> host = reg_name;
117
+
118
+ qi::rule<iterator, string_type ()> query, fragment;
119
+ // query = *( pchar / "/" / "?" )
120
+ query = qi::raw[*(pchar | qi::char_ (" /?" ))];
121
+ // fragment = *( pchar / "/" / "?" )
122
+ fragment = qi::raw[*(pchar | qi::char_ (" /?" ))];
38
123
39
124
bool ok = qi::parse (
40
- start_, end_,
125
+ start_, end_,
41
126
(
42
- qi::lexeme[(qi::alpha >> *(qi::alnum | qi::char_ (" +.-" )))]
43
- >> ' :'
44
- >>
45
- +(qi::char_ - (qi::cntrl | qi::space))
127
+ scheme >> ' :'
128
+ >> (
129
+ " //"
130
+ >> qi::omit[
131
+ -(user_info >> ' @' ) [phoenix::ref (parts.user_info ) = qi::_1]
132
+ >> host [phoenix::ref (parts.host ) = qi::_1]
133
+ >> -(' :' >> qi::ushort_) [phoenix::ref (parts.port ) = qi::_1]
134
+ ]
135
+ >> path_abempty
136
+ | path_absolute
137
+ | path_rootless
138
+ | path_empty
139
+ )
140
+ >> -(' ?' >> query)
141
+ >> -(' #' >> fragment)
46
142
),
47
143
result
48
- );
144
+ );
49
145
50
- if (ok) {
146
+ /* TODO, if (ok) {
51
147
ok = parse_specific(
52
148
parts.scheme_specific_part,
53
149
parts
54
150
);
55
- }
151
+ } */
56
152
57
153
return ok && start_ == end_;
58
154
}
0 commit comments