@@ -19,25 +19,23 @@ #include #import "OFURL.h" #import "OFArray.h" #import "OFDictionary.h" -#import "OFNumber.h" -#import "OFString.h" -#import "OFXMLElement.h" - #ifdef OF_HAVE_FILES # import "OFFileManager.h" # import "OFFileURLHandler.h" #endif +#import "OFNumber.h" +#import "OFOnce.h" +#import "OFString.h" +#import "OFXMLElement.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" -#import "once.h" - @interface OFURLAllowedCharacterSetBase: OFCharacterSet @end @interface OFURLAllowedCharacterSet: OFURLAllowedCharacterSetBase @end @@ -58,12 +56,13 @@ static OFCharacterSet *URLSchemeAllowedCharacterSet = nil; static OFCharacterSet *URLPathAllowedCharacterSet = nil; static OFCharacterSet *URLQueryOrFragmentAllowedCharacterSet = nil; static OFCharacterSet *URLQueryKeyValueAllowedCharacterSet = nil; -static of_once_t URLAllowedCharacterSetOnce = OF_ONCE_INIT; -static of_once_t URLQueryOrFragmentAllowedCharacterSetOnce = OF_ONCE_INIT; +static OFOnceControl URLAllowedCharacterSetOnce = OFOnceControlInitValue; +static OFOnceControl URLQueryOrFragmentAllowedCharacterSetOnce = + OFOnceControlInitValue; static void initURLAllowedCharacterSet(void) { URLAllowedCharacterSet = [[OFURLAllowedCharacterSet alloc] init]; @@ -99,24 +98,24 @@ OF_DIRECT_MEMBERS @interface OFInvertedCharacterSetWithoutPercent: OFCharacterSet { OFCharacterSet *_characterSet; - bool (*_characterIsMember)(id, SEL, of_unichar_t); + bool (*_characterIsMember)(id, SEL, OFUnichar); } - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet; @end bool -of_url_is_ipv6_host(OFString *host) +OFURLIsIPv6Host(OFString *host) { const char *UTF8String = host.UTF8String; bool hasColon = false; while (*UTF8String != '\0') { - if (!of_ascii_isdigit(*UTF8String) && *UTF8String != ':' && + if (!OFASCIIIsDigit(*UTF8String) && *UTF8String != ':' && (*UTF8String < 'a' || *UTF8String > 'f') && (*UTF8String < 'A' || *UTF8String > 'F')) return false; if (*UTF8String == ':') @@ -143,18 +142,18 @@ { } - (unsigned int)retainCount { - return OF_RETAIN_COUNT_MAX; + return OFMaxRetainCount; } @end @implementation OFURLAllowedCharacterSet -- (bool)characterIsMember: (of_unichar_t)character +- (bool)characterIsMember: (OFUnichar)character { - if (character < CHAR_MAX && of_ascii_isalnum(character)) + if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; switch (character) { case '-': case '.': @@ -177,13 +176,13 @@ } } @end @implementation OFURLSchemeAllowedCharacterSet -- (bool)characterIsMember: (of_unichar_t)character +- (bool)characterIsMember: (OFUnichar)character { - if (character < CHAR_MAX && of_ascii_isalnum(character)) + if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; switch (character) { case '+': case '-': @@ -194,13 +193,13 @@ } } @end @implementation OFURLPathAllowedCharacterSet -- (bool)characterIsMember: (of_unichar_t)character +- (bool)characterIsMember: (OFUnichar)character { - if (character < CHAR_MAX && of_ascii_isalnum(character)) + if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; switch (character) { case '-': case '.': @@ -226,13 +225,13 @@ } } @end @implementation OFURLQueryOrFragmentAllowedCharacterSet -- (bool)characterIsMember: (of_unichar_t)character +- (bool)characterIsMember: (OFUnichar)character { - if (character < CHAR_MAX && of_ascii_isalnum(character)) + if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; switch (character) { case '-': case '.': @@ -259,13 +258,13 @@ } } @end @implementation OFURLQueryKeyValueAllowedCharacterSet -- (bool)characterIsMember: (of_unichar_t)character +- (bool)characterIsMember: (OFUnichar)character { - if (character < CHAR_MAX && of_ascii_isalnum(character)) + if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; switch (character) { case '-': case '.': @@ -296,11 +295,11 @@ { self = [super init]; @try { _characterSet = [characterSet retain]; - _characterIsMember = (bool (*)(id, SEL, of_unichar_t)) + _characterIsMember = (bool (*)(id, SEL, OFUnichar)) [_characterSet methodForSelector: @selector(characterIsMember:)]; } @catch (id e) { [self release]; @throw e; @@ -314,88 +313,88 @@ [_characterSet release]; [super dealloc]; } -- (bool)characterIsMember: (of_unichar_t)character +- (bool)characterIsMember: (OFUnichar)character { return (character != '%' && !_characterIsMember(_characterSet, @selector(characterIsMember:), character)); } @end void -of_url_verify_escaped(OFString *string, OFCharacterSet *characterSet) +OFURLVerifyIsEscaped(OFString *string, OFCharacterSet *characterSet) { void *pool = objc_autoreleasePoolPush(); characterSet = [[[OFInvertedCharacterSetWithoutPercent alloc] initWithCharacterSet: characterSet] autorelease]; - if ([string indexOfCharacterFromSet: characterSet] != OF_NOT_FOUND) + if ([string indexOfCharacterFromSet: characterSet] != OFNotFound) @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); } @implementation OFCharacterSet (URLCharacterSets) + (OFCharacterSet *)URLSchemeAllowedCharacterSet { - static of_once_t onceControl = OF_ONCE_INIT; - of_once(&onceControl, initURLSchemeAllowedCharacterSet); + static OFOnceControl onceControl = OFOnceControlInitValue; + OFOnce(&onceControl, initURLSchemeAllowedCharacterSet); return URLSchemeAllowedCharacterSet; } + (OFCharacterSet *)URLHostAllowedCharacterSet { - of_once(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); + OFOnce(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); return URLAllowedCharacterSet; } + (OFCharacterSet *)URLUserAllowedCharacterSet { - of_once(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); + OFOnce(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); return URLAllowedCharacterSet; } + (OFCharacterSet *)URLPasswordAllowedCharacterSet { - of_once(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); + OFOnce(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); return URLAllowedCharacterSet; } + (OFCharacterSet *)URLPathAllowedCharacterSet { - static of_once_t onceControl = OF_ONCE_INIT; - of_once(&onceControl, initURLPathAllowedCharacterSet); + static OFOnceControl onceControl = OFOnceControlInitValue; + OFOnce(&onceControl, initURLPathAllowedCharacterSet); return URLPathAllowedCharacterSet; } + (OFCharacterSet *)URLQueryAllowedCharacterSet { - of_once(&URLQueryOrFragmentAllowedCharacterSetOnce, + OFOnce(&URLQueryOrFragmentAllowedCharacterSetOnce, initURLQueryOrFragmentAllowedCharacterSet); return URLQueryOrFragmentAllowedCharacterSet; } + (OFCharacterSet *)URLQueryKeyValueAllowedCharacterSet { - static of_once_t onceControl = OF_ONCE_INIT; - of_once(&onceControl, initURLQueryKeyValueAllowedCharacterSet); + static OFOnceControl onceControl = OFOnceControlInitValue; + OFOnce(&onceControl, initURLQueryKeyValueAllowedCharacterSet); return URLQueryKeyValueAllowedCharacterSet; } + (OFCharacterSet *)URLFragmentAllowedCharacterSet { - of_once(&URLQueryOrFragmentAllowedCharacterSetOnce, + OFOnce(&URLQueryOrFragmentAllowedCharacterSetOnce, initURLQueryOrFragmentAllowedCharacterSet); return URLQueryOrFragmentAllowedCharacterSet; } @end @@ -441,31 +440,26 @@ @try { void *pool = objc_autoreleasePoolPush(); char *tmp, *tmp2; bool isIPv6Host = false; - if ((UTF8String2 = of_strdup(string.UTF8String)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: - string.UTF8StringLength]; - - UTF8String = UTF8String2; + UTF8String = UTF8String2 = OFStrDup(string.UTF8String); if ((tmp = strchr(UTF8String, ':')) == NULL) @throw [OFInvalidFormatException exception]; if (strncmp(tmp, "://", 3) != 0) @throw [OFInvalidFormatException exception]; for (tmp2 = UTF8String; tmp2 < tmp; tmp2++) - *tmp2 = of_ascii_tolower(*tmp2); + *tmp2 = OFASCIIToLower(*tmp2); _URLEncodedScheme = [[OFString alloc] initWithUTF8String: UTF8String length: tmp - UTF8String]; - of_url_verify_escaped(_URLEncodedScheme, + OFURLVerifyIsEscaped(_URLEncodedScheme, [OFCharacterSet URLSchemeAllowedCharacterSet]); UTF8String = tmp + 3; if ((tmp = strchr(UTF8String, '/')) != NULL) { @@ -486,27 +480,27 @@ _URLEncodedUser = [[OFString alloc] initWithUTF8String: UTF8String]; _URLEncodedPassword = [[OFString alloc] initWithUTF8String: tmp3]; - of_url_verify_escaped(_URLEncodedPassword, + OFURLVerifyIsEscaped(_URLEncodedPassword, [OFCharacterSet URLPasswordAllowedCharacterSet]); } else _URLEncodedUser = [[OFString alloc] initWithUTF8String: UTF8String]; - of_url_verify_escaped(_URLEncodedUser, + OFURLVerifyIsEscaped(_URLEncodedUser, [OFCharacterSet URLUserAllowedCharacterSet]); UTF8String = tmp2; } if (UTF8String[0] == '[') { tmp2 = UTF8String++; - while (of_ascii_isdigit(*UTF8String) || + while (OFASCIIIsDigit(*UTF8String) || *UTF8String == ':' || (*UTF8String >= 'a' && *UTF8String <= 'f') || (*UTF8String >= 'A' && *UTF8String <= 'F')) UTF8String++; @@ -523,11 +517,11 @@ OFString *portString; tmp2 = ++UTF8String; while (*UTF8String != '\0') { - if (!of_ascii_isdigit(*UTF8String)) + if (!OFASCIIIsDigit(*UTF8String)) @throw [OFInvalidFormatException exception]; UTF8String++; } @@ -566,21 +560,21 @@ } else _URLEncodedHost = [[OFString alloc] initWithUTF8String: UTF8String]; if (!isIPv6Host) - of_url_verify_escaped(_URLEncodedHost, + OFURLVerifyIsEscaped(_URLEncodedHost, [OFCharacterSet URLHostAllowedCharacterSet]); if ((UTF8String = tmp) != NULL) { if ((tmp = strchr(UTF8String, '#')) != NULL) { *tmp = '\0'; _URLEncodedFragment = [[OFString alloc] initWithUTF8String: tmp + 1]; - of_url_verify_escaped(_URLEncodedFragment, + OFURLVerifyIsEscaped(_URLEncodedFragment, [OFCharacterSet URLFragmentAllowedCharacterSet]); } if ((tmp = strchr(UTF8String, '?')) != NULL) { @@ -587,11 +581,11 @@ *tmp = '\0'; _URLEncodedQuery = [[OFString alloc] initWithUTF8String: tmp + 1]; - of_url_verify_escaped(_URLEncodedQuery, + OFURLVerifyIsEscaped(_URLEncodedQuery, [OFCharacterSet URLQueryAllowedCharacterSet]); } UTF8String--; @@ -598,27 +592,26 @@ *UTF8String = '/'; _URLEncodedPath = [[OFString alloc] initWithUTF8String: UTF8String]; - of_url_verify_escaped(_URLEncodedPath, + OFURLVerifyIsEscaped(_URLEncodedPath, [OFCharacterSet URLPathAllowedCharacterSet]); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } @finally { - free(UTF8String2); + OFFreeMemory(UTF8String2); } return self; } -- (instancetype)initWithString: (OFString *)string - relativeToURL: (OFURL *)URL +- (instancetype)initWithString: (OFString *)string relativeToURL: (OFURL *)URL { char *UTF8String, *UTF8String2 = NULL; if ([string containsString: @"://"]) return [self initWithString: string]; @@ -633,32 +626,27 @@ _URLEncodedHost = [URL->_URLEncodedHost copy]; _port = [URL->_port copy]; _URLEncodedUser = [URL->_URLEncodedUser copy]; _URLEncodedPassword = [URL->_URLEncodedPassword copy]; - if ((UTF8String2 = of_strdup(string.UTF8String)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: - string.UTF8StringLength]; - - UTF8String = UTF8String2; + UTF8String = UTF8String2 = OFStrDup(string.UTF8String); if ((tmp = strchr(UTF8String, '#')) != NULL) { *tmp = '\0'; _URLEncodedFragment = [[OFString alloc] initWithUTF8String: tmp + 1]; - of_url_verify_escaped(_URLEncodedFragment, + OFURLVerifyIsEscaped(_URLEncodedFragment, [OFCharacterSet URLFragmentAllowedCharacterSet]); } if ((tmp = strchr(UTF8String, '?')) != NULL) { *tmp = '\0'; _URLEncodedQuery = [[OFString alloc] initWithUTF8String: tmp + 1]; - of_url_verify_escaped(_URLEncodedQuery, + OFURLVerifyIsEscaped(_URLEncodedQuery, [OFCharacterSet URLQueryAllowedCharacterSet]); } if (*UTF8String == '/') _URLEncodedPath = [[OFString alloc] @@ -675,15 +663,15 @@ OFMutableString *path = [OFMutableString stringWithString: (URL->_URLEncodedPath != nil ? URL->_URLEncodedPath : @"/")]; - of_range_t range = [path + OFRange range = [path rangeOfString: @"/" - options: OF_STRING_SEARCH_BACKWARDS]; + options: OFStringSearchBackwards]; - if (range.location == OF_NOT_FOUND) + if (range.location == OFNotFound) @throw [OFInvalidFormatException exception]; range.location++; range.length = path.length - range.location; @@ -694,19 +682,19 @@ _URLEncodedPath = [path copy]; } } - of_url_verify_escaped(_URLEncodedPath, + OFURLVerifyIsEscaped(_URLEncodedPath, [OFCharacterSet URLPathAllowedCharacterSet]); objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } @finally { - free(UTF8String2); + OFFreeMemory(UTF8String2); } return self; } @@ -715,21 +703,18 @@ { bool isDirectory; @try { void *pool = objc_autoreleasePoolPush(); - isDirectory = [path of_isDirectoryPath]; - objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } - self = [self initFileURLWithPath: path - isDirectory: isDirectory]; + self = [self initFileURLWithPath: path isDirectory: isDirectory]; return self; } - (instancetype)initFileURLWithPath: (OFString *)path @@ -777,11 +762,11 @@ void *pool = objc_autoreleasePoolPush(); OFString *stringValue; @try { if (![element.name isEqual: self.className] || - ![element.namespace isEqual: OF_SERIALIZATION_NS]) + ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; stringValue = element.stringValue; } @catch (id e) { [self release]; @@ -848,24 +833,24 @@ return true; } - (unsigned long)hash { - uint32_t hash; - - OF_HASH_INIT(hash); - - OF_HASH_ADD_HASH(hash, _URLEncodedScheme.hash); - OF_HASH_ADD_HASH(hash, _URLEncodedHost.hash); - OF_HASH_ADD_HASH(hash, _port.hash); - OF_HASH_ADD_HASH(hash, _URLEncodedUser.hash); - OF_HASH_ADD_HASH(hash, _URLEncodedPassword.hash); - OF_HASH_ADD_HASH(hash, _URLEncodedPath.hash); - OF_HASH_ADD_HASH(hash, _URLEncodedQuery.hash); - OF_HASH_ADD_HASH(hash, _URLEncodedFragment.hash); - - OF_HASH_FINALIZE(hash); + unsigned long hash; + + OFHashInit(&hash); + + OFHashAddHash(&hash, _URLEncodedScheme.hash); + OFHashAddHash(&hash, _URLEncodedHost.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); + + OFHashFinalize(&hash); return hash; } - (OFString *)scheme @@ -881,13 +866,13 @@ - (OFString *)host { if ([_URLEncodedHost hasPrefix: @"["] && [_URLEncodedHost hasSuffix: @"]"]) { OFString *host = [_URLEncodedHost substringWithRange: - of_range(1, _URLEncodedHost.length - 2)]; + OFRangeMake(1, _URLEncodedHost.length - 2)]; - if (!of_url_is_ipv6_host(host)) + if (!OFURLIsIPv6Host(host)) @throw [OFInvalidArgumentException exception]; return host; } @@ -948,22 +933,20 @@ OFString *path = [_URLEncodedPath of_URLPathToPathWithURLEncodedHost: nil]; ret = [[path.pathComponents mutableCopy] autorelease]; if (![ret.firstObject isEqual: @"/"]) - [ret insertObject: @"/" - atIndex: 0]; + [ret insertObject: @"/" atIndex: 0]; } else #endif ret = [[[_URLEncodedPath componentsSeparatedByString: @"/"] mutableCopy] autorelease]; count = ret.count; if (count > 0 && [ret.firstObject length] == 0) - [ret replaceObjectAtIndex: 0 - withObject: @"/"]; + [ret replaceObjectAtIndex: 0 withObject: @"/"]; for (size_t i = 0; i < count; i++) { OFString *component = [ret objectAtIndex: i]; #ifdef OF_HAVE_FILES @@ -1160,36 +1143,29 @@ #endif - (OFURL *)URLByAppendingPathComponent: (OFString *)component { OFMutableURL *URL = [[self mutableCopy] autorelease]; - [URL appendPathComponent: component]; [URL makeImmutable]; - return URL; } - (OFURL *)URLByAppendingPathComponent: (OFString *)component isDirectory: (bool)isDirectory { OFMutableURL *URL = [[self mutableCopy] autorelease]; - - [URL appendPathComponent: component - isDirectory: isDirectory]; + [URL appendPathComponent: component isDirectory: isDirectory]; [URL makeImmutable]; - return URL; } - (OFURL *)URLByStandardizingPath { OFMutableURL *URL = [[self mutableCopy] autorelease]; - [URL standardizePath]; [URL makeImmutable]; - return URL; } - (OFString *)description { @@ -1201,15 +1177,15 @@ { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className - namespace: OF_SERIALIZATION_NS + namespace: OFSerializationNS stringValue: self.string]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } @end