Index: src/OFArchiveIRIHandler.m ================================================================== --- src/OFArchiveIRIHandler.m +++ src/OFArchiveIRIHandler.m @@ -23,10 +23,11 @@ #import "OFIRI.h" #import "OFLHAArchive.h" #import "OFStream.h" #import "OFTarArchive.h" #import "OFZIPArchive.h" +#import "OFZooArchive.h" #import "OFInvalidArgumentException.h" #import "OFOpenItemFailedException.h" @interface OFArchiveIRIHandlerPathAllowedCharacterSet: OFCharacterSet @@ -125,10 +126,25 @@ } else if ([scheme isEqual: @"zip"]) { OFZIPArchive *archive = [OFZIPArchive archiveWithIRI: archiveIRI mode: @"r"]; stream = [archive streamForReadingFile: path]; + } else if ([scheme isEqual: @"zoo"]) { + OFZooArchive *archive = [OFZooArchive archiveWithIRI: archiveIRI + mode: @"r"]; + OFZooArchiveEntry *entry; + + while ((entry = [archive nextEntry]) != nil) { + if ([entry.fileName isEqual: path]) { + stream = [archive streamForReadingCurrentEntry]; + goto end; + } + } + + @throw [OFOpenItemFailedException exceptionWithIRI: IRI + mode: mode + errNo: ENOENT]; } else @throw [OFInvalidArgumentException exception]; end: stream = [stream retain]; Index: src/OFIRIHandler.m ================================================================== --- src/OFIRIHandler.m +++ src/OFIRIHandler.m @@ -71,10 +71,11 @@ #endif [self registerClass: [OFArchiveIRIHandler class] forScheme: @"gzip"]; [self registerClass: [OFArchiveIRIHandler class] forScheme: @"lha"]; [self registerClass: [OFArchiveIRIHandler class] forScheme: @"tar"]; [self registerClass: [OFArchiveIRIHandler class] forScheme: @"zip"]; + [self registerClass: [OFArchiveIRIHandler class] forScheme: @"zoo"]; } + (bool)registerClass: (Class)class forScheme: (OFString *)scheme { #ifdef OF_HAVE_THREADS Index: src/OFZooArchive.h ================================================================== --- src/OFZooArchive.h +++ src/OFZooArchive.h @@ -67,10 +67,21 @@ * "w" for creating a new file. * @return A new, autoreleased OFZooArchive */ + (instancetype)archiveWithIRI: (OFIRI *)IRI mode: (OFString *)mode; +/** + * @brief Creates an IRI for accessing the specified file within the specified + * Zoo archive. + * + * @param path The path of the file within the archive + * @param IRI The IRI of the archive + * @return An IRI for accessing the specified file within the specified Zoo + * archive + */ ++ (OFIRI *)IRIForFilePath: (OFString *)path inArchiveWithIRI: (OFIRI *)IRI; + - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFZooArchive object with the * specified stream. Index: src/OFZooArchive.m ================================================================== --- src/OFZooArchive.m +++ src/OFZooArchive.m @@ -20,10 +20,11 @@ #include #import "OFZooArchive.h" #import "OFZooArchiveEntry.h" #import "OFZooArchiveEntry+Private.h" +#import "OFArchiveIRIHandler.h" #import "OFCRC16.h" #import "OFIRI.h" #import "OFIRIHandler.h" #import "OFKernelEventObserver.h" #import "OFLHADecompressingStream.h" @@ -99,10 +100,15 @@ + (instancetype)archiveWithIRI: (OFIRI *)IRI mode: (OFString *)mode { return [[[self alloc] initWithIRI: IRI mode: mode] autorelease]; } + ++ (OFIRI *)IRIForFilePath: (OFString *)path inArchiveWithIRI: (OFIRI *)IRI +{ + return OFArchiveIRIHandlerIRIForFileInArchive(@"zoo", path, IRI); +} - (instancetype)init { OF_INVALID_INIT_METHOD }