--- a/src/pathut.cpp
+++ b/src/pathut.cpp
@@ -52,6 +52,7 @@
#include <stack>
#include <set>
#include <vector>
+#include <regex>
#include "pathut.h"
#include "smallut.h"
@@ -761,6 +762,96 @@
return url.find("file://") == 0;
}
+static std::regex
+re_uriparse("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?",
+ std::regex::extended);
+
+ParsedUri::ParsedUri(std::string uri)
+{
+ std::smatch mr;
+ parsed = regex_match(uri, mr, re_uriparse);
+ if (!parsed)
+ return;
+ // cf http://www.ietf.org/rfc/rfc2396.txt
+ // scheme = $2
+ // authority = $4
+ // path = $5
+ // query = $7
+ // fragment = $9
+ if (mr[2].matched) {
+ scheme = mr[2].str();
+ }
+ if (mr[4].matched) {
+ string auth = mr[4].str();
+ // user:pass@host, user@host
+ string::size_type at = auth.find_first_of('@');
+ if (at != string::npos) {
+ host = auth.substr(at+1);
+ string::size_type colon = auth.find_first_of(':');
+ if (colon != string::npos && colon < at) {
+ user = auth.substr(0, colon);
+ pass = auth.substr(colon+1, at-colon-1);
+ } else {
+ user = auth.substr(0, at);
+ }
+ } else {
+ host.swap(auth);
+ }
+ string::size_type pc = host.find_first_of(':');
+ if (pc != string::npos) {
+ port = host.substr(pc+1);
+ host = host.substr(0, pc);
+ }
+ }
+ if (mr[5].matched) {
+ path = mr[5].str();
+ }
+ if (mr[7].matched) {
+ query = mr[7].str();
+ string::size_type pos=0, amp, eq;
+ string nm, val;
+ for (;;) {
+ nm.clear();
+ val.clear();
+ amp = query.find_first_of('&', pos);
+ //cerr << "pos " << pos << " amp " << amp << endl;
+ if (amp > pos && amp != string::npos) {
+ eq = query.find_first_of('=', pos);
+ if (eq > amp || eq == string::npos) {
+ nm = query.substr(pos, amp-pos);
+ } else {
+ nm = query.substr(pos, eq-pos);
+ val = query.substr(eq+1, amp-eq-1);
+ }
+ pos = amp + 1;
+ } else if (amp == string::npos) {
+ if (pos < query.size()-1) {
+ eq = query.find_first_of('=', pos);
+ if (eq == string::npos) {
+ nm = query.substr(pos);
+ } else {
+ nm = query.substr(pos, eq-pos);
+ val = query.substr(eq+1);
+ }
+ }
+ pos = query.size()-1;
+ } else {
+ pos++;
+ }
+ if (!nm.empty()) {
+ parsedquery.push_back(pair<string,string>(nm, val));
+ }
+ if (pos >= query.size()-1) {
+ break;
+ }
+ }
+
+ }
+ if (mr[9].matched) {
+ fragment = mr[9].str();
+ }
+}
+
bool readdir(const string& dir, string& reason, set<string>& entries)
{
struct stat st;