Skip to content

Commit 436a29d

Browse files
committed
Bright idea means I realise I could put the URI range stuff in and make it work :)
1 parent 96b5267 commit 436a29d

File tree

4 files changed

+126
-65
lines changed

4 files changed

+126
-65
lines changed

boost/network/uri/detail/uri_parts.hpp

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# define BOOST_NETWORK_URL_DETAIL_URL_PARTS_HPP_
88

99

10+
# include <boost/range/iterator_range.hpp>
1011
# include <boost/optional.hpp>
1112

1213

@@ -15,32 +16,32 @@ namespace network {
1516
namespace uri {
1617
namespace detail {
1718
template <
18-
class String
19+
class FwdIter
1920
>
2021
struct hierarchical_part {
21-
boost::optional<String> user_info;
22-
boost::optional<String> host;
23-
boost::optional<String> port;
24-
boost::optional<String> path;
22+
optional<iterator_range<FwdIter> > user_info;
23+
optional<iterator_range<FwdIter> > host;
24+
optional<iterator_range<FwdIter> > port;
25+
optional<iterator_range<FwdIter> > path;
2526
};
2627

2728
template <
28-
class String
29+
class FwdIter
2930
>
3031
struct uri_parts {
31-
String scheme;
32-
hierarchical_part<String> hier_part;
33-
boost::optional<String> query;
34-
boost::optional<String> fragment;
32+
iterator_range<FwdIter> scheme;
33+
hierarchical_part<FwdIter> hier_part;
34+
optional<iterator_range<FwdIter> > query;
35+
optional<iterator_range<FwdIter> > fragment;
3536

3637
void clear() {
37-
scheme.clear();
38-
hier_part.user_info = boost::optional<String>();
39-
hier_part.host = boost::optional<String>();
40-
hier_part.port = boost::optional<String>();
41-
hier_part.path = boost::optional<String>();
42-
query = boost::optional<String>();
43-
fragment = boost::optional<String>();
38+
scheme = iterator_range<FwdIter>();
39+
hier_part.user_info = optional<iterator_range<FwdIter> >();
40+
hier_part.host = optional<iterator_range<FwdIter> >();
41+
hier_part.port = optional<iterator_range<FwdIter> >();
42+
hier_part.path = optional<iterator_range<FwdIter> >();
43+
query = optional<iterator_range<FwdIter> >();
44+
fragment = optional<iterator_range<FwdIter> >();
4445
}
4546
};
4647
} // namespace detail

boost/network/uri/uri.hpp

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace uri {
2222
namespace detail {
2323
bool parse(std::string::const_iterator first,
2424
std::string::const_iterator last,
25-
uri_parts<std::string> &parts);
25+
uri_parts<std::string::const_iterator> &parts);
2626
} // namespace detail
2727

2828

@@ -32,8 +32,8 @@ class uri
3232
public:
3333

3434
typedef std::string string_type;
35-
typedef string_type::iterator iterator;
3635
typedef string_type::const_iterator const_iterator;
36+
typedef boost::iterator_range<std::string::const_iterator> const_range_type;
3737

3838
uri()
3939
: is_valid_(false) {
@@ -80,60 +80,87 @@ class uri
8080
parse();
8181
}
8282

83-
iterator begin() {
84-
return uri_.begin();
85-
}
86-
8783
const_iterator begin() const {
8884
return uri_.begin();
8985
}
9086

91-
iterator end() {
92-
return uri_.end();
93-
}
94-
9587
const_iterator end() const {
9688
return uri_.end();
9789
}
9890

99-
string_type scheme() const {
91+
const_range_type scheme_range() const {
10092
return uri_parts_.scheme;
10193
}
10294

103-
string_type user_info() const {
95+
const_range_type user_info_range() const {
10496
return uri_parts_.hier_part.user_info?
10597
uri_parts_.hier_part.user_info.get() :
106-
string_type();
98+
const_range_type();
10799
}
108100

109-
string_type host() const {
101+
const_range_type host_range() const {
110102
return uri_parts_.hier_part.host?
111103
uri_parts_.hier_part.host.get() :
112-
string_type();
104+
const_range_type();
113105
}
114106

115-
string_type port() const {
107+
const_range_type port_range() const {
116108
return uri_parts_.hier_part.port?
117109
uri_parts_.hier_part.port.get() :
118-
string_type();
110+
const_range_type();
119111
}
120112

121-
string_type path() const {
113+
const_range_type path_range() const {
122114
return uri_parts_.hier_part.path?
123115
uri_parts_.hier_part.path.get() :
124-
string_type();
116+
const_range_type();
125117
}
126118

127-
string_type query() const {
119+
const_range_type query_range() const {
128120
return uri_parts_.query ?
129121
uri_parts_.query.get() :
130-
string_type();
122+
const_range_type();
131123
}
132124

133-
string_type fragment() const {
125+
const_range_type fragment_range() const {
134126
return uri_parts_.fragment?
135127
uri_parts_.fragment.get() :
136-
string_type();
128+
const_range_type();
129+
}
130+
131+
string_type scheme() const {
132+
const_range_type range = scheme_range();
133+
return string_type(boost::begin(range), boost::end(range));
134+
}
135+
136+
string_type user_info() const {
137+
const_range_type range = user_info_range();
138+
return string_type(boost::begin(range), boost::end(range));
139+
}
140+
141+
string_type host() const {
142+
const_range_type range = host_range();
143+
return string_type(boost::begin(range), boost::end(range));
144+
}
145+
146+
string_type port() const {
147+
const_range_type range = port_range();
148+
return string_type(boost::begin(range), boost::end(range));
149+
}
150+
151+
string_type path() const {
152+
const_range_type range = path_range();
153+
return string_type(boost::begin(range), boost::end(range));
154+
}
155+
156+
string_type query() const {
157+
const_range_type range = query_range();
158+
return string_type(boost::begin(range), boost::end(range));
159+
}
160+
161+
string_type fragment() const {
162+
const_range_type range = fragment_range();
163+
return string_type(boost::begin(range), boost::end(range));
137164
}
138165

139166
string_type string() const {
@@ -162,7 +189,7 @@ class uri
162189
void parse();
163190

164191
string_type uri_;
165-
detail::uri_parts<std::string> uri_parts_;
192+
detail::uri_parts<const_iterator> uri_parts_;
166193
bool is_valid_;
167194

168195
};

libs/network/src/uri/parse.cpp

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,22 @@
1111

1212
BOOST_FUSION_ADAPT_TPL_STRUCT
1313
(
14-
(String),
15-
(boost::network::uri::detail::hierarchical_part)(String),
16-
(boost::optional<String>, user_info)
17-
(boost::optional<String>, host)
18-
(boost::optional<String>, port)
19-
(boost::optional<String>, path)
14+
(FwdIter),
15+
(boost::network::uri::detail::hierarchical_part)(FwdIter),
16+
(boost::optional<boost::iterator_range<FwdIter> >, user_info)
17+
(boost::optional<boost::iterator_range<FwdIter> >, host)
18+
(boost::optional<boost::iterator_range<FwdIter> >, port)
19+
(boost::optional<boost::iterator_range<FwdIter> >, path)
2020
);
2121

2222
BOOST_FUSION_ADAPT_TPL_STRUCT
2323
(
24-
(String),
25-
(boost::network::uri::detail::uri_parts)(String),
26-
(String, scheme)
27-
(boost::network::uri::detail::hierarchical_part<String>, hier_part)
28-
(boost::optional<String>, query)
29-
(boost::optional<String>, fragment)
24+
(FwdIter),
25+
(boost::network::uri::detail::uri_parts)(FwdIter),
26+
(boost::iterator_range<FwdIter>, scheme)
27+
(boost::network::uri::detail::hierarchical_part<FwdIter>, hier_part)
28+
(boost::optional<boost::iterator_range<FwdIter> >, query)
29+
(boost::optional<boost::iterator_range<FwdIter> >, fragment)
3030
);
3131

3232
namespace boost {
@@ -40,7 +40,7 @@ template <
4040
>
4141
struct uri_grammar : qi::grammar<
4242
typename String::const_iterator
43-
, detail::uri_parts<String>()> {
43+
, detail::uri_parts<typename String::const_iterator>()> {
4444

4545
typedef String string_type;
4646
typedef typename String::const_iterator const_iterator;
@@ -176,9 +176,9 @@ struct uri_grammar : qi::grammar<
176176
)
177177
|
178178
(
179-
qi::attr(string_type())
180-
>> qi::attr(string_type())
181-
>> qi::attr(string_type())
179+
qi::attr(iterator_range<const_iterator>())
180+
>> qi::attr(iterator_range<const_iterator>())
181+
>> qi::attr(iterator_range<const_iterator>())
182182
>> (
183183
path_absolute
184184
| path_rootless
@@ -195,14 +195,14 @@ struct uri_grammar : qi::grammar<
195195
;
196196
}
197197

198-
qi::rule<const_iterator, typename string_type::value_type()>
198+
qi::rule<const_iterator, typename iterator_range<const_iterator>::value_type()>
199199
gen_delims, sub_delims, reserved, unreserved;
200200
qi::rule<const_iterator, string_type()>
201201
pct_encoded, pchar;
202202

203203
qi::rule<const_iterator, string_type()>
204204
segment, segment_nz, segment_nz_nc;
205-
qi::rule<const_iterator, string_type()>
205+
qi::rule<const_iterator, iterator_range<const_iterator>()>
206206
path_abempty, path_absolute, path_rootless, path_empty;
207207

208208
qi::rule<const_iterator, string_type()>
@@ -211,23 +211,23 @@ struct uri_grammar : qi::grammar<
211211
qi::rule<const_iterator, string_type()>
212212
h16, ls32;
213213

214-
qi::rule<const_iterator, string_type()>
214+
qi::rule<const_iterator, iterator_range<const_iterator>()>
215215
host, port;
216216

217-
qi::rule<const_iterator, string_type()>
217+
qi::rule<const_iterator, iterator_range<const_iterator>()>
218218
scheme, user_info, query, fragment;
219219

220-
qi::rule<const_iterator, hierarchical_part<string_type>()>
220+
qi::rule<const_iterator, hierarchical_part<const_iterator>()>
221221
hier_part;
222222

223223
// actual uri parser
224-
qi::rule<const_iterator, uri_parts<string_type>()> start;
224+
qi::rule<const_iterator, uri_parts<const_iterator>()> start;
225225

226226
};
227227

228228
bool parse(std::string::const_iterator first,
229229
std::string::const_iterator last,
230-
uri_parts<std::string> &parts) {
230+
uri_parts<std::string::const_iterator> &parts) {
231231
namespace qi = boost::spirit::qi;
232232
static detail::uri_grammar<std::string> grammar;
233233
bool is_valid = qi::parse(first, last, grammar, parts);

libs/network/test/uri/url_test.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
using namespace boost::network;
1717

18-
//BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(basic_uri_test, 1)
1918
BOOST_AUTO_TEST_CASE(basic_uri_test) {
2019
uri::uri instance("http://www.example.com/");
2120
BOOST_REQUIRE(uri::valid(instance));
@@ -28,6 +27,21 @@ BOOST_AUTO_TEST_CASE(basic_uri_test) {
2827
BOOST_CHECK_EQUAL(uri::fragment(instance), "");
2928
}
3029

30+
BOOST_AUTO_TEST_CASE(basic_uri_range_test) {
31+
uri::uri instance("http://www.example.com/");
32+
BOOST_REQUIRE(uri::valid(instance));
33+
BOOST_CHECK(instance.scheme_range());
34+
BOOST_CHECK(boost::equal(instance.scheme_range(), boost::as_literal("http")));
35+
BOOST_CHECK(!instance.user_info_range());
36+
BOOST_CHECK(instance.host_range());
37+
BOOST_CHECK(boost::equal(instance.host_range(), boost::as_literal("www.example.com")));
38+
BOOST_CHECK(!instance.port_range());
39+
BOOST_CHECK(instance.path_range());
40+
BOOST_CHECK(boost::equal(instance.path_range(), boost::as_literal("/")));
41+
BOOST_CHECK(!instance.query_range());
42+
BOOST_CHECK(!instance.fragment_range());
43+
}
44+
3145
BOOST_AUTO_TEST_CASE(full_uri_test) {
3246
uri::uri instance("http://user:password@www.example.com:80/path?query#fragment");
3347
BOOST_REQUIRE(uri::valid(instance));
@@ -42,6 +56,25 @@ BOOST_AUTO_TEST_CASE(full_uri_test) {
4256
BOOST_CHECK_EQUAL(uri::fragment(instance), "fragment");
4357
}
4458

59+
BOOST_AUTO_TEST_CASE(full_uri_range_test) {
60+
uri::uri instance("http://user:password@www.example.com:80/path?query#fragment");
61+
BOOST_REQUIRE(uri::valid(instance));
62+
BOOST_CHECK(instance.scheme_range());
63+
BOOST_CHECK(boost::equal(instance.scheme_range(), boost::as_literal("http")));
64+
BOOST_CHECK(instance.user_info_range());
65+
BOOST_CHECK(boost::equal(instance.user_info_range(), boost::as_literal("user:password")));
66+
BOOST_CHECK(instance.host_range());
67+
BOOST_CHECK(boost::equal(instance.host_range(), boost::as_literal("www.example.com")));
68+
BOOST_CHECK(instance.port_range());
69+
BOOST_CHECK(boost::equal(instance.port_range(), boost::as_literal("80")));
70+
BOOST_CHECK(instance.path_range());
71+
BOOST_CHECK(boost::equal(instance.path_range(), boost::as_literal("/path")));
72+
BOOST_CHECK(instance.query_range());
73+
BOOST_CHECK(boost::equal(instance.query_range(), boost::as_literal("query")));
74+
BOOST_CHECK(instance.fragment_range());
75+
BOOST_CHECK(boost::equal(instance.fragment_range(), boost::as_literal("fragment")));
76+
}
77+
4578
BOOST_AUTO_TEST_CASE(mailto_test) {
4679
uri::uri instance("mailto:john.doe@example.com");
4780
BOOST_REQUIRE(uri::valid(instance));

0 commit comments

Comments
 (0)