41 #ifndef _networkuri_cpp
42 #define _networkuri_cpp
44 #include "Network/uri.h"
45 #include "Network/networkenumerations.h"
47 #include "stringtool.h"
63 StringVector::const_iterator SegIt = Segments.begin();
64 const StringVector::const_iterator LastIt = --Segments.end();
65 while( SegIt != Segments.end() )
67 ToBuild.append( *SegIt );
68 if( SegIt != LastIt ) {
69 ToBuild.append(1,
'/');
82 if( *(Base.rbegin()) !=
'/' ) {
85 PathSegments.insert(PathSegments.end(),BaseSegs.begin(),BaseSegs.end());
87 if( !Relative.empty() ) {
89 PathSegments.insert(PathSegments.end(),RelativeSegs.begin(),RelativeSegs.end());
91 for( StringVector::const_iterator SegIt = PathSegments.begin() ; SegIt != PathSegments.end() ; ++SegIt )
93 if( (*SegIt) ==
".." ) {
94 if( !MergedSegments.empty() ) {
95 MergedSegments.pop_back();
97 }
else if( (*SegIt) !=
"." ){
98 MergedSegments.push_back( (*SegIt) );
101 BuildURIPath(Ret,MergedSegments);
102 if( !Relative.empty() && *(Relative.rbegin()) ==
'/' ) {
116 URIScheme(Other.URIScheme),
117 URIUserInfo(Other.URIUserInfo),
118 URIHost(Other.URIHost),
119 URIPath(Other.URIPath),
120 URIQuery(Other.URIQuery),
121 URIFragment(Other.URIFragment),
122 URIPort(Other.URIPort)
130 URIUserInfo(UserInfo),
134 URIFragment(Fragment),
135 URIPort(StringTools::ConvertToUInt16(Port))
140 URIUserInfo(UserInfo),
144 URIFragment(Fragment),
154 if( !isalpha( (*CurrIt) ) ) {
158 while( CurrIt != EndIt && (*CurrIt) !=
':' )
161 this->
URIScheme.append( 1, static_cast<Char8>( tolower( (*CurrIt) ) ) );
173 while( CurrIt != EndIt && (*CurrIt) !=
'@' )
175 if( (*CurrIt) ==
':' || URI::GenDelims.find( (*CurrIt) ) == String::npos ) {
188 while( CurrIt != EndIt && (*CurrIt) !=
':' && (*CurrIt) !=
'/' )
191 this->
URIHost.append( 1, static_cast<Char8>( tolower( (*CurrIt) ) ) );
204 while( CurrIt != EndIt && (*CurrIt) !=
'/' )
207 PortStr.append( 1, (*CurrIt) );
214 if( !PortStr.empty() ) {
223 while( CurrIt != EndIt && (*CurrIt) !=
'?' && (*CurrIt) !=
'#' )
225 if( (*CurrIt) !=
'[' && (*CurrIt) !=
']' ) {
226 this->
URIPath.append( 1, (*CurrIt) );
238 while( CurrIt != EndIt && (*CurrIt) !=
'#' )
240 if( (*CurrIt) !=
'[' && (*CurrIt) !=
']' ) {
241 this->
URIQuery.append( 1, static_cast<Char8>( (*CurrIt) ) );
253 while( CurrIt != EndIt )
255 if( (*CurrIt) !=
'#' && (*CurrIt) !=
'[' && (*CurrIt) !=
']' ) {
256 this->
URIFragment.append( 1, static_cast<Char8>( (*CurrIt) ) );
267 if( ( CurrIt != EndIt ) && ( (*CurrIt) ==
'/' && *(CurrIt + 1) ==
'/' ) ) {
286 while( CurrIt != EndIt && (*CurrIt) !=
'/' && (*CurrIt) !=
'?' && (*CurrIt) !=
'#' )
290 case '@': AtPos = CurrIt;
break;
291 case ':': ColonPos = CurrIt;
break;
299 if( AtPos != EndIt ) {
302 if( ColonPos != EndIt ) {
309 if( ColonPos != EndIt ) {
320 if( CurrIt != EndIt ) {
326 while( CurrIt != EndIt )
330 case '?': QuestPos = CurrIt;
break;
331 case '#': PoundPos = CurrIt;
break;
338 this->
ParsePath(BeginPos,( QuestPos != EndIt ? QuestPos : PoundPos ));
340 if( QuestPos != EndIt ) {
341 this->
ParseQuery(QuestPos+1,( PoundPos != EndIt ? PoundPos : CurrIt ));
344 if( PoundPos != EndIt ) {
356 PercentStream <<
'%' << std::hex << std::uppercase << std::setw(2) << int(ToEncode);
357 return PercentStream.str();
364 if( ToDecode.size() == 3 ) {
366 Ret.second += ToDecode[1] -
'0';
368 Ret.second += ( ToDecode[1] -
'a' ) + 10;
370 Ret.second += ( ToDecode[1] -
'A' ) + 10;
374 Ret.second = ( Ret.second << 4 );
376 Ret.second += ToDecode[2] -
'0';
378 Ret.second += ( ToDecode[2] -
'a' ) + 10;
380 Ret.second += ( ToDecode[2] -
'A' ) + 10;
397 if( ToAppend.first ) {
398 Destination.append( 1, ToAppend.second );
419 while( CurrIt != ToEncode.end() )
421 if(
GenDelims.find( *CurrIt ) != String::npos || AdditionalDelims.find( *CurrIt ) != String::npos ) {
424 Destination.append( 1, (*CurrIt) );
434 while( CurrIt != EndIt )
436 if( (*CurrIt) ==
'%' ) {
437 if( ( EndIt - CurrIt >= 4 ) &&
String(CurrIt,CurrIt+4) ==
"%%25" ) {
438 Destination.append(
"%25");
440 }
else if( EndIt - CurrIt >= 3 ) {
442 Destination.append( 1, Result.second );
447 }
else if( PlusToSpace && (*CurrIt) ==
'+' ) {
448 Destination.append( 1,
' ' );
451 Destination.append( 1, (*CurrIt) );
462 if( Scheme ==
"http" ) {
463 return Network::WKP_HTTP;
464 }
else if( Scheme ==
"https" ) {
465 return Network::WKP_HTTPS;
466 }
else if( Scheme ==
"ftp" ) {
467 return Network::WKP_FTPControl;
468 }
else if( Scheme ==
"ftps" ) {
469 return Network::WKP_FTPSControl;
470 }
else if( Scheme ==
"ssh" ) {
471 return Network::WKP_SSH;
472 }
else if( Scheme ==
"telnet" ) {
473 return Network::WKP_Telnet;
474 }
else if( Scheme ==
"xmpp" ) {
475 return Network::WKP_XMPP;
476 }
else if( Scheme ==
"nntp" ) {
477 return Network::WKP_NNTP;
478 }
else if( Scheme ==
"ldap" ) {
479 return Network::WKP_LDAP;
480 }
else if( Scheme ==
"rtsp" ) {
481 return Network::WKP_RTSP;
482 }
else if( Scheme ==
"sip" ) {
483 return Network::WKP_SIP;
484 }
else if( Scheme ==
"sips" ) {
485 return Network::WKP_SIPS;
493 if( !ToRemove.empty() ) {
496 StringVector::iterator SegIt = PathSegments.begin();
502 RetSegments.push_back( (*SegIt) );
503 }
else if( (*SegIt) !=
".." && (*SegIt) !=
"." ) {
504 RetSegments.push_back( (*SegIt) );
509 while( SegIt != PathSegments.end() )
511 if( (*SegIt) ==
".." ) {
512 if( !RetSegments.empty() ) {
519 RetSegments.pop_back();
522 }
else if( (*SegIt) !=
"." ) {
523 RetSegments.push_back( (*SegIt) );
529 BuildURIPath(ToRemove,RetSegments);
549 this->
ParseHost(Host.begin(),Host.end());
550 this->
ParsePort(Port.begin(),Port.end());
551 this->
ParsePath(Path.begin(),Path.end());
560 this->
ParseHost(Host.begin(),Host.end());
561 this->
ParsePath(Path.begin(),Path.end());
602 std::swap(this->
URIPath,TempPath);
607 std::swap(this->
URIQuery,TempQuery);
682 if( Relative.
URIPath.at(0) ==
'/' ) {
716 while( CurrIt != EndIt && URI::GenDelims.find( *CurrIt ) == Mezzanine::String::npos )
720 if( CurrIt != EndIt ) {
722 if( (*CurrIt) ==
':' ) {
729 }
else if( (*CurrIt) ==
'/' ) {
731 if( BeginIt == CurrIt ) {
763 URIStream <<
"?" << this->
GetQuery();
768 return URIStream.str();
774 QueryStream <<
"&" << Param <<
"=" << Value;
775 this->
URIQuery.append(QueryStream.str());
781 size_t ParamStartPos = 0;
782 while( ParamStartPos < this->
URIQuery.size() )
784 size_t ParamEndPos = this->
URIQuery.find_first_of(
"=",ParamStartPos);
785 size_t ValueEndPos = this->
URIQuery.find_first_of(
"&;",ParamEndPos + 1);
786 if( this->
URIQuery.substr(ParamStartPos,ParamEndPos - ParamStartPos) == Param ) {
787 return this->
URIQuery.substr(ParamEndPos + 1,ValueEndPos - (ParamEndPos + 1));
789 ParamStartPos = ValueEndPos + 1;
796 size_t ParamStartPos = 0;
797 while( ParamStartPos < this->
URIQuery.size() )
799 size_t ParamEndPos = this->
URIQuery.find_first_of(
"=",ParamStartPos);
800 if( this->
URIQuery.substr(ParamStartPos,ParamEndPos - ParamStartPos) == Param ) {
803 ParamStartPos = this->
URIQuery.find_first_of(
"&;",ParamEndPos) + 1;
837 this->
ParseHost(Host.begin(),Host.end());
851 this->
ParseHost(IPStr.begin(),IPStr.end());
859 {
return !( this->
URIHost.empty() ); }
862 { this->
URIPort = Port;
return *
this; }
868 {
return ( this->
URIPort != 0 ); }
872 this->
ParsePath(Path.begin(),Path.end());
880 {
return !( this->
URIPath.empty() ); }
892 {
return !( this->
URIQuery.empty() ); }
922 URIStream <<
":" << this->
URIPort;
925 return URIStream.str();
949 this->URIHost == Other.
URIHost &&
950 this->URIPath == Other.
URIPath &&
953 this->URIPort == Other.
URIPort );
960 this->URIHost != Other.
URIHost ||
961 this->URIPath != Other.
URIPath ||
964 this->URIPort != Other.
URIPort );
void ParseQuery(StringIterator CurrIt, const StringIterator EndIt)
Parses the Query of a URI String. an invalid character or an error is encountered a SYNTAX_ERROR_EXCE...
URI & SetQuery(const String &Query)
Sets the Query component of the URI.
URI & Normalize()
Makes minor adjustments to the content of this URI to make it easier to process/compare.
std::vector< String > StringVector
This is a simple datatype for a vector container of strings.
void ParseAuthorityNoSlash(StringIterator &CurrIt, const StringIterator EndIt)
Parses the Authority of a URI String, without checking for the preceding slashes. an invalid characte...
URI & SetHost(const String &Host)
Sets the Host component of the URI.
Boole HasPort() const
Gets whether or not the Port component of the URI has been set.
bool Boole
Generally acts a single bit, true or false.
String ConvertToString() const
Combines the set components of this URI into a usable String for transmission.
const String & GetHost() const
Gets the Host component of the URI.
static DecodeResult PercentDecodeSingle(const String &ToDecode)
Converts a String that is percent encoded into it's appropriate character.
URI & SetAuthority(const String &Authority)
Sets the Authority Fragments of the URI.
String URIHost
The domain or address of the Host where the resource is located.
Boole IsHierarchical() const
Gets whether or not this URI has hierarchical components.
String URIQuery
The optional Query to provide additional non-hierarchical information about the resource.
Boole HasScheme() const
Gets whether or not the Scheme component of the URI has been set.
String::const_iterator StringIterator
Convenience typedef for String iterators.
const String & GetUserInfo() const
Gets the User Information component of the URI.
void ParseHost(StringIterator CurrIt, const StringIterator EndIt)
Parses the Host of a URI String. an invalid character or an error is encountered a SYNTAX_ERROR_EXCEP...
URI & Swap(URI &Other)
Swaps the contents of this URI with another.
#define MEZZ_EXCEPTION(num, desc)
An easy way to throw exceptions with rich information.
Boole HasFragment() const
Gets whether or not the Fragment component of the URI has been set.
URI & SetPath(const String &Port)
Sets the Path component of the URI.
static UInt16 GetDefaultPort(const String &Scheme)
Gets the default port for a named protocol.
URI & SetPort(const UInt16 Port)
Sets the Port component of the URI.
Boole HasPath() const
Gets whether or not the Path component of the URI has been set.
static const String SubDelims
A String containing the sub-delimiters that some URI schemes may use to delimit scheme specific data...
void SetComponentsNoParse(const String &Scheme, const String &UserInfo, const String &Host, const String &Port, const String &Path, const String &Query, const String &Fragment)
Sets each component of this URI explicitly without actually parsing the strings (direct copy)...
static String PercentDecode(const String &ToDecode, const Boole PlusToSpace=false)
Creates a duplicate String with all percent encodings decoded and appends that to the destination Str...
This implements the exception hiearchy for Mezzanine.
Boole IsRelative() const
Gets whether or not this URI points to a relative resource location.
Boole HasQueryParameter(const String &Param) const
Checks if the named parameter exists in this URI.
std::stringstream StringStream
A Datatype used for streaming operations with strings.
UInt16 URIPort
The port number on the host to connect to in order to access the resource.
Internet Protocol version 6.
void ParsePathQueryFrag(StringIterator &CurrIt, const StringIterator EndIt)
Parses the Path, Query, and Fragment components of a URI String. an invalid character or an error is ...
std::pair< Boole, Char8 > DecodeResult
Convenience typedef for storing if a decode was successful and it's result.
char Char8
A datatype to represent one character.
const String & GetPath() const
Gets the Path component of the URI.
static String PercentEncode(const String &ToEncode, const String &AdditionalDelims)
Creates a duplicate String with all the reserved characters percent encoded and appends that to the d...
void SetComponents(const String &Scheme, const String &UserInfo, const String &Host, const String &Port, const String &Path, const String &Query, const String &Fragment)
Sets each component of this URI explicitly.
URI & SetScheme(const String &Scheme)
Sets the Scheme component of the URI.
uint16_t UInt16
An 16-bit unsigned integer.
Boole IsAbsolute() const
Gets whether or not this URI points to an absolute resource location.
URI Resolve(const URI &Relative) const
Computes the absolute referenced URI from a relative URI and the absolute URI it is relative to...
void ParsePath(StringIterator CurrIt, const StringIterator EndIt)
Parses the Path of a URI String. an invalid character or an error is encountered a SYNTAX_ERROR_EXCEP...
URI & SetUserInfo(const String &UserInfo)
Sets the User Information component of the URI.
This is a simple class for representing IP addresses used throughout the Network subsystem.
const String & GetScheme() const
Gets the Scheme component of the URI.
void ParseAuthority(StringIterator &CurrIt, const StringIterator EndIt)
Parses the Authority of a URI String. an invalid character or an error is encountered a SYNTAX_ERROR_...
Boole operator!=(const URI &Other) const
Inequality Comparison Operator.
void operator=(const URI &Other)
Assignment Operator.
URI & ParseFromString(const String &ToParse)
Parses the contents of a String into this URI.
String URIPath
The path to the resource on the Host machine holding the resource.
Thrown when a passed parameter is checked at runtime and not in the expected range.
static void RemoveDotSegments(String &ToRemove, const Boole Relative)
Removes frivolous parts of the path that mean nothing.
Boole operator==(const URI &Other) const
Equality Comparison Operator.
static String PercentEncodeSingle(const Char8 ToEncode)
Converts a character into a percent encoded string that is safe for use in URI's. ...
Thrown when parameters are checked at runtime and found invalid.
Boole HasUserInfo() const
Gets whether or not the User Information component of the URI has been set.
String GetAsString() const
Gets this IPAddress in a human readable format.
void ParseUserInfo(StringIterator CurrIt, const StringIterator EndIt)
Parses the User Information of a URI String. an invalid character or an error is encountered a SYNTAX...
Boole IsOpaque() const
Gets whether or not this URI lacks a hierarchy.
Network::NetworkLayerProtocol GetProtocol() const
Gets the type of IP address this is.
String URIScheme
The Scheme of the URI, usually noting the type of data the resource is.
URI & SetFragment(const String &Fragment)
Sets the Fragment component of the URI.
void ParsePort(StringIterator CurrIt, const StringIterator EndIt)
Parses the Port of a URI String. an invalid character or an error is encountered a SYNTAX_ERROR_EXCEP...
UInt16 GetPort() const
Gets the Port component of the URI.
A helper class for the reading and using of Uniform Resource Identifiers.
String GetAuthority() const
Gets the Authority Fragments of the URI.
String URIFragment
The optional Fragment providing additional direction to a subset of the resource. ...
The bulk of the engine components go in this namspace.
const String & GetQuery() const
Gets the Query component of the URI.
Boole HasAuthority() const
Gets whether or not any Authority component of the URI has been set.
URI & AddQueryParameter(const String &Param, const String &Value)
Adds a single param/value pair to the Query of this URI.
Boole HasHost() const
Gets whether or not the Host component of the URI has been set.
Thrown when some kind of syntax exception.
void ParseScheme(StringIterator CurrIt, const StringIterator EndIt)
Parses the Scheme of a URI String. an invalid character or an error is encountered a SYNTAX_ERROR_EXC...
void ParseFragment(StringIterator CurrIt, const StringIterator EndIt)
Parses the Fragment of a URI String. an invalid character or an error is encountered a SYNTAX_ERROR_E...
static const String GenDelims
A String containing the generic delimiters for URIs.
String URIUserInfo
The optional user authentication information to be used when accessing the resource.
std::string String
A datatype used to a series of characters.
Boole IsEmpty() const
Checks to see if the URI is currently empty.
Internet Protocol version 4.
String GetParameterValue(const String &Param) const
Gets the set value for a specific parameter in the Query of this URI.
const String & GetFragment() const
Gets the Fragment component of the URI.
URI & Clear()
Reverts this URI to a blank slate.
Boole HasQuery() const
Gets whether or not the Query component of the URI has been set.