Commit 090dd6e4 authored by rakshasa's avatar rakshasa

Progress on uri parser.

parent 08d5aab9
......@@ -89,16 +89,6 @@ is_not_unreserved_uri_query_char(char c) {
return !is_unreserved_uri_query_char(c);
}
template<typename MPtr, typename Ftor>
inline std::string::const_iterator
uri_parse_copy_until(std::string::const_iterator first, std::string::const_iterator last,
MPtr mptr, uri_state& state, Ftor check) {
std::string::const_iterator next = std::find_if(first, last, check);
state.*mptr = std::string(first, next);
return next;
}
template<typename Ftor>
inline std::string::const_iterator
uri_string_copy_until(std::string::const_iterator first, std::string::const_iterator last,
......@@ -129,17 +119,17 @@ uri_parse_str(std::string uri, uri_state& state) {
std::string::const_iterator first = state.uri.begin();
std::string::const_iterator last = state.uri.end();
// Parse schema:
first = uri_parse_copy_until(first, last, &uri_state::schema, state, std::ptr_fun(&is_not_unreserved_uri_char));
// Parse scheme:
first = uri_string_copy_until(first, last, state.scheme, std::ptr_fun(&is_not_unreserved_uri_char));
if (first == last)
goto uri_parse_success;
if (*first++ != ':')
uri_parse_throw_error("could not find ':' after schema, found character 0x", *--first);
uri_parse_throw_error("could not find ':' after scheme, found character 0x", *--first);
// Parse resource:
first = uri_parse_copy_until(first, last, &uri_state::resource, state, std::ptr_fun(&is_not_unreserved_uri_char));
first = uri_string_copy_until(first, last, state.resource, std::ptr_fun(&is_not_unreserved_uri_char));
if (first == last)
goto uri_parse_success;
......@@ -148,7 +138,7 @@ uri_parse_str(std::string uri, uri_state& state) {
uri_parse_throw_error("could not find '?' after resource, found character 0x", *--first);
// Parse query:
first = uri_parse_copy_until(first, last, &uri_state::query, state, std::ptr_fun(&is_not_valid_uri_query_char));
first = uri_string_copy_until(first, last, state.query, std::ptr_fun(&is_not_valid_uri_query_char));
if (first == last)
goto uri_parse_success;
......
......@@ -44,6 +44,9 @@
namespace torrent { namespace utils {
typedef std::vector<std::string> uri_resource_list;
typedef std::vector<std::string> uri_query_list;
struct uri_base_state {
static const int state_empty = 0;
static const int state_valid = 1;
......@@ -56,31 +59,38 @@ struct uri_base_state {
struct uri_state : uri_base_state {
std::string uri;
std::string schema;
std::string scheme;
std::string resource;
std::string query; // Replace with state.
std::string query;
std::string fragment;
};
typedef std::vector<std::string> uri_query_list;
struct uri_resource_state : public uri_base_state {
std::string resource;
uri_resource_list path;
};
struct uri_query_state : public uri_base_state {
std::string query;
uri_query_list elements;
};
class LIBTORRENT_EXPORT uri_error : public ::torrent::input_error {
public:
uri_error(const char* msg) : ::torrent::input_error(msg) {}
uri_error(const std::string& msg) : ::torrent::input_error(msg) {}
};
void uri_parse_str(std::string uri, uri_state& state) LIBTORRENT_EXPORT;
void uri_parse_c_str(const char* uri, uri_state& state) LIBTORRENT_EXPORT;
void uri_parse_resource(std::string query, uri_query_state& state) LIBTORRENT_EXPORT;
void uri_parse_resource_authority(std::string query, uri_query_state& state) LIBTORRENT_EXPORT;
void uri_parse_resource_path(std::string query, uri_query_state& state) LIBTORRENT_EXPORT;
void uri_parse_query_str(std::string query, uri_query_state& state) LIBTORRENT_EXPORT;
void uri_parse_query_c_str(const char* query, uri_query_state& state) LIBTORRENT_EXPORT;
class LIBTORRENT_EXPORT uri_error : public ::torrent::input_error {
public:
uri_error(const char* msg) : ::torrent::input_error(msg) {}
uri_error(const std::string& msg) : ::torrent::input_error(msg) {}
};
}}
#endif
......@@ -51,6 +51,7 @@
#include "torrent/tracker_list.h"
#include "torrent/utils/log.h"
#include "torrent/utils/option_strings.h"
#include "torrent/utils/uri_parser.h"
#include "tracker_udp.h"
#include "manager.h"
......@@ -66,6 +67,8 @@ namespace torrent {
TrackerUdp::TrackerUdp(TrackerList* parent, const std::string& url, int flags) :
Tracker(parent, url, flags),
m_port(0),
m_slot_resolver(NULL),
m_readBuffer(NULL),
m_writeBuffer(NULL) {
......@@ -92,6 +95,14 @@ TrackerUdp::send_state(int state) {
close_directly();
m_latest_event = state;
// try {
// utils::uri_state uri_state;
// uri_parse_str(m_url, uri_state);
// } catch (utils::uri_error& e) {
// return receive_failed("Could not parse UDP hostname or port: " + std::string(e.what()));
// }
char hostname[1024];
if (std::sscanf(m_url.c_str(), "udp://%1023[^:]:%i", hostname, &m_port) != 2 ||
......
......@@ -19,7 +19,7 @@ UriParserTest::tearDown() {
void
test_print_uri_state(torrent::utils::uri_state state) {
std::cerr << "state.uri: " << state.uri << std::endl;
std::cerr << "state.schema: " << state.schema << std::endl;
std::cerr << "state.scheme: " << state.scheme << std::endl;
std::cerr << "state.resource: " << state.resource << std::endl;
std::cerr << "state.query: " << state.query << std::endl;
std::cerr << "state.fragment: " << state.fragment << std::endl;
......@@ -47,7 +47,7 @@ UriParserTest::test_basic_magnet() {
CPPUNIT_ASSERT(state.state == torrent::utils::uri_state::state_valid);
CPPUNIT_ASSERT(state.uri == MAGNET_BASIC);
CPPUNIT_ASSERT(state.schema == "magnet");
CPPUNIT_ASSERT(state.scheme == "magnet");
CPPUNIT_ASSERT(state.resource == "");
CPPUNIT_ASSERT(state.query == "xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C");
CPPUNIT_ASSERT(state.fragment == "");
......@@ -74,7 +74,7 @@ UriParserTest::test_query_magnet() {
CPPUNIT_ASSERT(state.state == torrent::utils::uri_state::state_valid);
CPPUNIT_ASSERT(state.uri == QUERY_MAGNET);
CPPUNIT_ASSERT(state.schema == "magnet");
CPPUNIT_ASSERT(state.scheme == "magnet");
CPPUNIT_ASSERT(state.resource == "");
CPPUNIT_ASSERT(state.query == QUERY_MAGNET_QUERY);
CPPUNIT_ASSERT(state.fragment == "");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment