Compare commits
25 Commits
minizip2
...
unzCountEn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91e8bff0a7 | ||
|
|
4ae03a2145 | ||
|
|
fab301b90f | ||
|
|
e5962afc05 | ||
|
|
236f31d25a | ||
|
|
01d1d9e770 | ||
|
|
1fd7fa9c29 | ||
|
|
2886108b12 | ||
|
|
45d2faf540 | ||
|
|
308b7c9849 | ||
|
|
96d988d3f8 | ||
|
|
6746665b71 | ||
|
|
a9bb0f948c | ||
|
|
e38ad24bd8 | ||
|
|
a9eb253d90 | ||
|
|
181bdc693e | ||
|
|
df25a4a43e | ||
|
|
252fb76ff4 | ||
|
|
b8a68d1a08 | ||
|
|
ed887bd062 | ||
|
|
7ce0c7cc66 | ||
|
|
7143ecdc66 | ||
|
|
708a2c76d8 | ||
|
|
2ab252766d | ||
|
|
27cf1ec538 |
23
.travis.yml
23
.travis.yml
@@ -15,6 +15,22 @@ matrix:
|
||||
env: SDK="macosx"
|
||||
DEVICE="OS X 10.11"
|
||||
|
||||
- osx_image: xcode9
|
||||
env: SDK="appletvsimulator"
|
||||
DEVICE="Apple TV 4K (11.0)" # oldest/newest for tvOS 11.x
|
||||
|
||||
- osx_image: xcode8.3
|
||||
env: SDK="appletvsimulator"
|
||||
DEVICE="Apple TV 1080p (10.2)" # latest for tvOS 10.x
|
||||
|
||||
- osx_image: xcode8.3
|
||||
env: SDK="appletvsimulator"
|
||||
DEVICE="Apple TV 1080p (9.2)" # latest for tvOS 9.x
|
||||
|
||||
- osx_image: xcode7.3
|
||||
env: SDK="appletvsimulator"
|
||||
DEVICE="Apple TV 1080p (9.0)" # oldest for tvOS 9.x
|
||||
|
||||
- osx_image: xcode9
|
||||
env: SDK="iphonesimulator"
|
||||
DEVICE="iPhone X (11.0)" # oldest/newest for iOS 11.x
|
||||
@@ -46,9 +62,14 @@ matrix:
|
||||
before_install:
|
||||
- if [ ${SDK} = "macosx" ]; then
|
||||
SCHEME="ObjectiveCExample_macOS";
|
||||
DESTINATION="platform=macosx";
|
||||
elif [ ${SDK} = "appletvsimulator" ]; then
|
||||
SCHEME="ObjectiveCExample_tvOS";
|
||||
else
|
||||
SCHEME="ObjectiveCExample_iOS";
|
||||
fi
|
||||
- if [ ${SDK} = "macosx" ]; then
|
||||
DESTINATION="platform=macosx";
|
||||
else
|
||||
DESTINATION_UDID=$(instruments -s devices | grep "$DEVICE \[" | sed -E 's/.*\[([0-9A-F-]+)\].*/\1/g');
|
||||
`Prelaunching simulator to avoid timeout https://github.com/travis-ci/travis-ci/issues/6422`
|
||||
open -a Simulator --args -CurrentDeviceUDID $DESTINATION_UDID;
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
3754B1331F88961C00A58AA0 /* Empty.zip in Resources */ = {isa = PBXBuildFile; fileRef = 3754B1311F88961800A58AA0 /* Empty.zip */; };
|
||||
3754B1341F88961D00A58AA0 /* Empty.zip in Resources */ = {isa = PBXBuildFile; fileRef = 3754B1311F88961800A58AA0 /* Empty.zip */; };
|
||||
3754B1351F88961E00A58AA0 /* Empty.zip in Resources */ = {isa = PBXBuildFile; fileRef = 3754B1311F88961800A58AA0 /* Empty.zip */; };
|
||||
3773ADB61F7F453E009A4B2D /* CollectingDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DFE1A131BDAA0A800709011 /* CollectingDelegate.m */; };
|
||||
3773ADB71F7F4541009A4B2D /* SSZipArchiveTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DFE1A071BDA9FF300709011 /* SSZipArchiveTests.m */; };
|
||||
3773ADB81F7F4D13009A4B2D /* hello.zip in Resources */ = {isa = PBXBuildFile; fileRef = 8DFE1A161BDAA10100709011 /* hello.zip */; };
|
||||
@@ -83,6 +86,7 @@
|
||||
/* Begin PBXFileReference section */
|
||||
04CB37570807602F7E5C66D9 /* Pods-core-ObjectiveCExampleTests_macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-core-ObjectiveCExampleTests_macOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-core-ObjectiveCExampleTests_macOS/Pods-core-ObjectiveCExampleTests_macOS.release.xcconfig"; sourceTree = "<group>"; };
|
||||
254DE0B206EE66F57BBE7EEE /* Pods-core-ObjectiveCExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-core-ObjectiveCExample.release.xcconfig"; path = "Pods/Target Support Files/Pods-core-ObjectiveCExample/Pods-core-ObjectiveCExample.release.xcconfig"; sourceTree = "<group>"; };
|
||||
3754B1311F88961800A58AA0 /* Empty.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = Empty.zip; sourceTree = "<group>"; };
|
||||
3773ADAE1F7F44D8009A4B2D /* ObjectiveCExampleTests_macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ObjectiveCExampleTests_macOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3793E6D71F7F5F93000B1A19 /* ObjectiveCExampleTests_tvOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ObjectiveCExampleTests_tvOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
37FF0CB11F8533E0006E4361 /* CancelDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CancelDelegate.h; sourceTree = "<group>"; };
|
||||
@@ -251,6 +255,7 @@
|
||||
8DFE1A151BDAA10100709011 /* Fixtures */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3754B1311F88961800A58AA0 /* Empty.zip */,
|
||||
8DFE1A161BDAA10100709011 /* hello.zip */,
|
||||
8DFE1A171BDAA10100709011 /* IncorrectHeaders.zip */,
|
||||
8DFE1A181BDAA10100709011 /* PermissionsTestApp.app */,
|
||||
@@ -425,6 +430,7 @@
|
||||
3773ADC31F7F4D1C009A4B2D /* 3.m4a in Resources */,
|
||||
3773ADC21F7F4D1C009A4B2D /* 2.m4a in Resources */,
|
||||
3773ADC41F7F4D1C009A4B2D /* 4.m4a in Resources */,
|
||||
3754B1341F88961D00A58AA0 /* Empty.zip in Resources */,
|
||||
3773ADC01F7F4D1C009A4B2D /* 0.m4a in Resources */,
|
||||
3773ADC51F7F4D1C009A4B2D /* 5.m4a in Resources */,
|
||||
3773ADB91F7F4D13009A4B2D /* IncorrectHeaders.zip in Resources */,
|
||||
@@ -448,6 +454,7 @@
|
||||
3793E6E71F7F6052000B1A19 /* 6.m4a in Resources */,
|
||||
3793E6E91F7F6059000B1A19 /* hello.zip in Resources */,
|
||||
3793E6F01F7F605C000B1A19 /* PermissionsTestApp.app in Resources */,
|
||||
3754B1351F88961E00A58AA0 /* Empty.zip in Resources */,
|
||||
3793E6ED1F7F6059000B1A19 /* TestArchive.zip in Resources */,
|
||||
3793E6E61F7F6052000B1A19 /* 5.m4a in Resources */,
|
||||
3793E6E41F7F6052000B1A19 /* 3.m4a in Resources */,
|
||||
@@ -482,6 +489,7 @@
|
||||
8DFE1A321BDAA10100709011 /* 3.m4a in Resources */,
|
||||
8DFE1A311BDAA10100709011 /* 2.m4a in Resources */,
|
||||
8DFE1A331BDAA10100709011 /* 4.m4a in Resources */,
|
||||
3754B1331F88961C00A58AA0 /* Empty.zip in Resources */,
|
||||
8DFE1A2F1BDAA10100709011 /* 0.m4a in Resources */,
|
||||
8DFE1A341BDAA10100709011 /* 5.m4a in Resources */,
|
||||
8DFE1A2D1BDAA10100709011 /* TestPasswordArchive.zip in Resources */,
|
||||
@@ -835,7 +843,6 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = appletvos;
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
TVOS_DEPLOYMENT_TARGET = 11.1;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -857,7 +864,6 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = appletvos;
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
TVOS_DEPLOYMENT_TARGET = 11.1;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -914,6 +920,7 @@
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -962,6 +969,7 @@
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
|
||||
@@ -26,115 +26,123 @@
|
||||
|
||||
#pragma mark - Life Cycle
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
[super viewDidLoad];
|
||||
|
||||
_file1.text = @"";
|
||||
_file2.text = @"";
|
||||
_file3.text = @"";
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
}
|
||||
|
||||
#pragma mark - IBAction
|
||||
- (IBAction)zipPressed:(id)sender {
|
||||
NSString *sampleDataPath = [[NSBundle mainBundle].bundleURL
|
||||
URLByAppendingPathComponent:@"Sample Data"
|
||||
isDirectory:YES].path;
|
||||
_zipPath = [self tempZipPath];
|
||||
NSString *password = _passwordField.text;
|
||||
BOOL success = [SSZipArchive createZipFileAtPath:_zipPath
|
||||
withContentsOfDirectory:sampleDataPath
|
||||
withPassword:password.length > 0 ? password : nil];
|
||||
if (success) {
|
||||
_unzipButton.enabled = YES;
|
||||
_zipButton.enabled = NO;
|
||||
} else {
|
||||
NSLog(@"No success");
|
||||
}
|
||||
_resetButton.enabled = YES;
|
||||
NSString *sampleDataPath = [[NSBundle mainBundle].bundleURL
|
||||
URLByAppendingPathComponent:@"Sample Data"
|
||||
isDirectory:YES].path;
|
||||
_zipPath = [self tempZipPath];
|
||||
NSString *password = _passwordField.text;
|
||||
BOOL success = [SSZipArchive createZipFileAtPath:_zipPath
|
||||
withContentsOfDirectory:sampleDataPath
|
||||
keepParentDirectory:NO
|
||||
compressionLevel:-1
|
||||
password:password.length > 0 ? password : nil
|
||||
AES:YES
|
||||
progressHandler:nil];
|
||||
if (success) {
|
||||
NSLog(@"Success zip");
|
||||
_unzipButton.enabled = YES;
|
||||
_zipButton.enabled = NO;
|
||||
} else {
|
||||
NSLog(@"No success zip");
|
||||
}
|
||||
_resetButton.enabled = YES;
|
||||
}
|
||||
|
||||
- (IBAction)unzipPressed:(id)sender {
|
||||
if (!_zipPath) {
|
||||
return;
|
||||
}
|
||||
NSString *unzipPath = [self tempUnzipPath];
|
||||
if (!unzipPath) {
|
||||
return;
|
||||
}
|
||||
NSString *password = _passwordField.text;
|
||||
BOOL success = [SSZipArchive unzipFileAtPath:_zipPath
|
||||
toDestination:unzipPath
|
||||
overwrite:YES
|
||||
password:password.length > 0 ? password : nil
|
||||
error:nil];
|
||||
if (!success) {
|
||||
NSLog(@"No success");
|
||||
return;
|
||||
}
|
||||
NSError *error = nil;
|
||||
NSMutableArray<NSString *> *items = [[[NSFileManager defaultManager]
|
||||
contentsOfDirectoryAtPath:unzipPath
|
||||
error:&error] mutableCopy];
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
[items enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
switch (idx) {
|
||||
case 0: {
|
||||
self.file1.text = obj;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
self.file2.text = obj;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
self.file3.text = obj;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
NSLog(@"Went beyond index of assumed files");
|
||||
break;
|
||||
}
|
||||
if (!_zipPath) {
|
||||
return;
|
||||
}
|
||||
}];
|
||||
_unzipButton.enabled = NO;
|
||||
NSString *unzipPath = [self tempUnzipPath];
|
||||
if (!unzipPath) {
|
||||
return;
|
||||
}
|
||||
NSString *password = _passwordField.text;
|
||||
BOOL success = [SSZipArchive unzipFileAtPath:_zipPath
|
||||
toDestination:unzipPath
|
||||
preserveAttributes:YES
|
||||
overwrite:YES
|
||||
nestedZipLevel:0
|
||||
password:password.length > 0 ? password : nil
|
||||
error:nil
|
||||
delegate:nil
|
||||
progressHandler:nil
|
||||
completionHandler:nil];
|
||||
if (success) {
|
||||
NSLog(@"Success unzip");
|
||||
} else {
|
||||
NSLog(@"No success unzip");
|
||||
return;
|
||||
}
|
||||
NSError *error = nil;
|
||||
NSMutableArray<NSString *> *items = [[[NSFileManager defaultManager]
|
||||
contentsOfDirectoryAtPath:unzipPath
|
||||
error:&error] mutableCopy];
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
[items enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
switch (idx) {
|
||||
case 0: {
|
||||
self.file1.text = obj;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
self.file2.text = obj;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
self.file3.text = obj;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
NSLog(@"Went beyond index of assumed files");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}];
|
||||
_unzipButton.enabled = NO;
|
||||
}
|
||||
|
||||
- (IBAction)resetPressed:(id)sender {
|
||||
_file1.text = @"";
|
||||
_file2.text = @"";
|
||||
_file3.text = @"";
|
||||
_zipButton.enabled = YES;
|
||||
_unzipButton.enabled = NO;
|
||||
_resetButton.enabled = NO;
|
||||
_file1.text = @"";
|
||||
_file2.text = @"";
|
||||
_file3.text = @"";
|
||||
_zipButton.enabled = YES;
|
||||
_unzipButton.enabled = NO;
|
||||
_resetButton.enabled = NO;
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
- (NSString *)tempZipPath {
|
||||
NSString *path = [NSString stringWithFormat:@"%@/\%@.zip",
|
||||
NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0],
|
||||
[NSUUID UUID].UUIDString];
|
||||
return path;
|
||||
NSString *path = [NSString stringWithFormat:@"%@/\%@.zip",
|
||||
NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0],
|
||||
[NSUUID UUID].UUIDString];
|
||||
return path;
|
||||
}
|
||||
|
||||
- (NSString *)tempUnzipPath {
|
||||
NSString *path = [NSString stringWithFormat:@"%@/\%@",
|
||||
NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0],
|
||||
[NSUUID UUID].UUIDString];
|
||||
NSURL *url = [NSURL fileURLWithPath:path];
|
||||
NSError *error = nil;
|
||||
[[NSFileManager defaultManager] createDirectoryAtURL:url
|
||||
withIntermediateDirectories:YES
|
||||
attributes:nil
|
||||
error:&error];
|
||||
if (error) {
|
||||
return nil;
|
||||
}
|
||||
return url.path;
|
||||
NSString *path = [NSString stringWithFormat:@"%@/\%@",
|
||||
NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0],
|
||||
[NSUUID UUID].UUIDString];
|
||||
NSURL *url = [NSURL fileURLWithPath:path];
|
||||
NSError *error = nil;
|
||||
[[NSFileManager defaultManager] createDirectoryAtURL:url
|
||||
withIntermediateDirectories:YES
|
||||
attributes:nil
|
||||
error:&error];
|
||||
if (error) {
|
||||
return nil;
|
||||
}
|
||||
return url.path;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
BIN
ObjectiveCExample/ObjectiveCExampleTests/Fixtures/Empty.zip
Normal file
BIN
ObjectiveCExample/ObjectiveCExampleTests/Fixtures/Empty.zip
Normal file
Binary file not shown.
@@ -233,25 +233,24 @@
|
||||
testPath = [outputPath stringByAppendingPathComponent:@"LICENSE"];
|
||||
XCTAssertTrue([fileManager fileExistsAtPath:testPath], @"LICENSE unzipped");
|
||||
}
|
||||
|
||||
//Temp Disabled test, fix is not yet in the AES version of the unzip lib
|
||||
|
||||
//- (void)testUnzippingTruncatedFileFix {
|
||||
// NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"IncorrectHeaders" ofType:@"zip"];
|
||||
// NSString *outputPath = [self _cachesPath:@"IncorrectHeaders"];
|
||||
//
|
||||
// id<SSZipArchiveDelegate> delegate = [ProgressDelegate new];
|
||||
// BOOL success = [SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:delegate];
|
||||
// XCTAssertTrue(success);
|
||||
//
|
||||
// NSString *intendedReadmeTxtMD5 = @"31ac96301302eb388070c827447290b5";
|
||||
//
|
||||
// NSString *filePath = [outputPath stringByAppendingPathComponent:@"IncorrectHeaders/Readme.txt"];
|
||||
// NSData *data = [NSData dataWithContentsOfFile:filePath];
|
||||
//
|
||||
// NSString *actualReadmeTxtMD5 = [self _calculateMD5Digest:data];
|
||||
// XCTAssertTrue([actualReadmeTxtMD5 isEqualToString:intendedReadmeTxtMD5], @"Readme.txt MD5 digest should match original.");
|
||||
//}
|
||||
|
||||
- (void)testUnzippingTruncatedFileFix {
|
||||
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"IncorrectHeaders" ofType:@"zip"];
|
||||
NSString *outputPath = [self _cachesPath:@"IncorrectHeaders"];
|
||||
|
||||
id<SSZipArchiveDelegate> delegate = [ProgressDelegate new];
|
||||
BOOL success = [SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:delegate];
|
||||
XCTAssertTrue(success);
|
||||
|
||||
NSString *intendedReadmeTxtMD5 = @"31ac96301302eb388070c827447290b5";
|
||||
|
||||
NSString *filePath = [outputPath stringByAppendingPathComponent:@"IncorrectHeaders/Readme.txt"];
|
||||
NSData *data = [NSData dataWithContentsOfFile:filePath];
|
||||
|
||||
NSString *actualReadmeTxtMD5 = [self _calculateMD5Digest:data];
|
||||
XCTAssertTrue([actualReadmeTxtMD5 isEqualToString:intendedReadmeTxtMD5], @"Readme.txt MD5 digest should match original.");
|
||||
}
|
||||
|
||||
|
||||
- (void)testUnzippingWithSymlinkedFileInside {
|
||||
@@ -313,6 +312,14 @@
|
||||
XCTAssertTrue(unicodeFolderWasExtracted, @"Folders with names in unicode should be extracted propertly.");
|
||||
}
|
||||
|
||||
- (void)testUnzippingEmptyArchive {
|
||||
|
||||
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"Empty" ofType:@"zip"];
|
||||
NSString *outputPath = [self _cachesPath:@"Empty"];
|
||||
|
||||
BOOL success = [SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:nil];
|
||||
XCTAssertTrue(success);
|
||||
}
|
||||
|
||||
- (void)testZippingAndUnzippingForDate {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
PODS:
|
||||
- SSZipArchive (2.0.8)
|
||||
- SSZipArchive (2.1.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- SSZipArchive (from `..`)
|
||||
@@ -9,7 +9,7 @@ EXTERNAL SOURCES:
|
||||
:path: ..
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
SSZipArchive: e6ab66e1936fac7e3b5073e9f5eb364d91dfbfc7
|
||||
SSZipArchive: 1e8e53dcb11bca3ded4738958dc49fc467320a14
|
||||
|
||||
PODFILE CHECKSUM: 5e250843c66c607960128ebfe02ab7d6569102be
|
||||
|
||||
|
||||
17
README.md
17
README.md
@@ -3,18 +3,21 @@
|
||||
|
||||
# SSZipArchive
|
||||
|
||||
ZipArchive is a simple utility class for zipping and unzipping files on iOS and Mac.
|
||||
ZipArchive is a simple utility class for zipping and unzipping files on iOS, macOS and tvOS.
|
||||
|
||||
- Unzip zip files;
|
||||
- Unzip password protected zip files;
|
||||
- Create new zip files;
|
||||
- Unzip AES encrypted zip files;
|
||||
- Create zip files;
|
||||
- Create password protected zip files;
|
||||
- Create AES encrypted zip files;
|
||||
- Choose compression level;
|
||||
- Append to existing zip files;
|
||||
- Zip files;
|
||||
- Zip-up NSData instances. (with a filename)
|
||||
|
||||
## Installation and Setup
|
||||
|
||||
*The main release branch is configured to support Objective C and Swift 3+. There is a 'swift23' branch which is a tied to a older 1.x release and will not be upgraded. Xcode 8.3+ removes support for Swift 2.3*
|
||||
*The main release branch is configured to support Objective C and Swift 3+.*
|
||||
|
||||
SSZipArchive works on Xcode 7-9 and above, iOS 8-11 and above.
|
||||
|
||||
@@ -39,10 +42,10 @@ SSZipArchive requires ARC.
|
||||
|
||||
```objective-c
|
||||
// Create
|
||||
[SSZipArchive createZipFileAtPath: zipPath withContentsOfDirectory: sampleDataPath];
|
||||
[SSZipArchive createZipFileAtPath:zipPath withContentsOfDirectory:sampleDataPath];
|
||||
|
||||
// Unzip
|
||||
[SSZipArchive unzipFileAtPath:zipPath toDestination: unzipPath];
|
||||
[SSZipArchive unzipFileAtPath:zipPath toDestination:unzipPath];
|
||||
```
|
||||
|
||||
### Swift
|
||||
@@ -57,7 +60,7 @@ SSZipArchive.unzipFileAtPath(zipPath, toDestination: unzipPath)
|
||||
|
||||
## License
|
||||
|
||||
SSZipArchive is protected under the [MIT license](https://github.com/samsoffes/ssziparchive/raw/master/LICENSE) and our slightly modified version of [Minizip](https://github.com/nmoinvaz/minizip) 1.1 is licensed under the [Zlib license](http://www.zlib.net/zlib_license.html).
|
||||
SSZipArchive is protected under the [MIT license](https://github.com/samsoffes/ssziparchive/raw/master/LICENSE) and our slightly modified version of [Minizip](https://github.com/nmoinvaz/minizip) 1.2 is licensed under the [Zlib license](http://www.zlib.net/zlib_license.html).
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'SSZipArchive'
|
||||
s.version = '2.0.8'
|
||||
s.version = '2.1.0'
|
||||
s.summary = 'Utility class for zipping and unzipping files on iOS, tvOS, watchOS, and Mac.'
|
||||
s.description = 'SSZipArchive is a simple utility class for zipping and unzipping files on iOS, tvOS, watchOS, and Mac.'
|
||||
s.homepage = 'https://github.com/ZipArchive/ZipArchive'
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
//
|
||||
// SSZipArchive+Swift.swift
|
||||
// ZipArchive
|
||||
//
|
||||
// Created by William Dunay on 7/6/16.
|
||||
// Copyright © 2016 smumryak. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension SSZipArchive {
|
||||
|
||||
static func unzipFileAtPath(_ path: String, toDestination destination: String, overwrite: Bool, password: String?, delegate: SSZipArchiveDelegate?) throws -> Bool {
|
||||
|
||||
var success = false
|
||||
var error: NSError?
|
||||
|
||||
success = __unzipFile(atPath: path, toDestination: destination, overwrite: overwrite, password: password, error: &error, delegate: delegate)
|
||||
if let throwableError = error {
|
||||
throw throwableError
|
||||
}
|
||||
|
||||
return success
|
||||
}
|
||||
}
|
||||
@@ -59,17 +59,29 @@ typedef NS_ENUM(NSInteger, SSZipArchiveErrorCode) {
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||
toDestination:(NSString *)destination
|
||||
progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler;
|
||||
progressHandler:(void (^_Nullable)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^_Nullable)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler;
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||
toDestination:(NSString *)destination
|
||||
overwrite:(BOOL)overwrite
|
||||
password:(nullable NSString *)password
|
||||
progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler;
|
||||
progressHandler:(void (^_Nullable)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^_Nullable)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler;
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||
toDestination:(NSString *)destination
|
||||
preserveAttributes:(BOOL)preserveAttributes
|
||||
overwrite:(BOOL)overwrite
|
||||
nestedZipLevel:(NSInteger)nestedZipLevel
|
||||
password:(nullable NSString *)password
|
||||
error:(NSError **)error
|
||||
delegate:(nullable id<SSZipArchiveDelegate>)delegate
|
||||
progressHandler:(void (^_Nullable)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^_Nullable)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler;
|
||||
|
||||
// Zip
|
||||
// default compression level is Z_DEFAULT_COMPRESSION (from "zlib.h")
|
||||
|
||||
// without password
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray<NSString *> *)paths;
|
||||
@@ -77,7 +89,8 @@ typedef NS_ENUM(NSInteger, SSZipArchiveErrorCode) {
|
||||
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory;
|
||||
|
||||
// with password, password could be nil
|
||||
// with optional password, default encryption is AES
|
||||
// don't use AES if you need compatibility with native macOS unzip and Archive Utility
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray<NSString *> *)paths withPassword:(nullable NSString *)password;
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath withPassword:(nullable NSString *)password;
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory withPassword:(nullable NSString *)password;
|
||||
@@ -86,14 +99,28 @@ typedef NS_ENUM(NSInteger, SSZipArchiveErrorCode) {
|
||||
keepParentDirectory:(BOOL)keepParentDirectory
|
||||
withPassword:(nullable NSString *)password
|
||||
andProgressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler;
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path
|
||||
withContentsOfDirectory:(NSString *)directoryPath
|
||||
keepParentDirectory:(BOOL)keepParentDirectory
|
||||
compressionLevel:(int)compressionLevel
|
||||
password:(nullable NSString *)password
|
||||
AES:(BOOL)aes
|
||||
progressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
- (instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER;
|
||||
- (BOOL)open;
|
||||
- (BOOL)writeFile:(NSString *)path withPassword:(nullable NSString *)password;
|
||||
|
||||
/// write empty folder
|
||||
- (BOOL)writeFolderAtPath:(NSString *)path withFolderName:(NSString *)folderName withPassword:(nullable NSString *)password;
|
||||
/// write file
|
||||
- (BOOL)writeFile:(NSString *)path withPassword:(nullable NSString *)password;
|
||||
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(nullable NSString *)fileName withPassword:(nullable NSString *)password;
|
||||
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(nullable NSString *)fileName compressionLevel:(int)compressionLevel password:(nullable NSString *)password AES:(BOOL)aes;
|
||||
/// write data
|
||||
- (BOOL)writeData:(NSData *)data filename:(nullable NSString *)filename withPassword:(nullable NSString *)password;
|
||||
- (BOOL)writeData:(NSData *)data filename:(nullable NSString *)filename compressionLevel:(int)compressionLevel password:(nullable NSString *)password AES:(BOOL)aes;
|
||||
|
||||
- (BOOL)close;
|
||||
|
||||
@end
|
||||
|
||||
@@ -17,6 +17,7 @@ NSString *const SSZipArchiveErrorDomain = @"SSZipArchiveErrorDomain";
|
||||
|
||||
#define CHUNK 16384
|
||||
|
||||
int _zipOpenEntry(zipFile entry, NSString *name, const zip_fileinfo *zipfi, int level, NSString *password, BOOL aes);
|
||||
BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
|
||||
#ifndef API_AVAILABLE
|
||||
@@ -66,7 +67,7 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
|
||||
unzCloseCurrentFile(zip);
|
||||
ret = unzGoToNextFile(zip);
|
||||
} while (ret == UNZ_OK && UNZ_OK != UNZ_END_OF_LIST_OF_FILE);
|
||||
} while (ret == UNZ_OK);
|
||||
}
|
||||
|
||||
return NO;
|
||||
@@ -134,7 +135,7 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
|
||||
unzCloseCurrentFile(zip);
|
||||
ret = unzGoToNextFile(zip);
|
||||
} while (ret == UNZ_OK && UNZ_OK != UNZ_END_OF_LIST_OF_FILE);
|
||||
} while (ret == UNZ_OK);
|
||||
}
|
||||
|
||||
// No password required
|
||||
@@ -180,8 +181,8 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||
toDestination:(NSString *)destination
|
||||
progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler
|
||||
progressHandler:(void (^_Nullable)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^_Nullable)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler
|
||||
{
|
||||
return [self unzipFileAtPath:path toDestination:destination preserveAttributes:YES overwrite:YES password:nil error:nil delegate:nil progressHandler:progressHandler completionHandler:completionHandler];
|
||||
}
|
||||
@@ -203,9 +204,23 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
overwrite:(BOOL)overwrite
|
||||
password:(nullable NSString *)password
|
||||
error:(NSError **)error
|
||||
delegate:(id<SSZipArchiveDelegate>)delegate
|
||||
progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler
|
||||
delegate:(nullable id<SSZipArchiveDelegate>)delegate
|
||||
progressHandler:(void (^_Nullable)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^_Nullable)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler
|
||||
{
|
||||
return [self unzipFileAtPath:path toDestination:destination preserveAttributes:preserveAttributes overwrite:overwrite nestedZipLevel:0 password:password error:error delegate:delegate progressHandler:progressHandler completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||
toDestination:(NSString *)destination
|
||||
preserveAttributes:(BOOL)preserveAttributes
|
||||
overwrite:(BOOL)overwrite
|
||||
nestedZipLevel:(NSInteger)nestedZipLevel
|
||||
password:(nullable NSString *)password
|
||||
error:(NSError **)error
|
||||
delegate:(nullable id<SSZipArchiveDelegate>)delegate
|
||||
progressHandler:(void (^_Nullable)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^_Nullable)(NSString *path, BOOL succeeded, NSError * _Nullable error))completionHandler
|
||||
{
|
||||
// Guard against empty strings
|
||||
if (path.length == 0 || destination.length == 0)
|
||||
@@ -248,7 +263,9 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
unzGetGlobalInfo(zip, &globalInfo);
|
||||
|
||||
// Begin unzipping
|
||||
if (unzGoToFirstFile(zip) != UNZ_OK)
|
||||
int ret = 0;
|
||||
ret = unzGoToFirstFile(zip);
|
||||
if (ret != UNZ_OK && ret != UNZ_END_OF_LIST_OF_FILE)
|
||||
{
|
||||
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"failed to open first file in zip file"};
|
||||
NSError *err = [NSError errorWithDomain:SSZipArchiveErrorDomain code:SSZipArchiveErrorCodeFailedOpenFileInZip userInfo:userInfo];
|
||||
@@ -265,7 +282,6 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
|
||||
BOOL success = YES;
|
||||
BOOL canceled = NO;
|
||||
int ret = 0;
|
||||
int crc_ret = 0;
|
||||
unsigned char buffer[4096] = {0};
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
@@ -279,9 +295,12 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
[delegate zipArchiveProgressEvent:currentPosition total:fileSize];
|
||||
}
|
||||
|
||||
NSInteger currentFileNumber = 0;
|
||||
NSInteger currentFileNumber = -1;
|
||||
NSError *unzippingError;
|
||||
do {
|
||||
currentFileNumber++;
|
||||
if (ret == UNZ_END_OF_LIST_OF_FILE)
|
||||
break;
|
||||
@autoreleasepool {
|
||||
if (password.length == 0) {
|
||||
ret = unzOpenCurrentFile(zip);
|
||||
@@ -313,7 +332,8 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
if ([delegate respondsToSelector:@selector(zipArchiveShouldUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {
|
||||
if (![delegate zipArchiveShouldUnzipFileAtIndex:currentFileNumber
|
||||
totalFiles:(NSInteger)globalInfo.number_entry
|
||||
archivePath:path fileInfo:fileInfo]) {
|
||||
archivePath:path
|
||||
fileInfo:fileInfo]) {
|
||||
success = NO;
|
||||
canceled = YES;
|
||||
break;
|
||||
@@ -340,6 +360,12 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
BOOL fileIsSymbolicLink = _fileIsSymbolicLink(&fileInfo);
|
||||
|
||||
NSString * strPath = [SSZipArchive _filenameStringWithCString:filename size:fileInfo.size_filename];
|
||||
if ([strPath hasPrefix:@"__MACOSX/"]) {
|
||||
// ignoring resource forks: https://superuser.com/questions/104500/what-is-macosx-folder
|
||||
unzCloseCurrentFile(zip);
|
||||
ret = unzGoToNextFile(zip);
|
||||
continue;
|
||||
}
|
||||
if (!strPath.length) {
|
||||
// if filename data is unsalvageable, we default to currentFileNumber
|
||||
strPath = @(currentFileNumber).stringValue;
|
||||
@@ -416,16 +442,23 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
}
|
||||
|
||||
if (fp) {
|
||||
if ([fullPath.pathExtension.lowercaseString isEqualToString:@"zip"]) {
|
||||
NSLog(@"Unzipping nested .zip file: %@", fullPath.lastPathComponent);
|
||||
if ([self unzipFileAtPath:fullPath toDestination:fullPath.stringByDeletingLastPathComponent overwrite:overwrite password:password error:nil delegate:nil]) {
|
||||
[[NSFileManager defaultManager] removeItemAtPath:fullPath error:nil];
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (preserveAttributes) {
|
||||
if (nestedZipLevel
|
||||
&& [fullPath.pathExtension.lowercaseString isEqualToString:@"zip"]
|
||||
&& [self unzipFileAtPath:fullPath
|
||||
toDestination:fullPath.stringByDeletingLastPathComponent
|
||||
preserveAttributes:preserveAttributes
|
||||
overwrite:overwrite
|
||||
nestedZipLevel:nestedZipLevel - 1
|
||||
password:password
|
||||
error:nil
|
||||
delegate:nil
|
||||
progressHandler:nil
|
||||
completionHandler:nil]) {
|
||||
[directoriesModificationDates removeLastObject];
|
||||
[[NSFileManager defaultManager] removeItemAtPath:fullPath error:nil];
|
||||
} else if (preserveAttributes) {
|
||||
|
||||
// Set the original datetime property
|
||||
if (fileInfo.dos_date != 0) {
|
||||
@@ -530,7 +563,7 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
|
||||
crc_ret = unzCloseCurrentFile(zip);
|
||||
if (crc_ret == UNZ_CRCERROR) {
|
||||
//CRC ERROR
|
||||
// CRC ERROR
|
||||
success = NO;
|
||||
break;
|
||||
}
|
||||
@@ -545,7 +578,6 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
archivePath:path unzippedFilePath: fullPath];
|
||||
}
|
||||
|
||||
currentFileNumber++;
|
||||
if (progressHandler)
|
||||
{
|
||||
progressHandler(strPath, fileInfo, currentFileNumber, globalInfo.number_entry);
|
||||
@@ -653,6 +685,16 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
keepParentDirectory:(BOOL)keepParentDirectory
|
||||
withPassword:(nullable NSString *)password
|
||||
andProgressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler {
|
||||
return [self createZipFileAtPath:path withContentsOfDirectory:directoryPath keepParentDirectory:keepParentDirectory compressionLevel:Z_DEFAULT_COMPRESSION password:password AES:YES progressHandler:progressHandler];
|
||||
}
|
||||
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path
|
||||
withContentsOfDirectory:(NSString *)directoryPath
|
||||
keepParentDirectory:(BOOL)keepParentDirectory
|
||||
compressionLevel:(int)compressionLevel
|
||||
password:(nullable NSString *)password
|
||||
AES:(BOOL)aes
|
||||
progressHandler:(void(^ _Nullable)(NSUInteger entryNumber, NSUInteger total))progressHandler {
|
||||
|
||||
SSZipArchive *zipArchive = [[SSZipArchive alloc] initWithPath:path];
|
||||
BOOL success = [zipArchive open];
|
||||
@@ -674,15 +716,13 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
}
|
||||
|
||||
if (!isDir) {
|
||||
success &= [zipArchive writeFileAtPath:fullFilePath withFileName:fileName withPassword:password];
|
||||
success &= [zipArchive writeFileAtPath:fullFilePath withFileName:fileName compressionLevel:compressionLevel password:password AES:aes];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([[NSFileManager defaultManager] subpathsOfDirectoryAtPath:fullFilePath error:nil].count == 0)
|
||||
{
|
||||
NSString *tempFilePath = [self _temporaryPathForDiscardableFile];
|
||||
NSString *tempFileFilename = [fileName stringByAppendingPathComponent:tempFilePath.lastPathComponent];
|
||||
success &= [zipArchive writeFileAtPath:tempFilePath withFileName:tempFileFilename withPassword:password];
|
||||
success &= [zipArchive writeFolderAtPath:fullFilePath withFolderName:fileName withPassword:password];
|
||||
}
|
||||
}
|
||||
complete++;
|
||||
@@ -715,90 +755,35 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
return (NULL != _zip);
|
||||
}
|
||||
|
||||
|
||||
- (void)zipInfo:(zip_fileinfo *)zipInfo setDate:(NSDate *)date
|
||||
{
|
||||
NSCalendar *currentCalendar = SSZipArchive._gregorian;
|
||||
NSCalendarUnit flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
|
||||
NSDateComponents *components = [currentCalendar components:flags fromDate:date];
|
||||
struct tm tmz_date;
|
||||
tmz_date.tm_sec = (unsigned int)components.second;
|
||||
tmz_date.tm_min = (unsigned int)components.minute;
|
||||
tmz_date.tm_hour = (unsigned int)components.hour;
|
||||
tmz_date.tm_mday = (unsigned int)components.day;
|
||||
// ISO/IEC 9899 struct tm is 0-indexed for January but NSDateComponents for gregorianCalendar is 1-indexed for January
|
||||
tmz_date.tm_mon = (unsigned int)components.month - 1;
|
||||
// ISO/IEC 9899 struct tm is 0-indexed for AD 1900 but NSDateComponents for gregorianCalendar is 1-indexed for AD 1
|
||||
tmz_date.tm_year = (unsigned int)components.year - 1900;
|
||||
zipInfo->dos_date = tm_to_dosdate(&tmz_date);
|
||||
}
|
||||
|
||||
- (BOOL)writeFolderAtPath:(NSString *)path withFolderName:(NSString *)folderName withPassword:(nullable NSString *)password
|
||||
{
|
||||
NSAssert((_zip != NULL), @"Attempting to write to an archive which was never opened");
|
||||
|
||||
zip_fileinfo zipInfo = {};
|
||||
|
||||
NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error: nil];
|
||||
if (attr)
|
||||
{
|
||||
NSDate *fileDate = (NSDate *)attr[NSFileModificationDate];
|
||||
if (fileDate)
|
||||
{
|
||||
[self zipInfo:&zipInfo setDate: fileDate];
|
||||
}
|
||||
|
||||
// Write permissions into the external attributes, for details on this see here: http://unix.stackexchange.com/a/14727
|
||||
// Get the permissions value from the files attributes
|
||||
NSNumber *permissionsValue = (NSNumber *)attr[NSFilePosixPermissions];
|
||||
if (permissionsValue != nil) {
|
||||
// Get the short value for the permissions
|
||||
short permissionsShort = permissionsValue.shortValue;
|
||||
|
||||
// Convert this into an octal by adding 010000, 010000 being the flag for a regular file
|
||||
NSInteger permissionsOctal = 0100000 + permissionsShort;
|
||||
|
||||
// Convert this into a long value
|
||||
uLong permissionsLong = @(permissionsOctal).unsignedLongValue;
|
||||
|
||||
// Store this into the external file attributes once it has been shifted 16 places left to form part of the second from last byte
|
||||
|
||||
// Casted back to an unsigned int to match type of external_fa in minizip
|
||||
zipInfo.external_fa = (unsigned int)(permissionsLong << 16L);
|
||||
}
|
||||
}
|
||||
[SSZipArchive zipInfo:&zipInfo setAttributesOfItemAtPath:path];
|
||||
|
||||
int error = zipOpenNewFileInZip3(_zip,
|
||||
[folderName stringByAppendingString:@"/"].fileSystemRepresentation,
|
||||
&zipInfo,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
Z_DEFLATED,
|
||||
Z_NO_COMPRESSION,
|
||||
0,
|
||||
-MAX_WBITS,
|
||||
DEF_MEM_LEVEL,
|
||||
Z_DEFAULT_STRATEGY,
|
||||
password.UTF8String,
|
||||
0);
|
||||
unsigned int len = 0;
|
||||
zipWriteInFileInZip(_zip, &len, 0);
|
||||
int error = _zipOpenEntry(_zip, [folderName stringByAppendingString:@"/"], &zipInfo, Z_NO_COMPRESSION, password, 0);
|
||||
const void *buffer = NULL;
|
||||
zipWriteInFileInZip(_zip, buffer, 0);
|
||||
zipCloseFileInZip(_zip);
|
||||
return error == ZIP_OK;
|
||||
}
|
||||
|
||||
- (BOOL)writeFile:(NSString *)path withPassword:(nullable NSString *)password;
|
||||
- (BOOL)writeFile:(NSString *)path withPassword:(nullable NSString *)password
|
||||
{
|
||||
return [self writeFileAtPath:path withFileName:nil withPassword:password];
|
||||
}
|
||||
|
||||
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(nullable NSString *)fileName withPassword:(nullable NSString *)password
|
||||
{
|
||||
return [self writeFileAtPath:path withFileName:fileName compressionLevel:Z_DEFAULT_COMPRESSION password:password AES:YES];
|
||||
}
|
||||
|
||||
// supports writing files with logical folder/directory structure
|
||||
// *path* is the absolute path of the file that will be compressed
|
||||
// *fileName* is the relative name of the file how it is stored within the zip e.g. /folder/subfolder/text1.txt
|
||||
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(nullable NSString *)fileName withPassword:(nullable NSString *)password
|
||||
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(nullable NSString *)fileName compressionLevel:(int)compressionLevel password:(nullable NSString *)password AES:(BOOL)aes
|
||||
{
|
||||
NSAssert((_zip != NULL), @"Attempting to write to an archive which was never opened");
|
||||
|
||||
@@ -807,44 +792,13 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
return NO;
|
||||
}
|
||||
|
||||
const char *aFileName;
|
||||
if (!fileName) {
|
||||
aFileName = path.lastPathComponent.fileSystemRepresentation;
|
||||
}
|
||||
else {
|
||||
aFileName = fileName.fileSystemRepresentation;
|
||||
fileName = path.lastPathComponent;
|
||||
}
|
||||
|
||||
zip_fileinfo zipInfo = {};
|
||||
|
||||
NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error: nil];
|
||||
if (attr)
|
||||
{
|
||||
NSDate *fileDate = (NSDate *)attr[NSFileModificationDate];
|
||||
if (fileDate)
|
||||
{
|
||||
[self zipInfo:&zipInfo setDate: fileDate];
|
||||
}
|
||||
|
||||
// Write permissions into the external attributes, for details on this see here: http://unix.stackexchange.com/a/14727
|
||||
// Get the permissions value from the files attributes
|
||||
NSNumber *permissionsValue = (NSNumber *)attr[NSFilePosixPermissions];
|
||||
if (permissionsValue != nil) {
|
||||
// Get the short value for the permissions
|
||||
short permissionsShort = permissionsValue.shortValue;
|
||||
|
||||
// Convert this into an octal by adding 010000, 010000 being the flag for a regular file
|
||||
NSInteger permissionsOctal = 0100000 + permissionsShort;
|
||||
|
||||
// Convert this into a long value
|
||||
uLong permissionsLong = @(permissionsOctal).unsignedLongValue;
|
||||
|
||||
// Store this into the external file attributes once it has been shifted 16 places left to form part of the second from last byte
|
||||
|
||||
// Casted back to an unsigned int to match type of external_fa in minizip
|
||||
zipInfo.external_fa = (unsigned int)(permissionsLong << 16L);
|
||||
}
|
||||
}
|
||||
[SSZipArchive zipInfo:&zipInfo setAttributesOfItemAtPath:path];
|
||||
|
||||
void *buffer = malloc(CHUNK);
|
||||
if (buffer == NULL)
|
||||
@@ -853,7 +807,7 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
return NO;
|
||||
}
|
||||
|
||||
int error = zipOpenNewFileInZip3(_zip, aFileName, &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password.UTF8String, 0);
|
||||
int error = _zipOpenEntry(_zip, fileName, &zipInfo, compressionLevel, password, aes);
|
||||
|
||||
while (!feof(input) && !ferror(input))
|
||||
{
|
||||
@@ -867,7 +821,12 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
return error == ZIP_OK;
|
||||
}
|
||||
|
||||
- (BOOL)writeData:(NSData *)data filename:(nullable NSString *)filename withPassword:(nullable NSString *)password;
|
||||
- (BOOL)writeData:(NSData *)data filename:(nullable NSString *)filename withPassword:(nullable NSString *)password
|
||||
{
|
||||
return [self writeData:data filename:filename compressionLevel:Z_DEFAULT_COMPRESSION password:password AES:YES];
|
||||
}
|
||||
|
||||
- (BOOL)writeData:(NSData *)data filename:(nullable NSString *)filename compressionLevel:(int)compressionLevel password:(nullable NSString *)password AES:(BOOL)aes
|
||||
{
|
||||
if (!_zip) {
|
||||
return NO;
|
||||
@@ -876,9 +835,9 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
return NO;
|
||||
}
|
||||
zip_fileinfo zipInfo = {};
|
||||
[self zipInfo:&zipInfo setDate:[NSDate date]];
|
||||
[SSZipArchive zipInfo:&zipInfo setDate:[NSDate date]];
|
||||
|
||||
int error = zipOpenNewFileInZip3(_zip, filename.fileSystemRepresentation, &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password.UTF8String, 0);
|
||||
int error = _zipOpenEntry(_zip, filename, &zipInfo, compressionLevel, password, aes);
|
||||
|
||||
zipWriteInFileInZip(_zip, data.bytes, (unsigned int)data.length);
|
||||
|
||||
@@ -886,7 +845,6 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
return error == ZIP_OK;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)close
|
||||
{
|
||||
NSAssert((_zip != NULL), @"[SSZipArchive] Attempting to close an archive which was never opened");
|
||||
@@ -936,21 +894,53 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
return strPath;
|
||||
}
|
||||
|
||||
+ (NSString *)_temporaryPathForDiscardableFile
|
||||
+ (void)zipInfo:(zip_fileinfo *)zipInfo setAttributesOfItemAtPath:(NSString *)path
|
||||
{
|
||||
static NSString *discardableFileName = @".DS_Store";
|
||||
static NSString *discardableFilePath = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *temporaryDirectoryName = [NSUUID UUID].UUIDString;
|
||||
NSString *temporaryDirectory = [NSTemporaryDirectory() stringByAppendingPathComponent:temporaryDirectoryName];
|
||||
BOOL directoryCreated = [[NSFileManager defaultManager] createDirectoryAtPath:temporaryDirectory withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
if (directoryCreated) {
|
||||
discardableFilePath = [temporaryDirectory stringByAppendingPathComponent:discardableFileName];
|
||||
[@"" writeToFile:discardableFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
|
||||
NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error: nil];
|
||||
if (attr)
|
||||
{
|
||||
NSDate *fileDate = (NSDate *)attr[NSFileModificationDate];
|
||||
if (fileDate)
|
||||
{
|
||||
[self zipInfo:zipInfo setDate:fileDate];
|
||||
}
|
||||
});
|
||||
return discardableFilePath;
|
||||
|
||||
// Write permissions into the external attributes, for details on this see here: http://unix.stackexchange.com/a/14727
|
||||
// Get the permissions value from the files attributes
|
||||
NSNumber *permissionsValue = (NSNumber *)attr[NSFilePosixPermissions];
|
||||
if (permissionsValue != nil) {
|
||||
// Get the short value for the permissions
|
||||
short permissionsShort = permissionsValue.shortValue;
|
||||
|
||||
// Convert this into an octal by adding 010000, 010000 being the flag for a regular file
|
||||
NSInteger permissionsOctal = 0100000 + permissionsShort;
|
||||
|
||||
// Convert this into a long value
|
||||
uLong permissionsLong = @(permissionsOctal).unsignedLongValue;
|
||||
|
||||
// Store this into the external file attributes once it has been shifted 16 places left to form part of the second from last byte
|
||||
|
||||
// Casted back to an unsigned int to match type of external_fa in minizip
|
||||
zipInfo->external_fa = (unsigned int)(permissionsLong << 16L);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)zipInfo:(zip_fileinfo *)zipInfo setDate:(NSDate *)date
|
||||
{
|
||||
NSCalendar *currentCalendar = SSZipArchive._gregorian;
|
||||
NSCalendarUnit flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
|
||||
NSDateComponents *components = [currentCalendar components:flags fromDate:date];
|
||||
struct tm tmz_date;
|
||||
tmz_date.tm_sec = (unsigned int)components.second;
|
||||
tmz_date.tm_min = (unsigned int)components.minute;
|
||||
tmz_date.tm_hour = (unsigned int)components.hour;
|
||||
tmz_date.tm_mday = (unsigned int)components.day;
|
||||
// ISO/IEC 9899 struct tm is 0-indexed for January but NSDateComponents for gregorianCalendar is 1-indexed for January
|
||||
tmz_date.tm_mon = (unsigned int)components.month - 1;
|
||||
// ISO/IEC 9899 struct tm is 0-indexed for AD 1900 but NSDateComponents for gregorianCalendar is 1-indexed for AD 1
|
||||
tmz_date.tm_year = (unsigned int)components.year - 1900;
|
||||
zipInfo->dos_date = tm_to_dosdate(&tmz_date);
|
||||
}
|
||||
|
||||
+ (NSCalendar *)_gregorian
|
||||
@@ -999,6 +989,11 @@ BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo);
|
||||
|
||||
@end
|
||||
|
||||
int _zipOpenEntry(zipFile entry, NSString *name, const zip_fileinfo *zipfi, int level, NSString *password, BOOL aes)
|
||||
{
|
||||
return zipOpenNewFileInZip5(entry, name.fileSystemRepresentation, zipfi, NULL, 0, NULL, 0, NULL, 0, 0, Z_DEFLATED, level, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, password.UTF8String, aes);
|
||||
}
|
||||
|
||||
#pragma mark - Private tools for file info
|
||||
|
||||
BOOL _fileIsSymbolicLink(const unz_file_info *fileInfo)
|
||||
|
||||
@@ -252,19 +252,19 @@ static int unzReadUInt64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidp
|
||||
}
|
||||
|
||||
/* Locate the Central directory of a zip file (at the end, just before the global comment) */
|
||||
static uint64_t unzSearchCentralDir(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream)
|
||||
static int unzSearchCentralDir(const zlib_filefunc64_32_def *pzlib_filefunc_def, uint64_t *pos_found, voidpf filestream)
|
||||
{
|
||||
uint8_t buf[BUFREADCOMMENT + 4];
|
||||
uint64_t file_size = 0;
|
||||
uint64_t back_read = 4;
|
||||
uint64_t max_back = UINT16_MAX; /* maximum size of global comment */
|
||||
uint64_t pos_found = 0;
|
||||
uint32_t read_size = 0;
|
||||
uint64_t read_pos = 0;
|
||||
uint32_t i = 0;
|
||||
*pos_found = 0;
|
||||
|
||||
if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
|
||||
file_size = ZTELL64(*pzlib_filefunc_def, filestream);
|
||||
|
||||
@@ -293,52 +293,49 @@ static uint64_t unzSearchCentralDir(const zlib_filefunc64_32_def *pzlib_filefunc
|
||||
((*(buf+i+2)) == (ENDHEADERMAGIC >> 16 & 0xff)) &&
|
||||
((*(buf+i+3)) == (ENDHEADERMAGIC >> 24 & 0xff)))
|
||||
{
|
||||
pos_found = read_pos+i;
|
||||
break;
|
||||
*pos_found = read_pos+i;
|
||||
return UNZ_OK;
|
||||
}
|
||||
|
||||
if (pos_found != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return pos_found;
|
||||
return UNZ_ERRNO;
|
||||
}
|
||||
|
||||
/* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */
|
||||
static uint64_t unzSearchCentralDir64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,
|
||||
static int unzSearchCentralDir64(const zlib_filefunc64_32_def *pzlib_filefunc_def, uint64_t *offset, voidpf filestream,
|
||||
const uint64_t endcentraloffset)
|
||||
{
|
||||
uint64_t offset = 0;
|
||||
uint32_t value32 = 0;
|
||||
*offset = 0;
|
||||
|
||||
/* Zip64 end of central directory locator */
|
||||
if (ZSEEK64(*pzlib_filefunc_def, filestream, endcentraloffset - SIZECENTRALHEADERLOCATOR, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
|
||||
/* Read locator signature */
|
||||
if (unzReadUInt32(pzlib_filefunc_def, filestream, &value32) != UNZ_OK)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
if (value32 != ZIP64ENDLOCHEADERMAGIC)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
/* Number of the disk with the start of the zip64 end of central directory */
|
||||
if (unzReadUInt32(pzlib_filefunc_def, filestream, &value32) != UNZ_OK)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
/* Relative offset of the zip64 end of central directory record */
|
||||
if (unzReadUInt64(pzlib_filefunc_def, filestream, &offset) != UNZ_OK)
|
||||
return 0;
|
||||
if (unzReadUInt64(pzlib_filefunc_def, filestream, offset) != UNZ_OK)
|
||||
return UNZ_ERRNO;
|
||||
/* Total number of disks */
|
||||
if (unzReadUInt32(pzlib_filefunc_def, filestream, &value32) != UNZ_OK)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
/* Goto end of central directory record */
|
||||
if (ZSEEK64(*pzlib_filefunc_def, filestream, offset, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
||||
return 0;
|
||||
if (ZSEEK64(*pzlib_filefunc_def, filestream, *offset, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
||||
return UNZ_ERRNO;
|
||||
/* The signature */
|
||||
if (unzReadUInt32(pzlib_filefunc_def, filestream, &value32) != UNZ_OK)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
if (value32 != ZIP64ENDHEADERMAGIC)
|
||||
return 0;
|
||||
return UNZ_ERRNO;
|
||||
|
||||
return offset;
|
||||
return UNZ_OK;
|
||||
}
|
||||
|
||||
static unzFile unzOpenInternal(const void *path, zlib_filefunc64_32_def *pzlib_filefunc64_32_def)
|
||||
@@ -353,6 +350,7 @@ static unzFile unzOpenInternal(const void *path, zlib_filefunc64_32_def *pzlib_f
|
||||
uint64_t value64 = 0;
|
||||
voidpf filestream = NULL;
|
||||
int err = UNZ_OK;
|
||||
int err64 = UNZ_OK;
|
||||
|
||||
us.filestream = NULL;
|
||||
us.filestream_with_CD = NULL;
|
||||
@@ -373,8 +371,8 @@ static unzFile unzOpenInternal(const void *path, zlib_filefunc64_32_def *pzlib_f
|
||||
us.is_zip64 = 0;
|
||||
|
||||
/* Search for end of central directory header */
|
||||
central_pos = unzSearchCentralDir(&us.z_filefunc, us.filestream);
|
||||
if (central_pos)
|
||||
err = unzSearchCentralDir(&us.z_filefunc, ¢ral_pos, us.filestream);
|
||||
if (err == UNZ_OK)
|
||||
{
|
||||
if (ZSEEK64(us.z_filefunc, us.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
|
||||
err = UNZ_ERRNO;
|
||||
@@ -415,8 +413,8 @@ static unzFile unzOpenInternal(const void *path, zlib_filefunc64_32_def *pzlib_f
|
||||
if (err == UNZ_OK)
|
||||
{
|
||||
/* Search for Zip64 end of central directory header */
|
||||
central_pos64 = unzSearchCentralDir64(&us.z_filefunc, us.filestream, central_pos);
|
||||
if (central_pos64)
|
||||
err64 = unzSearchCentralDir64(&us.z_filefunc, ¢ral_pos64, us.filestream, central_pos);
|
||||
if (err64 == UNZ_OK)
|
||||
{
|
||||
central_pos = central_pos64;
|
||||
us.is_zip64 = 1;
|
||||
@@ -457,7 +455,7 @@ static unzFile unzOpenInternal(const void *path, zlib_filefunc64_32_def *pzlib_f
|
||||
if (unzReadUInt64(&us.z_filefunc, us.filestream, &us.offset_central_dir) != UNZ_OK)
|
||||
err = UNZ_ERRNO;
|
||||
}
|
||||
else if ((us.gi.number_entry == UINT16_MAX) || (us.size_central_dir == UINT16_MAX) || (us.offset_central_dir == UINT32_MAX))
|
||||
else if ((us.size_central_dir == UINT16_MAX) || (us.offset_central_dir == UINT32_MAX))
|
||||
err = UNZ_BADZIPFILE;
|
||||
}
|
||||
}
|
||||
@@ -494,6 +492,10 @@ static unzFile unzOpenInternal(const void *path, zlib_filefunc64_32_def *pzlib_f
|
||||
if (s != NULL)
|
||||
{
|
||||
*s = us;
|
||||
if (err64 != UNZ_OK)
|
||||
// workaround incorrect count #184
|
||||
s->gi.number_entry = unzCountEntries(s);
|
||||
|
||||
unzGoToFirstFile((unzFile)s);
|
||||
}
|
||||
return (unzFile)s;
|
||||
@@ -1029,6 +1031,29 @@ static int unzCheckCurrentFileCoherencyHeader(unz64_internal *s, uint32_t *psize
|
||||
return err;
|
||||
}
|
||||
|
||||
extern uint64_t ZEXPORT unzCountEntries(const unzFile file)
|
||||
{
|
||||
if (file == NULL)
|
||||
return 0;
|
||||
|
||||
unz64_internal s = *(unz64_internal*)file;
|
||||
|
||||
s.pos_in_central_dir = s.offset_central_dir;
|
||||
s.num_file = 0;
|
||||
while (UNZ_OK == unzGetCurrentFileInfoInternal(&s,
|
||||
&s.cur_file_info,
|
||||
&s.cur_file_info_internal,
|
||||
NULL, 0, NULL, 0, NULL, 0))
|
||||
{
|
||||
s.pos_in_central_dir += SIZECENTRALDIRITEM
|
||||
+ s.cur_file_info.size_filename
|
||||
+ s.cur_file_info.size_file_extra
|
||||
+ s.cur_file_info.size_file_comment;
|
||||
s.num_file += 1;
|
||||
}
|
||||
return s.num_file;
|
||||
}
|
||||
|
||||
/*
|
||||
Open for reading data the current file in the zipfile.
|
||||
If there is no error and the file is opened, the return value is UNZ_OK.
|
||||
@@ -1300,16 +1325,11 @@ extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, uint32_t len)
|
||||
s->pfile_in_zip_read->stream.next_out = (uint8_t*)buf;
|
||||
s->pfile_in_zip_read->stream.avail_out = (uint16_t)len;
|
||||
|
||||
if (s->pfile_in_zip_read->raw)
|
||||
if ((s->pfile_in_zip_read->compression_method == 0) || (s->pfile_in_zip_read->raw))
|
||||
{
|
||||
if (len > s->pfile_in_zip_read->rest_read_compressed + s->pfile_in_zip_read->stream.avail_in)
|
||||
s->pfile_in_zip_read->stream.avail_out = (uint16_t)s->pfile_in_zip_read->rest_read_compressed +
|
||||
s->pfile_in_zip_read->stream.avail_in;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len > s->pfile_in_zip_read->rest_read_uncompressed)
|
||||
s->pfile_in_zip_read->stream.avail_out = (uint16_t)s->pfile_in_zip_read->rest_read_uncompressed;
|
||||
s->pfile_in_zip_read->stream.avail_in;
|
||||
}
|
||||
|
||||
do
|
||||
@@ -1668,6 +1688,9 @@ extern int ZEXPORT unzGoToFirstFile2(unzFile file, unz_file_info64 *pfile_info,
|
||||
return UNZ_PARAMERROR;
|
||||
s = (unz64_internal*)file;
|
||||
|
||||
if (s->gi.number_entry == 0)
|
||||
return UNZ_END_OF_LIST_OF_FILE;
|
||||
|
||||
s->pos_in_central_dir = s->offset_central_dir;
|
||||
s->num_file = 0;
|
||||
|
||||
|
||||
@@ -100,6 +100,8 @@ extern int ZEXPORT unzGetGlobalComment(unzFile file, char *comment, uint16_t com
|
||||
uSizeBuf is the size of the szComment buffer.
|
||||
return the number of byte copied or an error code <0 */
|
||||
|
||||
extern uint64_t ZEXPORT unzCountEntries(const unzFile file);
|
||||
|
||||
/***************************************************************************/
|
||||
/* Reading the content of the current zipfile, you can open it, read data from it, and close it
|
||||
(you can close it before reading all the file) */
|
||||
|
||||
@@ -910,10 +910,25 @@ extern zipFile ZEXPORT zipOpen64(const void *path, int append)
|
||||
return zipOpen3(path, append, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits, int memLevel,
|
||||
int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64)
|
||||
extern int ZEXPORT zipOpenNewFileInZip_internal(zipFile file,
|
||||
const char *filename,
|
||||
const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local,
|
||||
uint16_t size_extrafield_local,
|
||||
const void *extrafield_global,
|
||||
uint16_t size_extrafield_global,
|
||||
const char *comment,
|
||||
uint16_t flag_base,
|
||||
int zip64,
|
||||
uint16_t method,
|
||||
int level,
|
||||
int raw,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy,
|
||||
const char *password,
|
||||
int aes,
|
||||
uint16_t version_madeby)
|
||||
{
|
||||
zip64_internal *zi = NULL;
|
||||
uint64_t size_available = 0;
|
||||
@@ -978,7 +993,8 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, c
|
||||
{
|
||||
zi->ci.flag |= 1;
|
||||
#ifdef HAVE_AES
|
||||
zi->ci.method = AES_METHOD;
|
||||
if (aes)
|
||||
zi->ci.method = AES_METHOD;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -1255,6 +1271,30 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, c
|
||||
return err;
|
||||
}
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip5(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t flag_base, int zip64, uint16_t method, int level, int raw,
|
||||
int windowBits, int memLevel, int strategy, const char *password, int aes)
|
||||
{
|
||||
return zipOpenNewFileInZip_internal(file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global,
|
||||
size_extrafield_global, comment, flag_base, zip64, method, level, raw, windowBits, memLevel, strategy, password, aes,
|
||||
VERSIONMADEBY);
|
||||
}
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits, int memLevel,
|
||||
int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64)
|
||||
{
|
||||
uint8_t aes = 0;
|
||||
#ifdef HAVE_AES
|
||||
aes = 1;
|
||||
#endif
|
||||
return zipOpenNewFileInZip_internal(file, filename, zipfi, extrafield_local, size_extrafield_local, extrafield_global,
|
||||
size_extrafield_global, comment, flag_base, zip64, method, level, raw, windowBits, memLevel, strategy, password, aes,
|
||||
version_madeby);
|
||||
}
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global,
|
||||
uint16_t size_extrafield_global, const char *comment, uint16_t method, int level, int raw, int windowBits,
|
||||
|
||||
@@ -166,6 +166,26 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, c
|
||||
int strategy, const char *password, ZIP_UNUSED uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64);
|
||||
/* Same as zipOpenNewFileInZip4 with zip64 support */
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip5(zipFile file,
|
||||
const char *filename,
|
||||
const zip_fileinfo *zipfi,
|
||||
const void *extrafield_local,
|
||||
uint16_t size_extrafield_local,
|
||||
const void *extrafield_global,
|
||||
uint16_t size_extrafield_global,
|
||||
const char *comment,
|
||||
uint16_t flag_base,
|
||||
int zip64,
|
||||
uint16_t method,
|
||||
int level,
|
||||
int raw,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy,
|
||||
const char *password,
|
||||
int aes);
|
||||
/* Allowing optional aes */
|
||||
|
||||
extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, uint32_t len);
|
||||
/* Write data in the zipfile */
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
PODS:
|
||||
- SSZipArchive (2.0.8)
|
||||
- SSZipArchive (2.1.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- SSZipArchive (from `..`)
|
||||
@@ -9,7 +9,7 @@ EXTERNAL SOURCES:
|
||||
:path: ..
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
SSZipArchive: e6ab66e1936fac7e3b5073e9f5eb364d91dfbfc7
|
||||
SSZipArchive: 1e8e53dcb11bca3ded4738958dc49fc467320a14
|
||||
|
||||
PODFILE CHECKSUM: 0dc500eb72745751ccba7677de4da5534fcef36d
|
||||
|
||||
|
||||
@@ -36,11 +36,6 @@ class ViewController: UIViewController {
|
||||
file3.text = ""
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
// MARK: IBAction
|
||||
|
||||
@IBAction func zipPressed(_: UIButton) {
|
||||
@@ -48,12 +43,19 @@ class ViewController: UIViewController {
|
||||
zipPath = tempZipPath()
|
||||
let password = passwordField.text
|
||||
|
||||
let success = SSZipArchive.createZipFile(atPath: zipPath!, withContentsOfDirectory: sampleDataPath, withPassword: password?.isEmpty == false ? password : nil)
|
||||
let success = SSZipArchive.createZipFile(atPath: zipPath!,
|
||||
withContentsOfDirectory: sampleDataPath,
|
||||
keepParentDirectory: false,
|
||||
compressionLevel: -1,
|
||||
password: password?.isEmpty == false ? password : nil,
|
||||
aes: true,
|
||||
progressHandler: nil)
|
||||
if success {
|
||||
print("Success zip")
|
||||
unzipButton.isEnabled = true
|
||||
zipButton.isEnabled = false
|
||||
} else {
|
||||
print("No success")
|
||||
print("No success zip")
|
||||
}
|
||||
resetButton.isEnabled = true
|
||||
}
|
||||
@@ -68,12 +70,20 @@ class ViewController: UIViewController {
|
||||
}
|
||||
|
||||
let password = passwordField.text
|
||||
let success: Void? = try? SSZipArchive.unzipFile(atPath: zipPath,
|
||||
toDestination: unzipPath,
|
||||
overwrite: true,
|
||||
password: password?.isEmpty == false ? password : nil)
|
||||
if success == nil {
|
||||
print("No success")
|
||||
let success: Bool = SSZipArchive.unzipFile(atPath: zipPath,
|
||||
toDestination: unzipPath,
|
||||
preserveAttributes: true,
|
||||
overwrite: true,
|
||||
nestedZipLevel: 1,
|
||||
password: password?.isEmpty == false ? password : nil,
|
||||
error: nil,
|
||||
delegate: nil,
|
||||
progressHandler: nil,
|
||||
completionHandler: nil)
|
||||
if success != false {
|
||||
print("Success unzip")
|
||||
} else {
|
||||
print("No success unzip")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -127,7 +137,6 @@ class ViewController: UIViewController {
|
||||
} catch {
|
||||
return nil
|
||||
}
|
||||
|
||||
return url.path
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,6 @@
|
||||
37952C551F63B7A000DD6677 /* pwd2key.h in Headers */ = {isa = PBXBuildFile; fileRef = 373913F81F0009310094DB3B /* pwd2key.h */; };
|
||||
37952C561F63B7A000DD6677 /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 373913F91F0009310094DB3B /* sha1.c */; };
|
||||
37952C571F63B7A000DD6677 /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 373913FA1F0009310094DB3B /* sha1.h */; };
|
||||
37952C581F63B8C400DD6677 /* SSZipArchive+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87ACF3E91D2DAFAD00ED2F7E /* SSZipArchive+Swift.swift */; };
|
||||
37952C661F63BBBB00DD6677 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = 373913FC1F0009320094DB3B /* crypt.c */; };
|
||||
37952C671F63BBBB00DD6677 /* ioapi_buf.c in Sources */ = {isa = PBXBuildFile; fileRef = 373913E41F0009310094DB3B /* ioapi_buf.c */; };
|
||||
37952C681F63BBBB00DD6677 /* ioapi_buf.h in Headers */ = {isa = PBXBuildFile; fileRef = 373913E51F0009310094DB3B /* ioapi_buf.h */; };
|
||||
@@ -138,12 +137,10 @@
|
||||
37952C871F63BBC000DD6677 /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 373913FA1F0009310094DB3B /* sha1.h */; };
|
||||
37952C881F63BBD500DD6677 /* SSZipArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = B423AE481C0DF7950004A2F1 /* SSZipArchive.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
37952C891F63BBDA00DD6677 /* SSZipArchive.m in Sources */ = {isa = PBXBuildFile; fileRef = B423AE491C0DF7950004A2F1 /* SSZipArchive.m */; };
|
||||
37952C8A1F63BBE100DD6677 /* SSZipArchive+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87ACF3E91D2DAFAD00ED2F7E /* SSZipArchive+Swift.swift */; };
|
||||
37952C8B1F63BBE400DD6677 /* ZipArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = B423AE4A1C0DF7950004A2F1 /* ZipArchive.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
37952C8C1F63BBED00DD6677 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = B423AE6E1C0DF83F0004A2F1 /* libz.tbd */; };
|
||||
37952C8D1F63BBF300DD6677 /* SSZipCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 389869341D5BC30100F18782 /* SSZipCommon.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
389869351D5BC30100F18782 /* SSZipCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 389869341D5BC30100F18782 /* SSZipCommon.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
87ACF3EA1D2DAFAD00ED2F7E /* SSZipArchive+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87ACF3E91D2DAFAD00ED2F7E /* SSZipArchive+Swift.swift */; };
|
||||
AFF75A2D1C3727F000F450AC /* ZipArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = B423AE4A1C0DF7950004A2F1 /* ZipArchive.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AFF75A2E1C37280200F450AC /* SSZipArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = B423AE481C0DF7950004A2F1 /* SSZipArchive.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AFF75A2F1C37280200F450AC /* SSZipArchive.m in Sources */ = {isa = PBXBuildFile; fileRef = B423AE491C0DF7950004A2F1 /* SSZipArchive.m */; };
|
||||
@@ -199,7 +196,6 @@
|
||||
37952C261F63B50D00DD6677 /* ZipArchive.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ZipArchive.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
37952C5E1F63BB7100DD6677 /* ZipArchive.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ZipArchive.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
389869341D5BC30100F18782 /* SSZipCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSZipCommon.h; sourceTree = "<group>"; };
|
||||
87ACF3E91D2DAFAD00ED2F7E /* SSZipArchive+Swift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SSZipArchive+Swift.swift"; sourceTree = "<group>"; };
|
||||
AFF75A241C37279600F450AC /* ZipArchive.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ZipArchive.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B423AE1A1C0DF76A0004A2F1 /* ZipArchive.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ZipArchive.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B423AE3D1C0DF7950004A2F1 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@@ -307,7 +303,6 @@
|
||||
B423AE3E1C0DF7950004A2F1 /* minizip */,
|
||||
B423AE481C0DF7950004A2F1 /* SSZipArchive.h */,
|
||||
B423AE491C0DF7950004A2F1 /* SSZipArchive.m */,
|
||||
87ACF3E91D2DAFAD00ED2F7E /* SSZipArchive+Swift.swift */,
|
||||
B423AE4A1C0DF7950004A2F1 /* ZipArchive.h */,
|
||||
);
|
||||
path = SSZipArchive;
|
||||
@@ -608,7 +603,6 @@
|
||||
files = (
|
||||
37952C541F63B7A000DD6677 /* pwd2key.c in Sources */,
|
||||
37952C521F63B7A000DD6677 /* prng.c in Sources */,
|
||||
37952C581F63B8C400DD6677 /* SSZipArchive+Swift.swift in Sources */,
|
||||
37952C401F63B78A00DD6677 /* ioapi_mem.c in Sources */,
|
||||
37952C561F63B7A000DD6677 /* sha1.c in Sources */,
|
||||
37952C4A1F63B7A000DD6677 /* aestab.c in Sources */,
|
||||
@@ -633,7 +627,6 @@
|
||||
files = (
|
||||
37952C801F63BBC000DD6677 /* hmac.c in Sources */,
|
||||
37952C841F63BBC000DD6677 /* pwd2key.c in Sources */,
|
||||
37952C8A1F63BBE100DD6677 /* SSZipArchive+Swift.swift in Sources */,
|
||||
37952C7E1F63BBC000DD6677 /* fileenc.c in Sources */,
|
||||
37952C891F63BBDA00DD6677 /* SSZipArchive.m in Sources */,
|
||||
37952C7A1F63BBC000DD6677 /* aestab.c in Sources */,
|
||||
@@ -682,7 +675,6 @@
|
||||
files = (
|
||||
3739141D1F0009FF0094DB3B /* hmac.c in Sources */,
|
||||
3739140E1F0009E50094DB3B /* aes_ni.c in Sources */,
|
||||
87ACF3EA1D2DAFAD00ED2F7E /* SSZipArchive+Swift.swift in Sources */,
|
||||
373914211F0009FF0094DB3B /* pwd2key.c in Sources */,
|
||||
373914171F0009FF0094DB3B /* aestab.c in Sources */,
|
||||
373914021F0009C80094DB3B /* minishared.c in Sources */,
|
||||
|
||||
Reference in New Issue
Block a user