forked from christianblunden/theweek
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Scott Turnquest
authored and
Scott Turnquest
committed
May 11, 2011
1 parent
a80d912
commit e209faf
Showing
13 changed files
with
4,548 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// | ||
// ZipArchive.h | ||
// | ||
// | ||
// Created by aish on 08-9-11. | ||
// acsolu@gmail.com | ||
// Copyright 2008 Inc. All rights reserved. | ||
// | ||
// History: | ||
// 09-11-2008 version 1.0 release | ||
// 10-18-2009 version 1.1 support password protected zip files | ||
// 10-21-2009 version 1.2 fix date bug | ||
|
||
#import <UIKit/UIKit.h> | ||
|
||
#include "minizip/zip.h" | ||
#include "minizip/unzip.h" | ||
|
||
|
||
@protocol ZipArchiveDelegate <NSObject> | ||
@optional | ||
-(void) ErrorMessage:(NSString*) msg; | ||
-(BOOL) OverWriteOperation:(NSString*) file; | ||
|
||
@end | ||
|
||
|
||
@interface ZipArchive : NSObject { | ||
@private | ||
zipFile _zipFile; | ||
unzFile _unzFile; | ||
|
||
NSString* _password; | ||
id _delegate; | ||
} | ||
|
||
@property (nonatomic, retain) id delegate; | ||
|
||
-(BOOL) CreateZipFile2:(NSString*) zipFile; | ||
-(BOOL) CreateZipFile2:(NSString*) zipFile Password:(NSString*) password; | ||
-(BOOL) addFileToZip:(NSString*) file newname:(NSString*) newname; | ||
-(BOOL) CloseZipFile2; | ||
|
||
-(BOOL) UnzipOpenFile:(NSString*) zipFile; | ||
-(BOOL) UnzipOpenFile:(NSString*) zipFile Password:(NSString*) password; | ||
-(BOOL) UnzipFileTo:(NSString*) path overWrite:(BOOL) overwrite; | ||
-(BOOL) UnzipCloseFile; | ||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,337 @@ | ||
// | ||
// ZipArchive.mm | ||
// | ||
// | ||
// Created by aish on 08-9-11. | ||
// acsolu@gmail.com | ||
// Copyright 2008 Inc. All rights reserved. | ||
// | ||
|
||
#import "ZipArchive.h" | ||
#import "zlib.h" | ||
#import "zconf.h" | ||
|
||
|
||
|
||
@interface ZipArchive (Private) | ||
|
||
-(void) OutputErrorMessage:(NSString*) msg; | ||
-(BOOL) OverWrite:(NSString*) file; | ||
-(NSDate*) Date1980; | ||
@end | ||
|
||
|
||
|
||
@implementation ZipArchive | ||
@synthesize delegate = _delegate; | ||
|
||
-(id) init | ||
{ | ||
if( self=[super init] ) | ||
{ | ||
_zipFile = NULL ; | ||
} | ||
return self; | ||
} | ||
|
||
-(void) dealloc | ||
{ | ||
[self CloseZipFile2]; | ||
[super dealloc]; | ||
} | ||
|
||
-(BOOL) CreateZipFile2:(NSString*) zipFile | ||
{ | ||
_zipFile = zipOpen( (const char*)[zipFile UTF8String], 0 ); | ||
if( !_zipFile ) | ||
return NO; | ||
return YES; | ||
} | ||
|
||
-(BOOL) CreateZipFile2:(NSString*) zipFile Password:(NSString*) password | ||
{ | ||
_password = password; | ||
return [self CreateZipFile2:zipFile]; | ||
} | ||
|
||
-(BOOL) addFileToZip:(NSString*) file newname:(NSString*) newname; | ||
{ | ||
if( !_zipFile ) | ||
return NO; | ||
// tm_zip filetime; | ||
time_t current; | ||
time( ¤t ); | ||
|
||
zip_fileinfo zipInfo = {0}; | ||
// zipInfo.dosDate = (unsigned long) current; | ||
|
||
NSDictionary* attr = [[NSFileManager defaultManager] fileAttributesAtPath:file traverseLink:YES]; | ||
if( attr ) | ||
{ | ||
NSDate* fileDate = (NSDate*)[attr objectForKey:NSFileModificationDate]; | ||
if( fileDate ) | ||
{ | ||
// some application does use dosDate, but tmz_date instead | ||
// zipInfo.dosDate = [fileDate timeIntervalSinceDate:[self Date1980] ]; | ||
NSCalendar* currCalendar = [NSCalendar currentCalendar]; | ||
uint flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | | ||
NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ; | ||
NSDateComponents* dc = [currCalendar components:flags fromDate:fileDate]; | ||
zipInfo.tmz_date.tm_sec = [dc second]; | ||
zipInfo.tmz_date.tm_min = [dc minute]; | ||
zipInfo.tmz_date.tm_hour = [dc hour]; | ||
zipInfo.tmz_date.tm_mday = [dc day]; | ||
zipInfo.tmz_date.tm_mon = [dc month] - 1; | ||
zipInfo.tmz_date.tm_year = [dc year]; | ||
} | ||
} | ||
|
||
int ret ; | ||
NSData* data = nil; | ||
if( [_password length] == 0 ) | ||
{ | ||
ret = zipOpenNewFileInZip( _zipFile, | ||
(const char*) [newname UTF8String], | ||
&zipInfo, | ||
NULL,0, | ||
NULL,0, | ||
NULL,//comment | ||
Z_DEFLATED, | ||
Z_DEFAULT_COMPRESSION ); | ||
} | ||
else | ||
{ | ||
data = [ NSData dataWithContentsOfFile:file]; | ||
uLong crcValue = crc32( 0L,NULL, 0L ); | ||
crcValue = crc32( crcValue, (const Bytef*)[data bytes], [data length] ); | ||
ret = zipOpenNewFileInZip3( _zipFile, | ||
(const char*) [newname UTF8String], | ||
&zipInfo, | ||
NULL,0, | ||
NULL,0, | ||
NULL,//comment | ||
Z_DEFLATED, | ||
Z_DEFAULT_COMPRESSION, | ||
0, | ||
15, | ||
8, | ||
Z_DEFAULT_STRATEGY, | ||
[_password cStringUsingEncoding:NSASCIIStringEncoding], | ||
crcValue ); | ||
} | ||
if( ret!=Z_OK ) | ||
{ | ||
return NO; | ||
} | ||
if( data==nil ) | ||
{ | ||
data = [ NSData dataWithContentsOfFile:file]; | ||
} | ||
unsigned int dataLen = [data length]; | ||
ret = zipWriteInFileInZip( _zipFile, (const void*)[data bytes], dataLen); | ||
if( ret!=Z_OK ) | ||
{ | ||
return NO; | ||
} | ||
ret = zipCloseFileInZip( _zipFile ); | ||
if( ret!=Z_OK ) | ||
return NO; | ||
return YES; | ||
} | ||
|
||
-(BOOL) CloseZipFile2 | ||
{ | ||
_password = nil; | ||
if( _zipFile==NULL ) | ||
return NO; | ||
BOOL ret = zipClose( _zipFile,NULL )==Z_OK?YES:NO; | ||
_zipFile = NULL; | ||
return ret; | ||
} | ||
|
||
-(BOOL) UnzipOpenFile:(NSString*) zipFile | ||
{ | ||
_unzFile = unzOpen( (const char*)[zipFile UTF8String] ); | ||
if( _unzFile ) | ||
{ | ||
unz_global_info globalInfo = {0}; | ||
if( unzGetGlobalInfo(_unzFile, &globalInfo )==UNZ_OK ) | ||
{ | ||
NSLog([NSString stringWithFormat:@"%d entries in the zip file",globalInfo.number_entry] ); | ||
} | ||
} | ||
return _unzFile!=NULL; | ||
} | ||
|
||
-(BOOL) UnzipOpenFile:(NSString*) zipFile Password:(NSString*) password | ||
{ | ||
_password = password; | ||
return [self UnzipOpenFile:zipFile]; | ||
} | ||
|
||
-(BOOL) UnzipFileTo:(NSString*) path overWrite:(BOOL) overwrite | ||
{ | ||
BOOL success = YES; | ||
int ret = unzGoToFirstFile( _unzFile ); | ||
unsigned char buffer[4096] = {0}; | ||
NSFileManager* fman = [NSFileManager defaultManager]; | ||
if( ret!=UNZ_OK ) | ||
{ | ||
[self OutputErrorMessage:@"Failed"]; | ||
} | ||
|
||
do{ | ||
if( [_password length]==0 ) | ||
ret = unzOpenCurrentFile( _unzFile ); | ||
else | ||
ret = unzOpenCurrentFilePassword( _unzFile, [_password cStringUsingEncoding:NSASCIIStringEncoding] ); | ||
if( ret!=UNZ_OK ) | ||
{ | ||
[self OutputErrorMessage:@"Error occurs"]; | ||
success = NO; | ||
break; | ||
} | ||
// reading data and write to file | ||
int read ; | ||
unz_file_info fileInfo ={0}; | ||
ret = unzGetCurrentFileInfo(_unzFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0); | ||
if( ret!=UNZ_OK ) | ||
{ | ||
[self OutputErrorMessage:@"Error occurs while getting file info"]; | ||
success = NO; | ||
unzCloseCurrentFile( _unzFile ); | ||
break; | ||
} | ||
char* filename = (char*) malloc( fileInfo.size_filename +1 ); | ||
unzGetCurrentFileInfo(_unzFile, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0); | ||
filename[fileInfo.size_filename] = '\0'; | ||
|
||
// check if it contains directory | ||
NSString * strPath = [NSString stringWithCString:filename]; | ||
BOOL isDirectory = NO; | ||
if( filename[fileInfo.size_filename-1]=='/' || filename[fileInfo.size_filename-1]=='\\') | ||
isDirectory = YES; | ||
free( filename ); | ||
if( [strPath rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"/\\"]].location!=NSNotFound ) | ||
{// contains a path | ||
strPath = [strPath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"]; | ||
} | ||
NSString* fullPath = [path stringByAppendingPathComponent:strPath]; | ||
|
||
if( isDirectory ) | ||
[fman createDirectoryAtPath:fullPath withIntermediateDirectories:YES attributes:nil error:nil]; | ||
else | ||
[fman createDirectoryAtPath:[fullPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil]; | ||
if( [fman fileExistsAtPath:fullPath] && !isDirectory && !overwrite ) | ||
{ | ||
if( ![self OverWrite:fullPath] ) | ||
{ | ||
unzCloseCurrentFile( _unzFile ); | ||
ret = unzGoToNextFile( _unzFile ); | ||
continue; | ||
} | ||
} | ||
FILE* fp = fopen( (const char*)[fullPath UTF8String], "wb"); | ||
while( fp ) | ||
{ | ||
read=unzReadCurrentFile(_unzFile, buffer, 4096); | ||
if( read > 0 ) | ||
{ | ||
fwrite(buffer, read, 1, fp ); | ||
} | ||
else if( read<0 ) | ||
{ | ||
[self OutputErrorMessage:@"Failed to reading zip file"]; | ||
break; | ||
} | ||
else | ||
break; | ||
} | ||
if( fp ) | ||
{ | ||
fclose( fp ); | ||
// set the orignal datetime property | ||
NSDate* orgDate = nil; | ||
|
||
//{{ thanks to brad.eaton for the solution | ||
NSDateComponents *dc = [[NSDateComponents alloc] init]; | ||
|
||
dc.second = fileInfo.tmu_date.tm_sec; | ||
dc.minute = fileInfo.tmu_date.tm_min; | ||
dc.hour = fileInfo.tmu_date.tm_hour; | ||
dc.day = fileInfo.tmu_date.tm_mday; | ||
dc.month = fileInfo.tmu_date.tm_mon+1; | ||
dc.year = fileInfo.tmu_date.tm_year; | ||
|
||
NSCalendar *gregorian = [[NSCalendar alloc] | ||
initWithCalendarIdentifier:NSGregorianCalendar]; | ||
|
||
orgDate = [gregorian dateFromComponents:dc] ; | ||
[dc release]; | ||
[gregorian release]; | ||
//}} | ||
|
||
|
||
NSDictionary* attr = [NSDictionary dictionaryWithObject:orgDate forKey:NSFileModificationDate]; //[[NSFileManager defaultManager] fileAttributesAtPath:fullPath traverseLink:YES]; | ||
if( attr ) | ||
{ | ||
// [attr setValue:orgDate forKey:NSFileCreationDate]; | ||
if( ![[NSFileManager defaultManager] setAttributes:attr ofItemAtPath:fullPath error:nil] ) | ||
{ | ||
// cann't set attributes | ||
NSLog(@"Failed to set attributes"); | ||
} | ||
|
||
} | ||
|
||
|
||
|
||
} | ||
unzCloseCurrentFile( _unzFile ); | ||
ret = unzGoToNextFile( _unzFile ); | ||
}while( ret==UNZ_OK && UNZ_OK!=UNZ_END_OF_LIST_OF_FILE ); | ||
return success; | ||
} | ||
|
||
-(BOOL) UnzipCloseFile | ||
{ | ||
_password = nil; | ||
if( _unzFile ) | ||
return unzClose( _unzFile )==UNZ_OK; | ||
return YES; | ||
} | ||
|
||
#pragma mark wrapper for delegate | ||
-(void) OutputErrorMessage:(NSString*) msg | ||
{ | ||
if( _delegate && [_delegate respondsToSelector:@selector(ErrorMessage)] ) | ||
[_delegate ErrorMessage:msg]; | ||
} | ||
|
||
-(BOOL) OverWrite:(NSString*) file | ||
{ | ||
if( _delegate && [_delegate respondsToSelector:@selector(OverWriteOperation)] ) | ||
return [_delegate OverWriteOperation:file]; | ||
return YES; | ||
} | ||
|
||
#pragma mark get NSDate object for 1980-01-01 | ||
-(NSDate*) Date1980 | ||
{ | ||
NSDateComponents *comps = [[NSDateComponents alloc] init]; | ||
[comps setDay:1]; | ||
[comps setMonth:1]; | ||
[comps setYear:1980]; | ||
NSCalendar *gregorian = [[NSCalendar alloc] | ||
initWithCalendarIdentifier:NSGregorianCalendar]; | ||
NSDate *date = [gregorian dateFromComponents:comps]; | ||
|
||
[comps release]; | ||
[gregorian release]; | ||
return date; | ||
} | ||
|
||
|
||
@end | ||
|
||
|
Oops, something went wrong.