Index: src/OFFile.m ================================================================== --- src/OFFile.m +++ src/OFFile.m @@ -236,13 +236,13 @@ flags, 0666); # endif if (handle == -1) @throw [OFOpenItemFailedException - exceptionWithURL: [OFURL fileURLWithPath: path] - mode: mode - errNo: errno]; + exceptionWithPath: path + mode: mode + errNo: errno]; #else handle = OFAllocMemory(1, sizeof(*handle)); @try { if ((flags = parseMode(mode.UTF8String, &handle->append)) == -1) @@ -249,11 +249,10 @@ @throw [OFInvalidArgumentException exception]; if ((handle->handle = Open([path cStringWithEncoding: [OFLocale encoding]], flags)) == 0) { int errNo; - OFURL *URL; switch (IoErr()) { case ERROR_OBJECT_IN_USE: case ERROR_DISK_NOT_VALIDATED: errNo = EBUSY; @@ -271,15 +270,14 @@ default: errNo = 0; break; } - URL = [OFURL fileURLWithPath: path]; @throw [OFOpenItemFailedException - exceptionWithURL: URL - mode: mode - errNo: errNo]; + exceptionWithPath: path + mode: mode + errNo: errNo]; } if (handle->append) { # if defined(OF_MORPHOS) if (Seek64(handle->handle, 0, @@ -288,17 +286,15 @@ if (ChangeFilePosition(handle->handle, 0, OFFSET_END) == -1) { # else if (Seek(handle->handle, 0, OFFSET_END) == -1) { # endif - OFURL *URL = - [OFURL fileURLWithPath: path]; Close(handle->handle); @throw [OFOpenItemFailedException - exceptionWithURL: URL - mode: mode - errNo: EIO]; + exceptionWithPath: path + mode: mode + errNo: EIO]; } } Forbid(); Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -1004,13 +1004,13 @@ @try { fileSize = [[OFFileManager defaultManager] attributesOfItemAtPath: path].fileSize; } @catch (OFRetrieveItemAttributesFailedException *e) { @throw [OFOpenItemFailedException - exceptionWithURL: [OFURL fileURLWithPath: path] - mode: @"r" - errNo: e.errNo]; + exceptionWithPath: path + mode: @"r" + errNo: e.errNo]; } objc_autoreleasePoolPop(pool); # if ULLONG_MAX > SIZE_MAX Index: src/OFZIPArchive.m ================================================================== --- src/OFZIPArchive.m +++ src/OFZIPArchive.m @@ -35,10 +35,11 @@ #import "OFChecksumMismatchException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" +#import "OFOpenItemFailedException.h" #import "OFOutOfRangeException.h" #import "OFSeekFailedException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedVersionException.h" #import "OFWriteFailedException.h" @@ -439,11 +440,13 @@ if (_mode != modeRead) @throw [OFInvalidArgumentException exception]; if ((entry = [_pathToEntryMap objectForKey: path]) == nil) - @throw [OFInvalidArgumentException exception]; + @throw [OFOpenItemFailedException exceptionWithPath: path + mode: @"r" + errNo: ENOENT]; [self of_closeLastReturnedStream]; offset64 = entry.of_localFileHeaderOffset; if (offset64 < 0 || (OFFileOffset)offset64 != offset64) @@ -493,11 +496,14 @@ pool = objc_autoreleasePoolPush(); entry = [[entry_ mutableCopy] autorelease]; if ([_pathToEntryMap objectForKey: entry.fileName] != nil) - @throw [OFInvalidArgumentException exception]; + @throw [OFOpenItemFailedException + exceptionWithPath: entry.fileName + mode: @"w" + errNo: EEXIST]; if (entry.compressionMethod != OFZIPArchiveEntryCompressionMethodNone) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; Index: src/exceptions/OFOpenItemFailedException.h ================================================================== --- src/exceptions/OFOpenItemFailedException.h +++ src/exceptions/OFOpenItemFailedException.h @@ -25,19 +25,25 @@ * * @brief An exception indicating an item could not be opened. */ @interface OFOpenItemFailedException: OFException { - OFURL *_URL; - OFString *_Nullable _mode; + OFURL *_Nullable _URL; + OFString *_Nullable _path; + OFString *_mode; int _errNo; } /** * @brief The URL of the item which could not be opened. */ -@property (readonly, nonatomic) OFURL *URL; +@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFURL *URL; + +/** + * @brief The path of the item which could not be opened. + */ +@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *path; /** * @brief The mode in which the item should have been opened. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *mode; @@ -57,10 +63,22 @@ */ + (instancetype)exceptionWithURL: (OFURL *)URL mode: (nullable OFString *)mode errNo: (int)errNo; +/** + * @brief Creates a new, autoreleased open item failed exception. + * + * @param path The path of the item which could not be opened + * @param mode A string with the mode in which the item should have been opened + * @param errNo The errno of the error that occurred + * @return A new, autoreleased open item failed exception + */ ++ (instancetype)exceptionWithPath: (OFString *)path + mode: (nullable OFString *)mode + errNo: (int)errNo; + + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated open item failed exception. * @@ -71,9 +89,21 @@ */ - (instancetype)initWithURL: (OFURL *)URL mode: (nullable OFString *)mode errNo: (int)errNo; +/** + * @brief Initializes an already allocated open item failed exception. + * + * @param path The path of the item which could not be opened + * @param mode A string with the mode in which the item should have been opened + * @param errNo The errno of the error that occurred + * @return An initialized open item failed exception + */ +- (instancetype)initWithPath: (OFString *)path + mode: (nullable OFString *)mode + errNo: (int)errNo; + - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/exceptions/OFOpenItemFailedException.m ================================================================== --- src/exceptions/OFOpenItemFailedException.m +++ src/exceptions/OFOpenItemFailedException.m @@ -18,20 +18,29 @@ #import "OFOpenItemFailedException.h" #import "OFString.h" #import "OFURL.h" @implementation OFOpenItemFailedException -@synthesize URL = _URL, mode = _mode, errNo = _errNo; +@synthesize URL = _URL, path = _path, mode = _mode, errNo = _errNo; + (instancetype)exceptionWithURL: (OFURL *)URL mode: (OFString *)mode errNo: (int)errNo { return [[[self alloc] initWithURL: URL mode: mode errNo: errNo] autorelease]; } + ++ (instancetype)exceptionWithPath: (OFString *)path + mode: (OFString *)mode + errNo: (int)errNo +{ + return [[[self alloc] initWithPath: path + mode: mode + errNo: errNo] autorelease]; +} + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } @@ -51,30 +60,56 @@ @throw e; } return self; } + +- (instancetype)initWithPath: (OFString *)path + mode: (OFString *)mode + errNo: (int)errNo +{ + self = [super init]; + + @try { + _path = [path copy]; + _mode = [mode copy]; + _errNo = errNo; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_URL release]; + [_path release]; [_mode release]; [super dealloc]; } - (OFString *)description { + id item = nil; + + if (_URL != nil) + item = _URL; + else if (_path != nil) + item = _path; + if (_mode != nil) return [OFString stringWithFormat: @"Failed to open item %@ with mode %@: %@", - _URL, _mode, OFStrError(_errNo)]; + item, _mode, OFStrError(_errNo)]; else return [OFString stringWithFormat: - @"Failed to open item %@: %@", _URL, OFStrError(_errNo)]; + @"Failed to open item %@: %@", item, OFStrError(_errNo)]; } @end