Permalink
Browse files

added -u switch

  • Loading branch information...
ttwj committed Jun 19, 2012
1 parent 38cc987 commit d354c78403ce39458d0b6c73991fb321fb6167ca
Submodule objective-zip added at 036235
View
@@ -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 "zip.h"
+#include "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 compression:(int) compression;
+-(BOOL) CloseZipFile2;
+
+-(BOOL) UnzipOpenFile:(NSString*) zipFile;
+-(BOOL) UnzipOpenFile:(NSString*) zipFile Password:(NSString*) password;
+-(BOOL) UnzipFileTo:(NSString*) path overWrite:(BOOL) overwrite;
+-(BOOL) UnzipCloseFile;
+@end
View
@@ -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 compression:(int)compression;
+{
+ if( !_zipFile )
+ return NO;
+// tm_zip filetime;
+ time_t current;
+ time( &current );
+
+ 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,
+ 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,
+ 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.

0 comments on commit d354c78

Please sign in to comment.