142 Commits

Author SHA1 Message Date
Douglas Bumby
28be5a67ab Add new name to README 2015-06-13 16:02:19 -07:00
Douglas Bumby
7ccc986657 Merge pull request #154 from dimohamdy/master
Fix testCase and Apply modern Objc
2015-06-06 13:11:44 -07:00
Ahmed Hamdy
cfee6b5b89 Testing unzipping 5 bytes zipped file #87 bug
it’s work
2015-06-06 21:03:19 +03:00
Ahmed Hamdy
676da25532 fix files not found reference 2015-06-06 20:51:51 +03:00
Ahmed Hamdy
8d2b39b5ec Fix testCase and apply modern Objc 2015-06-06 20:43:47 +03:00
Douglas Bumby
af85bf97a9 Merge pull request #148 from caldofran/master
fixed podspec pointing to non-existing tag in the main repo
2015-04-23 11:24:49 -04:00
Ruben Mendez
b07d0c5d51 fixed podspec pointing to non-existing tag in the main repo 2015-04-23 13:02:56 +02:00
Douglas Bumby
aab8d383b3 Merge pull request #147 from caldofran/master
PodSpec update
2015-04-22 13:04:52 -04:00
Ruben Mendez
4c97093700 change to point to the right tag 2015-04-22 10:07:37 +02:00
Ruben Mendez
a1cc7c1654 pointint to tag 2015-04-22 10:04:40 +02:00
Ruben Mendez
7a6c677c17 pod pointint to master 2015-04-22 10:02:57 +02:00
Douglas Bumby
d607ba044b Merge pull request #146 from iosphere/fix-shadowed-variable
Avoid shadowing variable when extracting ZIP64 extra header fields
2015-04-14 16:34:39 -04:00
Lukas Mollidor
c39636b71b Avoid shadowing variable when extracting ZIP64 extra header fields 2015-04-14 18:39:50 +02:00
Douglas Bumby
705a69840f Merge pull request #145 from djbe/master
Add delegate method with extracted file path
2015-04-09 14:37:38 -04:00
David Jennes
a9ece3bef7 Add delegate method with extracted file path 2015-04-09 20:07:03 +02:00
Douglas Bumby
fc61e0358d Merge pull request #144 from padinger/master
Fix calendar deprecation warning on OSX 10.10
2015-04-08 16:42:31 -04:00
Patrick Dinger
9761f045b2 Fix calendar deprecation warning on OSX 10.10 2015-04-08 14:44:43 +02:00
Douglas Bumby
2a1eee19b4 Merge pull request #139 from soffes/aceisScope-master
Aceis scope master
2015-04-06 23:53:18 -04:00
Douglas Bumby
35b181504c Merging in #138 2015-04-06 23:52:50 -04:00
Douglas Bumby
8be53bee68 Fix 2015-04-06 23:51:08 -04:00
Douglas Bumby
cc714460f9 Fix for #52 2015-04-06 23:43:15 -04:00
Douglas Bumby
88c2ab7516 Fixing issue #98 2015-04-06 23:39:19 -04:00
Douglas Bumby
c9d93d23e3 Change SSZipArchive to Tests 2015-04-06 19:17:27 -04:00
Douglas Bumby
bddefcebfe Re-organise Xcode Project using Synx 2015-04-06 19:14:29 -04:00
Douglas Bumby
95d3d3544a missed a spot 2015-04-06 17:18:40 -04:00
Douglas Bumby
4e3625684d cleanup 2015-04-06 17:18:27 -04:00
Douglas Bumby
cc24921107 Copyright year + miscellaneous changes 2015-04-06 17:17:26 -04:00
Douglas Bumby
487093160b Merge pull request #137 from soffes/TheRealKerni-patch-1
The real kerni patch 1
2015-04-06 17:08:51 -04:00
Douglas Bumby
dbc332ce70 #92 2015-04-06 17:08:24 -04:00
Douglas Bumby
cedaa5250c Merge pull request #136 from soffes/basitali-master
Basitali master
2015-04-06 17:06:13 -04:00
Douglas Bumby
938749897d MERGE: Add writeFileAtPath:withFileName: in SSZipArchive.h so that it can be called. 2015-04-06 17:05:47 -04:00
Douglas Bumby
c881c8528f Merge pull request #121 from rileytestut/master
Added option to keep parent directory when compressing directory contents
2015-04-06 16:53:21 -04:00
Douglas Bumby
13e3ab93b4 Merge pull request #135 from DimonDeveloper/patch-2
Archive empty folder in other folder
2015-04-06 16:47:25 -04:00
DimonDeveloper
5492b7bcea Archive empty folder in other folder 2015-04-06 23:39:15 +03:00
Douglas Bumby
8b046fc30b Version changed 2015-04-06 15:55:52 -04:00
Douglas Bumby
ef396cbd52 Merge pull request #133 from soffes/955dreams-master
955dreams master
2015-04-06 15:51:28 -04:00
Douglas Bumby
4b4cce2666 Merging in some changes 2015-04-06 15:51:07 -04:00
Douglas Bumby
d8a7fd0e8c Update README.md 2015-04-06 15:44:13 -04:00
Douglas Bumby
0b476953df Make use of Objective-C .gitignore template 2015-04-06 15:25:08 -04:00
Douglas Bumby
056fe04808 Update and rename LICENSE to LICENSE.txt 2015-04-06 15:23:36 -04:00
Douglas Bumby
292d95e41a Merge pull request #58 from mickrobk/master
writeFileAtPath does not close file handle
2015-04-06 15:18:56 -04:00
Douglas Bumby
fede9541b4 Merge pull request #132 from soffes/Cpu86-master
Cpu86 master
2015-04-06 15:13:48 -04:00
Douglas Bumby
ae50a6d40a fix the merges 2015-04-06 15:13:07 -04:00
Douglas Bumby
a75d901a85 Merge pull request #112 from iosphere/fix-shadowed-variable
Fix warning on shadowed variable when creating zip file
2015-04-06 15:00:27 -04:00
Douglas Bumby
cb037e1010 Merge pull request #113 from iosphere/zipArchiveProgressEvent-type
Report file size as unsigned long long to delegate
2015-04-06 14:59:07 -04:00
Douglas Bumby
c119896966 Merge pull request #95 from vtourraine/patch-1
Fix implicit conversion warning
2015-04-06 14:57:25 -04:00
Douglas Bumby
bf55cb47b7 Merge pull request #108 from taberrr/patch-1
Update SSZipArchive.podspec
2015-04-06 14:10:42 -04:00
Douglas Bumby
801d1198b5 Merge pull request #122 from boherna/master
Adds progress and completion handlers. Support for adding folders and subfolders to ZIP packages.
2015-04-06 14:09:09 -04:00
Douglas Bumby
94a6637002 Merge pull request #114 from xhacker/patch-1
Update Readme.markdown
2015-04-06 13:48:38 -04:00
Douglas Bumby
b37ab60ba0 Merge pull request #131 from soffes/zlandau-cancelunzip
Zlandau cancelunzip
2015-04-06 13:44:27 -04:00
Douglas Bumby
a90b2a9611 Merge fixes 2015-04-06 13:42:48 -04:00
Douglas Bumby
7e44caef39 Merge pull request #130 from soffes/revert-129-master
Revert "Add support for archives in folders"
2015-04-06 13:35:51 -04:00
Douglas Bumby
0c9aaee02b Revert "Add support for archives in folders" 2015-04-06 13:35:21 -04:00
Douglas Bumby
bd02992224 Merge pull request #129 from Binauric/master
Add support for archives in folders
2015-04-06 13:22:46 -04:00
Lars Immisch
9426653711 Add support for archives in folders 2015-03-27 10:53:38 +01:00
Riley Testut
33c7884202 Added option to keep parent directory when compressing directory contents 2014-12-21 18:02:19 -06:00
David Robles
67403e8a28 Update pod spec. 2014-11-05 15:40:12 -08:00
David Robles
74ce9fc2c7 Update Pod spec. 2014-11-05 15:34:55 -08:00
Bohdan Hernandez
553c4be486 Merge remote-tracking branch 'upstream/master'
* upstream/master:
  Fixed GCC_WARN_64_TO_32_BIT_CONVERSION warning
  Fixed GCC_WARN_64_TO_32_BIT_CONVERSION warning

Conflicts:
	SSZipArchive/minizip/ioapi.c
2014-11-05 20:51:56 +00:00
Sam Soffes
9f93d0c1b7 Merge pull request #120 from nicked/master
Fixed GCC_WARN_64_TO_32_BIT_CONVERSION warnings
2014-10-31 08:23:04 -07:00
nicked
55437a8b8e Fixed GCC_WARN_64_TO_32_BIT_CONVERSION warning 2014-10-31 11:09:31 +01:00
nicked
d68c99b890 Fixed GCC_WARN_64_TO_32_BIT_CONVERSION warning 2014-10-31 11:08:04 +01:00
Bohdan Hernandez
e1bfb6e8ed Merge remote-tracking branch 'upstream/master'
* upstream/master:
  Change the CalendarUnit for iOS 8.0
2014-10-29 13:22:06 +00:00
Sam Soffes
874ebd8651 Merge pull request #119 from liufan321/master
Change CalendarUnits for iOS 8.0
2014-10-26 21:48:47 -07:00
Fan Liu
a8f065f2a1 Change the CalendarUnit for iOS 8.0 2014-10-26 03:50:58 +08:00
Bohdan Hernandez
b89dfcf4fd Merge branch 'master' of https://github.com/soffes/ssziparchive
# By Adam Yanalunas (2) and Landon Fuller (1)
# Via Adam Yanalunas
* 'master' of https://github.com/soffes/ssziparchive:
  Updated podspec for v0.3.2
  Relative symlink fixture for new symlink detection in #91
  Replace symlink heuristic with a well-defined test.
2014-09-22 00:45:08 +01:00
LIU Dongyuan / 柳东原
b688b9859a Update Readme.markdown
createZipFileAtPath:withFilesAtPaths: creates an invalid zip for directory
2014-09-20 13:21:42 -07:00
Lukas Mollidor
54875c8192 Report file size as unsigned long long to delegate 2014-09-12 19:11:46 +02:00
Lukas Mollidor
df0d5536e8 Fix warning on shadowed variable when creating zip file 2014-09-12 18:44:36 +02:00
Adam Yanalunas
60f577ab9a Updated podspec for v0.3.2 2014-09-08 11:39:44 -07:00
Adam Yanalunas
60312c173b Merge pull request #111 from soffes/test/relative_path_fixture
Relative symlink fixture for new symlink detection in #91
2014-09-08 11:26:13 -07:00
Adam Yanalunas
c363747a15 Merge pull request #91 from landonf/master
Fix symlink detection
2014-09-08 11:26:01 -07:00
Adam Yanalunas
e29efca7bf Relative symlink fixture for new symlink detection in #91 2014-09-05 13:19:30 -07:00
Taber Buhl
024241a3e0 Update SSZipArchive.podspec
trying alternative source_files syntax
2014-08-01 17:22:06 -04:00
Bohdan Hernandez
47c50d0482 Adds progress and completion handlers. 2014-07-29 18:54:28 +01:00
Zacharyl Landau
2385ac9241 Add a delegate for cancelling unzips
This adds a zipArchiveShouldUnzipFileAtIndex, which is called before
each call to zipArchiveWillUnzipFileAtIndex, allowing a delegate to
cancel the unzip progress.
2014-07-16 11:28:25 -07:00
Bohdan Hernandez
b91fe135e2 Removes some compile warnings. 2014-05-12 09:52:50 +01:00
Bohdan Hernandez
57b6018ca0 Merge branch 'master' of https://github.com/soffes/ssziparchive
# By Andreas Dangel (2) and others
# Via Erickson Pacioles (1) and Sam Soffes (1)
* 'master' of https://github.com/soffes/ssziparchive:
  Fixed warnings from Xcode Analyzer
  Fix warnings on 64-bit
  Add a unit test for zipArchiveProgressEvent.
  Add a progress event while unzipping. The progress is determined by the compressed file size and zip entries.
2014-04-28 10:46:50 +01:00
Sam Soffes
89b32b9328 Merge pull request #99 from mr-fahrenheit/master
Fixed warnings from Xcode Analyzer
2014-04-06 09:25:57 -04:00
Mr. Fahrenheit
1b2ec1a9ec Fixed warnings from Xcode Analyzer 2014-04-06 19:42:33 +08:00
Sam Soffes
b4c9bde3fb Fix warnings on 64-bit 2014-03-22 08:01:08 -07:00
Andreas Dangel
4fca963b62 Add a unit test for zipArchiveProgressEvent. 2014-03-22 03:56:37 +01:00
Andreas Dangel
281571d99f Add a progress event while unzipping.
The progress is determined by the compressed file size and zip entries.
2014-03-14 21:22:20 -04:00
Vincent Tourraine
47afe71fa2 Fix implicit conversion warning
```
SSZipArchive/minizip/ioapi.c:195:33: Implicit conversion loses integer precision: 'ZPOS64_T' (aka 'unsigned long long') to 'long'
```
2014-03-03 11:38:04 +01:00
Bohdan Hernandez
de0ffe7478 Support for adding folders and subfolders to ZIP packages. 2014-02-09 02:48:44 +00:00
Andreas Linde
e422866c97 Fix clang analyzer warning appearing in line 1534
Removing the clang analyzer silencer in these lines fixed another clang analyzer warning that appeared in line 1534.
In addition these lines do not cause a static analyzer warning in latest Xcode any longer.
Tested with Xcode 5.0.2
2014-01-17 12:47:36 +01:00
Landon Fuller
653caaa9b2 Replace symlink heuristic with a well-defined test.
As per the PKWARE ZIP File Format Specification (6.3.2), this
patch tests the file 'version made by' field for the UNIX (3)
constant, and then interprets the external file attributes accordingly,
assuming an st_mode field in the high 16 bits.
2014-01-16 11:53:45 -05:00
Sam Soffes
d3c40f0e95 Happy New Year 🎉 2014-01-01 11:00:26 -08:00
Sam Soffes
ebc0b248ef Merge pull request #86 from dennda/master
Issue #85: Keep relative symbolic links relative.
2013-11-08 11:52:25 -08:00
Christopher Denter
f89c159b2a Issue #85: Add test for relative symlink preservation patch.
This test adds a fixture RelativeSymlinks.zip with the following
structure:

    RelativeSymbolicLink
    ├── symlinkedFile
    ├── symlinkedFolder
    └── symlinks
       ├── fileSymlink -> ../symlinkedFile
       └── folderSymlink -> ../symlinkedFolder

The test checks if both `fileSymlink` and `folderSymlink` still point to
the respective files in the parent directory after the fixture has been
unzipped.
2013-11-08 20:34:17 +01:00
Christopher Denter
a5de5b6bef Issue #85: Keep relative symbolic links relative.
Before, the library resolved symbolic links that are relative
into absolute paths, using the current working directory of the process
that's doing the unzipping, which to me seems pretty wrong.
This was due to using -[NSURL fileURLWithPath:], which transforms
relative URLs to absolute URLs automatically.

I don't see much of a reason to use NSFileManager here, so I made that
use symlink() directly. Alternatively, one could also use -[NSURL
URLWithString:].

This keeps relative symlinks relative after unzipping.
2013-11-08 19:04:42 +01:00
Sam Soffes
bf95dc2fd4 Fix 2013-09-11 08:56:12 -07:00
Sam Soffes
c2b33b42d0 There we go 2013-09-11 08:43:46 -07:00
Sam Soffes
b91252282e Simplify project structure 2013-09-10 00:03:11 -07:00
Sam Soffes
1fefbc022f Add shares scheme 2013-09-09 23:50:07 -07:00
Sam Soffes
273fc1b36e Fix minizip path 2013-09-09 09:04:04 -07:00
Sam Soffes
164ae9bfd3 Move minizip up 2013-09-09 09:00:52 -07:00
Sam Soffes
6ca6e0c28f Version 0.3.0 2013-09-07 08:52:49 -07:00
Sam Soffes
07cfb62107 Update readme 2013-09-07 08:38:55 -07:00
Sam Soffes
364be2ed4f Restructure project and move to XCTest 2013-09-07 08:33:47 -07:00
Sam Soffes
524ca1abae Add missing fclose. Thanks @aceisScope! 2013-09-07 08:22:56 -07:00
David Robles
d30b543f34 forgot to end pod spec. 2013-08-20 11:52:03 -07:00
David Robles
ce6cbe1193 Update out of date pod spec. 2013-08-20 10:57:34 -07:00
aceisScope
4cd142a39c fix bug of "fclose"; add test for zipping a large amount of files in sequence 2013-08-05 12:42:47 +08:00
Sam Soffes
c81002605b Version 0.2.5 2013-07-16 10:20:46 -04:00
Sam Soffes
5227bb251b Merge pull request #68 from marcelofabri/master
Fixing compilation error (missing ";")
2013-07-12 15:34:05 -07:00
Marcelo Fabri
3bb7fe8d26 Adding missing ";".
Fixes syntax error.
2013-07-12 19:31:18 -03:00
Sam Soffes
21c3694d0c Merge pull request #67 from ChristopherRogers/master
NSCalendar caching
2013-07-12 08:27:07 -07:00
Rogers, Christopher
84c8171151 Caching Gregorian NSCalendar for performance.
This was taking about 30% of the time unzipping on an iPhone 5.
2013-07-12 17:28:18 +09:00
Sam Soffes
f9136dd744 Merge pull request #65 from nibroc/master
Added check to ensure permissions are not explicitly set if they do not exist in the zip
2013-07-10 17:50:20 -07:00
Sam Soffes
d7ac059a8a Version 0.2.4 2013-07-03 08:58:01 -07:00
Corbin Hughes
adfc3cae92 Added a check to make sure 0 permissions are not set 2013-07-01 04:55:42 -05: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
Rob Mickle
45b93c037d close loose file handle in writeFileAtPath 2013-06-24 15:39:17 -06: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
Basit Ali
362b011990 Add writeFileAtPath:withFileName: in SSZipArchive.h so that it can be called. 2013-04-15 17:29:01 +05:00
Cpu86
92f1142056 Folder and subfolder zip functionality
Added functionality to zip folder and maintains subfolder tree
2013-03-30 19:50:50 +01: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
Sam Soffes
a311e60107 Version 0.2.3
* Update podspec
* Fix remote
* Bump year
* Release changes since last release
2013-01-29 01:54:19 -05:00
Sam Soffes
69fb8f4a4c Merge pull request #34 from cvisprogrammer/master
added fclose to writeFile
2013-01-18 08:14:24 -08:00
Farooq Ahmad
1d163e4db5 Added fclose to writeFile
need fclose to avoid running out of file handles
2012-11-28 09:16:10 -08:00
David Robles
a53f908392 Update pod spec to prevent *.podspec file from being included as a source file when the pod is installed. 2012-08-16 15:04:59 -07:00
Chris Stevenson
3e2424437f Bump the pod version number 2012-08-01 15:06:50 -07:00
Chris Stevenson
713835cc28 Add a delegate method that will report the file names of files that were unzipped 2012-08-01 15:03:29 -07:00
54 changed files with 2078 additions and 644 deletions

20
.gitignore vendored
View File

@@ -1,6 +1,20 @@
.DS_Store
*.mode1v3
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
*.xcworkspace
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
*.DS_Store
.DS_Store

View File

@@ -1,36 +0,0 @@
# SSZipArchive Changelog
### Version 0.2.1
[Released May 9, 2012](https://github.com/samsoffes/sskeychain/tree/0.2.1)
* Support for symbolic links — [@jparishy](http://github.com/jparishy)
* Fix several warnings
### Version 0.2.0
[Released May 7, 2012](https://github.com/samsoffes/sskeychain/tree/0.2.0)
* Add unzipping delegate — [@uppfinnarn](http://github.com/uppfinnarn)
* Fix unzipping with passwords
* Fix modified at dates — [@brantsears](http://github.com/brantsears)
* Fix truncated files. Ignore the zip headers and unzip until there is no more file. — [@jparishy](http://github.com/jparishy)
### Version 0.1.2
[Released December 26, 2011](https://github.com/samsoffes/sskeychain/tree/0.1.2)
* Add creation support. Thanks Johnnie Walker ([@randomsequence](https://github.com/randomsequence))!
### Version 0.1.1
[Released October 31, 2011](https://github.com/samsoffes/sskeychain/tree/0.1.1)
* Added basic tests
* Upgraded minizip to 1.1 to support zip64
### Version 0.1.0
[Released September 18, 2011](https://github.com/samsoffes/sskeychain/tree/0.1.0)
* Initial release

View File

@@ -1,4 +1,4 @@
Copyright (c) 2010-2012 Sam Soffes
Copyright (c) 2010-2015, Sam Soffes, http://soff.es
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

45
README.md Normal file
View File

@@ -0,0 +1,45 @@
#ZipArchive
ZipArchive is a simple utility class for zipping and unzipping files.
You can do the following:
- Unzip zip files
- Unzip password protected zip files
- Create new zip files
- Append to existing zip files
- Zip files
- Zip-up `NSData` instances (with a filename)
##How to add ZipArchive to your project
1. Add the `SSZipArchive` and `minizip` folders to your project.
2. Add the `libz` library to your target
ZipArchive requires ARC.
###Usage
```objective-c
// Unzipping
NSString *zipPath = @"path_to_your_zip_file";
NSString *destinationPath = @"path_to_the_folder_where_you_want_it_unzipped";
[SSZipArchive unzipFileAtPath:zipPath toDestination:destinationPath];
// Zipping
NSString *zippedPath = @"path_where_you_want_the_file_created";
NSArray *inputPaths = [NSArray arrayWithObjects:
[[NSBundle mainBundle] pathForResource:@"photo1" ofType:@"jpg"],
[[NSBundle mainBundle] pathForResource:@"photo2" ofType:@"jpg"]
nil];
[SSZipArchive createZipFileAtPath:zippedPath withFilesAtPaths:inputPaths];
// Zipping directory
[SSZipArchive createZipFileAtPath:zippedPath withContentsOfDirectory:inputPath];
```
###Licensing
ZipArchive is protected under the [MIT license](https://github.com/ZipArchive/ZipArchive/raw/master/LICENSE) and our slightly modified version of [Minizip](http://www.winimage.com/zLibDll/minizip.html) 1.1 is licensed under the [Zlib license](http://www.zlib.net/zlib_license.html).
## Acknowledgments
Big thanks to [Aish](http://code.google.com/p/ziparchive) for creating [ZipArchive](http://code.google.com/p/ziparchive). The project that inspired ZipArchive. Thank you [@randomsequence](https://github.com/randomsequence) for implementing the creation support tech and to [@johnezang](https://github.com/johnezang) for all his amazing help along the way.

View File

@@ -1,43 +0,0 @@
# SSZipArchive
SSZipArchive is a simple utility class for zipping and unzipping files. Features:
* Unzipping zip files
* Unzipping password protected zip files
* Creating zip files
* Appending to zip files
* Zipping files
* Zipping NSData with a filename
* Works in ARC and non-ARC projects
## Adding to your project
1. Add `SSZipArchive.h`, `SSZipArchive.m`, and `minizip` to your project.
2. Add the `libz` library to your target
You don't need to do anything regarding ARC. SSZipArchive will detect if you're not using ARC and add the required memory management code.
## Usage
``` objective-c
// Unzipping
NSString *zipPath = @"path_to_your_zip_file";
NSString *destinationPath = @"path_to_the_folder_where_you_want_it_unzipped";
[SSZipArchive unzipFileAtPath:zipPath toDestination:destinationPath];
// Zipping
NSString *zippedPath = @"path_where_you_want_the_file_created";
NSArray *inputPaths = [NSArray arrayWithObjects:
[[NSBundle mainBundle] pathForResource:@"photo1" ofType:@"jpg"],
[[NSBundle mainBundle] pathForResource:@"photo2" ofType:@"jpg"]
nil];
[SSZipArchive createZipFileAtPath:zippedPath withFilesAtPaths:inputPaths];
```
## 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).
## Thanks
Thanks [aish](http://code.google.com/p/ziparchive) for creating [ZipArchive](http://code.google.com/p/ziparchive) which SSZipArchive is based on, Johnnie Walker ([@randomsequence](https://github.com/randomsequence)) for implementing creation support, and John Engelhart ([@johnezang](https://github.com/johnezang)) for all his amazing help along the way.

View File

@@ -1,45 +0,0 @@
//
// SSZipArchive.h
// SSZipArchive
//
// Created by Sam Soffes on 7/21/10.
// Copyright (c) Sam Soffes 2010-2011. All rights reserved.
//
#import <Foundation/Foundation.h>
#include "minizip/unzip.h"
@protocol SSZipArchiveDelegate;
@interface SSZipArchive : NSObject
// Unzip
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination;
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error;
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination delegate:(id<SSZipArchiveDelegate>)delegate;
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error delegate:(id<SSZipArchiveDelegate>)delegate;
// Zip
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)filenames;
- (id)initWithPath:(NSString *)path;
- (BOOL)open;
- (BOOL)writeFile:(NSString *)path;
- (BOOL)writeData:(NSData *)data filename:(NSString *)filename;
- (BOOL)close;
@end
@protocol SSZipArchiveDelegate <NSObject>
@optional
- (void)zipArchiveWillUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo;
- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath;
- (void)zipArchiveWillUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;
- (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;
@end

View File

@@ -1,421 +0,0 @@
//
// SSZipArchive.m
// SSZipArchive
//
// Created by Sam Soffes on 7/21/10.
// Copyright (c) Sam Soffes 2010-2011. All rights reserved.
//
#import "SSZipArchive.h"
#include "minizip/zip.h"
#import "zlib.h"
#import "zconf.h"
#include <sys/stat.h>
#define CHUNK 16384
@interface SSZipArchive ()
+ (NSDate *)_dateWithMSDOSFormat:(UInt32)msdosDateTime;
@end
@implementation SSZipArchive {
NSString *_path;
NSString *_filename;
zipFile _zip;
}
#pragma mark - Unzipping
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination {
return [self unzipFileAtPath:path toDestination:destination delegate:nil];
}
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error {
return [self unzipFileAtPath:path toDestination:destination overwrite:overwrite password:password error:error delegate:nil];
}
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination delegate:(id<SSZipArchiveDelegate>)delegate {
return [self unzipFileAtPath:path toDestination:destination overwrite:YES password:nil error:nil delegate:delegate];
}
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error delegate:(id<SSZipArchiveDelegate>)delegate {
// Begin opening
zipFile zip = unzOpen((const char*)[path UTF8String]);
if (zip == NULL) {
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"failed to open zip file" forKey:NSLocalizedDescriptionKey];
if (error) {
*error = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:-1 userInfo:userInfo];
}
return NO;
}
unz_global_info globalInfo = {0ul, 0ul};
unzGetGlobalInfo(zip, &globalInfo);
// Begin unzipping
if (unzGoToFirstFile(zip) != UNZ_OK) {
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"failed to open first file in zip file" forKey:NSLocalizedDescriptionKey];
if (error) {
*error = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:-2 userInfo:userInfo];
}
return NO;
}
BOOL success = YES;
int ret = 0;
unsigned char buffer[4096] = {0};
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableSet *directoriesModificationDates = [[NSMutableSet alloc] init];
// Message delegate
if ([delegate respondsToSelector:@selector(zipArchiveWillUnzipArchiveAtPath:zipInfo:)]) {
[delegate zipArchiveWillUnzipArchiveAtPath:path zipInfo:globalInfo];
}
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];
if (attr) {
if ([fileManager setAttributes:attr ofItemAtPath:fullPath error:nil] == NO) {
// Can't set attributes
NSLog(@"[SSZipArchive] Failed to set attributes");
}
}
}
}
}
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++;
} while(ret == UNZ_OK && UNZ_OK != UNZ_END_OF_LIST_OF_FILE);
// Close
unzClose(zip);
// The process of decompressing the .zip archive causes the modification times on the folders
// to be set to the present time. So, when we are done, they need to be explicitly set.
// set the modification date on all of the directories.
NSError * err = nil;
for (NSDictionary * d in directoriesModificationDates) {
if (![[NSFileManager defaultManager] setAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[d objectForKey:@"modDate"], NSFileModificationDate, nil] ofItemAtPath:[d objectForKey:@"path"] error:&err]) {
NSLog(@"[SSZipArchive] Set attributes failed for directory: %@.", [d objectForKey:@"path"]);
}
if (err) {
NSLog(@"[SSZipArchive] Error setting directory file modification date attribute: %@",err.localizedDescription);
}
}
#if !__has_feature(objc_arc)
[directoriesModificationDates release];
#endif
// Message delegate
if (success && [delegate respondsToSelector:@selector(zipArchiveDidUnzipArchiveAtPath:zipInfo:unzippedPath:)]) {
[delegate zipArchiveDidUnzipArchiveAtPath:path zipInfo:globalInfo unzippedPath:destination];
}
return success;
}
#pragma mark - Zipping
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)paths {
BOOL success = NO;
SSZipArchive *zipArchive = [[SSZipArchive alloc] initWithPath:path];
if ([zipArchive open]) {
for (NSString *path in paths) {
[zipArchive writeFile:path];
}
success = [zipArchive close];
}
#if !__has_feature(objc_arc)
[zipArchive release];
#endif
return success;
}
- (id)initWithPath:(NSString *)path {
if ((self = [super init])) {
_path = [path copy];
}
return self;
}
#if !__has_feature(objc_arc)
- (void)dealloc {
[_path release];
[super dealloc];
}
#endif
- (BOOL)open {
NSAssert((_zip == NULL), @"Attempting open an archive which is already open");
_zip = zipOpen([_path UTF8String], APPEND_STATUS_CREATE);
return (NULL != _zip);
}
- (void)zipInfo:(zip_fileinfo*)zipInfo setDate:(NSDate*)date {
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
uint flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *components = [currentCalendar components:flags fromDate:date];
zipInfo->tmz_date.tm_sec = (unsigned int)components.second;
zipInfo->tmz_date.tm_min = (unsigned int)components.minute;
zipInfo->tmz_date.tm_hour = (unsigned int)components.hour;
zipInfo->tmz_date.tm_mday = (unsigned int)components.day;
zipInfo->tmz_date.tm_mon = (unsigned int)components.month - 1;
zipInfo->tmz_date.tm_year = (unsigned int)components.year;
}
- (BOOL)writeFile:(NSString *)path {
NSAssert((_zip != NULL), @"Attempting to write to an archive which was never opened");
FILE *input = fopen([path UTF8String], "r");
if (NULL == input) {
return NO;
}
zipOpenNewFileInZip(_zip, [[path lastPathComponent] UTF8String], NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED,
Z_DEFAULT_COMPRESSION);
void *buffer = malloc(CHUNK);
unsigned int len = 0;
while (!feof(input)) {
len = (unsigned int) fread(buffer, 1, CHUNK, input);
zipWriteInFileInZip(_zip, buffer, len);
}
zipCloseFileInZip(_zip);
free(buffer);
return YES;
}
- (BOOL)writeData:(NSData *)data filename:(NSString *)filename {
if (!_zip) {
return NO;
}
if (!data) {
return NO;
}
zip_fileinfo zipInfo = {{0,0,0,0,0,0},0,0,0};
[self zipInfo:&zipInfo setDate:[NSDate date]];
zipOpenNewFileInZip(_zip, [filename UTF8String], &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
zipWriteInFileInZip(_zip, data.bytes, (unsigned int)data.length);
zipCloseFileInZip(_zip);
return YES;
}
- (BOOL)close {
NSAssert((_zip != NULL), @"[SSZipArchive] Attempting to close an archive which was never opened");
zipClose(_zip, NULL);
return YES;
}
#pragma mark - Private
// Format from http://newsgroups.derkeiler.com/Archive/Comp/comp.os.msdos.programmer/2009-04/msg00060.html
// Two consecutive words, or a longword, YYYYYYYMMMMDDDDD hhhhhmmmmmmsssss
// YYYYYYY is years from 1980 = 0
// sssss is (seconds/2).
//
// 3658 = 0011 0110 0101 1000 = 0011011 0010 11000 = 27 2 24 = 2007-02-24
// 7423 = 0111 0100 0010 0011 - 01110 100001 00011 = 14 33 2 = 14:33:06
+ (NSDate *)_dateWithMSDOSFormat:(UInt32)msdosDateTime {
static const UInt32 kYearMask = 0xFE000000;
static const UInt32 kMonthMask = 0x1E00000;
static const UInt32 kDayMask = 0x1F0000;
static const UInt32 kHourMask = 0xF800;
static const UInt32 kMinuteMask = 0x7E0;
static const UInt32 kSecondMask = 0x1F;
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
NSAssert(0xFFFFFFFF == (kYearMask | kMonthMask | kDayMask | kHourMask | kMinuteMask | kSecondMask), @"[SSZipArchive] MSDOS date masks don't add up");
[components setYear:1980 + ((msdosDateTime & kYearMask) >> 25)];
[components setMonth:(msdosDateTime & kMonthMask) >> 21];
[components setDay:(msdosDateTime & kDayMask) >> 16];
[components setHour:(msdosDateTime & kHourMask) >> 11];
[components setMinute:(msdosDateTime & kMinuteMask) >> 5];
[components setSecond:(msdosDateTime & kSecondMask) * 2];
NSDate *date = [NSDate dateWithTimeInterval:0 sinceDate:[gregorian dateFromComponents:components]];
#if !__has_feature(objc_arc)
[gregorian release];
[components release];
#endif
return date;
}
@end

View File

@@ -1,18 +1,15 @@
Pod::Spec.new do |s|
s.name = 'SSZipArchive'
s.version = '0.2.2'
s.summary = 'Utility class for zipping and unzipping files on iOS and Mac.'
s.homepage = 'https://github.com/samsoffes/ssziparchive'
s.author = { 'Sam Soffes' => 'sam@samsoff.es' }
s.source = { :git => 'https://github.com/samsoffes/ssziparchive.git', :tag => '0.2.2' }
s.description = 'SSZipArchive is a simple utility class for zipping and unzipping files on iOS and Mac.'
s.source_files = 'SSZipArchive.*', 'minizip/*.{h,c}'
s.library = 'z'
s.preserve_paths = ['Tests', '.gitignore']
s.license = { :type => 'MIT', :file => 'LICENSE' }
# Maintain the dir structure for headers
def s.copy_header_mapping(from)
from
end
s.name = 'SSZipArchive'
s.version = '0.3.2'
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.txt' }
s.author = { 'Sam Soffes' => 'sam@soff.es' }
s.source = { :git => 'https://github.com/soffes/ssziparchive.git', :tag => "v#{s.version}" }
s.ios.deployment_target = '4.0'
s.osx.deployment_target = '10.6'
s.source_files = 'SSZipArchive/*', 'SSZipArchive/minizip/*'
s.library = 'z'
s.requires_arc = true
end

View File

@@ -0,0 +1,569 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
011F4B96182D71B700DE704F /* RelativeSymbolicLink.zip in Resources */ = {isa = PBXBuildFile; fileRef = 011F4B95182D71B700DE704F /* RelativeSymbolicLink.zip */; };
011F4B97182D72B400DE704F /* RelativeSymbolicLink.zip in Resources */ = {isa = PBXBuildFile; fileRef = 011F4B95182D71B700DE704F /* RelativeSymbolicLink.zip */; };
210D525417DEFB880060D41A /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 210D524C17DEFB880060D41A /* ioapi.c */; };
210D525517DEFB880060D41A /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 210D524C17DEFB880060D41A /* ioapi.c */; };
210D525617DEFB880060D41A /* mztools.c in Sources */ = {isa = PBXBuildFile; fileRef = 210D524E17DEFB880060D41A /* mztools.c */; };
210D525717DEFB880060D41A /* mztools.c in Sources */ = {isa = PBXBuildFile; fileRef = 210D524E17DEFB880060D41A /* mztools.c */; };
210D525817DEFB880060D41A /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 210D525017DEFB880060D41A /* unzip.c */; };
210D525917DEFB880060D41A /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 210D525017DEFB880060D41A /* unzip.c */; };
210D525A17DEFB880060D41A /* zip.c in Sources */ = {isa = PBXBuildFile; fileRef = 210D525217DEFB880060D41A /* zip.c */; };
210D525B17DEFB880060D41A /* zip.c in Sources */ = {isa = PBXBuildFile; fileRef = 210D525217DEFB880060D41A /* zip.c */; };
21CC41A917DB7D1300201DDC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21CC41A817DB7D1300201DDC /* Foundation.framework */; };
21CC41AB17DB7D1300201DDC /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21CC41AA17DB7D1300201DDC /* CoreGraphics.framework */; };
21CC41AD17DB7D1300201DDC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21CC41AC17DB7D1300201DDC /* UIKit.framework */; };
21CC41C217DB7D1300201DDC /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21CC41C117DB7D1300201DDC /* XCTest.framework */; };
21CC41C317DB7D1300201DDC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21CC41A817DB7D1300201DDC /* Foundation.framework */; };
21CC41C417DB7D1300201DDC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21CC41AC17DB7D1300201DDC /* UIKit.framework */; };
21CC41EC17DB7D2F00201DDC /* SSZipArchive.m in Sources */ = {isa = PBXBuildFile; fileRef = 21CC41E317DB7D2F00201DDC /* SSZipArchive.m */; };
21CC41ED17DB7D2F00201DDC /* SSZipArchive.m in Sources */ = {isa = PBXBuildFile; fileRef = 21CC41E317DB7D2F00201DDC /* SSZipArchive.m */; };
21CC41F817DB7D3500201DDC /* IncorrectHeaders.zip in Resources */ = {isa = PBXBuildFile; fileRef = 21CC41F017DB7D3500201DDC /* IncorrectHeaders.zip */; };
21CC41F917DB7D3500201DDC /* PermissionsTestApp.app in Resources */ = {isa = PBXBuildFile; fileRef = 21CC41F117DB7D3500201DDC /* PermissionsTestApp.app */; };
21CC41FA17DB7D3500201DDC /* SymbolicLink.zip in Resources */ = {isa = PBXBuildFile; fileRef = 21CC41F217DB7D3500201DDC /* SymbolicLink.zip */; };
21CC41FB17DB7D3500201DDC /* TestArchive.zip in Resources */ = {isa = PBXBuildFile; fileRef = 21CC41F317DB7D3500201DDC /* TestArchive.zip */; };
21CC41FC17DB7D3500201DDC /* TestPasswordArchive.zip in Resources */ = {isa = PBXBuildFile; fileRef = 21CC41F417DB7D3500201DDC /* TestPasswordArchive.zip */; };
21CC41FD17DB7D3500201DDC /* Unicode.zip in Resources */ = {isa = PBXBuildFile; fileRef = 21CC41F517DB7D3500201DDC /* Unicode.zip */; };
21CC41FF17DB7D3500201DDC /* SSZipArchiveTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 21CC41F717DB7D3500201DDC /* SSZipArchiveTests.m */; };
21CC421017DB7D7400201DDC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 21CC420517DB7D6300201DDC /* main.m */; };
21CC421117DB7D7900201DDC /* SSAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 21CC420317DB7D6300201DDC /* SSAppDelegate.m */; };
21CC421317DB7E0500201DDC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 21CC421217DB7E0500201DDC /* libz.dylib */; };
21CC421417DB7E0900201DDC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 21CC421217DB7E0500201DDC /* libz.dylib */; };
3D18E4BC1B2367A300627171 /* CollectingDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D18E4BB1B2367A300627171 /* CollectingDelegate.m */; };
3D18E4C51B236A7500627171 /* 0.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 3D18E4BD1B236A7500627171 /* 0.m4a */; };
3D18E4C61B236A7500627171 /* 1.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 3D18E4BE1B236A7500627171 /* 1.m4a */; };
3D18E4C71B236A7500627171 /* 2.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 3D18E4BF1B236A7500627171 /* 2.m4a */; };
3D18E4C81B236A7500627171 /* 3.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 3D18E4C01B236A7500627171 /* 3.m4a */; };
3D18E4C91B236A7500627171 /* 4.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 3D18E4C11B236A7500627171 /* 4.m4a */; };
3D18E4CA1B236A7500627171 /* 5.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 3D18E4C21B236A7500627171 /* 5.m4a */; };
3D18E4CB1B236A7500627171 /* 6.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 3D18E4C31B236A7500627171 /* 6.m4a */; };
3D18E4CC1B236A7500627171 /* 7.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 3D18E4C41B236A7500627171 /* 7.m4a */; };
3D18E4CE1B236C2A00627171 /* hello.zip in Resources */ = {isa = PBXBuildFile; fileRef = 3D18E4CD1B236C2A00627171 /* hello.zip */; };
A5CD0D3A1AD3490700E7F209 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A5CD0D391AD3490700E7F209 /* Default-568h@2x.png */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
21CC41C517DB7D1300201DDC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 21CC419D17DB7D1300201DDC /* Project object */;
proxyType = 1;
remoteGlobalIDString = 21CC41A417DB7D1300201DDC;
remoteInfo = SSZipArchive;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
011F4B95182D71B700DE704F /* RelativeSymbolicLink.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = RelativeSymbolicLink.zip; sourceTree = "<group>"; };
210D524B17DEFB880060D41A /* crypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = crypt.h; sourceTree = "<group>"; };
210D524C17DEFB880060D41A /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioapi.c; sourceTree = "<group>"; };
210D524D17DEFB880060D41A /* ioapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ioapi.h; sourceTree = "<group>"; };
210D524E17DEFB880060D41A /* mztools.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mztools.c; sourceTree = "<group>"; };
210D524F17DEFB880060D41A /* mztools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mztools.h; sourceTree = "<group>"; };
210D525017DEFB880060D41A /* unzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unzip.c; sourceTree = "<group>"; };
210D525117DEFB880060D41A /* unzip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unzip.h; sourceTree = "<group>"; };
210D525217DEFB880060D41A /* zip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zip.c; sourceTree = "<group>"; };
210D525317DEFB880060D41A /* zip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zip.h; sourceTree = "<group>"; };
21CC41A517DB7D1300201DDC /* SSZipArchive.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SSZipArchive.app; sourceTree = BUILT_PRODUCTS_DIR; };
21CC41A817DB7D1300201DDC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
21CC41AA17DB7D1300201DDC /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
21CC41AC17DB7D1300201DDC /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
21CC41C017DB7D1300201DDC /* SSZipArchiveTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SSZipArchiveTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
21CC41C117DB7D1300201DDC /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
21CC41E217DB7D2F00201DDC /* SSZipArchive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSZipArchive.h; sourceTree = "<group>"; };
21CC41E317DB7D2F00201DDC /* SSZipArchive.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSZipArchive.m; sourceTree = "<group>"; };
21CC41F017DB7D3500201DDC /* IncorrectHeaders.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = IncorrectHeaders.zip; sourceTree = "<group>"; };
21CC41F117DB7D3500201DDC /* PermissionsTestApp.app */ = {isa = PBXFileReference; lastKnownFileType = wrapper.application; path = PermissionsTestApp.app; sourceTree = "<group>"; };
21CC41F217DB7D3500201DDC /* SymbolicLink.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = SymbolicLink.zip; sourceTree = "<group>"; };
21CC41F317DB7D3500201DDC /* TestArchive.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = TestArchive.zip; sourceTree = "<group>"; };
21CC41F417DB7D3500201DDC /* TestPasswordArchive.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = TestPasswordArchive.zip; sourceTree = "<group>"; };
21CC41F517DB7D3500201DDC /* Unicode.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = Unicode.zip; sourceTree = "<group>"; };
21CC41F617DB7D3500201DDC /* SSZipArchiveTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SSZipArchiveTests-Info.plist"; sourceTree = "<group>"; };
21CC41F717DB7D3500201DDC /* SSZipArchiveTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSZipArchiveTests.m; sourceTree = "<group>"; };
21CC420217DB7D6300201DDC /* SSAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSAppDelegate.h; sourceTree = "<group>"; };
21CC420317DB7D6300201DDC /* SSAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSAppDelegate.m; sourceTree = "<group>"; };
21CC420517DB7D6300201DDC /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
21CC420617DB7D6300201DDC /* SSZipArchive-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SSZipArchive-Prefix.pch"; sourceTree = "<group>"; };
21CC420917DB7D6300201DDC /* SSZipArchive-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SSZipArchive-Info.plist"; sourceTree = "<group>"; };
21CC421217DB7E0500201DDC /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
3D18E4BA1B2367A300627171 /* CollectingDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectingDelegate.h; sourceTree = "<group>"; };
3D18E4BB1B2367A300627171 /* CollectingDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CollectingDelegate.m; sourceTree = "<group>"; };
3D18E4BD1B236A7500627171 /* 0.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; name = 0.m4a; path = Tests/Multi_Zip_Test/0.m4a; sourceTree = SOURCE_ROOT; };
3D18E4BE1B236A7500627171 /* 1.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; name = 1.m4a; path = Tests/Multi_Zip_Test/1.m4a; sourceTree = SOURCE_ROOT; };
3D18E4BF1B236A7500627171 /* 2.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; name = 2.m4a; path = Tests/Multi_Zip_Test/2.m4a; sourceTree = SOURCE_ROOT; };
3D18E4C01B236A7500627171 /* 3.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; name = 3.m4a; path = Tests/Multi_Zip_Test/3.m4a; sourceTree = SOURCE_ROOT; };
3D18E4C11B236A7500627171 /* 4.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; name = 4.m4a; path = Tests/Multi_Zip_Test/4.m4a; sourceTree = SOURCE_ROOT; };
3D18E4C21B236A7500627171 /* 5.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; name = 5.m4a; path = Tests/Multi_Zip_Test/5.m4a; sourceTree = SOURCE_ROOT; };
3D18E4C31B236A7500627171 /* 6.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; name = 6.m4a; path = Tests/Multi_Zip_Test/6.m4a; sourceTree = SOURCE_ROOT; };
3D18E4C41B236A7500627171 /* 7.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; name = 7.m4a; path = Tests/Multi_Zip_Test/7.m4a; sourceTree = SOURCE_ROOT; };
3D18E4CD1B236C2A00627171 /* hello.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = hello.zip; sourceTree = "<group>"; };
A5CD0D391AD3490700E7F209 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
21CC41A217DB7D1300201DDC /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
21CC421317DB7E0500201DDC /* libz.dylib in Frameworks */,
21CC41AB17DB7D1300201DDC /* CoreGraphics.framework in Frameworks */,
21CC41AD17DB7D1300201DDC /* UIKit.framework in Frameworks */,
21CC41A917DB7D1300201DDC /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
21CC41BD17DB7D1300201DDC /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
21CC421417DB7E0900201DDC /* libz.dylib in Frameworks */,
21CC41C217DB7D1300201DDC /* XCTest.framework in Frameworks */,
21CC41C417DB7D1300201DDC /* UIKit.framework in Frameworks */,
21CC41C317DB7D1300201DDC /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
210D524A17DEFB880060D41A /* minizip */ = {
isa = PBXGroup;
children = (
210D524B17DEFB880060D41A /* crypt.h */,
210D524C17DEFB880060D41A /* ioapi.c */,
210D524D17DEFB880060D41A /* ioapi.h */,
210D524E17DEFB880060D41A /* mztools.c */,
210D524F17DEFB880060D41A /* mztools.h */,
210D525017DEFB880060D41A /* unzip.c */,
210D525117DEFB880060D41A /* unzip.h */,
210D525217DEFB880060D41A /* zip.c */,
210D525317DEFB880060D41A /* zip.h */,
);
path = minizip;
sourceTree = "<group>";
};
21CC419C17DB7D1300201DDC = {
isa = PBXGroup;
children = (
21CC41D717DB7D2F00201DDC /* SSZipArchive */,
21CC41EE17DB7D3500201DDC /* Tests */,
21CC420017DB7D6300201DDC /* Sample Application */,
21CC41A717DB7D1300201DDC /* Frameworks */,
21CC41A617DB7D1300201DDC /* Products */,
);
sourceTree = "<group>";
};
21CC41A617DB7D1300201DDC /* Products */ = {
isa = PBXGroup;
children = (
21CC41A517DB7D1300201DDC /* SSZipArchive.app */,
21CC41C017DB7D1300201DDC /* SSZipArchiveTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
21CC41A717DB7D1300201DDC /* Frameworks */ = {
isa = PBXGroup;
children = (
21CC421217DB7E0500201DDC /* libz.dylib */,
21CC41A817DB7D1300201DDC /* Foundation.framework */,
21CC41AA17DB7D1300201DDC /* CoreGraphics.framework */,
21CC41AC17DB7D1300201DDC /* UIKit.framework */,
21CC41C117DB7D1300201DDC /* XCTest.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
21CC41D717DB7D2F00201DDC /* SSZipArchive */ = {
isa = PBXGroup;
children = (
21CC41E217DB7D2F00201DDC /* SSZipArchive.h */,
21CC41E317DB7D2F00201DDC /* SSZipArchive.m */,
210D524A17DEFB880060D41A /* minizip */,
);
path = SSZipArchive;
sourceTree = "<group>";
};
21CC41EE17DB7D3500201DDC /* Tests */ = {
isa = PBXGroup;
children = (
3D18E4BA1B2367A300627171 /* CollectingDelegate.h */,
3D18E4BB1B2367A300627171 /* CollectingDelegate.m */,
3D18E4A91B23679000627171 /* Multi_Zip_Test */,
21CC41EF17DB7D3500201DDC /* Fixtures */,
21CC41F617DB7D3500201DDC /* SSZipArchiveTests-Info.plist */,
21CC41F717DB7D3500201DDC /* SSZipArchiveTests.m */,
);
path = Tests;
sourceTree = "<group>";
};
21CC41EF17DB7D3500201DDC /* Fixtures */ = {
isa = PBXGroup;
children = (
3D18E4CD1B236C2A00627171 /* hello.zip */,
011F4B95182D71B700DE704F /* RelativeSymbolicLink.zip */,
21CC41F017DB7D3500201DDC /* IncorrectHeaders.zip */,
21CC41F117DB7D3500201DDC /* PermissionsTestApp.app */,
21CC41F217DB7D3500201DDC /* SymbolicLink.zip */,
21CC41F317DB7D3500201DDC /* TestArchive.zip */,
21CC41F417DB7D3500201DDC /* TestPasswordArchive.zip */,
21CC41F517DB7D3500201DDC /* Unicode.zip */,
);
path = Fixtures;
sourceTree = "<group>";
};
21CC420017DB7D6300201DDC /* Sample Application */ = {
isa = PBXGroup;
children = (
21CC420217DB7D6300201DDC /* SSAppDelegate.h */,
21CC420317DB7D6300201DDC /* SSAppDelegate.m */,
21CC420417DB7D6300201DDC /* Supporting Files */,
);
path = "Sample Application";
sourceTree = "<group>";
};
21CC420417DB7D6300201DDC /* Supporting Files */ = {
isa = PBXGroup;
children = (
A5CD0D391AD3490700E7F209 /* Default-568h@2x.png */,
21CC420517DB7D6300201DDC /* main.m */,
21CC420617DB7D6300201DDC /* SSZipArchive-Prefix.pch */,
21CC420917DB7D6300201DDC /* SSZipArchive-Info.plist */,
);
path = "Supporting Files";
sourceTree = "<group>";
};
3D18E4A91B23679000627171 /* Multi_Zip_Test */ = {
isa = PBXGroup;
children = (
3D18E4BD1B236A7500627171 /* 0.m4a */,
3D18E4BE1B236A7500627171 /* 1.m4a */,
3D18E4BF1B236A7500627171 /* 2.m4a */,
3D18E4C01B236A7500627171 /* 3.m4a */,
3D18E4C11B236A7500627171 /* 4.m4a */,
3D18E4C21B236A7500627171 /* 5.m4a */,
3D18E4C31B236A7500627171 /* 6.m4a */,
3D18E4C41B236A7500627171 /* 7.m4a */,
);
name = Multi_Zip_Test;
path = ../../../Pictures/ssziparchive/Tests/Multi_Zip_Test;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
21CC41A417DB7D1300201DDC /* SSZipArchive */ = {
isa = PBXNativeTarget;
buildConfigurationList = 21CC41D117DB7D1300201DDC /* Build configuration list for PBXNativeTarget "SSZipArchive" */;
buildPhases = (
21CC41A117DB7D1300201DDC /* Sources */,
21CC41A217DB7D1300201DDC /* Frameworks */,
21CC41A317DB7D1300201DDC /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = SSZipArchive;
productName = SSZipArchive;
productReference = 21CC41A517DB7D1300201DDC /* SSZipArchive.app */;
productType = "com.apple.product-type.application";
};
21CC41BF17DB7D1300201DDC /* SSZipArchiveTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 21CC41D417DB7D1300201DDC /* Build configuration list for PBXNativeTarget "SSZipArchiveTests" */;
buildPhases = (
21CC41BC17DB7D1300201DDC /* Sources */,
21CC41BD17DB7D1300201DDC /* Frameworks */,
21CC41BE17DB7D1300201DDC /* Resources */,
);
buildRules = (
);
dependencies = (
21CC41C617DB7D1300201DDC /* PBXTargetDependency */,
);
name = SSZipArchiveTests;
productName = SSZipArchiveTests;
productReference = 21CC41C017DB7D1300201DDC /* SSZipArchiveTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
21CC419D17DB7D1300201DDC /* Project object */ = {
isa = PBXProject;
attributes = {
CLASSPREFIX = SS;
LastUpgradeCheck = 0500;
ORGANIZATIONNAME = "Sam Soffes";
TargetAttributes = {
21CC41BF17DB7D1300201DDC = {
TestTargetID = 21CC41A417DB7D1300201DDC;
};
};
};
buildConfigurationList = 21CC41A017DB7D1300201DDC /* Build configuration list for PBXProject "SSZipArchive" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 21CC419C17DB7D1300201DDC;
productRefGroup = 21CC41A617DB7D1300201DDC /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
21CC41A417DB7D1300201DDC /* SSZipArchive */,
21CC41BF17DB7D1300201DDC /* SSZipArchiveTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
21CC41A317DB7D1300201DDC /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3D18E4C51B236A7500627171 /* 0.m4a in Resources */,
3D18E4CB1B236A7500627171 /* 6.m4a in Resources */,
3D18E4CC1B236A7500627171 /* 7.m4a in Resources */,
3D18E4C91B236A7500627171 /* 4.m4a in Resources */,
3D18E4C61B236A7500627171 /* 1.m4a in Resources */,
3D18E4CA1B236A7500627171 /* 5.m4a in Resources */,
011F4B96182D71B700DE704F /* RelativeSymbolicLink.zip in Resources */,
3D18E4CE1B236C2A00627171 /* hello.zip in Resources */,
A5CD0D3A1AD3490700E7F209 /* Default-568h@2x.png in Resources */,
3D18E4C81B236A7500627171 /* 3.m4a in Resources */,
3D18E4C71B236A7500627171 /* 2.m4a in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
21CC41BE17DB7D1300201DDC /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
011F4B97182D72B400DE704F /* RelativeSymbolicLink.zip in Resources */,
21CC41F817DB7D3500201DDC /* IncorrectHeaders.zip in Resources */,
21CC41FD17DB7D3500201DDC /* Unicode.zip in Resources */,
21CC41FA17DB7D3500201DDC /* SymbolicLink.zip in Resources */,
21CC41F917DB7D3500201DDC /* PermissionsTestApp.app in Resources */,
21CC41FB17DB7D3500201DDC /* TestArchive.zip in Resources */,
21CC41FC17DB7D3500201DDC /* TestPasswordArchive.zip in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
21CC41A117DB7D1300201DDC /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
210D525817DEFB880060D41A /* unzip.c in Sources */,
21CC41EC17DB7D2F00201DDC /* SSZipArchive.m in Sources */,
21CC421117DB7D7900201DDC /* SSAppDelegate.m in Sources */,
210D525417DEFB880060D41A /* ioapi.c in Sources */,
210D525A17DEFB880060D41A /* zip.c in Sources */,
21CC421017DB7D7400201DDC /* main.m in Sources */,
3D18E4BC1B2367A300627171 /* CollectingDelegate.m in Sources */,
210D525617DEFB880060D41A /* mztools.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
21CC41BC17DB7D1300201DDC /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
210D525517DEFB880060D41A /* ioapi.c in Sources */,
210D525917DEFB880060D41A /* unzip.c in Sources */,
21CC41FF17DB7D3500201DDC /* SSZipArchiveTests.m in Sources */,
210D525B17DEFB880060D41A /* zip.c in Sources */,
210D525717DEFB880060D41A /* mztools.c in Sources */,
21CC41ED17DB7D2F00201DDC /* SSZipArchive.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
21CC41C617DB7D1300201DDC /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 21CC41A417DB7D1300201DDC /* SSZipArchive */;
targetProxy = 21CC41C517DB7D1300201DDC /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
21CC41CF17DB7D1300201DDC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
21CC41D017DB7D1300201DDC /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
21CC41D217DB7D1300201DDC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "$(SRCROOT)/Sample Application/Supporting Files/SSZipArchive-Prefix.pch";
INFOPLIST_FILE = "$(SRCROOT)/Sample Application/Supporting Files/SSZipArchive-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Debug;
};
21CC41D317DB7D1300201DDC /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "$(SRCROOT)/Sample Application/Supporting Files/SSZipArchive-Prefix.pch";
INFOPLIST_FILE = "$(SRCROOT)/Sample Application/Supporting Files/SSZipArchive-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Release;
};
21CC41D517DB7D1300201DDC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/SSZipArchive.app/SSZipArchive";
CLANG_ENABLE_OBJC_ARC = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
);
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = "Tests/SSZipArchiveTests-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUNDLE_LOADER)";
WRAPPER_EXTENSION = xctest;
};
name = Debug;
};
21CC41D617DB7D1300201DDC /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/SSZipArchive.app/SSZipArchive";
CLANG_ENABLE_OBJC_ARC = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
);
INFOPLIST_FILE = "Tests/SSZipArchiveTests-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUNDLE_LOADER)";
WRAPPER_EXTENSION = xctest;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
21CC41A017DB7D1300201DDC /* Build configuration list for PBXProject "SSZipArchive" */ = {
isa = XCConfigurationList;
buildConfigurations = (
21CC41CF17DB7D1300201DDC /* Debug */,
21CC41D017DB7D1300201DDC /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
21CC41D117DB7D1300201DDC /* Build configuration list for PBXNativeTarget "SSZipArchive" */ = {
isa = XCConfigurationList;
buildConfigurations = (
21CC41D217DB7D1300201DDC /* Debug */,
21CC41D317DB7D1300201DDC /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
21CC41D417DB7D1300201DDC /* Build configuration list for PBXNativeTarget "SSZipArchiveTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
21CC41D517DB7D1300201DDC /* Debug */,
21CC41D617DB7D1300201DDC /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 21CC419D17DB7D1300201DDC /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:SSZipArchive.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0500"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "21CC41A417DB7D1300201DDC"
BuildableName = "SSZipArchive.app"
BlueprintName = "SSZipArchive"
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 = "21CC41BF17DB7D1300201DDC"
BuildableName = "SSZipArchiveTests.xctest"
BlueprintName = "SSZipArchiveTests"
ReferencedContainer = "container:SSZipArchive.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "21CC41A417DB7D1300201DDC"
BuildableName = "SSZipArchive.app"
BlueprintName = "SSZipArchive"
ReferencedContainer = "container:SSZipArchive.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "21CC41A417DB7D1300201DDC"
BuildableName = "SSZipArchive.app"
BlueprintName = "SSZipArchive"
ReferencedContainer = "container:SSZipArchive.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "21CC41A417DB7D1300201DDC"
BuildableName = "SSZipArchive.app"
BlueprintName = "SSZipArchive"
ReferencedContainer = "container:SSZipArchive.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,69 @@
//
// SSZipArchive.h
// SSZipArchive
//
// Created by Sam Soffes on 7/21/10.
// Copyright (c) Sam Soffes 2010-2015. All rights reserved.
//
#ifndef _SSZIPARCHIVE_H
#define _SSZIPARCHIVE_H
#import <Foundation/Foundation.h>
#include "unzip.h"
@protocol SSZipArchiveDelegate;
@interface SSZipArchive : NSObject
// Unzip
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination;
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination delegate:(id<SSZipArchiveDelegate>)delegate;
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error;
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error delegate:(id<SSZipArchiveDelegate>)delegate;
+ (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 *error))completionHandler;
+ (BOOL)unzipFileAtPath:(NSString *)path
toDestination:(NSString *)destination
overwrite:(BOOL)overwrite
password:(NSString *)password
progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler;
// Zip
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)filenames;
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath;
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory;
- (instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER;
@property (NS_NONATOMIC_IOSONLY, readonly) BOOL open;
- (BOOL)writeFile:(NSString *)path;
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(NSString *)fileName;
- (BOOL)writeData:(NSData *)data filename:(NSString *)filename;
@property (NS_NONATOMIC_IOSONLY, readonly) BOOL close;
@end
@protocol SSZipArchiveDelegate <NSObject>
@optional
- (void)zipArchiveWillUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo;
- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath;
- (BOOL)zipArchiveShouldUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;
- (void)zipArchiveWillUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;
- (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;
- (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath unzippedFilePath:(NSString *)unzippedFilePath;
- (void)zipArchiveProgressEvent:(unsigned long long)loaded total:(unsigned long long)total;
- (void)zipArchiveDidUnzipArchiveFile:(NSString *)zipFile entryPath:(NSString *)entryPath destPath:(NSString *)destPath;
@end
#endif /* _SSZIPARCHIVE_H */

672
SSZipArchive/SSZipArchive.m Normal file
View File

@@ -0,0 +1,672 @@
//
// SSZipArchive.m
// SSZipArchive
//
// Created by Sam Soffes on 7/21/10.
// Copyright (c) Sam Soffes 2010-2015. All rights reserved.
//
#import "SSZipArchive.h"
#include "zip.h"
#import "zlib.h"
#import "zconf.h"
#include <sys/stat.h>
#define CHUNK 16384
@interface SSZipArchive ()
+ (NSDate *)_dateWithMSDOSFormat:(UInt32)msdosDateTime;
@end
@implementation SSZipArchive
{
NSString *_path;
NSString *_filename;
zipFile _zip;
}
#pragma mark - Unzipping
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination
{
return [self unzipFileAtPath:path toDestination:destination delegate:nil];
}
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error
{
return [self unzipFileAtPath:path toDestination:destination overwrite:overwrite password:password error:error delegate:nil progressHandler:nil completionHandler:nil];
}
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination delegate:(id<SSZipArchiveDelegate>)delegate
{
return [self unzipFileAtPath:path toDestination:destination overwrite:YES password:nil error:nil delegate:delegate progressHandler:nil completionHandler:nil];
}
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error delegate:(id<SSZipArchiveDelegate>)delegate
{
return [self unzipFileAtPath:path toDestination:destination overwrite:overwrite password:password error:error delegate:delegate progressHandler:nil completionHandler:nil];
}
+ (BOOL)unzipFileAtPath:(NSString *)path
toDestination:(NSString *)destination
overwrite:(BOOL)overwrite
password:(NSString *)password
progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler
{
return [self unzipFileAtPath:path toDestination:destination overwrite:overwrite password:password error:nil delegate:nil progressHandler:progressHandler completionHandler:completionHandler];
}
+ (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 *error))completionHandler
{
return [self unzipFileAtPath:path toDestination:destination overwrite:YES password:nil error:nil delegate:nil progressHandler:progressHandler completionHandler:completionHandler];
}
+ (BOOL)unzipFileAtPath:(NSString *)path
toDestination:(NSString *)destination
overwrite:(BOOL)overwrite
password:(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 *error))completionHandler
{
// Begin opening
zipFile zip = unzOpen((const char*)[path UTF8String]);
if (zip == NULL)
{
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"failed to open zip file"};
NSError *err = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:-1 userInfo:userInfo];
if (error)
{
*error = err;
}
if (completionHandler)
{
completionHandler(nil, NO, err);
}
return NO;
}
NSDictionary * fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
unsigned long long fileSize = [fileAttributes[NSFileSize] unsignedLongLongValue];
unsigned long long currentPosition = 0;
unz_global_info globalInfo = {0ul, 0ul};
unzGetGlobalInfo(zip, &globalInfo);
// Begin unzipping
if (unzGoToFirstFile(zip) != UNZ_OK)
{
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"failed to open first file in zip file"};
NSError *err = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:-2 userInfo:userInfo];
if (error)
{
*error = err;
}
if (completionHandler)
{
completionHandler(nil, NO, err);
}
return NO;
}
BOOL success = YES;
BOOL canceled = NO;
int ret = 0;
unsigned char buffer[4096] = {0};
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableSet *directoriesModificationDates = [[NSMutableSet alloc] init];
// Message delegate
if ([delegate respondsToSelector:@selector(zipArchiveWillUnzipArchiveAtPath:zipInfo:)]) {
[delegate zipArchiveWillUnzipArchiveAtPath:path zipInfo:globalInfo];
}
if ([delegate respondsToSelector:@selector(zipArchiveProgressEvent:total:)]) {
[delegate zipArchiveProgressEvent:(NSInteger)currentPosition total:(NSInteger)fileSize];
}
NSInteger currentFileNumber = 0;
do {
@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;
}
currentPosition += fileInfo.compressed_size;
// Message delegate
if ([delegate respondsToSelector:@selector(zipArchiveShouldUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {
if (![delegate zipArchiveShouldUnzipFileAtIndex:currentFileNumber
totalFiles:(NSInteger)globalInfo.number_entry
archivePath:path fileInfo:fileInfo]) {
success = NO;
canceled = YES;
break;
}
}
if ([delegate respondsToSelector:@selector(zipArchiveWillUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {
[delegate zipArchiveWillUnzipFileAtIndex:currentFileNumber totalFiles:(NSInteger)globalInfo.number_entry
archivePath:path fileInfo:fileInfo];
}
if ([delegate respondsToSelector:@selector(zipArchiveProgressEvent:total:)]) {
[delegate zipArchiveProgressEvent:(NSInteger)currentPosition total:(NSInteger)fileSize];
}
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';
//
// Determine whether this is a symbolic link:
// - File is stored with 'version made by' value of UNIX (3),
// as per http://www.pkware.com/documents/casestudies/APPNOTE.TXT
// in the upper byte of the version field.
// - BSD4.4 st_mode constants are stored in the high 16 bits of the
// external file attributes (defacto standard, verified against libarchive)
//
// The original constants can be found here:
// http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.4BSD/usr/include/sys/stat.h
//
const uLong ZipUNIXVersion = 3;
const uLong BSD_SFMT = 0170000;
const uLong BSD_IFLNK = 0120000;
BOOL fileIsSymbolicLink = NO;
if (((fileInfo.version >> 8) == ZipUNIXVersion) && BSD_IFLNK == (BSD_SFMT & (fileInfo.external_fa >> 16))) {
fileIsSymbolicLink = NO;
}
// Check if it contains directory
NSString *strPath = @(filename);
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 = @{NSFileCreationDate: modDate, NSFileModificationDate: modDate};
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: @{@"path": fullPath, @"modDate": modDate}];
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) {
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);
// Set the original datetime property
if (fileInfo.dosDate != 0) {
NSDate *orgDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.dosDate];
NSDictionary *attr = @{NSFileModificationDate: orgDate};
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");
}
}
}
// Set the original permissions on the file
uLong permissions = fileInfo.external_fa >> 16;
if (permissions != 0) {
// 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");
}
#if !__has_feature(objc_arc)
[attrs release];
#endif
}
}
}
else
{
// Assemble the path for the symbolic link
NSMutableString* destinationPath = [NSMutableString string];
int bytesRead = 0;
while((bytesRead = unzReadCurrentFile(zip, buffer, 4096)) > 0)
{
buffer[bytesRead] = (int)0;
[destinationPath appendString:@((const char*)buffer)];
}
// Create the symbolic link (making sure it stays relative if it was relative before)
int symlinkError = symlink([destinationPath cStringUsingEncoding:NSUTF8StringEncoding],
[fullPath cStringUsingEncoding:NSUTF8StringEncoding]);
if(symlinkError != 0)
{
NSLog(@"Failed to create symbolic link at \"%@\" to \"%@\". symlink() error code: %d", fullPath, destinationPath, errno);
}
}
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 if ([delegate respondsToSelector: @selector(zipArchiveDidUnzipFileAtIndex:totalFiles:archivePath:unzippedFilePath:)]) {
[delegate zipArchiveDidUnzipFileAtIndex: currentFileNumber totalFiles: (NSInteger)globalInfo.number_entry
archivePath:path unzippedFilePath: fullPath];
}
currentFileNumber++;
if (progressHandler)
{
progressHandler(strPath, fileInfo, currentFileNumber, globalInfo.number_entry);
}
}
} while(ret == UNZ_OK && ret != UNZ_END_OF_LIST_OF_FILE);
// Close
unzClose(zip);
// The process of decompressing the .zip archive causes the modification times on the folders
// to be set to the present time. So, when we are done, they need to be explicitly set.
// set the modification date on all of the directories.
NSError * err = nil;
for (NSDictionary * d in directoriesModificationDates) {
if (![[NSFileManager defaultManager] setAttributes:@{NSFileModificationDate: d[@"modDate"]} ofItemAtPath:d[@"path"] error:&err]) {
NSLog(@"[SSZipArchive] Set attributes failed for directory: %@.", d[@"path"]);
}
if (err) {
NSLog(@"[SSZipArchive] Error setting directory file modification date attribute: %@",err.localizedDescription);
}
}
#if !__has_feature(objc_arc)
[directoriesModificationDates release];
#endif
// Message delegate
if (success && [delegate respondsToSelector:@selector(zipArchiveDidUnzipArchiveAtPath:zipInfo:unzippedPath:)]) {
[delegate zipArchiveDidUnzipArchiveAtPath:path zipInfo:globalInfo unzippedPath:destination];
}
// final progress event = 100%
if (!canceled && [delegate respondsToSelector:@selector(zipArchiveProgressEvent:total:)]) {
[delegate zipArchiveProgressEvent:fileSize total:fileSize];
}
if (completionHandler)
{
completionHandler(path, YES, nil);
}
return success;
}
#pragma mark - Zipping
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)paths
{
BOOL success = NO;
SSZipArchive *zipArchive = [[SSZipArchive alloc] initWithPath:path];
if ([zipArchive open]) {
for (NSString *filePath in paths) {
[zipArchive writeFile:filePath];
}
success = [zipArchive close];
}
#if !__has_feature(objc_arc)
[zipArchive release];
#endif
return success;
}
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath {
return [self createZipFileAtPath:path withContentsOfDirectory:directoryPath keepParentDirectory:NO];
}
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory {
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) {
if (keepParentDirectory)
{
fileName = [[directoryPath lastPathComponent] stringByAppendingPathComponent:fileName];
}
[zipArchive writeFileAtPath:fullFilePath withFileName:fileName];
}
else
{
if([[NSFileManager defaultManager] subpathsOfDirectoryAtPath:fullFilePath error:nil].count == 0)
{
NSString *tempName = [fullFilePath stringByAppendingPathComponent:@".DS_Store"];
[@"" writeToFile:tempName atomically:YES encoding:NSUTF8StringEncoding error:nil];
[zipArchive writeFileAtPath:tempName withFileName:[fileName stringByAppendingPathComponent:@".DS_Store"]];
[[NSFileManager defaultManager] removeItemAtPath:tempName error:nil];
}
}
}
success = [zipArchive close];
}
#if !__has_feature(objc_arc)
[fileManager release];
[zipArchive release];
#endif
return success;
}
- (instancetype)initWithPath:(NSString *)path
{
if ((self = [super init])) {
_path = [path copy];
}
return self;
}
#if !__has_feature(objc_arc)
- (void)dealloc
{
[_path release];
[super dealloc];
}
#endif
- (BOOL)open
{
NSAssert((_zip == NULL), @"Attempting open an archive which is already open");
_zip = zipOpen([_path UTF8String], APPEND_STATUS_CREATE);
return (NULL != _zip);
}
- (void)zipInfo:(zip_fileinfo*)zipInfo setDate:(NSDate*)date
{
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
#if defined(__IPHONE_8_0) || defined(__MAC_10_10)
uint flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
#else
uint flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
#endif
NSDateComponents *components = [currentCalendar components:flags fromDate:date];
zipInfo->tmz_date.tm_sec = (unsigned int)components.second;
zipInfo->tmz_date.tm_min = (unsigned int)components.minute;
zipInfo->tmz_date.tm_hour = (unsigned int)components.hour;
zipInfo->tmz_date.tm_mday = (unsigned int)components.day;
zipInfo->tmz_date.tm_mon = (unsigned int)components.month - 1;
zipInfo->tmz_date.tm_year = (unsigned int)components.year;
}
- (BOOL)writeFolderAtPath:(NSString *)path withFolderName:(NSString *)folderName
{
NSAssert((_zip != NULL), @"Attempting to write to an archive which was never opened");
zip_fileinfo zipInfo = {{0}};
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) {
// 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;
}
}
unsigned int len = 0;
zipOpenNewFileInZip(_zip, [[folderName stringByAppendingString:@"/"] UTF8String], &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_NO_COMPRESSION);
zipWriteInFileInZip(_zip, &len, 0);
zipCloseFileInZip(_zip);
return YES;
}
- (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}};
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) {
// 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))
{
len = (unsigned int) fread(buffer, 1, CHUNK, input);
zipWriteInFileInZip(_zip, buffer, len);
}
zipCloseFileInZip(_zip);
free(buffer);
return YES;
}
- (BOOL)writeData:(NSData *)data filename:(NSString *)filename
{
if (!_zip) {
return NO;
}
if (!data) {
return NO;
}
zip_fileinfo zipInfo = {{0,0,0,0,0,0},0,0,0};
[self zipInfo:&zipInfo setDate:[NSDate date]];
zipOpenNewFileInZip(_zip, [filename UTF8String], &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
zipWriteInFileInZip(_zip, data.bytes, (unsigned int)data.length);
zipCloseFileInZip(_zip);
return YES;
}
- (BOOL)close
{
NSAssert((_zip != NULL), @"[SSZipArchive] Attempting to close an archive which was never opened");
zipClose(_zip, NULL);
return YES;
}
#pragma mark - Private
// Format from http://newsgroups.derkeiler.com/Archive/Comp/comp.os.msdos.programmer/2009-04/msg00060.html
// Two consecutive words, or a longword, YYYYYYYMMMMDDDDD hhhhhmmmmmmsssss
// YYYYYYY is years from 1980 = 0
// sssss is (seconds/2).
//
// 3658 = 0011 0110 0101 1000 = 0011011 0010 11000 = 27 2 24 = 2007-02-24
// 7423 = 0111 0100 0010 0011 - 01110 100001 00011 = 14 33 2 = 14:33:06
+ (NSDate *)_dateWithMSDOSFormat:(UInt32)msdosDateTime
{
static const UInt32 kYearMask = 0xFE000000;
static const UInt32 kMonthMask = 0x1E00000;
static const UInt32 kDayMask = 0x1F0000;
static const UInt32 kHourMask = 0xF800;
static const UInt32 kMinuteMask = 0x7E0;
static const UInt32 kSecondMask = 0x1F;
static NSCalendar *gregorian;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
#if defined(__IPHONE_8_0) || defined(__MAC_10_10)
gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
#else
gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
#endif
});
NSDateComponents *components = [[NSDateComponents alloc] init];
NSAssert(0xFFFFFFFF == (kYearMask | kMonthMask | kDayMask | kHourMask | kMinuteMask | kSecondMask), @"[SSZipArchive] MSDOS date masks don't add up");
[components setYear:1980 + ((msdosDateTime & kYearMask) >> 25)];
[components setMonth:(msdosDateTime & kMonthMask) >> 21];
[components setDay:(msdosDateTime & kDayMask) >> 16];
[components setHour:(msdosDateTime & kHourMask) >> 11];
[components setMinute:(msdosDateTime & kMinuteMask) >> 5];
[components setSecond:(msdosDateTime & kSecondMask) * 2];
NSDate *date = [NSDate dateWithTimeInterval:0 sinceDate:[gregorian dateFromComponents:components]];
#if !__has_feature(objc_arc)
[components release];
#endif
return date;
}
@end

View File

@@ -192,9 +192,8 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T
}
ret = 0;
if(fseeko64((FILE *)stream, offset, fseek_origin) != 0)
if(fseeko64((FILE *)stream, (long)offset, fseek_origin) != 0)
ret = -1;
return ret;
}

View File

@@ -1038,7 +1038,7 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
/* ZIP64 extra fields */
if (headerId == 0x0001)
{
uLong uL;
uLong uLZip64;
if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)
{
@@ -1062,7 +1062,7 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
if(file_info.disk_num_start == (unsigned long)-1)
{
/* Disk Start Number */
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uLZip64) != UNZ_OK)
err=UNZ_ERRNO;
}
@@ -1514,6 +1514,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
pfile_in_zip_read_info->pos_local_extrafield=0;
pfile_in_zip_read_info->raw=raw;
pfile_in_zip_read_info->byte_before_the_zipfile = 0;
if (pfile_in_zip_read_info->read_buffer==NULL)
{
@@ -1554,9 +1555,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
pfile_in_zip_read_info->filestream=s->filestream;
pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
#ifndef __clang_analyzer__
pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
#endif
pfile_in_zip_read_info->stream.total_out = 0;

View File

@@ -0,0 +1,11 @@
//
// SSAppDelegate.h
// SSZipArchive
//
// Created by Sam Soffes on 9/7/13.
// Copyright (c) 2013-2014 Sam Soffes. All rights reserved.
//
@interface SSAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

View File

@@ -0,0 +1,19 @@
//
// SSAppDelegate.m
// SSZipArchive
//
// Created by Sam Soffes on 9/7/13.
// Copyright (c) 2013-2014 Sam Soffes. All rights reserved.
//
#import "SSAppDelegate.h"
@implementation SSAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
return YES;
}
@end

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,45 @@
<?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>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.samsoffes.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.3.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.3.3</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,16 @@
//
// Prefix header
//
// The contents of this file are implicitly included at the beginning of every source file.
//
#import <Availability.h>
#ifndef __IPHONE_3_0
#warning "This project uses features only available in iOS SDK 3.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif

View File

@@ -0,0 +1,15 @@
//
// main.m
// SSZipArchive
//
// Created by Sam Soffes on 9/7/13.
// Copyright (c) 2013-2014 Sam Soffes. All rights reserved.
//
#import "SSAppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([SSAppDelegate class]));
}
}

View File

@@ -0,0 +1,8 @@
#import <Foundation/Foundation.h>
/**
* Test delegate by collecting its calls
*/
@interface CollectingDelegate : NSObject <SSZipArchiveDelegate>
@property(nonatomic, retain) NSMutableArray *files;
@end

View File

@@ -0,0 +1,32 @@
//
// Created by chris on 8/1/12.
//
// To change the template use AppCode | Preferences | File Templates.
//
#import "SSZipArchive.h"
#import "CollectingDelegate.h"
@implementation CollectingDelegate {
}
@synthesize files = _files;
- (instancetype)init {
self = [super init];
if (self) {
self.files = [NSMutableArray array];
}
return self;
}
- (void)zipArchiveDidUnzipArchiveFile:(NSString *)zipFile entryPath:(NSString *)entryPath destPath:(NSString *)destPath {
[self.files addObject:entryPath];
}
@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>

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\
}

Binary file not shown.

BIN
Tests/Fixtures/hello.zip Normal file

Binary file not shown.

BIN
Tests/Multi_Zip_Test/0.m4a Executable file

Binary file not shown.

BIN
Tests/Multi_Zip_Test/1.m4a Executable file

Binary file not shown.

BIN
Tests/Multi_Zip_Test/2.m4a Executable file

Binary file not shown.

BIN
Tests/Multi_Zip_Test/3.m4a Executable file

Binary file not shown.

BIN
Tests/Multi_Zip_Test/4.m4a Executable file

Binary file not shown.

BIN
Tests/Multi_Zip_Test/5.m4a Executable file

Binary file not shown.

BIN
Tests/Multi_Zip_Test/6.m4a Executable file

Binary file not shown.

BIN
Tests/Multi_Zip_Test/7.m4a Executable file

Binary file not shown.

View File

@@ -7,6 +7,15 @@
objects = {
/* Begin PBXBuildFile section */
0472DDA417AF617E007BDB8D /* 0.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 0472DD9C17AF617E007BDB8D /* 0.m4a */; };
0472DDA517AF617E007BDB8D /* 1.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 0472DD9D17AF617E007BDB8D /* 1.m4a */; };
0472DDA617AF617E007BDB8D /* 2.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 0472DD9E17AF617E007BDB8D /* 2.m4a */; };
0472DDA717AF617E007BDB8D /* 3.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 0472DD9F17AF617E007BDB8D /* 3.m4a */; };
0472DDA817AF617E007BDB8D /* 4.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 0472DDA017AF617E007BDB8D /* 4.m4a */; };
0472DDA917AF617E007BDB8D /* 5.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 0472DDA117AF617E007BDB8D /* 5.m4a */; };
0472DDAA17AF617E007BDB8D /* 6.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 0472DDA217AF617E007BDB8D /* 6.m4a */; };
0472DDAB17AF617E007BDB8D /* 7.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 0472DDA317AF617E007BDB8D /* 7.m4a */; };
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 +33,15 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0472DD9C17AF617E007BDB8D /* 0.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = 0.m4a; sourceTree = "<group>"; };
0472DD9D17AF617E007BDB8D /* 1.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = 1.m4a; sourceTree = "<group>"; };
0472DD9E17AF617E007BDB8D /* 2.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = 2.m4a; sourceTree = "<group>"; };
0472DD9F17AF617E007BDB8D /* 3.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = 3.m4a; sourceTree = "<group>"; };
0472DDA017AF617E007BDB8D /* 4.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = 4.m4a; sourceTree = "<group>"; };
0472DDA117AF617E007BDB8D /* 5.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = 5.m4a; sourceTree = "<group>"; };
0472DDA217AF617E007BDB8D /* 6.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = 6.m4a; sourceTree = "<group>"; };
0472DDA317AF617E007BDB8D /* 7.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = 7.m4a; sourceTree = "<group>"; };
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; };
@@ -62,6 +80,21 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0472DD9B17AF617E007BDB8D /* multi_zip_test */ = {
isa = PBXGroup;
children = (
0472DD9C17AF617E007BDB8D /* 0.m4a */,
0472DD9D17AF617E007BDB8D /* 1.m4a */,
0472DD9E17AF617E007BDB8D /* 2.m4a */,
0472DD9F17AF617E007BDB8D /* 3.m4a */,
0472DDA017AF617E007BDB8D /* 4.m4a */,
0472DDA117AF617E007BDB8D /* 5.m4a */,
0472DDA217AF617E007BDB8D /* 6.m4a */,
0472DDA317AF617E007BDB8D /* 7.m4a */,
);
path = multi_zip_test;
sourceTree = "<group>";
};
B215FB04143AD3C7003AC546 = {
isa = PBXGroup;
children = (
@@ -120,6 +153,8 @@
B215FB5E143AD505003AC546 /* SSZipArchiveTests */ = {
isa = PBXGroup;
children = (
0472DD9B17AF617E007BDB8D /* multi_zip_test */,
AF313D08177B02A700478143 /* PermissionsTestApp.app */,
B2283D5C155AD80F00F9395A /* Unicode.zip */,
B215FB61143AD514003AC546 /* SSZipArchiveTests.m */,
B215FB5F143AD514003AC546 /* SSZipArchiveTests-Info.plist */,
@@ -185,9 +220,18 @@
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 */,
0472DDA417AF617E007BDB8D /* 0.m4a in Resources */,
0472DDA517AF617E007BDB8D /* 1.m4a in Resources */,
0472DDA617AF617E007BDB8D /* 2.m4a in Resources */,
0472DDA717AF617E007BDB8D /* 3.m4a in Resources */,
0472DDA817AF617E007BDB8D /* 4.m4a in Resources */,
0472DDA917AF617E007BDB8D /* 5.m4a in Resources */,
0472DDAA17AF617E007BDB8D /* 6.m4a in Resources */,
0472DDAB17AF617E007BDB8D /* 7.m4a in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -3,72 +3,178 @@
// SSZipArchiveTests
//
// Created by Sam Soffes on 10/3/11.
// Copyright (c) 2011 Sam Soffes. All rights reserved.
// Copyright (c) 2011-2014 Sam Soffes. All rights reserved.
//
#import "SSZipArchive.h"
#import <SenTestingKit/SenTestingKit.h>
#import <XCTest/XCTest.h>
#import "CollectingDelegate.h"
#import <XCTest/XCTest.h>
#import <CommonCrypto/CommonDigest.h>
@interface SSZipArchiveTests : SenTestCase <SSZipArchiveDelegate>
- (NSString *)_cachesPath:(NSString *)directory;
- (NSString *)_calculateMD5Digest:(NSData *)data;
@interface CancelDelegate : NSObject <SSZipArchiveDelegate>
@property (nonatomic, assign) int numFilesUnzipped;
@property (nonatomic, assign) int numFilesToUnzip;
@property (nonatomic, assign) BOOL didUnzipArchive;
@property (nonatomic, assign) int loaded;
@property (nonatomic, assign) int total;
@end
@implementation SSZipArchiveTests
@implementation CancelDelegate
- (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo
{
_numFilesUnzipped = fileIndex + 1;
}
- (BOOL)zipArchiveShouldUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo
{
//return YES;
return _numFilesUnzipped < _numFilesToUnzip;
}
- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath
{
_didUnzipArchive = YES;
}
- (void)zipArchiveProgressEvent:(NSInteger)loaded total:(NSInteger)total
{
_loaded = (int)loaded;
_total = (int)total;
}
@end
//- (void)setUp {
// [[NSFileManager defaultManager] removeItemAtPath:[self _cachesPath:nil] error:nil];
//}
@interface SSZipArchiveTests : XCTestCase <SSZipArchiveDelegate>
@end
@implementation SSZipArchiveTests {
NSMutableArray *progressEvents;
}
- (void)testZipping {
NSString *outputPath = [self _cachesPath:@"Zipped"];
NSArray *inputPaths = [NSArray arrayWithObjects:
[outputPath stringByAppendingPathComponent:@"Readme.markdown"],
[outputPath stringByAppendingPathComponent:@"LICENSE"],
nil];
NSString *archivePath = [outputPath stringByAppendingPathComponent:@"CreatedArchive.zip"];
[SSZipArchive createZipFileAtPath:archivePath withFilesAtPaths:inputPaths];
- (void)setUp {
[super setUp];
progressEvents = [NSMutableArray array];
}
// TODO: Make sure the files are actually unzipped. They are, but the test should be better.
STAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:archivePath], @"Archive created");
- (void)tearDown {
[super tearDown];
[[NSFileManager defaultManager] removeItemAtPath:[self _cachesPath:nil] error:nil];
}
- (void)testZipping {
// use extracted files from [-testUnzipping]
NSString *inputPath = [self _cachesPath:@"Regular"];
NSArray *inputPaths = @[[inputPath stringByAppendingPathComponent:@"Readme.markdown"],
[inputPath stringByAppendingPathComponent:@"LICENSE"]];
NSString *outputPath = [self _cachesPath:@"Zipped"];
NSString *archivePath = [outputPath stringByAppendingPathComponent:@"CreatedArchive.zip"];
[SSZipArchive createZipFileAtPath:archivePath withFilesAtPaths:inputPaths];
// TODO: Make sure the files are actually unzipped. They are, but the test should be better.
XCTAssertTrue([[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];
XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:archivePath], @"Folder Archive created");
}
- (void)testMultipleZippping{
NSArray *inputPaths = @[[[NSBundle mainBundle]pathForResource:@"0" ofType:@"m4a"],
[[NSBundle mainBundle]pathForResource:@"1" ofType:@"m4a"],
[[NSBundle mainBundle]pathForResource:@"2" ofType:@"m4a"],
[[NSBundle mainBundle]pathForResource:@"3" ofType:@"m4a"],
[[NSBundle mainBundle]pathForResource:@"4" ofType:@"m4a"],
[[NSBundle mainBundle]pathForResource:@"5" ofType:@"m4a"],
[[NSBundle mainBundle]pathForResource:@"6" ofType:@"m4a"],
[[NSBundle mainBundle]pathForResource:@"7" ofType:@"m4a"]
];
NSString *outputPath = [self _cachesPath:@"Zipped"];
// this is a monster
// if testing on iOS, within 30 loops it will fail; however, on OS X, it may take about 900 loops
for (int test = 0; test < 1000; test++)
{
// Zipping
NSString *archivePath = [outputPath stringByAppendingPathComponent:[NSString stringWithFormat:@"queue_test_%d.zip",test]];
[SSZipArchive createZipFileAtPath:archivePath withFilesAtPaths:inputPaths];
long long threshold = 510000; // 510kB:size slightly smaller than a successful zip, but much larger than a failed one
long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:archivePath error:nil][NSFileSize] longLongValue];
//STAssertTrue(fileSize > threshold, @"zipping failed at %@!",fileSize,archivePath);
}
}
- (void)testUnzipping {
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestArchive" ofType:@"zip"];
NSString *outputPath = [self _cachesPath:@"Regular"];
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:self];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *testPath = [outputPath stringByAppendingPathComponent:@"Readme.markdown"];
STAssertTrue([fileManager fileExistsAtPath:testPath], @"Readme unzipped");
testPath = [outputPath stringByAppendingPathComponent:@"LICENSE"];
STAssertTrue([fileManager fileExistsAtPath:testPath], @"LICENSE unzipped");
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestArchive" ofType:@"zip"];
NSString *outputPath = [self _cachesPath:@"Regular"];
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:self];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *testPath = [outputPath stringByAppendingPathComponent:@"Readme.markdown"];
XCTAssertTrue([fileManager fileExistsAtPath:testPath], @"Readme unzipped");
testPath = [outputPath stringByAppendingPathComponent:@"LICENSE"];
XCTAssertTrue([fileManager fileExistsAtPath:testPath], @"LICENSE unzipped");
}
- (void)testSmallFileUnzipping {
NSString *zipPath = [[NSBundle mainBundle] pathForResource:@"hello" ofType:@"zip"];
NSString *outputPath = [self _cachesPath:@"Regular"];
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:self];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *testPath = [outputPath stringByAppendingPathComponent:@"Readme.markdown"];
XCTAssertTrue([fileManager fileExistsAtPath:testPath], @"Readme unzipped");
testPath = [outputPath stringByAppendingPathComponent:@"LICENSE"];
XCTAssertTrue([fileManager fileExistsAtPath:testPath], @"LICENSE unzipped");
}
- (void)testUnzippingProgress {
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestArchive" ofType:@"zip"];
NSString *outputPath = [self _cachesPath:@"Progress"];
[progressEvents removeAllObjects];
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:self];
// 4 events: the first, then for each of the two files one, then the final event
XCTAssertTrue(4 == [progressEvents count], @"Expected 4 progress events");
XCTAssertTrue(0 == [progressEvents[0] intValue]);
XCTAssertTrue(619 == [progressEvents[1] intValue]);
XCTAssertTrue(1114 == [progressEvents[2] intValue]);
XCTAssertTrue(1436 == [progressEvents[3] intValue]);
}
- (void)testUnzippingWithPassword {
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestPasswordArchive" ofType:@"zip"];
NSString *outputPath = [self _cachesPath:@"Password"];
NSError *error = nil;
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath overwrite:YES password:@"passw0rd" error:&error delegate:self];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *testPath = [outputPath stringByAppendingPathComponent:@"Readme.markdown"];
STAssertTrue([fileManager fileExistsAtPath:testPath], @"Readme unzipped");
testPath = [outputPath stringByAppendingPathComponent:@"LICENSE"];
STAssertTrue([fileManager fileExistsAtPath:testPath], @"LICENSE unzipped");
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestPasswordArchive" ofType:@"zip"];
NSString *outputPath = [self _cachesPath:@"Password"];
NSError *error = nil;
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath overwrite:YES password:@"passw0rd" error:&error delegate:self];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *testPath = [outputPath stringByAppendingPathComponent:@"Readme.markdown"];
XCTAssertTrue([fileManager fileExistsAtPath:testPath], @"Readme unzipped");
testPath = [outputPath stringByAppendingPathComponent:@"LICENSE"];
XCTAssertTrue([fileManager fileExistsAtPath:testPath], @"LICENSE unzipped");
}
- (void)testUnzippingTruncatedFileFix {
NSString* zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"IncorrectHeaders" ofType:@"zip"];
NSString* outputPath = [self _cachesPath:@"IncorrectHeaders"];
@@ -81,9 +187,10 @@
NSData* data = [NSData dataWithContentsOfFile:filePath];
NSString* actualReadmeTxtMD5 = [self _calculateMD5Digest:data];
STAssertTrue([actualReadmeTxtMD5 isEqualToString:intendedReadmeTxtMD5], @"Readme.txt MD5 digest should match original.");
XCTAssertTrue([actualReadmeTxtMD5 isEqualToString:intendedReadmeTxtMD5], @"Readme.txt MD5 digest should match original.");
}
- (void)testUnzippingWithSymlinkedFileInside {
NSString* zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"SymbolicLink" ofType:@"zip"];
@@ -103,7 +210,38 @@
NSString *symlinkFilePath = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:testSymlinkFile error:&error];
bool symbolicLinkToFilePersists = ((symlinkFilePath != nil) && [symlinkFilePath isEqualToString:@"/Applications/GitHub.app/Contents/Resources/AppIcon.icns"]) && (error == nil);
STAssertTrue(symbolicLinkToFilePersists && symbolicLinkToFolderPersists, @"Symbolic links should persist from the original archive to the outputted files.");
XCTAssertTrue(symbolicLinkToFilePersists && symbolicLinkToFolderPersists, @"Symbolic links should persist from the original archive to the outputted files.");
}
- (void)testUnzippingWithRelativeSymlink {
NSString *resourceName = @"RelativeSymbolicLink";
NSString* zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:resourceName ofType:@"zip"];
NSString* outputPath = [self _cachesPath:resourceName];
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:self];
// Determine where the symlinks are
NSString *subfolderName = @"symlinks";
NSString *testBasePath = [NSString pathWithComponents:@[outputPath]];
NSString *testSymlinkFolder = [NSString pathWithComponents:@[testBasePath, subfolderName, @"folderSymlink"]];
NSString *testSymlinkFile = [NSString pathWithComponents:@[testBasePath, subfolderName, @"fileSymlink"]];
// Determine where the files they link to are
NSString *parentDir = @"../";
NSString *testSymlinkFolderTarget = [NSString pathWithComponents:@[parentDir, @"symlinkedFolder"]];
NSString *testSymlinkFileTarget = [NSString pathWithComponents:@[parentDir, @"symlinkedFile"]];
NSError *error = nil;
NSString *symlinkFolderPath = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:testSymlinkFolder error:&error];
bool symbolicLinkToFolderPersists = ((symlinkFolderPath != nil) && [symlinkFolderPath isEqualToString:testSymlinkFolderTarget]) && (error == nil);
error = nil;
NSString *symlinkFilePath = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:testSymlinkFile error:&error];
bool symbolicLinkToFilePersists = ((symlinkFilePath != nil) && [symlinkFilePath isEqualToString:testSymlinkFileTarget]) && (error == nil);
XCTAssertTrue(symbolicLinkToFilePersists && symbolicLinkToFolderPersists, @"Relative symbolic links should persist from the original archive to the outputted files (and also remain relative).");
}
- (void)testUnzippingWithUnicodeFilenameInside {
@@ -117,8 +255,94 @@
bool unicodeFolderWasExtracted = [[NSFileManager defaultManager] fileExistsAtPath:[outputPath stringByAppendingPathComponent:@"Fólder/Nothing.txt"]];
STAssertTrue(unicodeFilenameWasExtracted, @"Files with filenames in unicode should be extracted properly.");
STAssertTrue(unicodeFolderWasExtracted, @"Folders with names in unicode should be extracted propertly.");
XCTAssertTrue(unicodeFilenameWasExtracted, @"Files with filenames in unicode should be extracted properly.");
XCTAssertTrue(unicodeFolderWasExtracted, @"Folders with names in unicode should be extracted propertly.");
}
- (void)testZippingAndUnzippingForDate {
NSString *inputPath = [self _cachesPath:@"Regular"];
NSArray *inputPaths = @[[inputPath stringByAppendingPathComponent:@"Readme.markdown"]];
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];
XCTAssertEqualObjects(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
XCTAssertEqual(fileAttributes[NSFilePosixPermissions], preZipAttributes[NSFilePosixPermissions], @"File permissions should be retained during compression and de-compression");
}
- (void)testUnzippingWithCancel {
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestArchive" ofType:@"zip"];
NSString *outputPath = [self _cachesPath:@"Cancel1"];
CancelDelegate *delegate = [[CancelDelegate alloc] init];
delegate.numFilesToUnzip = 1;
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:delegate];
XCTAssertEqual(delegate.numFilesUnzipped, 1);
XCTAssertFalse(delegate.didUnzipArchive);
XCTAssertNotEqual(delegate.loaded, delegate.total);
outputPath = [self _cachesPath:@"Cancel2"];
delegate = [[CancelDelegate alloc] init];
delegate.numFilesToUnzip = 1000;
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:delegate];
XCTAssertEqual(delegate.numFilesUnzipped, 2);
XCTAssertTrue(delegate.didUnzipArchive);
XCTAssertEqual(delegate.loaded, delegate.total);
}
// Commented out to avoid checking in several gig file into the repository. Simply add a file named
@@ -127,60 +351,80 @@
//- (void)testUnzippingLargeFiles {
// NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"LargeArchive" ofType:@"zip"];
// NSString *outputPath = [self _cachesPath:@"Large"];
//
//
// [SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath];
//}
-(void)testShouldProvidePathOfUnzippedFileInDelegateCallback {
CollectingDelegate *collector = [CollectingDelegate new];
NSString *zipPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestArchive" ofType:@"zip"];
NSString *outputPath = [self _cachesPath:@"Regular"];
[SSZipArchive unzipFileAtPath:zipPath toDestination:outputPath delegate:collector];
// STAssertEqualObjects([collector.files objectAtIndex:0], @"LICENSE.txt", nil);
// STAssertEqualObjects([collector.files objectAtIndex:1], @"README.md", nil);
}
#pragma mark - SSZipArchiveDelegate
- (void)zipArchiveWillUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo {
NSLog(@"*** zipArchiveWillUnzipArchiveAtPath: `%@` zipInfo:", path);
NSLog(@"*** zipArchiveWillUnzipArchiveAtPath: `%@` zipInfo:", path);
}
- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath {
NSLog(@"*** zipArchiveDidUnzipArchiveAtPath: `%@` zipInfo: unzippedPath: `%@`", path, unzippedPath);
NSLog(@"*** zipArchiveDidUnzipArchiveAtPath: `%@` zipInfo: unzippedPath: `%@`", path, unzippedPath);
}
- (BOOL)zipArchiveShouldUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo
{
NSLog(@"*** zipArchiveShouldUnzipFileAtIndex: `%d` totalFiles: `%d` archivePath: `%@` fileInfo:", (int)fileIndex, (int)totalFiles, archivePath);
return YES;
}
- (void)zipArchiveWillUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo {
NSLog(@"*** zipArchiveWillUnzipFileAtIndex: `%ld` totalFiles: `%ld` archivePath: `%@` fileInfo:", fileIndex, totalFiles, archivePath);
NSLog(@"*** zipArchiveWillUnzipFileAtIndex: `%d` totalFiles: `%d` archivePath: `%@` fileInfo:", (int)fileIndex, (int)totalFiles, archivePath);
}
- (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo {
NSLog(@"*** zipArchiveDidUnzipFileAtIndex: `%ld` totalFiles: `%ld` archivePath: `%@` fileInfo:", fileIndex, totalFiles, archivePath);
NSLog(@"*** zipArchiveDidUnzipFileAtIndex: `%d` totalFiles: `%d` archivePath: `%@` fileInfo:", (int)fileIndex, (int)totalFiles, archivePath);
}
- (void)zipArchiveProgressEvent:(NSInteger)loaded total:(NSInteger)total {
NSLog(@"*** zipArchiveProgressEvent: loaded: `%d` total: `%d`", (int)loaded, (int)total);
[progressEvents addObject:@(loaded)];
}
#pragma mark - Private
- (NSString *)_cachesPath:(NSString *)directory {
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]
stringByAppendingPathComponent:@"com.samsoffes.ssziparchive.tests"];
if (directory) {
path = [path stringByAppendingPathComponent:directory];
}
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:path]) {
[fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
}
return path;
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]
stringByAppendingPathComponent:@"com.samsoffes.ssziparchive.tests"];
if (directory) {
path = [path stringByAppendingPathComponent:directory];
}
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:path]) {
[fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
}
return path;
}
// Taken from https://github.com/samsoffes/sstoolkit/blob/master/SSToolkit/NSData+SSToolkitAdditions.m
- (NSString *)_calculateMD5Digest:(NSData *)data {
unsigned char digest[CC_MD5_DIGEST_LENGTH], i;
CC_MD5(data.bytes, (unsigned int)data.length, digest);
NSMutableString *ms = [NSMutableString string];
for (i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[ms appendFormat: @"%02x", (int)(digest[i])];
}
return [ms copy];
unsigned char digest[CC_MD5_DIGEST_LENGTH], i;
CC_MD5(data.bytes, (unsigned int)data.length, digest);
NSMutableString *ms = [NSMutableString string];
for (i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[ms appendFormat: @"%02x", (int)(digest[i])];
}
return [ms copy];
}
@end