From b59b5e759f0ec437b3fe8efc54990d96b1910492 Mon Sep 17 00:00:00 2001 From: Glen Low Date: Wed, 3 Sep 2014 10:38:07 +0800 Subject: [PATCH] Improve archive init API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * No more separate mutable archive subclass (ref #24). * Initializers and factory methods may now return nil, along with error information. * Initializers now take an options dictionary, which allows for expansion. For now, you can set ZZOpenOptionsEncodingKey for string encoding and ZZOpenOptionsCreateIfMissingKey to create the archive file if it is missing. * Drop the public load: method, as initializers and updateEntries: do any necessary loading. It’s fairly cheap to create a new archive object to reload changed contents, and we no longer lazily load contents and entries. * The redesign prevents creating erroneous objects e.g. file not found may be a legitimate problem, and prevents swallowing of read errors during lazy loading. * Update podspec to version 8.0. --- README.markdown | 8 +-- zipzap.podspec.json | 4 +- zipzap.xcodeproj/project.pbxproj | 6 ++ zipzap/ZZArchive.h | 54 ++++++-------- zipzap/ZZArchive.mm | 120 +++++++++++++++---------------- zipzap/ZZArchiveEntry.h | 2 +- zipzap/ZZConstants.h | 12 +++- zipzap/ZZConstants.m | 13 ++++ zipzap/ZZDataChannel.m | 9 +++ zipzapTests/ZZUnzipTests.m | 36 ++++++---- zipzapTests/ZZZipTests.m | 14 ++-- 11 files changed, 161 insertions(+), 117 deletions(-) create mode 100644 zipzap/ZZConstants.m diff --git a/README.markdown b/README.markdown index b4fa8f5f..c86ae05e 100644 --- a/README.markdown +++ b/README.markdown @@ -4,7 +4,7 @@ The zip file is an ideal container for compound Objective-C documents. Zip files are widely used and well understood. You can randomly access their parts. The format compresses decently and has extensive operating system and tool support. So we want to make this format an even easier choice for you. Thus, the library features: -* **Easy-to-use interface**: The public API offers just three classes! Yet you can look through zip files using familiar *NSArray* collections and properties. And you can zip, unzip and rezip zip files through familiar *NSData*, *NSStream* and Image I/O classes. +* **Easy-to-use interface**: The public API offers just two classes! Yet you can look through zip files using familiar *NSArray* collections and properties. And you can zip, unzip and rezip zip files through familiar *NSData*, *NSStream* and Image I/O classes. * **Efficient implementation**: We've optimized zip file reading and writing to reduce virtual memory pressure and disk file thrashing. Depending on how your compound document is organized, updating a single entry can be faster than writing the same data to a separate file. * **File format compatibility**: Since *zipzap* closely follows the [zip file format specification](http://www.pkware.com/documents/casestudies/APPNOTE.TXT), it works with most Mac, Linux and Windows zip tools. @@ -37,14 +37,14 @@ Header includes: Reading an existing zip file: - ZZArchive* oldArchive = [ZZArchive archiveWithContentsOfURL:[NSURL fileURLWithPath:@"/tmp/old.zip"]]; + ZZArchive* oldArchive = [ZZArchive archiveWithURL:[NSURL fileURLWithPath:@"/tmp/old.zip"] error:nil]; ZZArchiveEntry* firstArchiveEntry = oldArchive.entries[0]; NSLog(@"The first entry's uncompressed size is %lu bytes.", firstArchiveEntry.uncompressedSize); NSLog(@"The first entry's data is: %@.", [firstArchiveEntry newData]); Writing a new zip file: - ZZMutableArchive* newArchive = [ZZMutableArchive archiveWithContentsOfURL:[NSURL fileURLWithPath:@"/tmp/new.zip"]]; + ZZArchive* newArchive = [ZZArchive archiveWithURL:[NSURL fileURLWithPath:@"/tmp/new.zip"] error:nil]; [newArchive updateEntries: @[ [ZZArchiveEntry archiveEntryWithFileName:@"first.text" @@ -58,7 +58,7 @@ Writing a new zip file: Updating an existing zip file: - ZZMutableArchive* oldArchive = [ZZMutableArchive archiveWithContentsOfURL:[NSURL fileURLWithPath:@"/tmp/old.zip"]]; + ZZArchive* oldArchive = [ZZArchive archiveWithURL:[NSURL fileURLWithPath:@"/tmp/old.zip"] error:nil]; [oldArchive updateEntries: [oldArchive.entries arrayByAddingObject: [ZZArchiveEntry archiveEntryWithFileName:@"second.text" diff --git a/zipzap.podspec.json b/zipzap.podspec.json index a4588ee0..0c9bd036 100644 --- a/zipzap.podspec.json +++ b/zipzap.podspec.json @@ -1,6 +1,6 @@ { "name": "zipzap", - "version": "7.0", + "version": "8.0", "authors": { "Pixelglow Software": "glen.low@pixelglow.com" }, @@ -8,7 +8,7 @@ "homepage": "https://github.com/pixelglow/zipzap", "source": { "git": "https://github.com/pixelglow/zipzap.git", - "tag": "7.0" + "tag": "8.0" }, "summary": "zipzap is a zip file I/O library for Mac OS X and iOS.", "description": "The zip file is an ideal container for compound Objective-C documents. Zip files are widely used and well understood. You can randomly access their parts. The format compresses decently and has extensive operating system and tool support. So we want to make this format an even easier choice for you. Thus, the library features:\n\n- Easy-to-use interface: The public API offers just three classes! Yet you can look through zip files using familiar NSArray collections and properties. And you can zip, unzip and rezip zip files through familiar NSData, NSStream and Image I/O classes.\n- Efficient implementation: We've optimized zip file reading and writing to reduce virtual memory pressure and disk file thrashing. Depending on how your compound document is organized, updating a single entry can be faster than writing the same data to a separate file.\n- File format compatibility: Since zipzap closely follows the zip file format specification, it is works with most Mac, Linux and Windows zip tools.\n", diff --git a/zipzap.xcodeproj/project.pbxproj b/zipzap.xcodeproj/project.pbxproj index de62f0af..e2a81354 100644 --- a/zipzap.xcodeproj/project.pbxproj +++ b/zipzap.xcodeproj/project.pbxproj @@ -35,6 +35,8 @@ D84A44CF16A0F8B400CF00A9 /* ZZDataChannelOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = D84A44CD16A0F8B400CF00A9 /* ZZDataChannelOutput.h */; }; D84A44D016A0F8B400CF00A9 /* ZZDataChannelOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = D84A44CE16A0F8B400CF00A9 /* ZZDataChannelOutput.m */; }; D84A44D116A0F8B400CF00A9 /* ZZDataChannelOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = D84A44CE16A0F8B400CF00A9 /* ZZDataChannelOutput.m */; }; + D85CB4D119B5A91000815A36 /* ZZConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = D85CB4D019B5A91000815A36 /* ZZConstants.m */; }; + D85CB4D219B5A91000815A36 /* ZZConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = D85CB4D019B5A91000815A36 /* ZZConstants.m */; }; D86B400C18A8A0BA00017A91 /* ZZConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B50392518706368002B2B12 /* ZZConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; D86B400D18A8A0DA00017A91 /* ZZConstants.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5B50392518706368002B2B12 /* ZZConstants.h */; }; D86B400E18A8A0FF00017A91 /* ZZError.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = D8366ACC16B1F8B400BC012E /* ZZError.h */; }; @@ -146,6 +148,7 @@ D84A44AE16A0E8D600CF00A9 /* ZZDataChannel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZZDataChannel.m; sourceTree = ""; }; D84A44CD16A0F8B400CF00A9 /* ZZDataChannelOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZZDataChannelOutput.h; sourceTree = ""; }; D84A44CE16A0F8B400CF00A9 /* ZZDataChannelOutput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZZDataChannelOutput.m; sourceTree = ""; }; + D85CB4D019B5A91000815A36 /* ZZConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZZConstants.m; sourceTree = ""; }; D88E8DFD16375C66002207B3 /* dog.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = dog.jpg; sourceTree = ""; }; D88E8DFE16375C66002207B3 /* dog.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dog.png; sourceTree = ""; }; D88E8E05163816FD002207B3 /* ZZOldArchiveEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZZOldArchiveEntry.h; sourceTree = ""; }; @@ -239,6 +242,7 @@ D899CFD8162C608300112F49 /* ZZArchiveEntry.h */, D899CFD9162C608300112F49 /* ZZArchiveEntry.m */, 5B50392518706368002B2B12 /* ZZConstants.h */, + D85CB4D019B5A91000815A36 /* ZZConstants.m */, D8366ACC16B1F8B400BC012E /* ZZError.h */, D8366ACD16B1F8B400BC012E /* ZZError.m */, ); @@ -554,6 +558,7 @@ D899CFEE162C608300112F49 /* ZZArchive.mm in Sources */, D899CFF4162C608300112F49 /* ZZDeflateOutputStream.m in Sources */, D899CFF7162C608300112F49 /* ZZStoreOutputStream.m in Sources */, + D85CB4D119B5A91000815A36 /* ZZConstants.m in Sources */, D899CFFA162C608300112F49 /* ZZOldArchiveEntryWriter.mm in Sources */, D899CFFE162C608300112F49 /* ZZNewArchiveEntry.mm in Sources */, D834256318767E1900E7A559 /* ZZStandardDecryptInputStream.mm in Sources */, @@ -588,6 +593,7 @@ D899CFEF162C608300112F49 /* ZZArchive.mm in Sources */, D899CFF5162C608300112F49 /* ZZDeflateOutputStream.m in Sources */, 5BC58CAC18745D22002FAE04 /* ZZStandardCryptoEngine.cpp in Sources */, + D85CB4D219B5A91000815A36 /* ZZConstants.m in Sources */, D899CFF8162C608300112F49 /* ZZStoreOutputStream.m in Sources */, D834256418767E1900E7A559 /* ZZStandardDecryptInputStream.mm in Sources */, D899CFFB162C608300112F49 /* ZZOldArchiveEntryWriter.mm in Sources */, diff --git a/zipzap/ZZArchive.h b/zipzap/ZZArchive.h index aa443ad6..8470970e 100644 --- a/zipzap/ZZArchive.h +++ b/zipzap/ZZArchive.h @@ -56,60 +56,50 @@ /** * Creates a new archive with the zip file at the given file URL. * - * The archive will use UTF-8 encoding for reading entry file names and comments. + * The archive will use UTF-8 encoding for reading entry file names and comments, and will not create the file if it is missing. * * @param URL The file URL of the zip file. - * @return The initialized archive. If the zip file does not exist, this will have no entries. + * @param error The error information when an error occurs. Pass in nil if you do not want error information. + * @return The initialized archive. Returns nil if the archive cannot be initialized. */ -+ (instancetype)archiveWithContentsOfURL:(NSURL*)URL; ++ (instancetype)archiveWithURL:(NSURL*)URL + error:(out NSError**)error; /** * Creates a new archive with the raw zip file data given. * - * The archive will use UTF-8 encoding for reading entry file names and comments. + * The archive will use UTF-8 encoding for reading entry file names and comments, and will not create the data if it is missing. * - * @param data The raw data of the zip file - * @return The initialized archive. + * @param data The raw data of the zip file. + * @param error The error information when an error occurs. Pass in nil if you do not want error information. + * @return The initialized archive. Returns nil if the archive cannot be initialized. */ -+ (instancetype)archiveWithData:(NSData*)data; ++ (instancetype)archiveWithData:(NSData*)data + error:(out NSError**)error; /** * Initializes a new archive with the zip file at the given file URL. * * @param URL The file URL of the zip file. - * @param encoding The encoding for reading entry file names and comments. - * @return The initialized archive. If the zip file does not exist, this will have no entries. + * @param options The options to consider when opening the zip file. + * @param error The error information when an error occurs. Pass in nil if you do not want error information. + * @return The initialized archive. Returns nil if the archive cannot be initialized. */ -- (id)initWithContentsOfURL:(NSURL*)URL - encoding:(NSStringEncoding)encoding; +- (id)initWithURL:(NSURL*)URL + options:(NSDictionary*)options + error:(out NSError**)error; /** * Initializes a new archive with the raw zip file data given. * * @param data The raw data of the zip file - * @param encoding The encoding for reading entry file names and comments. - * @return The initialized archive. - */ -- (id)initWithData:(NSData*)data - encoding:(NSStringEncoding)encoding; - -/** - * Loads the contents and entries from the source. Any old entries will then be considered invalid. - * - * Whenever you access entries or contents, the receiver will load them as needed. - * You only need to call this method to force a reload from source, or to check for errors when loading. - * + * @param options The options to consider when opening the zip file. * @param error The error information when an error occurs. Pass in nil if you do not want error information. - * @return Whether the load was successful or not. + * @return The initialized archive. Returns nil if the archive cannot be initialized. */ -- (BOOL)load:(out NSError**)error; - -@end - -/** - * The ZZMutableArchive class represents a zip file for reading and writing. - */ -@interface ZZMutableArchive : ZZArchive +- (id)initWithData:(NSData*)data + options:(NSDictionary*)options + error:(out NSError**)error; /** * Updates the entries and writes them to the source. diff --git a/zipzap/ZZArchive.mm b/zipzap/ZZArchive.mm index ce380aa1..c5d2e9be 100644 --- a/zipzap/ZZArchive.mm +++ b/zipzap/ZZArchive.mm @@ -23,48 +23,69 @@ static const size_t ENDOFCENTRALDIRECTORY_MINSEARCH = sizeof(ZZEndOfCentralDirectory) - sizeof(ZZEndOfCentralDirectory::signature); @interface ZZArchive () -{ -@protected - id _channel; - NSStringEncoding _encoding; - NSData* _contents; - NSArray* _entries; -} + +- (id)initWithChannel:(id)channel + options:(NSDictionary*)options + error:(out NSError**)error; + +- (BOOL)loadCanMiss:(BOOL)canMiss error:(out NSError**)error; @end @implementation ZZArchive +{ + id _channel; + NSStringEncoding _encoding; +} -+ (instancetype)archiveWithContentsOfURL:(NSURL*)URL ++ (instancetype)archiveWithURL:(NSURL*)URL + error:(out NSError**)error { - return [[self alloc] initWithContentsOfURL:URL - encoding:NSUTF8StringEncoding]; + return [[self alloc] initWithChannel:[[ZZFileChannel alloc] initWithURL:URL] + options:nil + error:error]; } + (instancetype)archiveWithData:(NSData*)data + error:(out NSError**)error { - return [[self alloc] initWithData:data - encoding:NSUTF8StringEncoding]; + return [[self alloc] initWithChannel:[[ZZDataChannel alloc] initWithData:data] + options:nil + error:error]; } -- (id)initWithContentsOfURL:(NSURL*)URL - encoding:(NSStringEncoding)encoding +- (id)initWithURL:(NSURL*)URL + options:(NSDictionary*)options + error:(out NSError**)error { - if ((self = [super init])) - { - _channel = [[ZZFileChannel alloc] initWithURL:URL]; - _encoding = encoding; - } - return self; + return [self initWithChannel:[[ZZFileChannel alloc] initWithURL:URL] + options:options + error:error]; } - (id)initWithData:(NSData*)data - encoding:(NSStringEncoding)encoding + options:(NSDictionary*)options + error:(out NSError**)error +{ + return [self initWithChannel:[[ZZDataChannel alloc] initWithData:data] + options:options + error:error]; +} + +- (id)initWithChannel:(id)channel + options:(NSDictionary*)options + error:(out NSError**)error { if ((self = [super init])) { - _channel = [[ZZDataChannel alloc] initWithData:data]; - _encoding = encoding; + _channel = channel; + + NSNumber* encoding = options[ZZOpenOptionsEncodingKey]; + _encoding = encoding ? encoding.unsignedIntegerValue : NSUTF8StringEncoding; + + NSNumber* createIfMissing = options[ZZOpenOptionsCreateIfMissingKey]; + if (![self loadCanMiss:createIfMissing.boolValue error:error]) + return nil; } return self; } @@ -74,32 +95,23 @@ - (NSURL*)URL return _channel.URL; } -- (NSData*)contents -{ - // lazily load in contents + refresh entries - if (!_contents) - [self load:nil]; - - return _contents; -} - -- (NSArray*)entries -{ - // lazily load in contents + refresh entries - if (!_contents) - [self load:nil]; - - return _entries; -} - -- (BOOL)load:(NSError**)error +- (BOOL)loadCanMiss:(BOOL)canMiss error:(out NSError**)error { // memory-map the contents from the zip file NSError* __autoreleasing readError; NSData* contents = [_channel newInput:&readError]; if (!contents) - return ZZRaiseErrorNo(error, ZZOpenReadErrorCode, @{NSUnderlyingErrorKey : readError}); - + { + if (canMiss && readError.code == NSFileReadNoSuchFileError && [readError.domain isEqualToString:NSCocoaErrorDomain]) + { + _contents = nil; + _entries = nil; + return YES; + } + else + return ZZRaiseErrorNo(error, ZZOpenReadErrorCode, @{NSUnderlyingErrorKey : readError}); + } + // search for the end of directory signature in last 64K of file const uint8_t* beginContent = (const uint8_t*)contents.bytes; const uint8_t* endContent = beginContent + contents.length; @@ -160,22 +172,13 @@ - (BOOL)load:(NSError**)error // having successfully negotiated the new contents + entries, replace in one go _contents = contents; - _entries = [NSArray arrayWithArray:entries]; + _entries = entries; return YES; } -@end - -@implementation ZZMutableArchive - - (BOOL)updateEntries:(NSArray*)newEntries - error:(NSError**)error + error:(out NSError**)error { - // NOTE: we want to avoid loading at all when entries are being overwritten, even in the face of lazy loading: - // consider that nil _contents implies that no valid entries have been loaded, and newEntries cannot possibly contain any of our old entries - // therefore, if _contents are nil, we don't need to lazily load them in since these newEntries are meant to totally overwrite the archive - // or, if _contents are non-nil, the contents have already been loaded and we also don't need to lazily load them in - // determine how many entries to skip, where initial old and new entries match NSUInteger oldEntriesCount = _entries.count; NSUInteger newEntriesCount = newEntries.count; @@ -270,11 +273,8 @@ - (BOOL)updateEntries:(NSArray*)newEntries error:&underlyingError]) return ZZRaiseErrorNo(error, ZZReplaceWriteErrorCode, @{NSUnderlyingErrorKey : underlyingError}); - // clear entries + content - _contents = nil; - _entries = nil; - - return YES; + // reload entries + content + return [self loadCanMiss:NO error:error]; } @end diff --git a/zipzap/ZZArchiveEntry.h b/zipzap/ZZArchiveEntry.h index e77bff8a..c92e9f7c 100644 --- a/zipzap/ZZArchiveEntry.h +++ b/zipzap/ZZArchiveEntry.h @@ -41,7 +41,7 @@ @protocol ZZArchiveEntryWriter; /** - * The ZZArchiveEntry class represents an entry in the ZZArchive or ZZMutableArchive instance. + * The ZZArchiveEntry class represents an entry in the ZZArchive instance. */ @interface ZZArchiveEntry : NSObject diff --git a/zipzap/ZZConstants.h b/zipzap/ZZConstants.h index 3958f00e..ac681427 100644 --- a/zipzap/ZZConstants.h +++ b/zipzap/ZZConstants.h @@ -68,4 +68,14 @@ typedef NS_ENUM(uint8_t, ZZAESEncryptionStrength) * Use 256-bit AES for encryption. */ ZZAESEncryptionStrength256 = 0x03 -}; \ No newline at end of file +}; + +/** + * An NSNumber object that contains the string encoding to use for entry file names and comments. Default is NSUTF8StringEncoding. + */ +extern NSString* const ZZOpenOptionsEncodingKey; + +/** + * An NSNumber object that determines whether to create the archive file if it is missing. Creation occurs during -[ZZArchive updateEntries:error:]. Default is @NO. + */ +extern NSString* const ZZOpenOptionsCreateIfMissingKey; diff --git a/zipzap/ZZConstants.m b/zipzap/ZZConstants.m new file mode 100644 index 00000000..7227bfd0 --- /dev/null +++ b/zipzap/ZZConstants.m @@ -0,0 +1,13 @@ +// +// ZZConstants.m +// zipzap +// +// Created by Glen Low on 2/09/14. +// +// + +#import "ZZConstants.h" + +NSString* const ZZOpenOptionsEncodingKey = @"ZZOpenOptionsEncodingKey"; + +NSString* const ZZOpenOptionsCreateIfMissingKey = @"ZZOpenOptionsCreateIfMissingKey"; \ No newline at end of file diff --git a/zipzap/ZZDataChannel.m b/zipzap/ZZDataChannel.m index 5b94e86c..eda77ea2 100644 --- a/zipzap/ZZDataChannel.m +++ b/zipzap/ZZDataChannel.m @@ -45,6 +45,15 @@ - (void)removeAsTemporary - (NSData*)newInput:(out NSError**)error { + if (_allData.length == 0) + { + // no data available: consider it as file not found + if (error) + *error = [NSError errorWithDomain:NSCocoaErrorDomain + code:NSFileReadNoSuchFileError + userInfo:@{}]; + return nil; + } return _allData; } diff --git a/zipzapTests/ZZUnzipTests.m b/zipzapTests/ZZUnzipTests.m index 80c3c945..f92b731d 100644 --- a/zipzapTests/ZZUnzipTests.m +++ b/zipzapTests/ZZUnzipTests.m @@ -39,7 +39,8 @@ - (void)setUp [ZZTasks zipFiles:_entryFilePaths toPath:_zipFileURL.path]; - _zipFile = [ZZArchive archiveWithContentsOfURL:_zipFileURL]; + _zipFile = [ZZArchive archiveWithURL:_zipFileURL + error:nil]; } - (void)tearDown @@ -195,7 +196,8 @@ - (void)testZipEntryConsistentWithOriginalFile - (void)testZipFromDataConsistentWithZipFromURL { NSData* rawData = [NSData dataWithContentsOfURL:_zipFileURL]; - ZZArchive* zipFileFromData = [[ZZArchive alloc] initWithData:rawData encoding:NSUTF8StringEncoding]; + ZZArchive* zipFileFromData = [ZZArchive archiveWithData:rawData + error:nil]; XCTAssertEqual(_zipFile.entries.count, zipFileFromData.entries.count, @@ -304,7 +306,8 @@ - (void)testExtractingZipEntryDataProviderImage - (void)testExtractingAndStandardDecryptingWrongPassword { // This file was small to begin with, encrypted with Standard and Store compression mode - ZZArchive* zipFile = [ZZArchive archiveWithContentsOfURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"small-test-encrypted-standard" withExtension:@"zip"]]; + ZZArchive* zipFile = [ZZArchive archiveWithURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"small-test-encrypted-standard" withExtension:@"zip"] + error:nil]; ZZArchiveEntry *fileEntry = zipFile.entries[0]; NSError* error = nil; @@ -315,7 +318,8 @@ - (void)testExtractingAndStandardDecryptingWrongPassword - (void)testExtractingAndStandardDecryptingSmallZipEntryData { // This file was small to begin with, encrypted with Standard and Store compression mode - ZZArchive* zipFile = [ZZArchive archiveWithContentsOfURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"small-test-encrypted-standard" withExtension:@"zip"]]; + ZZArchive* zipFile = [ZZArchive archiveWithURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"small-test-encrypted-standard" withExtension:@"zip"] + error:nil]; ZZArchiveEntry *fileEntry = zipFile.entries[0]; @@ -326,7 +330,8 @@ - (void)testExtractingAndStandardDecryptingSmallZipEntryData - (void)testExtractingAndStandardDecryptingLargeZipEntryData { // This file was large to begin with, encrypted with Standard and Deflate compression mode - ZZArchive* zipFile = [ZZArchive archiveWithContentsOfURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"large-test-encrypted-standard" withExtension:@"zip"]]; + ZZArchive* zipFile = [ZZArchive archiveWithURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"large-test-encrypted-standard" withExtension:@"zip"] + error:nil]; ZZArchiveEntry *fileEntry = zipFile.entries[0]; @@ -363,7 +368,8 @@ - (void)testExtractingAndStandardDecryptingLargeZipEntryData - (void)testExtractingAndAes128DecryptingWrongPassword { // This file was small to begin with, encrypted with AES and Store compression mode - ZZArchive* zipFile = [ZZArchive archiveWithContentsOfURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"small-test-encrypted-aes128" withExtension:@"zip"]]; + ZZArchive* zipFile = [ZZArchive archiveWithURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"small-test-encrypted-aes128" withExtension:@"zip"] + error:nil]; ZZArchiveEntry *fileEntry = zipFile.entries[0]; NSError* error = nil; @@ -374,7 +380,8 @@ - (void)testExtractingAndAes128DecryptingWrongPassword - (void)testExtractingAndAes128DecryptingSmallZipEntryData { // This file was small to begin with, encrypted with AES and Store compression mode - ZZArchive* zipFile = [ZZArchive archiveWithContentsOfURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"small-test-encrypted-aes128" withExtension:@"zip"]]; + ZZArchive* zipFile = [ZZArchive archiveWithURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"small-test-encrypted-aes128" withExtension:@"zip"] + error:nil]; ZZArchiveEntry *fileEntry = zipFile.entries[0]; @@ -385,7 +392,8 @@ - (void)testExtractingAndAes128DecryptingSmallZipEntryData - (void)testExtractingAndAes128DecryptingLargeZipEntryData { // This file was large to begin with, encrypted with AES and Deflate compression mode - ZZArchive* zipFile = [ZZArchive archiveWithContentsOfURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"large-test-encrypted-aes128" withExtension:@"zip"]]; + ZZArchive* zipFile = [ZZArchive archiveWithURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"large-test-encrypted-aes128" withExtension:@"zip"] + error:nil]; ZZArchiveEntry *fileEntry = zipFile.entries[0]; @@ -422,7 +430,8 @@ - (void)testExtractingAndAes128DecryptingLargeZipEntryData - (void)testExtractingAndAes192DecryptingSmallZipEntryData { // This file was small to begin with, encrypted with AES and Store compression mode - ZZArchive* zipFile = [ZZArchive archiveWithContentsOfURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"small-test-encrypted-aes192" withExtension:@"zip"]]; + ZZArchive* zipFile = [ZZArchive archiveWithURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"small-test-encrypted-aes192" withExtension:@"zip"] + error:nil]; ZZArchiveEntry *fileEntry = zipFile.entries[0]; @@ -433,7 +442,8 @@ - (void)testExtractingAndAes192DecryptingSmallZipEntryData - (void)testExtractingAndAes192DecryptingLargeZipEntryData { // This file was large to begin with, encrypted with AES and Deflate compression mode - ZZArchive* zipFile = [ZZArchive archiveWithContentsOfURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"large-test-encrypted-aes192" withExtension:@"zip"]]; + ZZArchive* zipFile = [ZZArchive archiveWithURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"large-test-encrypted-aes192" withExtension:@"zip"] + error:nil]; ZZArchiveEntry *fileEntry = zipFile.entries[0]; @@ -470,7 +480,8 @@ - (void)testExtractingAndAes192DecryptingLargeZipEntryData - (void)testExtractingAndAes256DecryptingSmallZipEntryData { // This file was small to begin with, encrypted with AES and Store compression mode - ZZArchive* zipFile = [ZZArchive archiveWithContentsOfURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"small-test-encrypted-aes256" withExtension:@"zip"]]; + ZZArchive* zipFile = [ZZArchive archiveWithURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"small-test-encrypted-aes256" withExtension:@"zip"] + error:nil]; ZZArchiveEntry *fileEntry = zipFile.entries[0]; @@ -481,7 +492,8 @@ - (void)testExtractingAndAes256DecryptingSmallZipEntryData - (void)testExtractingAndAes256DecryptingLargeZipEntryData { // This file was large to begin with, encrypted with AES and Deflate compression mode - ZZArchive* zipFile = [ZZArchive archiveWithContentsOfURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"large-test-encrypted-aes256" withExtension:@"zip"]]; + ZZArchive* zipFile = [ZZArchive archiveWithURL:[[NSBundle bundleForClass:ZZUnzipTests.class] URLForResource:@"large-test-encrypted-aes256" withExtension:@"zip"] + error:nil]; ZZArchiveEntry *fileEntry = zipFile.entries[0]; diff --git a/zipzapTests/ZZZipTests.m b/zipzapTests/ZZZipTests.m index 92544346..846b16a7 100644 --- a/zipzapTests/ZZZipTests.m +++ b/zipzapTests/ZZZipTests.m @@ -43,7 +43,7 @@ @implementation ZZZipTests NSURL* _zipFileURL; NSArray* _entryFilePaths; NSString* _extraFilePath; - ZZMutableArchive* _zipFile; + ZZArchive* _zipFile; } - (NSError*)someError @@ -78,12 +78,16 @@ - (NSData*)dataAtFilePath:(NSString*)filePath - (void)createEmptyFileZip { - _zipFile = [ZZMutableArchive archiveWithContentsOfURL:_zipFileURL]; + _zipFile = [[ZZArchive alloc] initWithURL:_zipFileURL + options:@{ ZZOpenOptionsCreateIfMissingKey: @YES } + error:nil]; } - (void)createEmptyDataZip { - _zipFile = [ZZMutableArchive archiveWithData:[NSMutableData data]]; + _zipFile = [[ZZArchive alloc] initWithData:[NSMutableData data] + options:@{ ZZOpenOptionsCreateIfMissingKey: @YES } + error:nil]; } - (void)createFullFileZip @@ -91,7 +95,7 @@ - (void)createFullFileZip [ZZTasks zipFiles:_entryFilePaths toPath:_zipFileURL.path]; - _zipFile = [ZZMutableArchive archiveWithContentsOfURL:_zipFileURL]; + _zipFile = [ZZArchive archiveWithURL:_zipFileURL error:nil]; } - (void)createFullDataZip @@ -99,7 +103,7 @@ - (void)createFullDataZip [ZZTasks zipFiles:_entryFilePaths toPath:_zipFileURL.path]; - _zipFile = [ZZMutableArchive archiveWithData:[NSMutableData dataWithContentsOfURL:_zipFileURL]]; + _zipFile = [ZZArchive archiveWithData:[NSMutableData dataWithContentsOfURL:_zipFileURL] error:nil]; } - (NSArray*)recordsForZipEntries:(NSArray*)zipEntries