Skip to content

Commit db2fcc3

Browse files
committed
Major parser rewrite
1 parent 564642c commit db2fcc3

File tree

6 files changed

+244
-63
lines changed

6 files changed

+244
-63
lines changed

boost/network/uri.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99
#include <boost/network/tags.hpp>
1010
#include <boost/network/traits/string.hpp>
1111
#include <boost/network/uri/basic_uri.hpp>
12-
#include <boost/network/uri/http/uri.hpp>
12+
// TODO, #include <boost/network/uri/http/uri.hpp>
1313

1414
namespace boost { namespace network { namespace uri {
1515

1616
typedef basic_uri<boost::network::tags::default_string> uri;
1717
typedef basic_uri<boost::network::tags::default_wstring> wuri;
1818

19-
namespace http {
19+
/* TODO, namespace http {
2020
typedef basic_uri<tags::http_default_8bit_tcp_resolve> uri;
21-
}
21+
} */
2222

2323
} // namespace uri
2424
} // namespace network

boost/network/uri/basic_uri.hpp

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
#ifndef BOOST_NETWORK_URL_BASIC_URL_
22
#define BOOST_NETWORK_URL_BASIC_URL_
33

4-
// Copyright 2009 Dean Michael Berris.
4+
// Copyright 2009 Dean Michael Berris, Jeroen Habraken.
55
// Distributed under the Boost Software License, Version 1.0.
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/adapted/std_pair.hpp>
109
#include <boost/range.hpp>
1110

1211
#include <boost/network/tags.hpp>
@@ -45,17 +44,38 @@ namespace boost { namespace network { namespace uri {
4544

4645
void swap(uri_base & other) {
4746
using std::swap;
47+
4848
swap(other.raw_, raw_);
4949
swap(other.parts_, parts_);
5050
swap(other.valid_, valid_);
5151
}
5252

53-
string_type protocol() const {
53+
string_type scheme() const {
5454
return parts_.scheme;
5555
}
5656

57-
string_type rest() const {
58-
return parts_.scheme_specific_part;
57+
string_type user_info() const {
58+
return parts_.user_info ? *parts_.user_info : string_type();
59+
}
60+
61+
string_type host() const {
62+
return parts_.host ? *parts_.host : string_type();
63+
}
64+
65+
uint16_t port() const {
66+
return parts_.port ? *parts_.port : 0;
67+
}
68+
69+
string_type path() const {
70+
return parts_.path;
71+
}
72+
73+
string_type query() const {
74+
return parts_.query ? *parts_.query : string_type();
75+
}
76+
77+
string_type fragment() const {
78+
return parts_.fragment ? *parts_.fragment : string_type();
5979
}
6080

6181
bool valid() const {
@@ -97,15 +117,50 @@ namespace boost { namespace network { namespace uri {
97117
template <class Tag>
98118
inline
99119
typename string<Tag>::type
100-
protocol(basic_uri<Tag> const & uri) {
101-
return uri.protocol();
120+
scheme(basic_uri<Tag> const & uri) {
121+
return uri.scheme();
102122
}
103123

104124
template <class Tag>
105-
inline
106-
typename string<Tag>::type
107-
rest(basic_uri<Tag> const & uri) {
108-
return uri.rest();
125+
inline
126+
typename string<Tag>::type
127+
user_info(basic_uri<Tag> const & uri) {
128+
return uri.user_info();
129+
}
130+
131+
template <class Tag>
132+
inline
133+
typename string<Tag>::type
134+
host(basic_uri<Tag> const & uri) {
135+
return uri.host();
136+
}
137+
138+
template <class Tag>
139+
inline
140+
uint16_t
141+
port(basic_uri<Tag> const & uri) {
142+
return uri.port();
143+
}
144+
145+
template <class Tag>
146+
inline
147+
typename string<Tag>::type
148+
path(basic_uri<Tag> const & uri) {
149+
return uri.path();
150+
}
151+
152+
template <class Tag>
153+
inline
154+
typename string<Tag>::type
155+
query(basic_uri<Tag> const & uri) {
156+
return uri.query();
157+
}
158+
159+
template <class Tag>
160+
inline
161+
typename string<Tag>::type
162+
fragment(basic_uri<Tag> const & uri) {
163+
return uri.fragment();
109164
}
110165

111166
template <class Tag>

boost/network/uri/detail/parse_uri.hpp

Lines changed: 112 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@
77
// http://www.boost.org/LICENSE_1_0.txt)
88

99
#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>
1212
#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>
1415
#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>
1721

1822
namespace boost { namespace network { namespace uri {
1923

@@ -29,30 +33,122 @@ namespace boost { namespace network { namespace uri {
2933
namespace qi = boost::spirit::qi;
3034

3135
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;
3339

3440
iterator start_ = begin(range);
3541
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_("/?"))];
38123

39124
bool ok = qi::parse(
40-
start_, end_,
125+
start_, end_,
41126
(
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)
46142
),
47143
result
48-
);
144+
);
49145

50-
if (ok) {
146+
/* TODO, if (ok) {
51147
ok = parse_specific(
52148
parts.scheme_specific_part,
53149
parts
54150
);
55-
}
151+
} */
56152

57153
return ok && start_ == end_;
58154
}

boost/network/uri/detail/uri_parts.hpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
#ifndef BOOST_NETWORK_URL_DETAIL_URL_PARTS_HPP_
22
#define BOOST_NETWORK_URL_DETAIL_URL_PARTS_HPP_
33

4-
// Copyright 2009 Dean Michael Berris.
4+
// Copyright 2009 Dean Michael Berris, Jeroen Habraken.
55
// Distributed under the Boost Software License, Version 1.0.
66
// (See accompanying file LICENSE_1_0.txt of copy at
77
// http://www.boost.org/LICENSE_1_0.txt)
88

9+
#include <boost/cstdint.hpp>
10+
#include <boost/optional.hpp>
11+
912
#include <boost/network/traits/string.hpp>
1013

1114
namespace boost { namespace network { namespace uri {
@@ -15,21 +18,39 @@ namespace boost { namespace network { namespace uri {
1518
template <class Tag>
1619
struct uri_parts {
1720
typedef typename string<Tag>::type string_type;
21+
1822
string_type scheme;
19-
string_type scheme_specific_part;
23+
boost::optional<string_type> user_info;
24+
boost::optional<string_type> host;
25+
boost::optional<boost::uint16_t> port;
26+
string_type path;
27+
boost::optional<string_type> query;
28+
boost::optional<string_type> fragment;
2029
};
2130

2231
template <class Tag>
2332
inline void swap(uri_parts<Tag> & l, uri_parts<Tag> & r) {
2433
using std::swap;
34+
2535
swap(l.scheme, r.scheme);
26-
swap(l.scheme_specific_part, r.scheme_specific_part);
36+
swap(l.user_info, r.user_info);
37+
swap(l.host, r.host);
38+
swap(l.port, r.port);
39+
swap(l.path, r.path);
40+
swap(l.query, r.query);
41+
swap(l.fragment, r.fragment);
2742
}
2843

2944
template <class Tag>
3045
inline
3146
bool operator==(uri_parts<Tag> const & l, uri_parts<Tag> const & r) {
32-
return (l.scheme == r.scheme) && (l.scheme_specific_part == r.scheme_specific_part);
47+
return (l.scheme == r.scheme) &&
48+
(l.user_info == r.user_info) &&
49+
(l.host == r.host) &&
50+
(l.port == r.port) &&
51+
(l.path == r.path) &&
52+
(l.query == r.query) &&
53+
(l.fragment == r.fragment);
3354
}
3455

3556
template <class Tag>

boost/network/uri/uri_concept.hpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef BOOST_NETWORK_URL_URL_CONCEPT_HPP_
22
#define BOOST_NETWORK_URL_URL_CONCEPT_HPP_
33

4-
// Copyright 2009 Dean Michael Berris.
4+
// Copyright 2009 Dean Michael Berris, Jeroen Habraken.
55
// Distributed under the Boost Software License, Version 1.0.
66
// (See accompanying file LICENSE_1_0.txt or copy at
77
// http://www.boost.org/LICENSE_1_0.txt)
@@ -17,10 +17,19 @@ namespace boost { namespace network { namespace uri {
1717
BOOST_CONCEPT_USAGE(URI)
1818
{
1919
U uri_(uri); // copy constructable
20+
2021
U temp;
2122
swap(temp, uri_); // swappable
22-
string_type protocol_ = protocol(uri); // support protocol function
23-
string_type rest_ = rest(uri);
23+
24+
string_type scheme_ = scheme(uri); // support functions
25+
string_type user_info_ = user_info(uri);
26+
string_type host_ = host(uri);
27+
uint16_t port_ = port(uri);
28+
port_ = 0;
29+
string_type path_ = path(uri);
30+
string_type query_ = query(uri);
31+
string_type fragment_ = fragment(uri);
32+
2433
bool valid_ = valid(uri);
2534
valid_ = false;
2635
}

0 commit comments

Comments
 (0)