Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit551a6b6

Browse files
committed
Rewritten as a grammar, added IPv4 support
1 parentf48c117 commit551a6b6

File tree

4 files changed

+240
-121
lines changed

4 files changed

+240
-121
lines changed

‎boost/network/uri/detail/parse_uri.hpp

Lines changed: 210 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -6,148 +6,243 @@
66
// (See accompanying file LICENSE_1_0.txt or copy at
77
// http://www.boost.org/LICENSE_1_0.txt)
88

9-
#include<boost/fusion/tuple.hpp>
109
#include<boost/spirit/include/phoenix_operator.hpp>
11-
#include<boost/spirit/include/qi_char_.hpp>
10+
#include<boost/spirit/include/qi_attr.hpp>
1211
#include<boost/spirit/include/qi_core.hpp>
1312
#include<boost/spirit/include/qi_eps.hpp>
13+
#include<boost/spirit/include/qi_grammar.hpp>
1414
#include<boost/spirit/include/qi_omit.hpp>
15-
#include<boost/spirit/include/qi_parse.hpp>
1615
#include<boost/spirit/include/qi_raw.hpp>
1716
#include<boost/spirit/include/qi_rule.hpp>
1817
#include<boost/spirit/include/qi_sequence.hpp>
18+
#include<boost/spirit/include/version.hpp>
1919

2020
#include<boost/network/uri/detail/uri_parts.hpp>
2121

22+
namespaceboost {namespacespirit {namespacetraits {
23+
24+
template<classTag>
25+
structtransform_attribute<
26+
boost::network::uri::detail::uri_parts<Tag>,
27+
typename boost::network::uri::detail::uri_parts_tuple<Tag>::type
28+
>
29+
{
30+
typedeftypename boost::network::uri::detail::uri_parts_tuple<Tag>::type type;
31+
32+
static typepre(boost::network::uri::detail::uri_parts<Tag> & parts) {
33+
typedeftypename boost::network::string<Tag>::type string_type;
34+
35+
boost::fusion::tuple<
36+
boost::optional<string_type> &,
37+
boost::optional<string_type> &,
38+
boost::optional<boost::uint16_t> &,
39+
string_type &
40+
> hier_part =
41+
boost::fusion::tie(
42+
parts.user_info,
43+
parts.host,
44+
parts.port,
45+
parts.path
46+
);
47+
48+
returnboost::fusion::tie(
49+
parts.scheme,
50+
hier_part,
51+
parts.query,
52+
parts.fragment
53+
);
54+
}
55+
56+
staticvoidpost(boost::network::uri::detail::uri_parts<Tag> &, typeconst &) { }
57+
58+
#if SPIRIT_VERSION >= 0x2030
59+
staticvoidfail(boost::network::uri::detail::uri_parts<Tag> & val) { }
60+
#endif
61+
};
62+
63+
#if SPIRIT_VERSION < 0x2030
64+
template<typename Exposed,typename Transformed>
65+
structtransform_attribute<
66+
optional<Exposed>,
67+
Transformed,
68+
typename disable_if<is_same<optional<Exposed>, Transformed> >::type
69+
>
70+
{
71+
typedef Transformed & type;
72+
73+
static Transformed &pre(optional<Exposed> & val) {
74+
if (!val)
75+
val =Transformed();
76+
return boost::get<Transformed>(val);
77+
}
78+
79+
staticvoidpost(optional<Exposed> &, Transformedconst &) { }
80+
};
81+
#endif
82+
83+
}// namespace traits
84+
85+
}// namespace spirit
86+
87+
}// namespace boost
88+
2289
namespaceboost {namespacenetwork {namespaceuri {
2390

2491
namespacedetail {
2592

93+
namespaceqi= boost::spirit::qi;
94+
95+
template<typename Iterator,classTag>
96+
structuri_grammar : qi::grammar<Iterator, uri_parts<Tag>()> {
97+
uri_grammar() : uri_grammar::base_type(start,"uri") {
98+
// gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
99+
gen_delims =qi::char_(":/?#[]@");
100+
// sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
101+
sub_delims =qi::char_("!$&'()*+,;=");
102+
// reserved = gen-delims / sub-delims
103+
reserved = gen_delims | sub_delims;
104+
// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
105+
unreserved = qi::alnum |qi::char_("-._~");
106+
// pct-encoded = "%" HEXDIG HEXDIG
107+
pct_encoded =qi::char_("%") >>qi::repeat(2)[qi::xdigit];
108+
109+
// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
110+
pchar = qi::raw[
111+
unreserved | pct_encoded | sub_delims |qi::char_(":@")
112+
];
113+
114+
// segment = *pchar
115+
segment = qi::raw[*pchar];
116+
// segment-nz = 1*pchar
117+
segment_nz = qi::raw[+pchar];
118+
// segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
119+
segment_nz_nc = qi::raw[
120+
+(unreserved | pct_encoded | sub_delims |qi::char_("@"))
121+
];
122+
// path-abempty = *( "/" segment )
123+
path_abempty = qi::raw[*(qi::char_("/") >> segment)];
124+
// path-absolute = "/" [ segment-nz *( "/" segment ) ]
125+
path_absolute = qi::raw[
126+
qi::char_("/")
127+
>> -(segment_nz >> *(qi::char_("/") >> segment))
128+
];
129+
// path-rootless = segment-nz *( "/" segment )
130+
path_rootless = qi::raw[
131+
segment_nz >> *(qi::char_("/") >> segment)
132+
];
133+
// path-empty = 0<pchar>
134+
path_empty = qi::eps;
135+
136+
// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
137+
scheme = qi::alpha >> *(qi::alnum |qi::char_("+.-"));
138+
139+
// user_info = *( unreserved / pct-encoded / sub-delims / ":" )
140+
user_info = qi::raw[
141+
*(unreserved | pct_encoded | sub_delims |qi::char_(":"))
142+
];
143+
144+
// dec-octet = DIGIT / %x31-39 DIGIT / "1" 2DIGIT / "2" %x30-34 DIGIT / "25" %x30-35
145+
dec_octet =
146+
!(qi::lit('0') >> qi::digit)
147+
>> qi::raw[
148+
qi::uint_parser<boost::uint8_t,10,1,3>()
149+
];
150+
// IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
151+
ipv4address = qi::raw[
152+
dec_octet >>qi::repeat(3)[qi::lit('.') >> dec_octet]
153+
];
154+
// reg-name = *( unreserved / pct-encoded / sub-delims )
155+
reg_name = qi::raw[
156+
*(unreserved | pct_encoded | sub_delims)
157+
];
158+
// TODO, host = IP-literal / IPv4address / reg-name
159+
host = ipv4address | reg_name;
160+
161+
// query = *( pchar / "/" / "?" )
162+
query = qi::raw[*(pchar |qi::char_("/?"))];
163+
// fragment = *( pchar / "/" / "?" )
164+
fragment = qi::raw[*(pchar |qi::char_("/?"))];
165+
166+
// hier-part = "//" authority path-abempty / path-absolute / path-rootless / path-empty
167+
// authority = [ userinfo "@" ] host [ ":" port ]
168+
hier_part =
169+
(
170+
"//"
171+
>> -(user_info >>'@')
172+
>> host
173+
>> -(':' >> qi::ushort_)
174+
>> path_abempty
175+
)
176+
|
177+
(
178+
qi::attr(optional<typename boost::network::string<Tag>::type>())
179+
>>qi::attr(optional<typename boost::network::string<Tag>::type>())
180+
>>qi::attr(optional<boost::uint16_t>())
181+
>> (
182+
path_absolute
183+
| path_rootless
184+
| path_empty
185+
)
186+
);
187+
188+
start = uri;
189+
uri =
190+
scheme >>':'
191+
>> hier_part
192+
>> -('?' >> query)
193+
>> -('#' >> fragment);
194+
}
195+
196+
typedeftypename string<Tag>::type string_type;
197+
198+
qi::rule<Iterator,typenamestring_type::value_type()>
199+
gen_delims, sub_delims, reserved, unreserved;
200+
qi::rule<Iterator, string_type()>
201+
pct_encoded, pchar;
202+
203+
qi::rule<Iterator, string_type()>
204+
segment, segment_nz, segment_nz_nc;
205+
qi::rule<Iterator, string_type()>
206+
path_abempty, path_absolute, path_rootless, path_empty;
207+
208+
qi::rule<Iterator, string_type()>
209+
dec_octet, ipv4address, reg_name, host;
210+
211+
qi::rule<Iterator, string_type()>
212+
scheme, user_info, query, fragment;
213+
214+
qi::rule<Iterator, boost::fusion::tuple<
215+
optional<string_type> &,
216+
optional<string_type> &,
217+
optional<boost::uint16_t> &,
218+
string_type &
219+
>()> hier_part;
220+
221+
// start rule of grammar
222+
qi::rule<Iterator, uri_parts<Tag>()> start;
223+
224+
// actual uri parser
225+
qi::rule<Iterator,typename uri_parts_tuple<Tag>::type()> uri;
226+
};
227+
26228
template<classTag>
27229
inlineboolparse_specific(uri_parts<Tag> & parts) {
28230
returntrue;
29231
}
30232

31233
template<classRange,classTag>
32234
inlineboolparse_uri(Range & range, uri_parts<Tag> & parts) {
33-
namespaceqi= boost::spirit::qi;
34-
35235
typedeftypename range_iterator<Range>::type iterator;
36236

37-
typedeftypename string<Tag>::type string_type;
38-
typedeftypename string<Tag>::type::value_type char_type;
39-
40237
iterator start_ =begin(range);
41238
iterator end_ =end(range);
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-
);
54239

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_("/?"))];
123-
124-
bool ok =qi::parse(
125-
start_, end_,
126-
(
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)
142-
),
143-
result
144-
);
240+
uri_grammar<iterator, Tag> grammar;
145241

146-
if (ok) {
147-
ok =parse_specific(
148-
parts
149-
);
150-
}
242+
bool ok =qi::parse(start_, end_, grammar, parts);
243+
244+
if (ok)
245+
ok =parse_specific(parts);
151246

152247
return ok && start_ == end_;
153248
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp