adding url

This commit is contained in:
Daniel Larimer 2012-12-15 09:41:55 -05:00
parent 8c39a39dd6
commit 4be0f82dc9
2 changed files with 143 additions and 0 deletions

40
include/fc/url.hpp Normal file
View file

@ -0,0 +1,40 @@
#pragma once
#include <fc/string.hpp>
#include <fc/optional.hpp>
#include <stdint.h>
namespace fc {
typedef fc::optional<fc::string> ostring;
struct url {
url(){}
url( const string& url );
/*
url( const url& u );
url( url&& u );
url& operator=(url&& c);
url& operator=(const url& c);
*/
operator string()const { return to_string(); }
string to_string()const;
url& from_string( const string& s );
bool operator==( const url& cmp )const;
string proto; // file, ssh, tcp, http, ssl, etc...
ostring host;
ostring user;
ostring pass;
ostring path;
ostring args;
fc::optional<uint16_t> port;
};
} // namespace fc
#include <fc/reflect.hpp>
FC_REFLECT( fc::url, (proto)(host)(user)(pass)(path)(args)(port) )

103
src/url.cpp Normal file
View file

@ -0,0 +1,103 @@
#include <fc/url.hpp>
#include <fc/Value.hpp>
#include <fc/error_report.hpp>
#include <fc/lexical_cast.hpp>
#include <fc/value_cast.hpp>
#include <fc/sstream.hpp>
namespace fc {
// url::url( const url& u );
#if 0
url::url( url&& u )
:proto(fc::move(u.proto)),
host(fc::move(u.host)),
user(fc::move(u.user)),
pass(fc::move(u.pass)),
path(fc::move(u.path)),
args(fc::move(u.args)),
port(u.port){}
url& url::operator=(url&& c)
{
fc::swap(*this,c);
return *this;
}
// url::url& operator=(const url& c) {
// }
#endif
url::url( const string& s ) {
from_string(s);
}
string url::to_string()const {
fc::stringstream ss;
ss<<proto<<"://";
if( user ) {
ss << *user;
if( pass ) {
ss<<":"<<*pass;
}
ss<<"@";
}
ss<<*host;
if( port ) ss<<":"<<*port;
if( path ) ss<<"/"<<*path;
if( args ) ss<<"?"<<*args;
return ss.str();
}
/**
* proto://user:pass@host:port/~/path?args
* proto://user:pass@host:port/absolute?args
*/
url& url::from_string( const string& s ) {
fc::stringstream ss(s);
fc::string _proto,skip,_user,_pass,_host,_port,_path,_args;
fc::getline( ss, _proto, ':' );
fc::getline( ss, skip, '/' );
fc::getline( ss, skip, '/' );
if( s.find('@') != fc::string::npos ) {
fc::string user_pass;
fc::getline( ss, user_pass, '@' );
fc::stringstream upss(user_pass);
if( user_pass.find( ':' ) != fc::string::npos ) {
fc::getline( upss, _user, ':' );
fc::getline( upss, _pass, ':' );
user = fc::move(_user);
pass = fc::move(_pass);
} else {
user = fc::move(user_pass);
}
}
fc::string host_port;
fc::getline( ss, host_port, '/' );
auto pos = host_port.find( ':' );
if( pos != fc::string::npos ) {
try {
port = fc::lexical_cast<uint16_t>( host_port.substr( pos+1 ) );
} catch ( ... ) {
FC_THROW_REPORT( "Unable to parse port field in url", value().set( "url", s ) );
}
host = host_port.substr(0,pos);
} else {
host = fc::move(host_port);
}
fc::getline( ss, _path, '?' );
fc::getline( ss, _args );
path = fc::move(_path);
if( _args.size() ) args = fc::move(_args);
return *this;
}
bool url::operator==( const url& cmp )const {
return cmp.proto == proto &&
cmp.host == host &&
cmp.user == user &&
cmp.pass == pass &&
cmp.path == path &&
cmp.args == args &&
cmp.port == port;
}
} // namespace fc