@@ -20,19 +20,21 @@ #include #include #import "OFData.h" #import "OFData+Private.h" -#import "OFString.h" +#import "OFDictionary.h" #ifdef OF_HAVE_FILES # import "OFFile.h" # import "OFFileManager.h" #endif -#import "OFURL.h" -#import "OFDictionary.h" -#import "OFXMLElement.h" +#import "OFStream.h" +#import "OFString.h" #import "OFSystemInfo.h" +#import "OFURL.h" +#import "OFURLHandler.h" +#import "OFXMLElement.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerReplyException.h" #import "OFOutOfMemoryException.h" @@ -231,33 +233,52 @@ return self; } #endif -#if defined(OF_HAVE_FILES) || defined(OF_HAVE_SOCKETS) - (instancetype)initWithContentsOfURL: (OFURL *)URL { - void *pool; - OFString *scheme; - - pool = objc_autoreleasePoolPush(); - - scheme = [URL scheme]; - -# ifdef OF_HAVE_FILES - if ([scheme isEqual: @"file"]) - self = [self initWithContentsOfFile: - [URL fileSystemRepresentation]]; - else -# endif - @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; - - objc_autoreleasePoolPop(pool); + self = [super init]; + + @try { + void *pool = objc_autoreleasePoolPush(); + OFURLHandler *URLHandler; + OFStream *stream; + size_t pageSize; + unsigned char *buffer; + + if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil) + @throw [OFUnsupportedProtocolException + exceptionWithURL: URL]; + + _itemSize = 1; + _count = 0; + + pageSize = [OFSystemInfo pageSize]; + buffer = [self allocMemoryWithSize: pageSize]; + + while (![stream isAtEndOfStream]) { + size_t length = [stream readIntoBuffer: buffer + length: pageSize]; + + if (SIZE_MAX - _count < length) + @throw [OFOutOfRangeException exception]; + + _items = [self resizeMemory: _items + size: _count + length]; + memcpy(_items + _count, buffer, length); + _count += length; + } + + objc_autoreleasePoolPop(pool); + } @catch (id e) { + [self release]; + @throw e; + } return self; } -#endif - (instancetype)initWithStringRepresentation: (OFString *)string { self = [super init];