22 Commits

Author SHA1 Message Date
Sam Soffes
d7ac059a8a Version 0.2.4 2013-07-03 08:58:01 -07:00
Joshua Garnham
9d322d173f Added tests for compressing and uncompressing files with permissions 2013-06-26 12:16:29 +01:00
Joshua Garnham
c91865d01b Adds support for maintaining file permissions when compressing and decompressing 2013-06-25 17:11:08 +01:00
frytaz
548b3acbba Fix for file creation date + tests 2013-06-25 13:45:30 +02:00
djskinner
7627a1b4fc wrapped main loop in @autorelease pool
Massively reduces the memory overhead whilst unzipping
2013-06-17 15:33:44 +02:00
Sam Soffes
481ddf2096 Merge pull request #53 from randomsequence/master
Fix NSFileManager leak when building without ARC
2013-05-03 06:15:24 -07:00
Johnnie Walker
b078433f2e Fix warning with -Widiomatic-parentheses enabled 2013-05-01 12:38:44 +01:00
Johnnie Walker
ceae6ae819 Fix warning with -Wmissing-braces enabled 2013-05-01 12:36:32 +01:00
Johnnie Walker
d7c7955cdc Fix NSFileManager leak when building without ARC 2013-05-01 12:03:48 +01:00
Sam Soffes
ffbacdb288 Merge pull request #51 from carlj/master
Notice file date when save file
2013-04-23 02:03:25 -07:00
Carl Jahn
4ac78e3121 fixed bug: writeFileAtPath now notice the file date 2013-04-19 15:05:54 +02:00
Sam Soffes
b4fa2e4739 Merge pull request #44 from iggycoder/master
zipping folders
2013-03-09 09:40:39 -08:00
Ingmar
7aea62f0dd - add folder zipping functionality
- fixed zipping test case [testZipping] (zipped an empty archive)
2013-03-09 05:36:20 -08:00
Sam Soffes
798a317bdc Merge pull request #40 from Keithbsmiley/master
Podspec fix
2013-03-03 10:55:22 -08:00
Sam Soffes
ec5de8e02b Merge pull request #43 from levigroker/master
#define added to the .h which allows conditional compilation for third parties wishing to conditionally add functionality based on the presence of SSZipArchive.
2013-03-03 10:53:15 -08:00
Levi Brown
a15c76e057 Fixed podspec.
Signed-off-by: Levi Brown <levi@grokers.net>
2013-03-01 17:17:35 -07:00
Levi Brown
f7266f6b4d Adding #define of SSZipArchive header inclusion to allow for conditional compilation of libraries which can add functionality conditionally, if SSZipArchive is present.
Signed-off-by: Levi Brown <levi@grokers.net>
2013-03-01 14:40:28 -07:00
Sam Soffes
d6f5b1c7a3 Update readme 2013-02-25 16:09:47 -08:00
Sam Soffes
2f05d42988 Add Travis CI 2013-02-25 06:46:56 -05:00
Sam Soffes
d630ae5f5e Merge pull request #41 from xenosoz/master
This fixes a small typo.
2013-02-24 16:11:58 -08:00
Xenosoz Hwang
04605b7967 Fix bad loop end condition for unzip. 2013-02-24 10:40:21 -08:00
Keith Smiley
294cd2992b Fixed podspec 2013-02-07 11:45:12 -05:00
18 changed files with 533 additions and 173 deletions

3
.travis.yml Normal file
View File

@@ -0,0 +1,3 @@
language: objective-c
before_install: "sudo gem update --system && bundle install"
script: bundle exec rake test --trace

3
Gemfile Normal file
View File

@@ -0,0 +1,3 @@
source 'https://rubygems.org'
gem 'rake'

10
Gemfile.lock Normal file
View File

@@ -0,0 +1,10 @@
GEM
remote: https://rubygems.org/
specs:
rake (10.0.3)
PLATFORMS
ruby
DEPENDENCIES
rake

6
Rakefile Normal file
View File

@@ -0,0 +1,6 @@
desc 'Run the tests'
task :test do
system 'xcodebuild -project Tests/SSZipArchive.xcodeproj -scheme SSZipArchiveTests TEST_AFTER_BUILD=YES'
end
task :default => :test

View File

@@ -34,6 +34,12 @@ NSArray *inputPaths = [NSArray arrayWithObjects:
[SSZipArchive createZipFileAtPath:zippedPath withFilesAtPaths:inputPaths];
```
## Tests
Simply, open the Xcode project in the Tests directory and press Command-U to run the tests.
[![Build Status](https://staging.travis-ci.org/soffes/ssziparchive.png?branch=master)](https://staging.travis-ci.org/soffes/ssziparchive)
## License
SSZipArchive is licensed under the [MIT license](https://github.com/samsoffes/ssziparchive/raw/master/LICENSE). A slightly modified version of [Minizip](http://www.winimage.com/zLibDll/minizip.html) 1.1 is also included and is licensed under the [Zlib license](http://www.zlib.net/zlib_license.html).

View File

@@ -6,6 +6,9 @@
// Copyright (c) Sam Soffes 2010-2013. All rights reserved.
//
#ifndef _SSZIPARCHIVE_H
#define _SSZIPARCHIVE_H
#import <Foundation/Foundation.h>
#include "minizip/unzip.h"
@@ -22,6 +25,7 @@
// Zip
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)filenames;
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath;
- (id)initWithPath:(NSString *)path;
- (BOOL)open;
@@ -43,3 +47,5 @@
- (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;
@end
#endif /* _SSZIPARCHIVE_H */

View File

@@ -80,169 +80,192 @@
NSInteger currentFileNumber = 0;
do {
if ([password length] == 0) {
ret = unzOpenCurrentFile(zip);
} else {
ret = unzOpenCurrentFilePassword(zip, [password cStringUsingEncoding:NSASCIIStringEncoding]);
}
if (ret != UNZ_OK) {
success = NO;
break;
}
// Reading data and write to file
unz_file_info fileInfo;
memset(&fileInfo, 0, sizeof(unz_file_info));
ret = unzGetCurrentFileInfo(zip, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
if (ret != UNZ_OK) {
success = NO;
unzCloseCurrentFile(zip);
break;
}
// Message delegate
if ([delegate respondsToSelector:@selector(zipArchiveWillUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {
[delegate zipArchiveWillUnzipFileAtIndex:currentFileNumber totalFiles:(NSInteger)globalInfo.number_entry
archivePath:path fileInfo:fileInfo];
}
char *filename = (char *)malloc(fileInfo.size_filename + 1);
unzGetCurrentFileInfo(zip, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0);
filename[fileInfo.size_filename] = '\0';
//
// NOTE
// I used the ZIP spec from here:
// http://www.pkware.com/documents/casestudies/APPNOTE.TXT
//
// ...to deduce this method of detecting whether the file in the ZIP is a symbolic link.
// If it is, it is listed as a directory but has a data size greater than zero (real
// directories have it equal to 0) and the included, uncompressed data is the symbolic link path.
//
// ZIP files did not originally include support for symbolic links so the specification
// doesn't include anything in them that isn't part of a unix extension that isn't being used
// by the archivers we're testing. Most of this is figured out through trial and error and
// reading ZIP headers in hex editors. This seems to do the trick though.
//
const uLong ZipCompressionMethodStore = 0;
BOOL fileIsSymbolicLink = NO;
if((fileInfo.compression_method == ZipCompressionMethodStore) && // Is it compressed?
(S_ISDIR(fileInfo.external_fa)) && // Is it marked as a directory
(fileInfo.compressed_size > 0)) // Is there any data?
{
fileIsSymbolicLink = YES;
}
// Check if it contains directory
NSString *strPath = [NSString stringWithCString:filename encoding:NSUTF8StringEncoding];
BOOL isDirectory = NO;
if (filename[fileInfo.size_filename-1] == '/' || filename[fileInfo.size_filename-1] == '\\') {
isDirectory = YES;
}
free(filename);
// Contains a path
if ([strPath rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"/\\"]].location != NSNotFound) {
strPath = [strPath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"];
}
NSString *fullPath = [destination stringByAppendingPathComponent:strPath];
NSError *err = nil;
NSDate *modDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.dosDate];
NSDictionary *directoryAttr = [NSDictionary dictionaryWithObjectsAndKeys:modDate, NSFileCreationDate, modDate, NSFileModificationDate, nil];
if (isDirectory) {
[fileManager createDirectoryAtPath:fullPath withIntermediateDirectories:YES attributes:directoryAttr error:&err];
} else {
[fileManager createDirectoryAtPath:[fullPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:directoryAttr error:&err];
}
if (nil != err) {
NSLog(@"[SSZipArchive] Error: %@", err.localizedDescription);
}
if(!fileIsSymbolicLink)
[directoriesModificationDates addObject: [NSDictionary dictionaryWithObjectsAndKeys:fullPath, @"path", modDate, @"modDate", nil]];
if ([fileManager fileExistsAtPath:fullPath] && !isDirectory && !overwrite) {
unzCloseCurrentFile(zip);
ret = unzGoToNextFile(zip);
continue;
}
if(!fileIsSymbolicLink)
{
FILE *fp = fopen((const char*)[fullPath UTF8String], "wb");
while (fp) {
int readBytes = unzReadCurrentFile(zip, buffer, 4096);
if (readBytes > 0) {
fwrite(buffer, readBytes, 1, fp );
} else {
break;
}
}
if (fp) {
fclose(fp);
// Set the original datetime property
if (fileInfo.dosDate != 0) {
NSDate *orgDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.dosDate];
NSDictionary *attr = [NSDictionary dictionaryWithObject:orgDate forKey:NSFileModificationDate];
@autoreleasepool {
if ([password length] == 0) {
ret = unzOpenCurrentFile(zip);
} else {
ret = unzOpenCurrentFilePassword(zip, [password cStringUsingEncoding:NSASCIIStringEncoding]);
}
if (ret != UNZ_OK) {
success = NO;
break;
}
// Reading data and write to file
unz_file_info fileInfo;
memset(&fileInfo, 0, sizeof(unz_file_info));
ret = unzGetCurrentFileInfo(zip, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
if (ret != UNZ_OK) {
success = NO;
unzCloseCurrentFile(zip);
break;
}
// Message delegate
if ([delegate respondsToSelector:@selector(zipArchiveWillUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {
[delegate zipArchiveWillUnzipFileAtIndex:currentFileNumber totalFiles:(NSInteger)globalInfo.number_entry
archivePath:path fileInfo:fileInfo];
}
char *filename = (char *)malloc(fileInfo.size_filename + 1);
unzGetCurrentFileInfo(zip, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0);
filename[fileInfo.size_filename] = '\0';
//
// NOTE
// I used the ZIP spec from here:
// http://www.pkware.com/documents/casestudies/APPNOTE.TXT
//
// ...to deduce this method of detecting whether the file in the ZIP is a symbolic link.
// If it is, it is listed as a directory but has a data size greater than zero (real
// directories have it equal to 0) and the included, uncompressed data is the symbolic link path.
//
// ZIP files did not originally include support for symbolic links so the specification
// doesn't include anything in them that isn't part of a unix extension that isn't being used
// by the archivers we're testing. Most of this is figured out through trial and error and
// reading ZIP headers in hex editors. This seems to do the trick though.
//
const uLong ZipCompressionMethodStore = 0;
BOOL fileIsSymbolicLink = NO;
if((fileInfo.compression_method == ZipCompressionMethodStore) && // Is it compressed?
(S_ISDIR(fileInfo.external_fa)) && // Is it marked as a directory
(fileInfo.compressed_size > 0)) // Is there any data?
{
fileIsSymbolicLink = YES;
}
// Check if it contains directory
NSString *strPath = [NSString stringWithCString:filename encoding:NSUTF8StringEncoding];
BOOL isDirectory = NO;
if (filename[fileInfo.size_filename-1] == '/' || filename[fileInfo.size_filename-1] == '\\') {
isDirectory = YES;
}
free(filename);
// Contains a path
if ([strPath rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"/\\"]].location != NSNotFound) {
strPath = [strPath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"];
}
NSString *fullPath = [destination stringByAppendingPathComponent:strPath];
NSError *err = nil;
NSDate *modDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.dosDate];
NSDictionary *directoryAttr = [NSDictionary dictionaryWithObjectsAndKeys:modDate, NSFileCreationDate, modDate, NSFileModificationDate, nil];
if (isDirectory) {
[fileManager createDirectoryAtPath:fullPath withIntermediateDirectories:YES attributes:directoryAttr error:&err];
} else {
[fileManager createDirectoryAtPath:[fullPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:directoryAttr error:&err];
}
if (nil != err) {
NSLog(@"[SSZipArchive] Error: %@", err.localizedDescription);
}
if(!fileIsSymbolicLink)
[directoriesModificationDates addObject: [NSDictionary dictionaryWithObjectsAndKeys:fullPath, @"path", modDate, @"modDate", nil]];
if ([fileManager fileExistsAtPath:fullPath] && !isDirectory && !overwrite) {
unzCloseCurrentFile(zip);
ret = unzGoToNextFile(zip);
continue;
}
if(!fileIsSymbolicLink)
{
FILE *fp = fopen((const char*)[fullPath UTF8String], "wb");
while (fp) {
int readBytes = unzReadCurrentFile(zip, buffer, 4096);
if (readBytes > 0) {
fwrite(buffer, readBytes, 1, fp );
} else {
break;
}
}
if (fp) {
fclose(fp);
// Set the original datetime property
if (fileInfo.dosDate != 0) {
NSDate *orgDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.dosDate];
NSDictionary *attr = [NSDictionary dictionaryWithObject:orgDate forKey:NSFileModificationDate];
if (attr) {
if ([fileManager setAttributes:attr ofItemAtPath:fullPath error:nil] == NO) {
// Can't set attributes
NSLog(@"[SSZipArchive] Failed to set attributes - whilst setting modification date");
}
}
}
if (attr) {
if ([fileManager setAttributes:attr ofItemAtPath:fullPath error:nil] == NO) {
// Can't set attributes
NSLog(@"[SSZipArchive] Failed to set attributes");
// Set the original permissions on the file
if (fileInfo.external_fa != 0) {
// Get the permissions
uLong permissions = fileInfo.external_fa >> 16;
// Store it into a NSNumber
NSNumber *permissionsValue = @(permissions);
// Retrieve any existing attributes
NSMutableDictionary *attrs = [[NSMutableDictionary alloc] initWithDictionary:[fileManager attributesOfItemAtPath:fullPath error:nil]];
// Set the value in the attributes dict
attrs[NSFilePosixPermissions] = permissionsValue;
// Update attributes
if ([fileManager setAttributes:attrs ofItemAtPath:fullPath error:nil] == NO) {
// Unable to set the permissions attribute
NSLog(@"[SSZipArchive] Failed to set attributes - whilst setting permissions");
}
}
}
}
}
else
{
// Get the path for the symbolic link
NSURL* symlinkURL = [NSURL fileURLWithPath:fullPath];
NSMutableString* destinationPath = [NSMutableString string];
int bytesRead = 0;
while((bytesRead = unzReadCurrentFile(zip, buffer, 4096)) > 0)
{
buffer[bytesRead] = 0;
[destinationPath appendString:[NSString stringWithUTF8String:(const char*)buffer]];
}
//NSLog(@"Symlinking to: %@", destinationPath);
NSURL* destinationURL = [NSURL fileURLWithPath:destinationPath];
// Create the symbolic link
NSError* symlinkError = nil;
[fileManager createSymbolicLinkAtURL:symlinkURL withDestinationURL:destinationURL error:&symlinkError];
if(symlinkError != nil)
{
NSLog(@"Failed to create symbolic link at \"%@\" to \"%@\". Error: %@", symlinkURL.absoluteString, destinationURL.absoluteString, symlinkError.localizedDescription);
}
}
unzCloseCurrentFile( zip );
ret = unzGoToNextFile( zip );
// Message delegate
if ([delegate respondsToSelector:@selector(zipArchiveDidUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {
[delegate zipArchiveDidUnzipFileAtIndex:currentFileNumber totalFiles:(NSInteger)globalInfo.number_entry
archivePath:path fileInfo:fileInfo];
}
}
else
{
// Get the path for the symbolic link
NSURL* symlinkURL = [NSURL fileURLWithPath:fullPath];
NSMutableString* destinationPath = [NSMutableString string];
int bytesRead = 0;
while((bytesRead = unzReadCurrentFile(zip, buffer, 4096)) > 0)
{
buffer[bytesRead] = 0;
[destinationPath appendString:[NSString stringWithUTF8String:(const char*)buffer]];
}
//NSLog(@"Symlinking to: %@", destinationPath);
NSURL* destinationURL = [NSURL fileURLWithPath:destinationPath];
// Create the symbolic link
NSError* symlinkError = nil;
[fileManager createSymbolicLinkAtURL:symlinkURL withDestinationURL:destinationURL error:&symlinkError];
if(symlinkError != nil)
{
NSLog(@"Failed to create symbolic link at \"%@\" to \"%@\". Error: %@", symlinkURL.absoluteString, destinationURL.absoluteString, symlinkError.localizedDescription);
}
}
unzCloseCurrentFile( zip );
ret = unzGoToNextFile( zip );
// Message delegate
if ([delegate respondsToSelector:@selector(zipArchiveDidUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {
[delegate zipArchiveDidUnzipFileAtIndex:currentFileNumber totalFiles:(NSInteger)globalInfo.number_entry
archivePath:path fileInfo:fileInfo];
}
currentFileNumber++;
}
currentFileNumber++;
} while(ret == UNZ_OK && UNZ_OK != UNZ_END_OF_LIST_OF_FILE);
} while(ret == UNZ_OK && ret != UNZ_END_OF_LIST_OF_FILE);
// Close
unzClose(zip);
@@ -293,6 +316,38 @@
}
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath {
BOOL success = NO;
NSFileManager *fileManager = nil;
SSZipArchive *zipArchive = [[SSZipArchive alloc] initWithPath:path];
if ([zipArchive open]) {
// use a local filemanager (queue/thread compatibility)
fileManager = [[NSFileManager alloc] init];
NSDirectoryEnumerator *dirEnumerator = [fileManager enumeratorAtPath:directoryPath];
NSString *fileName;
while ((fileName = [dirEnumerator nextObject])) {
BOOL isDir;
NSString *fullFilePath = [directoryPath stringByAppendingPathComponent:fileName];
[fileManager fileExistsAtPath:fullFilePath isDirectory:&isDir];
if (!isDir) {
[zipArchive writeFileAtPath:fullFilePath withFileName:fileName];
}
}
success = [zipArchive close];
}
#if !__has_feature(objc_arc)
[fileManager release];
[zipArchive release];
#endif
return success;
}
- (id)initWithPath:(NSString *)path {
if ((self = [super init])) {
_path = [path copy];
@@ -329,27 +384,72 @@
}
- (BOOL)writeFile:(NSString *)path {
NSAssert((_zip != NULL), @"Attempting to write to an archive which was never opened");
- (BOOL)writeFile:(NSString *)path
{
return [self writeFileAtPath:path withFileName:nil];
}
// 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:(NSString *)fileName {
NSAssert((_zip != NULL), @"Attempting to write to an archive which was never opened");
FILE *input = fopen([path UTF8String], "r");
if (NULL == input) {
return NO;
}
const char *afileName;
if (!fileName) {
afileName = [path.lastPathComponent UTF8String];
}
else {
afileName = [fileName UTF8String];
}
zip_fileinfo zipInfo = {{0}};
zipOpenNewFileInZip(_zip, [[path lastPathComponent] UTF8String], NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED,
Z_DEFAULT_COMPRESSION);
NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error: nil];
if( attr )
{
NSDate *fileDate = (NSDate *)[attr objectForKey: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 objectForKey:NSFilePosixPermissions];
if (permissionsValue) {
// 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
zipInfo.external_fa = permissionsLong << 16L;
}
}
zipOpenNewFileInZip(_zip, afileName, &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
void *buffer = malloc(CHUNK);
unsigned int len = 0;
while (!feof(input)) {
while (!feof(input))
{
len = (unsigned int) fread(buffer, 1, CHUNK, input);
zipWriteInFileInZip(_zip, buffer, len);
}
zipCloseFileInZip(_zip);
free(buffer);
fclose(input);
return YES;
}

View File

@@ -1,15 +1,15 @@
Pod::Spec.new do |s|
s.name = 'SSZipArchive'
s.version = '0.2.3'
s.version = '0.2.4'
s.summary = 'Utility class for zipping and unzipping files on iOS and Mac.'
s.description = 'SSZipArchive is a simple utility class for zipping and unzipping files on iOS and Mac.'
s.homepage = 'https://github.com/soffes/ssziparchive'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Sam Soffes' => 'sam@soff.es' }
s.source = { :git => 'https://github.com/soffes/ssziparchive.git', :tag => '0.2.3' }
s.source = { :git => 'https://github.com/soffes/ssziparchive.git', :tag => 'v0.2.4' }
s.ios.deployment_target = '4.0'
s.osx.deployment_target = '10.6'
s.source_files = 'SSZipArchive.{h,m}', 'minizip/*.{h,c}'
s.preserve_paths = 'minizip'
s.header_dir = 'minizip'
s.library = 'z'
end

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>13A476u</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>TestProject</string>
<key>CFBundleIdentifier</key>
<string>com.squaredtiki.TestProject</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>TestProject</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>5A11314m</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>13A476n</string>
<key>DTSDKName</key>
<string>macosx10.9</string>
<key>DTXcode</key>
<string>0500</string>
<key>DTXcodeBuild</key>
<string>5A11314m</string>
<key>LSMinimumSystemVersion</key>
<string>10.9</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2013 TestBench. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

Binary file not shown.

View File

@@ -0,0 +1 @@
APPL????

View File

@@ -0,0 +1,29 @@
{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
{\colortbl;\red255\green255\blue255;}
\paperw9840\paperh8400
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\b\fs24 \cf0 Engineering:
\b0 \
Some people\
\
\b Human Interface Design:
\b0 \
Some other people\
\
\b Testing:
\b0 \
Hopefully not nobody\
\
\b Documentation:
\b0 \
Whoever\
\
\b With special thanks to:
\b0 \
Mom\
}

View File

@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
AF313D09177B02A700478143 /* PermissionsTestApp.app in Resources */ = {isa = PBXBuildFile; fileRef = AF313D08177B02A700478143 /* PermissionsTestApp.app */; };
B215FB32143AD3C7003AC546 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B215FB31143AD3C7003AC546 /* SenTestingKit.framework */; };
B215FB63143AD514003AC546 /* SSZipArchiveTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B215FB61143AD514003AC546 /* SSZipArchiveTests.m */; };
B215FB65143AD527003AC546 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B215FB64143AD527003AC546 /* libz.dylib */; };
@@ -24,6 +25,7 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
AF313D08177B02A700478143 /* PermissionsTestApp.app */ = {isa = PBXFileReference; lastKnownFileType = wrapper.application; path = PermissionsTestApp.app; sourceTree = "<group>"; };
B215FB18143AD3C7003AC546 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
B215FB30143AD3C7003AC546 /* SSZipArchiveTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SSZipArchiveTests.octest; sourceTree = BUILT_PRODUCTS_DIR; };
B215FB31143AD3C7003AC546 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
@@ -120,6 +122,7 @@
B215FB5E143AD505003AC546 /* SSZipArchiveTests */ = {
isa = PBXGroup;
children = (
AF313D08177B02A700478143 /* PermissionsTestApp.app */,
B2283D5C155AD80F00F9395A /* Unicode.zip */,
B215FB61143AD514003AC546 /* SSZipArchiveTests.m */,
B215FB5F143AD514003AC546 /* SSZipArchiveTests-Info.plist */,
@@ -185,6 +188,7 @@
files = (
B215FB6D143AD6FF003AC546 /* TestArchive.zip in Resources */,
B23FCC7F1558F1B70026375C /* TestPasswordArchive.zip in Resources */,
AF313D09177B02A700478143 /* PermissionsTestApp.app in Resources */,
C5AE4E64155A12760045F3ED /* IncorrectHeaders.zip in Resources */,
C5AE4E6D155A8B010045F3ED /* SymbolicLink.zip in Resources */,
B2283D5D155AD80F00F9395A /* Unicode.zip in Resources */,

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B215FB2F143AD3C7003AC546"
BuildableName = "SSZipArchiveTests.octest"
BlueprintName = "SSZipArchiveTests"
ReferencedContainer = "container:SSZipArchive.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B215FB2F143AD3C7003AC546"
BuildableName = "SSZipArchiveTests.octest"
BlueprintName = "SSZipArchiveTests"
ReferencedContainer = "container:SSZipArchive.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -26,11 +26,15 @@
- (void)testZipping {
NSString *outputPath = [self _cachesPath:@"Zipped"];
// use extracted files from [-testUnzipping]
NSString *inputPath = [self _cachesPath:@"Regular"];
NSArray *inputPaths = [NSArray arrayWithObjects:
[outputPath stringByAppendingPathComponent:@"Readme.markdown"],
[outputPath stringByAppendingPathComponent:@"LICENSE"],
[inputPath stringByAppendingPathComponent:@"Readme.markdown"],
[inputPath stringByAppendingPathComponent:@"LICENSE"],
nil];
NSString *outputPath = [self _cachesPath:@"Zipped"];
NSString *archivePath = [outputPath stringByAppendingPathComponent:@"CreatedArchive.zip"];
[SSZipArchive createZipFileAtPath:archivePath withFilesAtPaths:inputPaths];
@@ -38,6 +42,17 @@
STAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:archivePath], @"Archive created");
}
- (void)testDirectoryZipping {
// use Unicode as folder (has a file in root and a file in subfolder)
NSString *inputPath = [self _cachesPath:@"Unicode"];
NSString *outputPath = [self _cachesPath:@"FolderZipped"];
NSString *archivePath = [outputPath stringByAppendingPathComponent:@"ArchiveWithFolders.zip"];
[SSZipArchive createZipFileAtPath:archivePath withContentsOfDirectory:inputPath];
STAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:archivePath], @"Folder Archive created");
}
- (void)testUnzipping {
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestArchive" ofType:@"zip"];
@@ -121,6 +136,66 @@
STAssertTrue(unicodeFolderWasExtracted, @"Folders with names in unicode should be extracted propertly.");
}
- (void)testZippingAndUnzippingForDate {
NSString *inputPath = [self _cachesPath:@"Regular"];
NSArray *inputPaths = [NSArray arrayWithObjects:
[inputPath stringByAppendingPathComponent:@"Readme.markdown"],
nil];
NSDictionary *originalFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[inputPath stringByAppendingPathComponent:@"Readme.markdown"] error:nil];
NSString *outputPath = [self _cachesPath:@"ZippedDate"];
NSString *archivePath = [outputPath stringByAppendingPathComponent:@"CreatedArchive.zip"];
[SSZipArchive createZipFileAtPath:archivePath withFilesAtPaths:inputPaths];
[SSZipArchive unzipFileAtPath:archivePath toDestination:outputPath delegate:self];
NSDictionary *createdFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[outputPath stringByAppendingPathComponent:@"Readme.markdown"] error:nil];
STAssertEquals(originalFileAttributes[NSFileCreationDate], createdFileAttributes[@"NSFileCreationDate"], @"Orginal file creationDate should match created one");
}
- (void)testZippingAndUnzippingForPermissions {
// File we're going to test permissions on before and after zipping
NSString *targetFile = @"/Contents/MacOS/TestProject";
/********** Zipping ********/
// The .app file we're going to zip up
NSString *inputFile = [[NSBundle mainBundle] pathForResource:@"PermissionsTestApp" ofType:@"app"];
// The path to the target file in the app before zipping
NSString *targetFilePreZipPath = [inputFile stringByAppendingPathComponent:targetFile];
// Atribtues for the target file before zipping
NSDictionary *preZipAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:targetFilePreZipPath error:nil];
// Directory to output our created zip file
NSString *outputDir = [self _cachesPath:@"PermissionsTest"];
// The path to where the archive shall be created
NSString *archivePath = [outputDir stringByAppendingPathComponent:@"TestAppArchive.zip"];
// Create the zip file using the contents of the .app file as the input
[SSZipArchive createZipFileAtPath:archivePath withContentsOfDirectory:inputFile];
/********** Un-zipping *******/
// Using this newly created zip file, unzip it
[SSZipArchive unzipFileAtPath:archivePath toDestination:outputDir];
// Get the path to the target file after unzipping
NSString *targetFilePath = [outputDir stringByAppendingPathComponent:@"/Contents/MacOS/TestProject"];
// Get the file attributes of the target file following the unzipping
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:targetFilePath error:nil];
// Compare the value of the permissions attribute to assert equality
STAssertEquals(fileAttributes[NSFilePosixPermissions], preZipAttributes[NSFilePosixPermissions], @"File permissions should be retained during compression and de-compression");
}
// Commented out to avoid checking in several gig file into the repository. Simply add a file named
// `LargeArchive.zip` to the project and uncomment out these lines to test.
//