Permalink
Browse files

Adding PKZipUnarchiver for unzip with progress delegate.

  • Loading branch information...
1 parent 0fdfe16 commit 876416128b97a683ccf9117c00274fc101ded513 @pk committed Jul 15, 2011
Showing with 151 additions and 0 deletions.
  1. +40 −0 Foundation/PKZipUnarchiver.h
  2. +105 −0 Foundation/PKZipUnarchiver.m
  3. +6 −0 PKToolbox.xcodeproj/project.pbxproj
@@ -0,0 +1,40 @@
+//
+// PKZipUnarchiver.h
+// PKToolbox
+//
+// Created by Pavel Kunc on 29/04/2011.
+// Copyright (C) 2011 by Pavel Kunc, http://pavelkunc.cz
+
+#import <Foundation/Foundation.h>
+
+#import "ZipFile.h"
+#import "ZipFileInfo.h"
+#import "ZipReadStream.h"
+
+
+#ifndef
+#define PK_ZIPUNARCHIVER_BUFFER_SIZE (1024 * 32)
+#endif
+
+@protocol PKZipUnarchiverDelegate <NSObject>
+@optional
+-(void)didStartUncompressingZip;
+-(void)didUncompressBytes:(NSUInteger)bytes total:(NSUInteger)total;
+-(void)didFinishUncompressingZip;
+@end
+
+
+@interface PKZipUnarchiver : NSObject {
+@private
+ NSString *_zipPath;
+ id<PKZipUnarchiverDelegate> _delegate;
+}
+
+@property (nonatomic, assign, readwrite) id<PKZipUnarchiverDelegate> delegate;
+
+- (id)initWithZipAtPath:(NSString *)aPath;
+- (id)initWithZipAtPath:(NSString *)aPath delegate:(id<PKZipUnarchiverDelegate>)aDelegate;
+- (BOOL)unzipTo:(NSString *)aDestination error:(NSError **)outError;
+
+@end
+
@@ -0,0 +1,105 @@
+//
+// PKZipUnarchiver.m
+// PKToolbox
+//
+// Created by Pavel Kunc on 29/04/2011.
+// Copyright (C) 2011 by Pavel Kunc, http://pavelkunc.cz
+
+
+#import "PKZipUnarchiver.h"
+
+@interface PKZipUnarchiver ()
+@property (nonatomic, assign, readonly) NSUInteger totalUncompressedSize;
+@property (nonatomic, copy, readonly) NSString *zipPath;
+@end
+
+
+@implementation PKZipUnarchiver
+
+@synthesize delegate = _delegate;
+@synthesize zipPath = _zipPath;
+
+
+#pragma mark - Initialization/dealloc
+
+- (void)dealloc {
+ [_zipPath release];
+ [super dealloc];
+}
+
+- (id)initWithZipAtPath:(NSString *)aPath delegate:(id<PKZipUnarchiverDelegate>)aDelegate {
+ if (self != nil) {
+ _zipPath = [aPath copy];
+ _delegate = aDelegate;
+ }
+ return self;
+}
+
+- (id)initWithZipAtPath:(NSString *)aPath {
+ return [self initWithZipAtPath:aPath delegate:nil];
+}
+
+
+#pragma mark - Unzip methods
+
+- (BOOL)unzipTo:(NSString *)aDestination error:(NSError **)outError {
+ ZipFile *zipFile = [[ZipFile alloc] initWithFileName:_zipPath mode:ZipFileModeUnzip];
+
+ if (![zipFile goToFirstFileInZip:&outError]) {
+ return NO;
+ }
+
+ NSUInteger totalUncompressedSize = 0;
+ if ([self.delegate respondsToSelector:@selector(didUncompressBytes:total:)]) {
+ NSArray *zipFileInformation = [zipFile containedFiles];
+ ZipFileInfo *fileInfo;
+ for (fileInfo in zipFileInformation) {
+ totalUncompressedSize += fileInfo.length;
+ }
+ }
+
+ BOOL isDirectory;
+ NSFileManager *fileManager = [[NSFileManager alloc] init];
+ NSString *currentFilePath;
+ NSUInteger currentFileIndex = 0;
+ do {
+ ZipReadStream *file = [zipFile readCurrentFileInZip:&outError];
+ ZipFileInfo *fileInfo = [zipFileInformation objectAtIndex:currentFileIndex];
+ isDirectory = [fileInfo.name hasSuffix:@"/"];
+ currentFilePath = [aDestination stringByAppendingPathComponent:fileInfo.name];
+
+ if (isDirectory) {
+ [fileManager createDirectoryAtPath:currentFilePath
+ withIntermediateDirectories:YES
+ attributes:nil
+ error:&outError];
+ } else {
+ [fileManager createFileAtPath:currentFilePath
+ contents:nil
+ attributes:nil];
+
+ NSUInteger bytesRead = 0;
+ NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:currentFilePath];
+ NSMutableData *buffer = [[NSMutableData alloc] initWithLength:BUFFER_SIZE];
+ while ((bytesRead = [file readDataWithBuffer:buffer error:&outError]) != 0) {
+ [fileHandle writeData:buffer];
+ if ([self.delegate respondsToSelector:@selector(didUncompressBytes:total:)]) {
+ [self.delegate didUncompressBytes:bytesRead total:totalUncompressedSize];
+ }
+ }
+ [buffer release]; buffer = nil;
+ [fileHandle closeFile];
+ }
+ [file finishedReadingWithError:&outError];
+ currentFileIndex++;
+ } while([zipFile goToNextFileInZip:&outError]);
+
+ [fileManager release];
+ [zipFile close];
+ [zipFile release];
+
+ return YES;
+}
+
+@end
+
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ E9321CD613D0832B00428D25 /* PKZipUnarchiver.m in Sources */ = {isa = PBXBuildFile; fileRef = E9321CD513D0832B00428D25 /* PKZipUnarchiver.m */; };
E93514A4136EC71F001D0F1D /* PKMultiButtonBarButtonItem.m in Sources */ = {isa = PBXBuildFile; fileRef = E93514A3136EC71F001D0F1D /* PKMultiButtonBarButtonItem.m */; };
E93514A5136EC71F001D0F1D /* PKMultiButtonBarButtonItem.m in Sources */ = {isa = PBXBuildFile; fileRef = E93514A3136EC71F001D0F1D /* PKMultiButtonBarButtonItem.m */; };
E93514AA136ED26A001D0F1D /* MainWindow-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = E93514A8136ED26A001D0F1D /* MainWindow-iPad.xib */; };
@@ -29,6 +30,8 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ E9321CD413D0832B00428D25 /* PKZipUnarchiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PKZipUnarchiver.h; sourceTree = "<group>"; };
+ E9321CD513D0832B00428D25 /* PKZipUnarchiver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PKZipUnarchiver.m; sourceTree = "<group>"; };
E93514A2136EC71F001D0F1D /* PKMultiButtonBarButtonItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PKMultiButtonBarButtonItem.h; sourceTree = "<group>"; };
E93514A3136EC71F001D0F1D /* PKMultiButtonBarButtonItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PKMultiButtonBarButtonItem.m; sourceTree = "<group>"; };
E93514A9136ED26A001D0F1D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = "iPad/en.lproj/MainWindow-iPad.xib"; sourceTree = "<group>"; };
@@ -111,6 +114,8 @@
E96E18E0136B54980090E90A /* Foundation */ = {
isa = PBXGroup;
children = (
+ E9321CD413D0832B00428D25 /* PKZipUnarchiver.h */,
+ E9321CD513D0832B00428D25 /* PKZipUnarchiver.m */,
);
path = Foundation;
sourceTree = "<group>";
@@ -299,6 +304,7 @@
files = (
E96E18FE136B54E40090E90A /* PKToolboxTests.m in Sources */,
E93514A4136EC71F001D0F1D /* PKMultiButtonBarButtonItem.m in Sources */,
+ E9321CD613D0832B00428D25 /* PKZipUnarchiver.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

0 comments on commit 8764161

Please sign in to comment.