Index: src/OFData.m ================================================================== --- src/OFData.m +++ src/OFData.m @@ -219,21 +219,14 @@ { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); - OFURLHandler *URLHandler; - OFStream *stream; + OFStream *stream = [OFURLHandler openItemAtURL: URL mode: @"r"]; size_t pageSize; unsigned char *buffer; - if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil) - @throw [OFUnsupportedProtocolException - exceptionWithURL: URL]; - - stream = [URLHandler openItemAtURL: URL mode: @"r"]; - _count = 0; _itemSize = 1; _freeWhenDone = true; pageSize = [OFSystemInfo pageSize]; @@ -599,16 +592,12 @@ #endif - (void)writeToURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); - OFURLHandler *URLHandler; - if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil) - @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; - - [[URLHandler openItemAtURL: URL mode: @"w"] writeData: self]; + [[OFURLHandler openItemAtURL: URL mode: @"w"] writeData: self]; objc_autoreleasePoolPop(pool); } - (OFXMLElement *)XMLElementBySerializing Index: src/OFFileManager.m ================================================================== --- src/OFFileManager.m +++ src/OFFileManager.m @@ -658,16 +658,15 @@ OFStream *destinationStream = nil; char *buffer; buffer = OFAllocMemory(1, pageSize); @try { - sourceStream = [[OFURLHandler handlerForURL: source] - openItemAtURL: source - mode: @"r"]; - destinationStream = [[OFURLHandler handlerForURL: - destination] openItemAtURL: destination - mode: @"w"]; + sourceStream = [OFURLHandler openItemAtURL: source + mode: @"r"]; + destinationStream = [OFURLHandler + openItemAtURL: destination + mode: @"w"]; while (!sourceStream.atEndOfStream) { size_t length; length = [sourceStream Index: src/OFHTTPURLHandler.m ================================================================== --- src/OFHTTPURLHandler.m +++ src/OFHTTPURLHandler.m @@ -19,12 +19,11 @@ #import "OFHTTPClient.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" @implementation OFHTTPURLHandler -- (OFStream *)openItemAtURL: (OFURL *)URL - mode: (OFString *)mode +- (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode { void *pool = objc_autoreleasePoolPush(); OFHTTPClient *client = [OFHTTPClient client]; OFHTTPRequest *request = [OFHTTPRequest requestWithURL: URL]; OFHTTPResponse *response = [client performRequest: request]; Index: src/OFINIFile.m ================================================================== --- src/OFINIFile.m +++ src/OFINIFile.m @@ -116,12 +116,11 @@ OFStream *file; OFINICategory *category = nil; OFString *line; @try { - file = [[OFURLHandler handlerForURL: URL] openItemAtURL: URL - mode: @"r"]; + file = [OFURLHandler openItemAtURL: URL mode: @"r"]; } @catch (OFOpenItemFailedException *e) { /* Handle missing file like an empty file */ if (e.errNo == ENOENT) return; @@ -160,13 +159,11 @@ } - (void)writeToURL: (OFURL *)URL encoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); - OFStream *file = [[OFURLHandler handlerForURL: URL] - openItemAtURL: URL - mode: @"w"]; + OFStream *file = [OFURLHandler openItemAtURL: URL mode: @"w"]; bool first = true; for (OFINICategory *category in _categories) if ([category of_writeToStream: file encoding: encoding Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -2756,17 +2756,13 @@ } - (void)writeToURL: (OFURL *)URL encoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); - OFURLHandler *URLHandler; OFStream *stream; - if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil) - @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; - - stream = [URLHandler openItemAtURL: URL mode: @"w"]; + stream = [OFURLHandler openItemAtURL: URL mode: @"w"]; [stream writeString: self encoding: encoding]; objc_autoreleasePoolPop(pool); } Index: src/OFURLHandler.h ================================================================== --- src/OFURLHandler.h +++ src/OFURLHandler.h @@ -56,11 +56,34 @@ /** * @brief Returns the handler for the specified URL. * * @return The handler for the specified URL. */ -+ (OF_KINDOF(OFURLHandler *))handlerForURL: (OFURL *)URL; ++ (OFURLHandler *)handlerForURL: (OFURL *)URL; + +/** + * @brief Opens the item at the specified URL. + * + * @param URL The URL of the item which should be opened + * @param mode The mode in which the file should be opened.@n + * Possible modes are: + * @n + * Mode | Description + * ---------------|------------------------------------- + * `r` | Read-only + * `r+` | Read-write + * `w` | Write-only, create or truncate + * `wx` | Write-only, create or fail, exclusive + * `w+` | Read-write, create or truncate + * `w+x` | Read-write, create or fail, exclusive + * `a` | Write-only, create or append + * `a+` | Read-write, create or append + * @n + * The handler is allowed to not implement all modes and is also + * allowed to implement additional, scheme-specific modes. + */ ++ (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes the handler for the specified scheme. Index: src/OFURLHandler.m ================================================================== --- src/OFURLHandler.m +++ src/OFURLHandler.m @@ -94,11 +94,11 @@ #endif return true; } -+ (OF_KINDOF(OFURLHandler *))handlerForURL: (OFURL *)URL ++ (OFURLHandler *)handlerForURL: (OFURL *)URL { OF_KINDOF(OFURLHandler *) handler; #ifdef OF_HAVE_THREADS [mutex lock]; @@ -114,10 +114,15 @@ if (handler == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; return handler; } + ++ (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode +{ + return [[self handlerForURL: URL] openItemAtURL: URL mode: mode]; +} - (instancetype)init { OF_INVALID_INIT_METHOD } Index: tests/OFHMACTests.m ================================================================== --- tests/OFHMACTests.m +++ tests/OFHMACTests.m @@ -50,12 +50,11 @@ @implementation TestsAppDelegate (OFHMACTests) - (void)HMACTests { void *pool = objc_autoreleasePoolPush(); OFURL *URL = [OFURL URLWithString: @"objfw-embedded:///testfile.bin"]; - OFStream *file = [[OFURLHandler handlerForURL: URL] - openItemAtURL: URL mode: @"r"]; + OFStream *file = [OFURLHandler openItemAtURL: URL mode: @"r"]; OFHMAC *HMACMD5, *HMACSHA1, *HMACRMD160; OFHMAC *HMACSHA256, *HMACSHA384, *HMACSHA512; TEST(@"+[HMACWithHashClass:] with MD5", (HMACMD5 = [OFHMAC HMACWithHashClass: [OFMD5Hash class] Index: tests/OFMD5HashTests.m ================================================================== --- tests/OFMD5HashTests.m +++ tests/OFMD5HashTests.m @@ -28,12 +28,11 @@ - (void)MD5HashTests { void *pool = objc_autoreleasePoolPush(); OFMD5Hash *MD5, *MD5Copy; OFURL *URL = [OFURL URLWithString: @"objfw-embedded:///testfile.bin"]; - OFStream *file = [[OFURLHandler handlerForURL: URL] - openItemAtURL: URL mode: @"r"]; + OFStream *file = [OFURLHandler openItemAtURL: URL mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (MD5 = [OFMD5Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { Index: tests/OFRIPEMD160HashTests.m ================================================================== --- tests/OFRIPEMD160HashTests.m +++ tests/OFRIPEMD160HashTests.m @@ -29,12 +29,11 @@ - (void)RIPEMD160HashTests { void *pool = objc_autoreleasePoolPush(); OFRIPEMD160Hash *RIPEMD160, *RIPEMD160Copy; OFURL *URL = [OFURL URLWithString: @"objfw-embedded:///testfile.bin"]; - OFStream *file = [[OFURLHandler handlerForURL: URL] - openItemAtURL: URL mode: @"r"]; + OFStream *file = [OFURLHandler openItemAtURL: URL mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (RIPEMD160 = [OFRIPEMD160Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { Index: tests/OFSHA1HashTests.m ================================================================== --- tests/OFSHA1HashTests.m +++ tests/OFSHA1HashTests.m @@ -29,12 +29,11 @@ - (void)SHA1HashTests { void *pool = objc_autoreleasePoolPush(); OFSHA1Hash *SHA1, *SHA1Copy; OFURL *URL = [OFURL URLWithString: @"objfw-embedded:///testfile.bin"]; - OFStream *file = [[OFURLHandler handlerForURL: URL] - openItemAtURL: URL mode: @"r"]; + OFStream *file = [OFURLHandler openItemAtURL: URL mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (SHA1 = [OFSHA1Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { Index: tests/OFSHA224HashTests.m ================================================================== --- tests/OFSHA224HashTests.m +++ tests/OFSHA224HashTests.m @@ -29,12 +29,11 @@ - (void)SHA224HashTests { void *pool = objc_autoreleasePoolPush(); OFSHA224Hash *SHA224, *SHA224Copy; OFURL *URL = [OFURL URLWithString: @"objfw-embedded:///testfile.bin"]; - OFStream *file = [[OFURLHandler handlerForURL: URL] - openItemAtURL: URL mode: @"r"]; + OFStream *file = [OFURLHandler openItemAtURL: URL mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (SHA224 = [OFSHA224Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { Index: tests/OFSHA256HashTests.m ================================================================== --- tests/OFSHA256HashTests.m +++ tests/OFSHA256HashTests.m @@ -29,12 +29,11 @@ - (void)SHA256HashTests { void *pool = objc_autoreleasePoolPush(); OFSHA256Hash *SHA256, *SHA256Copy; OFURL *URL = [OFURL URLWithString: @"objfw-embedded:///testfile.bin"]; - OFStream *file = [[OFURLHandler handlerForURL: URL] - openItemAtURL: URL mode: @"r"]; + OFStream *file = [OFURLHandler openItemAtURL: URL mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (SHA256 = [OFSHA256Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { Index: tests/OFSHA384HashTests.m ================================================================== --- tests/OFSHA384HashTests.m +++ tests/OFSHA384HashTests.m @@ -30,12 +30,11 @@ - (void)SHA384HashTests { void *pool = objc_autoreleasePoolPush(); OFSHA384Hash *SHA384, *SHA384Copy; OFURL *URL = [OFURL URLWithString: @"objfw-embedded:///testfile.bin"]; - OFStream *file = [[OFURLHandler handlerForURL: URL] - openItemAtURL: URL mode: @"r"]; + OFStream *file = [OFURLHandler openItemAtURL: URL mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (SHA384 = [OFSHA384Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { Index: tests/OFSHA512HashTests.m ================================================================== --- tests/OFSHA512HashTests.m +++ tests/OFSHA512HashTests.m @@ -31,12 +31,11 @@ - (void)SHA512HashTests { void *pool = objc_autoreleasePoolPush(); OFSHA512Hash *SHA512, *SHA512Copy; OFURL *URL = [OFURL URLWithString: @"objfw-embedded:///testfile.bin"]; - OFStream *file = [[OFURLHandler handlerForURL: URL] - openItemAtURL: URL mode: @"r"]; + OFStream *file = [OFURLHandler openItemAtURL: URL mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (SHA512 = [OFSHA512Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) {