30 init( std::string() ) ;
40 return join( m_protocol , m_authorisation , address() , m_path , m_params , m_anchor ) ;
43 std::string
G::Url::join(
const std::string & protocol ,
const std::string & authorisation ,
44 const std::string & address ,
const std::string & path ,
const std::string & params ,
45 const std::string & anchor )
48 result.reserve( 6U + protocol.size() + authorisation.size() +
49 address.size() + path.size() + params.size() + anchor.size() ) ;
51 if( !protocol.empty() )
52 result.append( protocol +
"://" ) ;
54 if( !authorisation.empty() )
55 result.append( authorisation +
"@" ) ;
57 if( !address.empty() )
58 result.append( address ) ;
60 result.append( path ) ;
62 result.append(
"/" ) ;
65 result.append(
"?" + params ) ;
68 result.append(
"#" + anchor ) ;
75 std::ostringstream ss ;
76 ss << protocol() <<
"://" << address() ;
82 void G::Url::init( std::string url )
84 typedef std::string::size_type pos_t ;
85 const pos_t npos = std::string::npos ;
92 if( (pos = url.find(
"://")) != npos )
103 if( (pos = m_address.find(
"@")) != npos )
108 if( m_address.find(
'[') == 0U && m_address.find(
']') != std::string::npos )
110 size_t closepos = m_address.find(
']') ;
111 size_t colonpos = m_address.rfind(
':') ;
112 if( colonpos != std::string::npos && colonpos < closepos )
113 colonpos = std::string::npos ;
114 m_host =
G::Str::head( m_address , colonpos , m_address ) ;
121 size_t colonpos = m_address.rfind(
':') ;
122 m_host =
G::Str::head( m_address , colonpos , m_address ) ;
133 pos = url.find(
"?") ;
139 if( m_path.size() > 1U && m_path.at(m_path.size()-1U) ==
'/' )
140 m_path.resize( m_path.size() - 1U ) ;
142 G_ASSERT( !m_path.empty() ) ;
145 if( (pos = url.find(
"#")) != npos )
157 for( G::StringArray::iterator p = parts.begin() ; p != parts.end() ; ++p )
159 pos = (*p).find(
"=") ;
162 m_params_map.insert( Map::value_type(key,value) ) ;
168 return path() + (m_params.empty()?
"":
"?") + m_params ;
178 return m_params_map ;
193 return m_port.empty() ? default_ : m_port ;
203 G_ASSERT( !default_port.empty() ) ;
204 if( default_port.empty() )
return host() +
":0" ;
205 return G::Str::join(
":" , host() , port(default_port) ) ;
210 return m_params_map.find(key) != m_params_map.end() ;
215 Map::const_iterator p = m_params_map.find(key) ;
216 if( p == m_params_map.end() )
229 return m_authorisation ;
237 size_t G::Url::colonpos(
const std::string & address )
240 const std::string::size_type npos = std::string::npos ;
241 if( address.empty() )
return npos ;
242 size_t colon = address.rfind(
":" ) ;
243 if( colon == npos )
return npos ;
244 size_t end = address.at(0U) ==
'[' ? address.rfind(
"]") : npos ;
245 return ( end != npos && colon < end ) ? npos : colon ;
251 result.reserve( s.size() ) ;
252 size_t n = s.size() ;
253 for(
size_t i = 0U ; i < n ; i++ )
255 if( s.at(i) ==
'%' && (i+2U) < n )
257 static std::string map =
"00112233445566778899aAbBcCdDeEfF" ;
258 char c1 = s.at(++i) ;
259 char c2 = s.at(++i) ;
260 size_t n1 = map.find(c1) ;
261 size_t n2 = map.find(c2) ;
262 if( n1 == std::string::npos ) n1 = 0U ;
263 if( n2 == std::string::npos ) n2 = 0U ;
264 unsigned int x = ((n1>>1)<<4) | (n2>>1) ;
265 result.append( 1U , static_cast<char>(x) ) ;
267 else if( s.at(i) ==
'+' )
269 result.append( 1U ,
' ' ) ;
273 result.append( 1U , s.at(i) ) ;
282 result.reserve( s.size() ) ;
283 size_t sn = s.size() ;
284 for(
size_t i = 0U ; i < sn ; i++ )
287 if( ( c >=
'A' && c <=
'Z' ) || ( c >=
'a' && c <=
'z' ) || ( c >=
'0' && c <=
'9' ) ||
288 c ==
'-' || c ==
'_' || c ==
'.' || c ==
'~' )
290 result.append( 1U , c ) ;
292 else if( c ==
' ' && plus_for_space )
294 result.append( 1U ,
'+' ) ;
298 static const char * map =
"0123456789ABCDEF" ;
299 unsigned int n =
static_cast<unsigned char>(c) ;
300 result.append( 1U ,
'%' ) ;
301 result.append( 1U , map[(n>>4)%16U] ) ;
302 result.append( 1U , map[n%16U] ) ;
std::string port(const std::string &default_=std::string()) const
Returns the port or service-name, or the specified default if none.
std::vector< std::string > StringArray
A std::vector of std::strings.
std::string host() const
Returns the hostname or network address part.
static void splitIntoTokens(const std::string &in, StringArray &out, const std::string &ws)
Splits the string into 'ws'-delimited tokens.
static std::string decode(const std::string &)
Does url-decoding (rfc3986 2.1).
std::string parameter(std::string key, std::string default_=std::string()) const
Returns the decode()d value of the named parameter, or a default value.
static std::string tail(const std::string &in, std::string::size_type pos, const std::string &default_=std::string())
Returns the last part of the string after the given position.
std::string request() const
Returns the path and parameters, suitable for a GET request.
std::string path() const
Returns the path part, including the leading slash.
bool has(const std::string &key) const
Returns true if the named parameter is present.
static std::string head(const std::string &in, std::string::size_type pos, const std::string &default_=std::string())
Returns the first part of the string up to just before the given position.
static std::string unique(std::string s, char c= ' ', char r= ' ')
Returns a string with repeated 'c' charaters replaced by one 'r' character.
std::string parameters() const
Returns the parameters string.
std::string str() const
Returns the string representation. Returns "/" if default constructed.
Url()
Default constructor for a url with a path of "/".
Map pmap() const
Returns the decode()d parameters as a multimap.
std::string protocol() const
Returns the protocol part eg. "http".
static std::string join(const std::string &sep, const StringArray &strings)
Concatenates an array of strings.
std::string authorisation() const
Returns the "user:pwd" part.
static void removeAll(std::string &, char)
Removes all occurrences of the character from the string.
static std::string encode(const std::string &, bool plus_for_space=true)
Does url-encoding.
std::string summary() const
Returns a summary of the url for logging purposes, specifically excluding username/password but also ...
std::string anchor() const
Returns the "#anchor" part.
std::string address() const
Returns the address part, which might include the port, and which might use ipv6 square brackets...
static std::string join(const std::string &protocol, const std::string &authorisation, const std::string &address, const std::string &path, const std::string ¶ms, const std::string &anchor=std::string())
Returns a concatenation of the given url parts, with the correct separators inserted.