537 lines
16 KiB
Objective-C
537 lines
16 KiB
Objective-C
//
|
|
// Objective_ZipViewController.m
|
|
// Objective-Zip
|
|
//
|
|
// Created by Gianluca Bertani on 25/12/09.
|
|
// Copyright Flying Dolphin Studio 2009. All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions
|
|
// are met:
|
|
//
|
|
// * Redistributions of source code must retain the above copyright notice,
|
|
// this list of conditions and the following disclaimer.
|
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
// and/or other materials provided with the distribution.
|
|
// * Neither the name of Gianluca Bertani nor the names of its contributors
|
|
// may be used to endorse or promote products derived from this software
|
|
// without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
|
|
#import "Objective_ZipViewController.h"
|
|
#import "Objective-Zip.h"
|
|
|
|
#define HUGE_TEST_BLOCK_LENGTH (50000)
|
|
#define HUGE_TEST_NUMBER_OF_BLOCKS (100000)
|
|
|
|
|
|
@interface Objective_ZipViewController ()
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Tests
|
|
|
|
- (void) test1;
|
|
- (void) test2;
|
|
- (void) test3;
|
|
- (void) test4;
|
|
- (void) test5;
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Logging
|
|
|
|
- (void) log:(NSString *)format, ...;
|
|
|
|
|
|
@end
|
|
|
|
|
|
@implementation Objective_ZipViewController
|
|
|
|
|
|
- (void) loadView {
|
|
[super loadView];
|
|
|
|
_textView.font= [UIFont fontWithName:@"Helvetica" size:11.0];
|
|
}
|
|
|
|
|
|
- (void) didReceiveMemoryWarning {
|
|
[super didReceiveMemoryWarning];
|
|
}
|
|
|
|
- (IBAction) zipUnzip {
|
|
|
|
_testThread= [[NSThread alloc] initWithTarget:self selector:@selector(test1) object:nil];
|
|
[_testThread start];
|
|
}
|
|
|
|
- (IBAction) zipUnzip2 {
|
|
|
|
_testThread= [[NSThread alloc] initWithTarget:self selector:@selector(test2) object:nil];
|
|
[_testThread start];
|
|
}
|
|
|
|
- (IBAction) zipCheck1 {
|
|
|
|
_testThread= [[NSThread alloc] initWithTarget:self selector:@selector(test3) object:nil];
|
|
[_testThread start];
|
|
}
|
|
|
|
- (IBAction) zipCheck2 {
|
|
|
|
_testThread= [[NSThread alloc] initWithTarget:self selector:@selector(test4) object:nil];
|
|
[_testThread start];
|
|
}
|
|
|
|
- (IBAction) errorWrapping {
|
|
|
|
_testThread= [[NSThread alloc] initWithTarget:self selector:@selector(test5) object:nil];
|
|
[_testThread start];
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Test 1: zip & unzip
|
|
|
|
- (void) test1 {
|
|
@autoreleasepool {
|
|
|
|
NSString *documentsDir= [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
|
|
NSString *filePath= [documentsDir stringByAppendingPathComponent:@"test.zip"];
|
|
|
|
@try {
|
|
[[NSFileManager defaultManager] removeItemAtPath:filePath error:NULL];
|
|
|
|
[self log:@"Test 1: opening zip file for writing..."];
|
|
|
|
OZZipFile *zipFile= [[OZZipFile alloc] initWithFileName:filePath mode:OZZipFileModeCreate];
|
|
|
|
[self log:@"Test 1: adding first file..."];
|
|
|
|
OZZipWriteStream *stream1= [zipFile writeFileInZipWithName:@"abc.txt" fileDate:[NSDate dateWithTimeIntervalSinceNow:-86400.0] compressionLevel:OZZipCompressionLevelBest];
|
|
|
|
[self log:@"Test 1: writing to first file's stream..."];
|
|
|
|
NSString *text= @"abc";
|
|
[stream1 writeData:[text dataUsingEncoding:NSUTF8StringEncoding]];
|
|
|
|
[self log:@"Test 1: closing first file's stream..."];
|
|
|
|
[stream1 finishedWriting];
|
|
|
|
[self log:@"Test 1: adding second file..."];
|
|
|
|
NSString *file2name= @"x/y/z/xyz.txt";
|
|
OZZipWriteStream *stream2= [zipFile writeFileInZipWithName:file2name compressionLevel:OZZipCompressionLevelNone];
|
|
|
|
[self log:@"Test 1: writing to second file's stream..."];
|
|
|
|
NSString *text2= @"XYZ";
|
|
[stream2 writeData:[text2 dataUsingEncoding:NSUTF8StringEncoding]];
|
|
|
|
[self log:@"Test 1: closing second file's stream..."];
|
|
|
|
[stream2 finishedWriting];
|
|
|
|
[self log:@"Test 1: closing zip file..."];
|
|
|
|
[zipFile close];
|
|
|
|
[self log:@"Test 1: opening zip file for reading..."];
|
|
|
|
OZZipFile *unzipFile= [[OZZipFile alloc] initWithFileName:filePath mode:OZZipFileModeUnzip];
|
|
|
|
[self log:@"Test 1: reading file infos..."];
|
|
|
|
NSArray *infos= [unzipFile listFileInZipInfos];
|
|
for (OZFileInZipInfo *info in infos)
|
|
[self log:@"Test 1: - %@ %@ %d (%d)", info.name, info.date, info.size, info.level];
|
|
|
|
[self log:@"Test 1: opening first file..."];
|
|
|
|
[unzipFile goToFirstFileInZip];
|
|
OZZipReadStream *read1= [unzipFile readCurrentFileInZip];
|
|
|
|
[self log:@"Test 1: reading from first file's stream..."];
|
|
|
|
NSMutableData *data1= [[NSMutableData alloc] initWithLength:256];
|
|
NSUInteger bytesRead1= [read1 readDataWithBuffer:data1];
|
|
|
|
BOOL ok= NO;
|
|
if (bytesRead1 == 3) {
|
|
NSString *fileText1= [[NSString alloc] initWithBytes:[data1 bytes] length:bytesRead1 encoding:NSUTF8StringEncoding];
|
|
if ([fileText1 isEqualToString:@"abc"])
|
|
ok= YES;
|
|
}
|
|
|
|
if (ok)
|
|
[self log:@"Test 1: content of first file is OK"];
|
|
else
|
|
[self log:@"Test 1: content of first file is WRONG"];
|
|
|
|
[self log:@"Test 1: closing first file's stream..."];
|
|
|
|
[read1 finishedReading];
|
|
|
|
[self log:@"Test 1: opening second file..."];
|
|
|
|
[unzipFile locateFileInZip:file2name];
|
|
OZZipReadStream *read2= [unzipFile readCurrentFileInZip];
|
|
|
|
[self log:@"Test 1: reading from second file's stream..."];
|
|
|
|
NSMutableData *data2= [[NSMutableData alloc] initWithLength:256];
|
|
NSUInteger bytesRead2= [read2 readDataWithBuffer:data2];
|
|
|
|
ok= NO;
|
|
if (bytesRead2 == 3) {
|
|
NSString *fileText2= [[NSString alloc] initWithBytes:[data2 bytes] length:bytesRead2 encoding:NSUTF8StringEncoding];
|
|
if ([fileText2 isEqualToString:@"XYZ"])
|
|
ok= YES;
|
|
}
|
|
|
|
if (ok)
|
|
[self log:@"Test 1: content of second file is OK"];
|
|
else
|
|
[self log:@"Test 1: content of second file is WRONG"];
|
|
|
|
[self log:@"Test 1: closing second file's stream..."];
|
|
|
|
[read2 finishedReading];
|
|
|
|
[self log:@"Test 1: closing zip file..."];
|
|
|
|
[unzipFile close];
|
|
|
|
[self log:@"Test 1: test terminated succesfully"];
|
|
|
|
} @catch (OZZipException *ze) {
|
|
[self log:@"Test 1: caught a ZipException (see logs), terminating..."];
|
|
|
|
NSLog(@"Test 1: ZipException caught: %ld - %@", (long) ze.error, [ze reason]);
|
|
|
|
} @catch (id e) {
|
|
[self log:@"Test 1: caught a generic exception (see logs), terminating..."];
|
|
|
|
NSLog(@"Test 1: Exception caught: %@ - %@", [[e class] description], [e description]);
|
|
|
|
} @finally {
|
|
[[NSFileManager defaultManager] removeItemAtPath:filePath error:NULL];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Test 2: zip & unzip 5 GB
|
|
|
|
- (void) test2 {
|
|
@autoreleasepool {
|
|
|
|
NSString *documentsDir= [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
|
|
NSString *filePath= [documentsDir stringByAppendingPathComponent:@"huge_test.zip"];
|
|
|
|
@try {
|
|
[[NSFileManager defaultManager] removeItemAtPath:filePath error:NULL];
|
|
|
|
[self log:@"Test 2: opening zip file for writing..."];
|
|
|
|
OZZipFile *zipFile= [[OZZipFile alloc] initWithFileName:filePath mode:OZZipFileModeCreate];
|
|
|
|
[self log:@"Test 2: adding file..."];
|
|
|
|
OZZipWriteStream *stream= [zipFile writeFileInZipWithName:@"huge_file.txt" compressionLevel:OZZipCompressionLevelBest];
|
|
|
|
[self log:@"Test 2: writing to file's stream..."];
|
|
|
|
NSMutableData *data= [[NSMutableData alloc] initWithLength:HUGE_TEST_BLOCK_LENGTH];
|
|
SecRandomCopyBytes(kSecRandomDefault, [data length], [data mutableBytes]);
|
|
|
|
NSData *checkData= [data subdataWithRange:NSMakeRange(0, 100)];
|
|
|
|
NSMutableData *buffer= [[NSMutableData alloc] initWithLength:HUGE_TEST_BLOCK_LENGTH]; // For use later
|
|
|
|
for (int i= 0; i < HUGE_TEST_NUMBER_OF_BLOCKS; i++) {
|
|
[stream writeData:data];
|
|
|
|
if (i % 100 == 0)
|
|
[self log:@"Test 2: written %d KB...", ([data length] / 1024) * (i +1)];
|
|
}
|
|
|
|
[self log:@"Test 2: closing file's stream..."];
|
|
|
|
[stream finishedWriting];
|
|
|
|
[self log:@"Test 2: closing zip file..."];
|
|
|
|
[zipFile close];
|
|
|
|
[self log:@"Test 2: opening zip file for reading..."];
|
|
|
|
OZZipFile *unzipFile= [[OZZipFile alloc] initWithFileName:filePath mode:OZZipFileModeUnzip];
|
|
|
|
[self log:@"Test 2: opening file..."];
|
|
|
|
[unzipFile goToFirstFileInZip];
|
|
OZZipReadStream *read= [unzipFile readCurrentFileInZip];
|
|
|
|
[self log:@"Test 2: reading from file's stream..."];
|
|
|
|
for (int i= 0; i < HUGE_TEST_NUMBER_OF_BLOCKS; i++) {
|
|
NSUInteger bytesRead= [read readDataWithBuffer:buffer];
|
|
|
|
BOOL ok= NO;
|
|
if (bytesRead == [data length]) {
|
|
NSRange range= [buffer rangeOfData:checkData options:0 range:NSMakeRange(0, [buffer length])];
|
|
if (range.location == 0)
|
|
ok= YES;
|
|
}
|
|
|
|
if (!ok)
|
|
[self log:@"Test 2: content of file is WRONG at position %d KB", ([buffer length] / 1024) * i];
|
|
|
|
if (i % 100 == 0)
|
|
[self log:@"Test 2: read %d KB...", ([buffer length] / 1024) * (i +1)];
|
|
}
|
|
|
|
[self log:@"Test 2: closing file's stream..."];
|
|
|
|
[read finishedReading];
|
|
|
|
[self log:@"Test 2: closing zip file..."];
|
|
|
|
[unzipFile close];
|
|
|
|
[self log:@"Test 2: test terminated succesfully"];
|
|
|
|
} @catch (OZZipException *ze) {
|
|
[self log:@"Test 2: caught a ZipException (see logs), terminating..."];
|
|
|
|
NSLog(@"Test 2: ZipException caught: %ld - %@", (long) ze.error, [ze reason]);
|
|
|
|
} @catch (id e) {
|
|
[self log:@"Test 2: caught a generic exception (see logs), terminating..."];
|
|
|
|
NSLog(@"Test 2: Exception caught: %@ - %@", [[e class] description], [e description]);
|
|
|
|
} @finally {
|
|
[[NSFileManager defaultManager] removeItemAtPath:filePath error:NULL];
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Test 3: unzip & check Mac zip file
|
|
|
|
- (void) test3 {
|
|
@autoreleasepool {
|
|
|
|
NSString *filePath= [[NSBundle mainBundle] pathForResource:@"mac_test_file" ofType:@"zip"];
|
|
|
|
@try {
|
|
[self log:@"Test 3: opening zip file for reading..."];
|
|
|
|
OZZipFile *unzipFile= [[OZZipFile alloc] initWithFileName:filePath mode:OZZipFileModeUnzip];
|
|
|
|
[self log:@"Test 3: opening file..."];
|
|
|
|
[unzipFile goToFirstFileInZip];
|
|
OZZipReadStream *read= [unzipFile readCurrentFileInZip];
|
|
|
|
[self log:@"Test 3: reading from file's stream..."];
|
|
|
|
NSMutableData *buffer= [[NSMutableData alloc] initWithLength:1024];
|
|
|
|
NSUInteger bytesRead= [read readDataWithBuffer:buffer];
|
|
|
|
NSString *fileText= [[NSString alloc] initWithBytes:[buffer bytes] length:bytesRead encoding:NSUTF8StringEncoding];
|
|
if ([fileText isEqualToString:@"Objective-Zip Mac test file\n"])
|
|
[self log:@"Test 3: content of Mac file is OK"];
|
|
else
|
|
[self log:@"Test 3: content of Mac file is WRONG"];
|
|
|
|
[self log:@"Test 3: closing file's stream..."];
|
|
|
|
[read finishedReading];
|
|
|
|
[self log:@"Test 3: closing zip file..."];
|
|
|
|
[unzipFile close];
|
|
|
|
[self log:@"Test 3: test terminated succesfully"];
|
|
|
|
} @catch (OZZipException *ze) {
|
|
[self log:@"Test 3: caught a ZipException (see logs), terminating..."];
|
|
|
|
NSLog(@"Test 3: ZipException caught: %ld - %@", (long) ze.error, [ze reason]);
|
|
|
|
} @catch (id e) {
|
|
[self log:@"Test 3: caught a generic exception (see logs), terminating..."];
|
|
|
|
NSLog(@"Test 3: Exception caught: %@ - %@", [[e class] description], [e description]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Test 4: unzip & check Win zip file
|
|
|
|
- (void) test4 {
|
|
@autoreleasepool {
|
|
|
|
NSString *filePath= [[NSBundle mainBundle] pathForResource:@"win_test_file" ofType:@"zip"];
|
|
|
|
@try {
|
|
[self log:@"Test 4: opening zip file for reading..."];
|
|
|
|
OZZipFile *unzipFile= [[OZZipFile alloc] initWithFileName:filePath mode:OZZipFileModeUnzip];
|
|
|
|
[self log:@"Test 4: opening file..."];
|
|
|
|
[unzipFile goToFirstFileInZip];
|
|
OZZipReadStream *read= [unzipFile readCurrentFileInZip];
|
|
|
|
[self log:@"Test 4: reading from file's stream..."];
|
|
|
|
NSMutableData *buffer= [[NSMutableData alloc] initWithLength:1024];
|
|
|
|
NSUInteger bytesRead= [read readDataWithBuffer:buffer];
|
|
|
|
NSString *fileText= [[NSString alloc] initWithBytes:[buffer bytes] length:bytesRead encoding:NSUTF8StringEncoding];
|
|
if ([fileText isEqualToString:@"Objective-Zip Windows test file\r\n"])
|
|
[self log:@"Test 4: content of Win file is OK"];
|
|
else
|
|
[self log:@"Test 4: content of Win file is WRONG"];
|
|
|
|
[self log:@"Test 4: closing file's stream..."];
|
|
|
|
[read finishedReading];
|
|
|
|
[self log:@"Test 4: closing zip file..."];
|
|
|
|
[unzipFile close];
|
|
|
|
[self log:@"Test 4: test terminated succesfully"];
|
|
|
|
} @catch (OZZipException *ze) {
|
|
[self log:@"Test 4: caught a ZipException (see logs), terminating..."];
|
|
|
|
NSLog(@"Test 4: ZipException caught: %ld - %@", (long) ze.error, [ze reason]);
|
|
|
|
} @catch (id e) {
|
|
[self log:@"Test 4: caught a generic exception (see logs), terminating..."];
|
|
|
|
NSLog(@"Test 4: Exception caught: %@ - %@", [[e class] description], [e description]);
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma mark -
|
|
#pragma mark Test 5: error wrapping
|
|
|
|
- (void) test5 {
|
|
@autoreleasepool {
|
|
|
|
NSString *filePath= @"/root.zip";
|
|
|
|
@try {
|
|
[self log:@"Test 5: opening impossible zip file for writing..."];
|
|
|
|
OZZipFile *zipFile= [[OZZipFile alloc] initWithFileName:filePath mode:OZZipFileModeCreate];
|
|
|
|
[self log:@"Test 5: test failed, no error reported"];
|
|
|
|
[zipFile close];
|
|
|
|
} @catch (OZZipException *ze) {
|
|
if (ze.error != ERROR_NO_SUCH_FILE) {
|
|
[self log:@"Test 5: test failed, wrong error reported"];
|
|
|
|
} else {
|
|
[self log:@"Test 5: correct error reported"];
|
|
}
|
|
|
|
} @catch (id e) {
|
|
[self log:@"Test 5: caught a generic exception (see logs)"];
|
|
|
|
NSLog(@"Test 5: Exception caught: %@ - %@", [[e class] description], [e description]);
|
|
}
|
|
|
|
@try {
|
|
[self log:@"Test 5: opening again impossible zip file for writing..."];
|
|
|
|
NSError *error= nil;
|
|
OZZipFile *zipFile= [[OZZipFile alloc] initWithFileName:filePath mode:OZZipFileModeCreate error:&error];
|
|
|
|
if (zipFile || (!error)) {
|
|
[self log:@"Test 5: test failed, no error reported"];
|
|
|
|
[zipFile close];
|
|
|
|
} else {
|
|
if (error.code != ERROR_NO_SUCH_FILE) {
|
|
[self log:@"Test 5: test failed, wrong error reported"];
|
|
|
|
} else {
|
|
[self log:@"Test 5: correct error reported"];
|
|
[self log:@"Test 5: test terminated succesfully"];
|
|
}
|
|
}
|
|
|
|
} @catch (id e) {
|
|
[self log:@"Test 5: caught a generic exception (see logs), terminating..."];
|
|
|
|
NSLog(@"Test 5: Exception caught: %@ - %@", [[e class] description], [e description]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Logging
|
|
|
|
- (void) log:(NSString *)format, ... {
|
|
|
|
// Variable arguments formatting
|
|
va_list arguments;
|
|
va_start(arguments, format);
|
|
NSString *logLine= [[NSString alloc] initWithFormat:format arguments:arguments];
|
|
va_end(arguments);
|
|
|
|
[self performSelectorOnMainThread:@selector(printLog:) withObject:logLine waitUntilDone:YES];
|
|
|
|
}
|
|
|
|
- (void) printLog:(NSString *)logLine {
|
|
NSLog(@"%@", logLine);
|
|
|
|
_textView.text= [_textView.text stringByAppendingString:logLine];
|
|
_textView.text= [_textView.text stringByAppendingString:@"\n"];
|
|
|
|
NSRange range;
|
|
range.location= [_textView.text length] -6;
|
|
range.length= 5;
|
|
[_textView scrollRangeToVisible:range];
|
|
}
|
|
|
|
|
|
@end
|