@@ -16,16 +16,16 @@ #include "config.h" #include #include -#import "OFURL.h" +#import "OFURI.h" #import "OFArray.h" #import "OFDictionary.h" #ifdef OF_HAVE_FILES # import "OFFileManager.h" -# import "OFFileURLHandler.h" +# import "OFFileURIHandler.h" #endif #import "OFNumber.h" #import "OFOnce.h" #import "OFString.h" #import "OFXMLElement.h" @@ -32,70 +32,70 @@ #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" -@interface OFURLAllowedCharacterSetBase: OFCharacterSet -@end - -@interface OFURLAllowedCharacterSet: OFURLAllowedCharacterSetBase -@end - -@interface OFURLSchemeAllowedCharacterSet: OFURLAllowedCharacterSetBase -@end - -@interface OFURLPathAllowedCharacterSet: OFURLAllowedCharacterSetBase -@end - -@interface OFURLQueryOrFragmentAllowedCharacterSet: OFURLAllowedCharacterSetBase -@end - -@interface OFURLQueryKeyValueAllowedCharacterSet: OFURLAllowedCharacterSetBase -@end - -static OFCharacterSet *URLAllowedCharacterSet = nil; -static OFCharacterSet *URLSchemeAllowedCharacterSet = nil; -static OFCharacterSet *URLPathAllowedCharacterSet = nil; -static OFCharacterSet *URLQueryOrFragmentAllowedCharacterSet = nil; -static OFCharacterSet *URLQueryKeyValueAllowedCharacterSet = nil; - -static OFOnceControl URLAllowedCharacterSetOnce = OFOnceControlInitValue; -static OFOnceControl URLQueryOrFragmentAllowedCharacterSetOnce = +@interface OFURIAllowedCharacterSetBase: OFCharacterSet +@end + +@interface OFURIAllowedCharacterSet: OFURIAllowedCharacterSetBase +@end + +@interface OFURISchemeAllowedCharacterSet: OFURIAllowedCharacterSetBase +@end + +@interface OFURIPathAllowedCharacterSet: OFURIAllowedCharacterSetBase +@end + +@interface OFURIQueryOrFragmentAllowedCharacterSet: OFURIAllowedCharacterSetBase +@end + +@interface OFURIQueryKeyValueAllowedCharacterSet: OFURIAllowedCharacterSetBase +@end + +static OFCharacterSet *URIAllowedCharacterSet = nil; +static OFCharacterSet *URISchemeAllowedCharacterSet = nil; +static OFCharacterSet *URIPathAllowedCharacterSet = nil; +static OFCharacterSet *URIQueryOrFragmentAllowedCharacterSet = nil; +static OFCharacterSet *URIQueryKeyValueAllowedCharacterSet = nil; + +static OFOnceControl URIAllowedCharacterSetOnce = OFOnceControlInitValue; +static OFOnceControl URIQueryOrFragmentAllowedCharacterSetOnce = OFOnceControlInitValue; static void -initURLAllowedCharacterSet(void) -{ - URLAllowedCharacterSet = [[OFURLAllowedCharacterSet alloc] init]; -} - -static void -initURLSchemeAllowedCharacterSet(void) -{ - URLSchemeAllowedCharacterSet = - [[OFURLSchemeAllowedCharacterSet alloc] init]; -} - -static void -initURLPathAllowedCharacterSet(void) -{ - URLPathAllowedCharacterSet = - [[OFURLPathAllowedCharacterSet alloc] init]; -} - -static void -initURLQueryOrFragmentAllowedCharacterSet(void) -{ - URLQueryOrFragmentAllowedCharacterSet = - [[OFURLQueryOrFragmentAllowedCharacterSet alloc] init]; -} - -static void -initURLQueryKeyValueAllowedCharacterSet(void) -{ - URLQueryKeyValueAllowedCharacterSet = - [[OFURLQueryKeyValueAllowedCharacterSet alloc] init]; +initURIAllowedCharacterSet(void) +{ + URIAllowedCharacterSet = [[OFURIAllowedCharacterSet alloc] init]; +} + +static void +initURISchemeAllowedCharacterSet(void) +{ + URISchemeAllowedCharacterSet = + [[OFURISchemeAllowedCharacterSet alloc] init]; +} + +static void +initURIPathAllowedCharacterSet(void) +{ + URIPathAllowedCharacterSet = + [[OFURIPathAllowedCharacterSet alloc] init]; +} + +static void +initURIQueryOrFragmentAllowedCharacterSet(void) +{ + URIQueryOrFragmentAllowedCharacterSet = + [[OFURIQueryOrFragmentAllowedCharacterSet alloc] init]; +} + +static void +initURIQueryKeyValueAllowedCharacterSet(void) +{ + URIQueryKeyValueAllowedCharacterSet = + [[OFURIQueryKeyValueAllowedCharacterSet alloc] init]; } OF_DIRECT_MEMBERS @interface OFInvertedCharacterSetWithoutPercent: OFCharacterSet { @@ -105,11 +105,11 @@ - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet; @end bool -OFURLIsIPv6Host(OFString *host) +OFURIIsIPv6Host(OFString *host) { const char *UTF8String = host.UTF8String; bool hasColon = false; while (*UTF8String != '\0') { @@ -125,11 +125,11 @@ } return hasColon; } -@implementation OFURLAllowedCharacterSetBase +@implementation OFURIAllowedCharacterSetBase - (instancetype)autorelease { return self; } @@ -146,11 +146,11 @@ { return OFMaxRetainCount; } @end -@implementation OFURLAllowedCharacterSet +@implementation OFURIAllowedCharacterSet - (bool)characterIsMember: (OFUnichar)character { if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; @@ -175,11 +175,11 @@ return false; } } @end -@implementation OFURLSchemeAllowedCharacterSet +@implementation OFURISchemeAllowedCharacterSet - (bool)characterIsMember: (OFUnichar)character { if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; @@ -192,11 +192,11 @@ return false; } } @end -@implementation OFURLPathAllowedCharacterSet +@implementation OFURIPathAllowedCharacterSet - (bool)characterIsMember: (OFUnichar)character { if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; @@ -224,11 +224,11 @@ return false; } } @end -@implementation OFURLQueryOrFragmentAllowedCharacterSet +@implementation OFURIQueryOrFragmentAllowedCharacterSet - (bool)characterIsMember: (OFUnichar)character { if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; @@ -257,11 +257,11 @@ return false; } } @end -@implementation OFURLQueryKeyValueAllowedCharacterSet +@implementation OFURIQueryKeyValueAllowedCharacterSet - (bool)characterIsMember: (OFUnichar)character { if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; @@ -321,11 +321,11 @@ @selector(characterIsMember:), character)); } @end void -OFURLVerifyIsEscaped(OFString *string, OFCharacterSet *characterSet) +OFURIVerifyIsEscaped(OFString *string, OFCharacterSet *characterSet) { void *pool = objc_autoreleasePoolPush(); characterSet = [[[OFInvertedCharacterSetWithoutPercent alloc] initWithCharacterSet: characterSet] autorelease]; @@ -334,101 +334,101 @@ @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); } -@implementation OFCharacterSet (URLCharacterSets) -+ (OFCharacterSet *)URLSchemeAllowedCharacterSet -{ - static OFOnceControl onceControl = OFOnceControlInitValue; - OFOnce(&onceControl, initURLSchemeAllowedCharacterSet); - - return URLSchemeAllowedCharacterSet; -} - -+ (OFCharacterSet *)URLHostAllowedCharacterSet -{ - OFOnce(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); - - return URLAllowedCharacterSet; -} - -+ (OFCharacterSet *)URLUserAllowedCharacterSet -{ - OFOnce(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); - - return URLAllowedCharacterSet; -} - -+ (OFCharacterSet *)URLPasswordAllowedCharacterSet -{ - OFOnce(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); - - return URLAllowedCharacterSet; -} - -+ (OFCharacterSet *)URLPathAllowedCharacterSet -{ - static OFOnceControl onceControl = OFOnceControlInitValue; - OFOnce(&onceControl, initURLPathAllowedCharacterSet); - - return URLPathAllowedCharacterSet; -} - -+ (OFCharacterSet *)URLQueryAllowedCharacterSet -{ - OFOnce(&URLQueryOrFragmentAllowedCharacterSetOnce, - initURLQueryOrFragmentAllowedCharacterSet); - - return URLQueryOrFragmentAllowedCharacterSet; -} - -+ (OFCharacterSet *)URLQueryKeyValueAllowedCharacterSet -{ - static OFOnceControl onceControl = OFOnceControlInitValue; - OFOnce(&onceControl, initURLQueryKeyValueAllowedCharacterSet); - - return URLQueryKeyValueAllowedCharacterSet; -} - -+ (OFCharacterSet *)URLFragmentAllowedCharacterSet -{ - OFOnce(&URLQueryOrFragmentAllowedCharacterSetOnce, - initURLQueryOrFragmentAllowedCharacterSet); - - return URLQueryOrFragmentAllowedCharacterSet; +@implementation OFCharacterSet (URICharacterSets) ++ (OFCharacterSet *)URISchemeAllowedCharacterSet +{ + static OFOnceControl onceControl = OFOnceControlInitValue; + OFOnce(&onceControl, initURISchemeAllowedCharacterSet); + + return URISchemeAllowedCharacterSet; +} + ++ (OFCharacterSet *)URIHostAllowedCharacterSet +{ + OFOnce(&URIAllowedCharacterSetOnce, initURIAllowedCharacterSet); + + return URIAllowedCharacterSet; +} + ++ (OFCharacterSet *)URIUserAllowedCharacterSet +{ + OFOnce(&URIAllowedCharacterSetOnce, initURIAllowedCharacterSet); + + return URIAllowedCharacterSet; +} + ++ (OFCharacterSet *)URIPasswordAllowedCharacterSet +{ + OFOnce(&URIAllowedCharacterSetOnce, initURIAllowedCharacterSet); + + return URIAllowedCharacterSet; +} + ++ (OFCharacterSet *)URIPathAllowedCharacterSet +{ + static OFOnceControl onceControl = OFOnceControlInitValue; + OFOnce(&onceControl, initURIPathAllowedCharacterSet); + + return URIPathAllowedCharacterSet; +} + ++ (OFCharacterSet *)URIQueryAllowedCharacterSet +{ + OFOnce(&URIQueryOrFragmentAllowedCharacterSetOnce, + initURIQueryOrFragmentAllowedCharacterSet); + + return URIQueryOrFragmentAllowedCharacterSet; +} + ++ (OFCharacterSet *)URIQueryKeyValueAllowedCharacterSet +{ + static OFOnceControl onceControl = OFOnceControlInitValue; + OFOnce(&onceControl, initURIQueryKeyValueAllowedCharacterSet); + + return URIQueryKeyValueAllowedCharacterSet; +} + ++ (OFCharacterSet *)URIFragmentAllowedCharacterSet +{ + OFOnce(&URIQueryOrFragmentAllowedCharacterSetOnce, + initURIQueryOrFragmentAllowedCharacterSet); + + return URIQueryOrFragmentAllowedCharacterSet; } @end -@implementation OFURL -+ (instancetype)URL +@implementation OFURI ++ (instancetype)URI { return [[[self alloc] init] autorelease]; } -+ (instancetype)URLWithString: (OFString *)string ++ (instancetype)URIWithString: (OFString *)string { return [[[self alloc] initWithString: string] autorelease]; } -+ (instancetype)URLWithString: (OFString *)string - relativeToURL: (OFURL *)URL ++ (instancetype)URIWithString: (OFString *)string + relativeToURI: (OFURI *)URI { return [[[self alloc] initWithString: string - relativeToURL: URL] autorelease]; + relativeToURI: URI] autorelease]; } #ifdef OF_HAVE_FILES -+ (instancetype)fileURLWithPath: (OFString *)path ++ (instancetype)fileURIWithPath: (OFString *)path { - return [[[self alloc] initFileURLWithPath: path] autorelease]; + return [[[self alloc] initFileURIWithPath: path] autorelease]; } -+ (instancetype)fileURLWithPath: (OFString *)path ++ (instancetype)fileURIWithPath: (OFString *)path isDirectory: (bool)isDirectory { - return [[[self alloc] initFileURLWithPath: path + return [[[self alloc] initFileURIWithPath: path isDirectory: isDirectory] autorelease]; } #endif - (instancetype)initWithString: (OFString *)string @@ -451,16 +451,16 @@ @throw [OFInvalidFormatException exception]; for (tmp2 = UTF8String; tmp2 < tmp; tmp2++) *tmp2 = OFASCIIToLower(*tmp2); - _URLEncodedScheme = [[OFString alloc] + _percentEncodedScheme = [[OFString alloc] initWithUTF8String: UTF8String length: tmp - UTF8String]; - OFURLVerifyIsEscaped(_URLEncodedScheme, - [OFCharacterSet URLSchemeAllowedCharacterSet]); + OFURIVerifyIsEscaped(_percentEncodedScheme, + [OFCharacterSet URISchemeAllowedCharacterSet]); UTF8String = tmp + 3; if ((tmp = strchr(UTF8String, '/')) != NULL) { *tmp = '\0'; @@ -475,24 +475,24 @@ if ((tmp3 = strchr(UTF8String, ':')) != NULL) { *tmp3 = '\0'; tmp3++; - _URLEncodedUser = [[OFString alloc] + _percentEncodedUser = [[OFString alloc] initWithUTF8String: UTF8String]; - _URLEncodedPassword = [[OFString alloc] + _percentEncodedPassword = [[OFString alloc] initWithUTF8String: tmp3]; - OFURLVerifyIsEscaped(_URLEncodedPassword, + OFURIVerifyIsEscaped(_percentEncodedPassword, [OFCharacterSet - URLPasswordAllowedCharacterSet]); + URIPasswordAllowedCharacterSet]); } else - _URLEncodedUser = [[OFString alloc] + _percentEncodedUser = [[OFString alloc] initWithUTF8String: UTF8String]; - OFURLVerifyIsEscaped(_URLEncodedUser, - [OFCharacterSet URLUserAllowedCharacterSet]); + OFURIVerifyIsEscaped(_percentEncodedUser, + [OFCharacterSet URIUserAllowedCharacterSet]); UTF8String = tmp2; } if (UTF8String[0] == '[') { @@ -507,11 +507,11 @@ if (*UTF8String != ']') @throw [OFInvalidFormatException exception]; UTF8String++; - _URLEncodedHost = [[OFString alloc] + _percentEncodedHost = [[OFString alloc] initWithUTF8String: tmp2 length: UTF8String - tmp2]; if (*UTF8String == ':') { OFString *portString; @@ -545,11 +545,11 @@ OFString *portString; *tmp2 = '\0'; tmp2++; - _URLEncodedHost = [[OFString alloc] + _percentEncodedHost = [[OFString alloc] initWithUTF8String: UTF8String]; portString = [OFString stringWithUTF8String: tmp2]; if (portString.unsignedLongLongValue > 65535) @@ -556,44 +556,44 @@ @throw [OFInvalidFormatException exception]; _port = [[OFNumber alloc] initWithUnsignedShort: portString.unsignedLongLongValue]; } else { - _URLEncodedHost = [[OFString alloc] + _percentEncodedHost = [[OFString alloc] initWithUTF8String: UTF8String]; - if (_URLEncodedHost.length == 0) { - [_URLEncodedHost release]; - _URLEncodedHost = nil; + if (_percentEncodedHost.length == 0) { + [_percentEncodedHost release]; + _percentEncodedHost = nil; } } - if (_URLEncodedHost != nil && !isIPv6Host) - OFURLVerifyIsEscaped(_URLEncodedHost, - [OFCharacterSet URLHostAllowedCharacterSet]); + if (_percentEncodedHost != nil && !isIPv6Host) + OFURIVerifyIsEscaped(_percentEncodedHost, + [OFCharacterSet URIHostAllowedCharacterSet]); if ((UTF8String = tmp) != NULL) { if ((tmp = strchr(UTF8String, '#')) != NULL) { *tmp = '\0'; - _URLEncodedFragment = [[OFString alloc] + _percentEncodedFragment = [[OFString alloc] initWithUTF8String: tmp + 1]; - OFURLVerifyIsEscaped(_URLEncodedFragment, + OFURIVerifyIsEscaped(_percentEncodedFragment, [OFCharacterSet - URLFragmentAllowedCharacterSet]); + URIFragmentAllowedCharacterSet]); } if ((tmp = strchr(UTF8String, '?')) != NULL) { *tmp = '\0'; - _URLEncodedQuery = [[OFString alloc] + _percentEncodedQuery = [[OFString alloc] initWithUTF8String: tmp + 1]; - OFURLVerifyIsEscaped(_URLEncodedQuery, + OFURIVerifyIsEscaped(_percentEncodedQuery, [OFCharacterSet - URLQueryAllowedCharacterSet]); + URIQueryAllowedCharacterSet]); } /* * Some versions of GCC issue a false-positive warning * (turned error) about a string overflow. This is a @@ -612,15 +612,15 @@ *UTF8String = '/'; #if OF_GCC_VERSION >= 402 # pragma GCC diagnostic pop #endif - _URLEncodedPath = [[OFString alloc] + _percentEncodedPath = [[OFString alloc] initWithUTF8String: UTF8String]; - OFURLVerifyIsEscaped(_URLEncodedPath, - [OFCharacterSet URLPathAllowedCharacterSet]); + OFURIVerifyIsEscaped(_percentEncodedPath, + [OFCharacterSet URIPathAllowedCharacterSet]); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @@ -630,11 +630,11 @@ } return self; } -- (instancetype)initWithString: (OFString *)string relativeToURL: (OFURL *)URL +- (instancetype)initWithString: (OFString *)string relativeToURI: (OFURI *)URI { char *UTF8String, *UTF8String2 = NULL; if ([string containsString: @"://"]) return [self initWithString: string]; @@ -643,52 +643,52 @@ @try { void *pool = objc_autoreleasePoolPush(); char *tmp; - _URLEncodedScheme = [URL->_URLEncodedScheme copy]; - _URLEncodedHost = [URL->_URLEncodedHost copy]; - _port = [URL->_port copy]; - _URLEncodedUser = [URL->_URLEncodedUser copy]; - _URLEncodedPassword = [URL->_URLEncodedPassword copy]; + _percentEncodedScheme = [URI->_percentEncodedScheme copy]; + _percentEncodedHost = [URI->_percentEncodedHost copy]; + _port = [URI->_port copy]; + _percentEncodedUser = [URI->_percentEncodedUser copy]; + _percentEncodedPassword = [URI->_percentEncodedPassword copy]; UTF8String = UTF8String2 = OFStrDup(string.UTF8String); if ((tmp = strchr(UTF8String, '#')) != NULL) { *tmp = '\0'; - _URLEncodedFragment = [[OFString alloc] + _percentEncodedFragment = [[OFString alloc] initWithUTF8String: tmp + 1]; - OFURLVerifyIsEscaped(_URLEncodedFragment, - [OFCharacterSet URLFragmentAllowedCharacterSet]); + OFURIVerifyIsEscaped(_percentEncodedFragment, + [OFCharacterSet URIFragmentAllowedCharacterSet]); } if ((tmp = strchr(UTF8String, '?')) != NULL) { *tmp = '\0'; - _URLEncodedQuery = [[OFString alloc] + _percentEncodedQuery = [[OFString alloc] initWithUTF8String: tmp + 1]; - OFURLVerifyIsEscaped(_URLEncodedQuery, - [OFCharacterSet URLQueryAllowedCharacterSet]); + OFURIVerifyIsEscaped(_percentEncodedQuery, + [OFCharacterSet URIQueryAllowedCharacterSet]); } if (*UTF8String == '/') - _URLEncodedPath = [[OFString alloc] + _percentEncodedPath = [[OFString alloc] initWithUTF8String: UTF8String]; else { OFString *relativePath = [OFString stringWithUTF8String: UTF8String]; - if ([URL->_URLEncodedPath hasSuffix: @"/"]) - _URLEncodedPath = [[URL->_URLEncodedPath + if ([URI->_percentEncodedPath hasSuffix: @"/"]) + _percentEncodedPath = [[URI->_percentEncodedPath stringByAppendingString: relativePath] copy]; else { OFMutableString *path = [OFMutableString stringWithString: - (URL->_URLEncodedPath != nil - ? URL->_URLEncodedPath + (URI->_percentEncodedPath != nil + ? URI->_percentEncodedPath : @"/")]; OFRange range = [path rangeOfString: @"/" options: OFStringSearchBackwards]; @@ -701,16 +701,16 @@ [path replaceCharactersInRange: range withString: relativePath]; [path makeImmutable]; - _URLEncodedPath = [path copy]; + _percentEncodedPath = [path copy]; } } - OFURLVerifyIsEscaped(_URLEncodedPath, - [OFCharacterSet URLPathAllowedCharacterSet]); + OFURIVerifyIsEscaped(_percentEncodedPath, + [OFCharacterSet URIPathAllowedCharacterSet]); objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; @@ -720,11 +720,11 @@ return self; } #ifdef OF_HAVE_FILES -- (instancetype)initFileURLWithPath: (OFString *)path +- (instancetype)initFileURIWithPath: (OFString *)path { bool isDirectory; @try { void *pool = objc_autoreleasePoolPush(); @@ -733,23 +733,23 @@ } @catch (id e) { [self release]; @throw e; } - self = [self initFileURLWithPath: path isDirectory: isDirectory]; + self = [self initFileURIWithPath: path isDirectory: isDirectory]; return self; } -- (instancetype)initFileURLWithPath: (OFString *)path +- (instancetype)initFileURIWithPath: (OFString *)path isDirectory: (bool)isDirectory { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); - OFString *URLEncodedHost = nil; + OFString *percentEncodedHost = nil; if (!path.absolutePath) { OFString *currentDirectoryPath = [OFFileManager defaultManager].currentDirectoryPath; @@ -756,21 +756,21 @@ path = [currentDirectoryPath stringByAppendingPathComponent: path]; path = path.stringByStandardizingPath; } - path = [path - of_pathToURLPathWithURLEncodedHost: &URLEncodedHost]; - _URLEncodedHost = [URLEncodedHost copy]; + path = [path of_pathToURIPathWithPercentEncodedHost: + &percentEncodedHost]; + _percentEncodedHost = [percentEncodedHost copy]; if (isDirectory && ![path hasSuffix: @"/"]) path = [path stringByAppendingString: @"/"]; - _URLEncodedScheme = @"file"; - _URLEncodedPath = [[path - stringByURLEncodingWithAllowedCharacters: - [OFCharacterSet URLPathAllowedCharacterSet]] copy]; + _percentEncodedScheme = @"file"; + _percentEncodedPath = [[path + stringByAddingPercentEncodingWithAllowedCharacters: + [OFCharacterSet URIPathAllowedCharacterSet]] copy]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; @@ -803,56 +803,56 @@ return self; } - (void)dealloc { - [_URLEncodedScheme release]; - [_URLEncodedHost release]; + [_percentEncodedScheme release]; + [_percentEncodedHost release]; [_port release]; - [_URLEncodedUser release]; - [_URLEncodedPassword release]; - [_URLEncodedPath release]; - [_URLEncodedQuery release]; - [_URLEncodedFragment release]; + [_percentEncodedUser release]; + [_percentEncodedPassword release]; + [_percentEncodedPath release]; + [_percentEncodedQuery release]; + [_percentEncodedFragment release]; [super dealloc]; } - (bool)isEqual: (id)object { - OFURL *URL; + OFURI *URI; if (object == self) return true; - if (![object isKindOfClass: [OFURL class]]) - return false; - - URL = object; - - if (URL->_URLEncodedScheme != _URLEncodedScheme && - ![URL->_URLEncodedScheme isEqual: _URLEncodedScheme]) - return false; - if (URL->_URLEncodedHost != _URLEncodedHost && - ![URL->_URLEncodedHost isEqual: _URLEncodedHost]) - return false; - if (URL->_port != _port && ![URL->_port isEqual: _port]) - return false; - if (URL->_URLEncodedUser != _URLEncodedUser && - ![URL->_URLEncodedUser isEqual: _URLEncodedUser]) - return false; - if (URL->_URLEncodedPassword != _URLEncodedPassword && - ![URL->_URLEncodedPassword isEqual: _URLEncodedPassword]) - return false; - if (URL->_URLEncodedPath != _URLEncodedPath && - ![URL->_URLEncodedPath isEqual: _URLEncodedPath]) - return false; - if (URL->_URLEncodedQuery != _URLEncodedQuery && - ![URL->_URLEncodedQuery isEqual: _URLEncodedQuery]) - return false; - if (URL->_URLEncodedFragment != _URLEncodedFragment && - ![URL->_URLEncodedFragment isEqual: _URLEncodedFragment]) + if (![object isKindOfClass: [OFURI class]]) + return false; + + URI = object; + + if (URI->_percentEncodedScheme != _percentEncodedScheme && + ![URI->_percentEncodedScheme isEqual: _percentEncodedScheme]) + return false; + if (URI->_percentEncodedHost != _percentEncodedHost && + ![URI->_percentEncodedHost isEqual: _percentEncodedHost]) + return false; + if (URI->_port != _port && ![URI->_port isEqual: _port]) + return false; + if (URI->_percentEncodedUser != _percentEncodedUser && + ![URI->_percentEncodedUser isEqual: _percentEncodedUser]) + return false; + if (URI->_percentEncodedPassword != _percentEncodedPassword && + ![URI->_percentEncodedPassword isEqual: _percentEncodedPassword]) + return false; + if (URI->_percentEncodedPath != _percentEncodedPath && + ![URI->_percentEncodedPath isEqual: _percentEncodedPath]) + return false; + if (URI->_percentEncodedQuery != _percentEncodedQuery && + ![URI->_percentEncodedQuery isEqual: _percentEncodedQuery]) + return false; + if (URI->_percentEncodedFragment != _percentEncodedFragment && + ![URI->_percentEncodedFragment isEqual: _percentEncodedFragment]) return false; return true; } @@ -860,110 +860,110 @@ { unsigned long hash; OFHashInit(&hash); - OFHashAddHash(&hash, _URLEncodedScheme.hash); - OFHashAddHash(&hash, _URLEncodedHost.hash); + OFHashAddHash(&hash, _percentEncodedScheme.hash); + OFHashAddHash(&hash, _percentEncodedHost.hash); OFHashAddHash(&hash, _port.hash); - OFHashAddHash(&hash, _URLEncodedUser.hash); - OFHashAddHash(&hash, _URLEncodedPassword.hash); - OFHashAddHash(&hash, _URLEncodedPath.hash); - OFHashAddHash(&hash, _URLEncodedQuery.hash); - OFHashAddHash(&hash, _URLEncodedFragment.hash); + OFHashAddHash(&hash, _percentEncodedUser.hash); + OFHashAddHash(&hash, _percentEncodedPassword.hash); + OFHashAddHash(&hash, _percentEncodedPath.hash); + OFHashAddHash(&hash, _percentEncodedQuery.hash); + OFHashAddHash(&hash, _percentEncodedFragment.hash); OFHashFinalize(&hash); return hash; } - (OFString *)scheme { - return _URLEncodedScheme.stringByURLDecoding; + return _percentEncodedScheme.stringByRemovingPercentEncoding; } -- (OFString *)URLEncodedScheme +- (OFString *)percentEncodedScheme { - return _URLEncodedScheme; + return _percentEncodedScheme; } - (OFString *)host { - if ([_URLEncodedHost hasPrefix: @"["] && - [_URLEncodedHost hasSuffix: @"]"]) { - OFString *host = [_URLEncodedHost substringWithRange: - OFMakeRange(1, _URLEncodedHost.length - 2)]; + if ([_percentEncodedHost hasPrefix: @"["] && + [_percentEncodedHost hasSuffix: @"]"]) { + OFString *host = [_percentEncodedHost substringWithRange: + OFMakeRange(1, _percentEncodedHost.length - 2)]; - if (!OFURLIsIPv6Host(host)) + if (!OFURIIsIPv6Host(host)) @throw [OFInvalidArgumentException exception]; return host; } - return _URLEncodedHost.stringByURLDecoding; + return _percentEncodedHost.stringByRemovingPercentEncoding; } -- (OFString *)URLEncodedHost +- (OFString *)percentEncodedHost { - return _URLEncodedHost; + return _percentEncodedHost; } - (OFNumber *)port { return _port; } - (OFString *)user { - return _URLEncodedUser.stringByURLDecoding; + return _percentEncodedUser.stringByRemovingPercentEncoding; } -- (OFString *)URLEncodedUser +- (OFString *)percentEncodedUser { - return _URLEncodedUser; + return _percentEncodedUser; } - (OFString *)password { - return _URLEncodedPassword.stringByURLDecoding; + return _percentEncodedPassword.stringByRemovingPercentEncoding; } -- (OFString *)URLEncodedPassword +- (OFString *)percentEncodedPassword { - return _URLEncodedPassword; + return _percentEncodedPassword; } - (OFString *)path { - return _URLEncodedPath.stringByURLDecoding; + return _percentEncodedPath.stringByRemovingPercentEncoding; } -- (OFString *)URLEncodedPath +- (OFString *)percentEncodedPath { - return _URLEncodedPath; + return _percentEncodedPath; } - (OFArray *)pathComponents { void *pool = objc_autoreleasePoolPush(); #ifdef OF_HAVE_FILES - bool isFile = [_URLEncodedScheme isEqual: @"file"]; + bool isFile = [_percentEncodedScheme isEqual: @"file"]; #endif OFMutableArray *ret; size_t count; #ifdef OF_HAVE_FILES if (isFile) { - OFString *path = [_URLEncodedPath - of_URLPathToPathWithURLEncodedHost: nil]; + OFString *path = [_percentEncodedPath + of_URIPathToPathWithPercentEncodedHost: nil]; ret = [[path.pathComponents mutableCopy] autorelease]; if (![ret.firstObject isEqual: @"/"]) [ret insertObject: @"/" atIndex: 0]; } else #endif - ret = [[[_URLEncodedPath componentsSeparatedByString: @"/"] + ret = [[[_percentEncodedPath componentsSeparatedByString: @"/"] mutableCopy] autorelease]; count = ret.count; if (count > 0 && [ret.firstObject length] == 0) @@ -973,15 +973,15 @@ OFString *component = [ret objectAtIndex: i]; #ifdef OF_HAVE_FILES if (isFile) component = - [component of_pathComponentToURLPathComponent]; + [component of_pathComponentToURIPathComponent]; #endif - [ret replaceObjectAtIndex: i - withObject: component.stringByURLDecoding]; + component = component.stringByRemovingPercentEncoding; + [ret replaceObjectAtIndex: i withObject: component]; } [ret makeImmutable]; [ret retain]; @@ -991,11 +991,11 @@ } - (OFString *)lastPathComponent { void *pool = objc_autoreleasePoolPush(); - OFString *path = _URLEncodedPath; + OFString *path = _percentEncodedPath; const char *UTF8String, *lastComponent; size_t length; OFString *ret; if (path == nil) { @@ -1022,48 +1022,53 @@ } ret = [OFString stringWithUTF8String: lastComponent length: length - (lastComponent - UTF8String)]; - ret = [ret.stringByURLDecoding retain]; + ret = [ret.stringByRemovingPercentEncoding retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)query { - return _URLEncodedQuery.stringByURLDecoding; + return _percentEncodedQuery.stringByRemovingPercentEncoding; } -- (OFString *)URLEncodedQuery +- (OFString *)percentEncodedQuery { - return _URLEncodedQuery; + return _percentEncodedQuery; } - (OFDictionary OF_GENERIC(OFString *, OFString *) *)queryDictionary { void *pool; OFArray OF_GENERIC(OFString *) *pairs; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *ret; - if (_URLEncodedQuery == nil) + if (_percentEncodedQuery == nil) return nil; pool = objc_autoreleasePoolPush(); - pairs = [_URLEncodedQuery componentsSeparatedByString: @"&"]; + pairs = [_percentEncodedQuery componentsSeparatedByString: @"&"]; ret = [OFMutableDictionary dictionaryWithCapacity: pairs.count]; for (OFString *pair in pairs) { OFArray *parts = [pair componentsSeparatedByString: @"="]; + OFString *name, *value; if (parts.count != 2) @throw [OFInvalidFormatException exception]; - [ret setObject: [[parts objectAtIndex: 1] stringByURLDecoding] - forKey: [[parts objectAtIndex: 0] stringByURLDecoding]]; + name = [[parts objectAtIndex: 0] + stringByRemovingPercentEncoding]; + value = [[parts objectAtIndex: 1] + stringByRemovingPercentEncoding]; + + [ret setObject: value forKey: name]; } [ret makeImmutable]; [ret retain]; @@ -1072,36 +1077,36 @@ return [ret autorelease]; } - (OFString *)fragment { - return _URLEncodedFragment.stringByURLDecoding; + return _percentEncodedFragment.stringByRemovingPercentEncoding; } -- (OFString *)URLEncodedFragment +- (OFString *)percentEncodedFragment { - return _URLEncodedFragment; + return _percentEncodedFragment; } - (id)copy { return [self retain]; } - (id)mutableCopy { - OFURL *copy = [[OFMutableURL alloc] init]; + OFURI *copy = [[OFMutableURI alloc] init]; @try { - copy->_URLEncodedScheme = [_URLEncodedScheme copy]; - copy->_URLEncodedHost = [_URLEncodedHost copy]; + copy->_percentEncodedScheme = [_percentEncodedScheme copy]; + copy->_percentEncodedHost = [_percentEncodedHost copy]; copy->_port = [_port copy]; - copy->_URLEncodedUser = [_URLEncodedUser copy]; - copy->_URLEncodedPassword = [_URLEncodedPassword copy]; - copy->_URLEncodedPath = [_URLEncodedPath copy]; - copy->_URLEncodedQuery = [_URLEncodedQuery copy]; - copy->_URLEncodedFragment = [_URLEncodedFragment copy]; + copy->_percentEncodedUser = [_percentEncodedUser copy]; + copy->_percentEncodedPassword = [_percentEncodedPassword copy]; + copy->_percentEncodedPath = [_percentEncodedPath copy]; + copy->_percentEncodedQuery = [_percentEncodedQuery copy]; + copy->_percentEncodedFragment = [_percentEncodedFragment copy]; } @catch (id e) { [copy release]; @throw e; } @@ -1110,35 +1115,36 @@ - (OFString *)string { OFMutableString *ret = [OFMutableString string]; - [ret appendFormat: @"%@://", _URLEncodedScheme]; + [ret appendFormat: @"%@://", _percentEncodedScheme]; - if (_URLEncodedUser != nil && _URLEncodedPassword != nil) + if (_percentEncodedUser != nil && _percentEncodedPassword != nil) [ret appendFormat: @"%@:%@@", - _URLEncodedUser, _URLEncodedPassword]; - else if (_URLEncodedUser != nil) - [ret appendFormat: @"%@@", _URLEncodedUser]; + _percentEncodedUser, + _percentEncodedPassword]; + else if (_percentEncodedUser != nil) + [ret appendFormat: @"%@@", _percentEncodedUser]; - if (_URLEncodedHost != nil) - [ret appendString: _URLEncodedHost]; + if (_percentEncodedHost != nil) + [ret appendString: _percentEncodedHost]; if (_port != nil) [ret appendFormat: @":%@", _port]; - if (_URLEncodedPath != nil) { - if (![_URLEncodedPath hasPrefix: @"/"]) + if (_percentEncodedPath != nil) { + if (![_percentEncodedPath hasPrefix: @"/"]) @throw [OFInvalidFormatException exception]; - [ret appendString: _URLEncodedPath]; + [ret appendString: _percentEncodedPath]; } - if (_URLEncodedQuery != nil) - [ret appendFormat: @"?%@", _URLEncodedQuery]; + if (_percentEncodedQuery != nil) + [ret appendFormat: @"?%@", _percentEncodedQuery]; - if (_URLEncodedFragment != nil) - [ret appendFormat: @"#%@", _URLEncodedFragment]; + if (_percentEncodedFragment != nil) + [ret appendFormat: @"#%@", _percentEncodedFragment]; [ret makeImmutable]; return ret; } @@ -1147,49 +1153,50 @@ - (OFString *)fileSystemRepresentation { void *pool = objc_autoreleasePoolPush(); OFString *path; - if (![_URLEncodedScheme isEqual: @"file"]) + if (![_percentEncodedScheme isEqual: @"file"]) @throw [OFInvalidArgumentException exception]; - if (![_URLEncodedPath hasPrefix: @"/"]) + if (![_percentEncodedPath hasPrefix: @"/"]) @throw [OFInvalidFormatException exception]; - path = [self.path of_URLPathToPathWithURLEncodedHost: _URLEncodedHost]; + path = [self.path + of_URIPathToPathWithPercentEncodedHost: _percentEncodedHost]; [path retain]; objc_autoreleasePoolPop(pool); return [path autorelease]; } #endif -- (OFURL *)URLByAppendingPathComponent: (OFString *)component +- (OFURI *)URIByAppendingPathComponent: (OFString *)component { - OFMutableURL *URL = [[self mutableCopy] autorelease]; - [URL appendPathComponent: component]; - [URL makeImmutable]; - return URL; + OFMutableURI *URI = [[self mutableCopy] autorelease]; + [URI appendPathComponent: component]; + [URI makeImmutable]; + return URI; } -- (OFURL *)URLByAppendingPathComponent: (OFString *)component +- (OFURI *)URIByAppendingPathComponent: (OFString *)component isDirectory: (bool)isDirectory { - OFMutableURL *URL = [[self mutableCopy] autorelease]; - [URL appendPathComponent: component isDirectory: isDirectory]; - [URL makeImmutable]; - return URL; + OFMutableURI *URI = [[self mutableCopy] autorelease]; + [URI appendPathComponent: component isDirectory: isDirectory]; + [URI makeImmutable]; + return URI; } -- (OFURL *)URLByStandardizingPath +- (OFURI *)URIByStandardizingPath { - OFMutableURL *URL = [[self mutableCopy] autorelease]; - [URL standardizePath]; - [URL makeImmutable]; - return URL; + OFMutableURI *URI = [[self mutableCopy] autorelease]; + [URI standardizePath]; + [URI makeImmutable]; + return URI; } - (OFString *)description { return [OFString stringWithFormat: @"<%@: %@>",