Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added ZipKit sources

  • Loading branch information...
commit bb357d83d2621b1274fb6d14c8127e0548468ca6 1 parent 4cd7f4d
@0xced authored
Showing with 3,936 additions and 0 deletions.
  1. +42 −0 External/ZipKit/COPYING.TXT
  2. +21 −0 External/ZipKit/Credits.html
  3. +15 −0 External/ZipKit/GMAppleDouble+ZKAdditions.h
  4. +58 −0 External/ZipKit/GMAppleDouble+ZKAdditions.m
  5. +128 −0 External/ZipKit/MacFUSE/COPYING.TXT
  6. +167 −0 External/ZipKit/MacFUSE/GMAppleDouble.h
  7. +196 −0 External/ZipKit/MacFUSE/GMAppleDouble.m
  8. +36 −0 External/ZipKit/NSData+ZKAdditions.h
  9. +178 −0 External/ZipKit/NSData+ZKAdditions.m
  10. +15 −0 External/ZipKit/NSDate+ZKAdditions.h
  11. +31 −0 External/ZipKit/NSDate+ZKAdditions.m
  12. +16 −0 External/ZipKit/NSDictionary+ZKAdditions.h
  13. +29 −0 External/ZipKit/NSDictionary+ZKAdditions.m
  14. +14 −0 External/ZipKit/NSFileHandle+ZKAdditions.h
  15. +23 −0 External/ZipKit/NSFileHandle+ZKAdditions.m
  16. +32 −0 External/ZipKit/NSFileManager+ZKAdditions.h
  17. +185 −0 External/ZipKit/NSFileManager+ZKAdditions.m
  18. +15 −0 External/ZipKit/NSString+ZKAdditions.h
  19. +22 −0 External/ZipKit/NSString+ZKAdditions.m
  20. +70 −0 External/ZipKit/ZKArchive.h
  21. +261 −0 External/ZipKit/ZKArchive.m
  22. +67 −0 External/ZipKit/ZKCDHeader.h
  23. +247 −0 External/ZipKit/ZKCDHeader.m
  24. +40 −0 External/ZipKit/ZKCDTrailer.h
  25. +142 −0 External/ZipKit/ZKCDTrailer.m
  26. +41 −0 External/ZipKit/ZKCDTrailer64.h
  27. +80 −0 External/ZipKit/ZKCDTrailer64.m
  28. +29 −0 External/ZipKit/ZKCDTrailer64Locator.h
  29. +62 −0 External/ZipKit/ZKCDTrailer64Locator.m
  30. +32 −0 External/ZipKit/ZKDataArchive.h
  31. +377 −0 External/ZipKit/ZKDataArchive.m
  32. +50 −0 External/ZipKit/ZKDefs.h
  33. +38 −0 External/ZipKit/ZKDefs.m
  34. +31 −0 External/ZipKit/ZKFileArchive.h
  35. +719 −0 External/ZipKit/ZKFileArchive.m
  36. +48 −0 External/ZipKit/ZKLFHeader.h
  37. +185 −0 External/ZipKit/ZKLFHeader.m
  38. +52 −0 External/ZipKit/ZKLog.h
  39. +142 −0 External/ZipKit/ZKLog.m
View
42 External/ZipKit/COPYING.TXT
@@ -0,0 +1,42 @@
+ZipKit is covered under the following BSD-style license:
+ ================================================================
+ Copyright (c) 2009, Karl Moskowski
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Karl Moskowski nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ================================================================
+
+Acknowledgement using this text is appreciated:
+ ZipKit developed by Karl Moskowski.
+ http://bitbucket.org/kolpanic/zipkit/
+
+------------------------------------------------------------------------------------------------
+
+The GMAppleDouble class used in this project is part of the MacFUSE project by Google Inc.
+ <http://code.google.com/p/macfuse/>
+
+See the file COPYING.TXT in the MacFUSE folder for license details.
View
21 External/ZipKit/Credits.html
@@ -0,0 +1,21 @@
+<html>
+ <style type="text/css">
+ body {
+ font-family: Arial,Helvetica,Verdana, sans-serif;
+ font-size: 10px;
+ text-align: center;
+ }
+ </style>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+ <title>ZipKit Credits</title>
+ </head>
+ <body>
+ <p>
+ Thanks to <a href="http://jaka.kubje.org/">Jaka Jančar</a> for manual memory management &amp; iPhoneOS support.
+ </p>
+ <p>
+ Portions of <a href="http://code.google.com/p/macfuse/">MacFUSE</a> used with appreciation.
+ </p>
+ </body>
+</html>
View
15 External/ZipKit/GMAppleDouble+ZKAdditions.h
@@ -0,0 +1,15 @@
+//
+// GMAppleDouble+ZKAdditions.h
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import "GMAppleDouble.h"
+
+@interface GMAppleDouble (ZKAdditions)
+
++ (NSData *) zk_appleDoubleDataForPath:(NSString *)path;
++ (void) zk_restoreAppleDoubleData:(NSData *)appleDoubleData toPath:(NSString *)path;
+
+@end
View
58 External/ZipKit/GMAppleDouble+ZKAdditions.m
@@ -0,0 +1,58 @@
+//
+// GMAppleDouble+ZKAdditions.m
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import "GMAppleDouble+ZKAdditions.h"
+#include <sys/xattr.h>
+
+@implementation GMAppleDouble (ZKAdditions)
+
++ (NSData *) zk_appleDoubleDataForPath:(NSString *)path {
+ // extract a file's Finder info metadata and resource fork to a NSData object suitable for writing to a ._ file
+ NSData *appleDoubleData = nil;
+ if ([[[NSFileManager new] autorelease] fileExistsAtPath:path]) {
+ GMAppleDouble *appleDouble = [GMAppleDouble appleDouble];
+ NSMutableData *data;
+
+ ssize_t finderInfoSize = getxattr([path fileSystemRepresentation], XATTR_FINDERINFO_NAME, NULL, ULONG_MAX, 0, XATTR_NOFOLLOW);
+ if (finderInfoSize > 0) {
+ data = [NSMutableData dataWithLength:finderInfoSize];
+ if (getxattr([path fileSystemRepresentation], XATTR_FINDERINFO_NAME, [data mutableBytes], [data length], 0, XATTR_NOFOLLOW) > 0)
+ [appleDouble addEntryWithID:DoubleEntryFinderInfo data:data];
+ }
+
+ ssize_t resourceForkSize = getxattr([path fileSystemRepresentation], XATTR_RESOURCEFORK_NAME, NULL, ULONG_MAX, 0, XATTR_NOFOLLOW);
+ if (resourceForkSize > 0) {
+ data = [NSMutableData dataWithLength:resourceForkSize];
+ if (getxattr([path fileSystemRepresentation], XATTR_RESOURCEFORK_NAME, [data mutableBytes], [data length], 0, XATTR_NOFOLLOW) > 0)
+ [appleDouble addEntryWithID:DoubleEntryResourceFork data:data];
+ }
+
+ if ([[appleDouble entries] count])
+ appleDoubleData = [appleDouble data];
+ }
+ return appleDoubleData;
+}
+
++ (void) zk_restoreAppleDoubleData:(NSData *)appleDoubleData toPath:(NSString *)path {
+ // retsore AppleDouble NSData to a file's Finder info metadata and resource fork
+ if ([[[NSFileManager new] autorelease] fileExistsAtPath:path]) {
+ GMAppleDouble *appleDouble = [GMAppleDouble appleDoubleWithData:appleDoubleData];
+ if ([appleDouble entries] && [[appleDouble entries] count] > 0) {
+ for (GMAppleDoubleEntry *entry in [appleDouble entries]) {
+ char *key = NULL;
+ if ([entry entryID] == DoubleEntryFinderInfo)
+ key = XATTR_FINDERINFO_NAME;
+ else if ([entry entryID] == DoubleEntryResourceFork)
+ key = XATTR_RESOURCEFORK_NAME;
+ if (key != NULL)
+ setxattr([path fileSystemRepresentation], key, [[entry data] bytes], [[entry data] length], 0, XATTR_NOFOLLOW);
+ }
+ }
+ }
+}
+
+@end
View
128 External/ZipKit/MacFUSE/COPYING.TXT
@@ -0,0 +1,128 @@
+MacFUSE is a package developed by Google and is covered under the following
+BSD-style license:
+
+ ================================================================
+ Copyright (c) 2007-2009 Google Inc.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ================================================================
+
+Note that Google's patches to the FUSE library (libfuse/*.patch) (and to
+the SSHFS user-space program (filesystems/sshfs/*.patch) are also released
+under the BSD license.
+
+Portions of this package were derived from code developed by other authors.
+Please read further for specific details.
+
+* fusefs/fuse_kernel.h is an unmodified copy of the interface header from
+ the Linux FUSE distribution (http://fuse.sourceforge.net). fuse_kernel.h
+ can be redistributed either under the GPL or under the BSD license. It
+ is being redistributed here under the BSD license.
+
+* Unless otherwise noted, parts of MacFUSE (multiple files in fusefs/) contain
+ code derived from the FreeBSD version of FUSE (http://fuse4bsd.creo.hu),
+ which is covered by the following BSD-style license:
+
+ ================================================================
+ Copyright (C) 2005 Csaba Henk. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ ================================================================
+
+* fusefs/fuse_nodehash.c is a modified version of HashNode.c from an
+ Apple Developer Technical Support (DTS) sample code example. The original
+ source, which is available on http://developer.apple.com/samplecode/, has
+ the following disclaimer:
+
+ ================================================================
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by
+ Apple Computer, Inc. Apple") in consideration of your agreement
+ to the following terms, and your use, installation, modification
+ or redistribution of this Apple software constitutes acceptance
+ of these terms. If you do not agree with these terms, please do
+ not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms,
+ and subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software
+ (the "Apple Software"), to use, reproduce, modify and redistribute
+ the Apple Software, with or without modifications, in source and/or
+ binary forms; provided that if you redistribute the Apple Software
+ in its entirety and without modifications, you must retain this
+ notice and the following text and disclaimers in all such
+ redistributions of the Apple Software. Neither the name,
+ trademarks, service marks or logos of Apple Computer, Inc. may be
+ used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses,
+ express or implied, are granted by Apple herein, including but
+ not limited to any patent rights that may be infringed by your
+ derivative works or by other works in which the Apple Software
+ may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR
+ ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT,
+ INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
+ REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE,
+ HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
+ NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ================================================================
+
+* Parts of the mount_fusefs and the load_fusefs command-line programs
+ (implemented in fusefs/mount_fusefs/ and fusefs/load_fusefs/, respectively)
+ come from Apple's Darwin sources and are covered under the Apple Public
+ Source License (APSL). You can read the APSL at:
+
+ http://www.publicsource.apple.com/apsl/
View
167 External/ZipKit/MacFUSE/GMAppleDouble.h
@@ -0,0 +1,167 @@
+// ================================================================
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// ================================================================
+//
+// GMAppleDouble.h
+// MacFUSE
+//
+// Created by ted on 12/29/07.
+//
+
+/*!
+ * @header GMAppleDouble
+ *
+ * A utility class to construct an AppleDouble (._) file.
+ *
+ * AppleDouble files contain information about a corresponding file and are
+ * typically used on file systems that do not support extended attributes.
+ */
+
+#import <Foundation/Foundation.h>
+
+#define GM_EXPORT __attribute__((visibility("default")))
+
+/*!
+ * <pre>
+ * Based on "AppleSingle/AppleDouble Formats for Foreign Files Developer's Note"
+ *
+ * Notes:
+ * DoubleEntryFileDatesInfo
+ * File creation, modification, backup, and access times as number of seconds
+ * before or after 12:00 AM Jan 1 2000 GMT as SInt32.
+ * DoubleEntryFinderInfo
+ * 16 bytes of FinderInfo followed by 16 bytes of extended FinderInfo.
+ * New FinderInfo should be zero'd out. For a directory, when the Finder
+ * encounters an entry with the init'd bit cleared, it will initialize the
+ * frView field of the to a value indicating how the contents of the
+ * directory should be shown. Recommend to set frView to value of 256.
+ * DoubleEntryMacFileInfo
+ * This is a 32 bit flag that stores locked (bit 0) and protected (bit 1).
+ * </pre>
+ */
+typedef enum {
+ DoubleEntryInvalid = 0,
+ DoubleEntryDataFork = 1,
+ DoubleEntryResourceFork = 2,
+ DoubleEntryRealName = 3,
+ DoubleEntryComment = 4,
+ DoubleEntryBlackAndWhiteIcon = 5,
+ DoubleEntryColorIcon = 6,
+ DoubleEntryFileDatesInfo = 8, // See notes
+ DoubleEntryFinderInfo = 9, // See notes
+ DoubleEntryMacFileInfo = 10, // See notes
+ DoubleEntryProDosFileInfo = 11,
+ DoubleEntryMSDosFileinfo = 12,
+ DoubleEntryShortName = 13,
+ DoubleEntryAFPFileInfo = 14,
+ DoubleEntryDirectoryID = 15,
+} GMAppleDoubleEntryID;
+
+/*!
+ * @class
+ * @discussion This class represents a single entry in an AppleDouble file.
+ */
+GM_EXPORT @interface GMAppleDoubleEntry : NSObject {
+@private
+ GMAppleDoubleEntryID entryID_;
+ NSData* data_; // Format depends on entryID_
+}
+/*!
+ * @abstract Initializes an AppleDouble entry with ID and data.
+ * @param entryID A valid entry identifier
+ * @param data Raw data for the entry
+ */
+- (id)initWithEntryID:(GMAppleDoubleEntryID)entryID data:(NSData *)data;
+
+/*! @abstract The entry ID */
+- (GMAppleDoubleEntryID)entryID;
+
+/*! @abstract The entry data */
+- (NSData *)data;
+@end
+
+/*!
+ * @class
+ * @discussion This class can be used to construct raw AppleDouble data.
+ */
+GM_EXPORT @interface GMAppleDouble : NSObject {
+@private
+ NSMutableArray* entries_;
+}
+
+/*! @abstract An autoreleased empty GMAppleDouble file */
++ (GMAppleDouble *)appleDouble;
+
+/*!
+ * @abstract An autoreleased GMAppleDouble file.
+ * @discussion The GMAppleDouble is pre-filled with entries from the raw
+ * AppleDouble file data.
+ * @param data Raw AppleDouble file data.
+ */
++ (GMAppleDouble *)appleDoubleWithData:(NSData *)data;
+
+/*!
+ * @abstract Adds an entry to the AppleDouble file.
+ * @param entry The entry to add
+ */
+- (void)addEntry:(GMAppleDoubleEntry *)entry;
+
+/*!
+ * @abstract Adds an entry to the AppleDouble file with ID and data.
+ * @param entryID The ID of the entry to add
+ * @param data The raw data for the entry to add (retained)
+ */
+- (void)addEntryWithID:(GMAppleDoubleEntryID)entryID data:(NSData *)data;
+
+/*!
+ * @abstract Adds entries based on the provided raw AppleDouble file data.
+ * @discussion This will attempt to parse the given data as an AppleDouble file
+ * and add all entries found.
+ * @param data Raw AppleDouble file data
+ * @param data The raw data for the entry to add (retained)
+ * @result YES if the provided data was parsed correctly.
+ */
+- (BOOL)addEntriesFromAppleDoubleData:(NSData *)data;
+
+/*!
+ * @abstract The set of GMAppleDoubleEntry present in this GMAppleDouble.
+ * @result An array of GMAppleDoubleEntry.
+ */
+- (NSArray *)entries;
+
+/*!
+ * @abstract Constructs raw data for the AppleDouble file.
+ * @result The raw data for an AppleDouble file represented by this GMAppleDouble.
+ */
+- (NSData *)data;
+
+@end
+
+#undef GM_EXPORT
View
196 External/ZipKit/MacFUSE/GMAppleDouble.m
@@ -0,0 +1,196 @@
+// ================================================================
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// ================================================================
+//
+// GMAppleDouble.m
+// MacFUSE
+//
+// Created by ted on 12/29/07.
+//
+#import "GMAppleDouble.h"
+#import "libkern/OSByteOrder.h"
+
+#define GM_APPLE_DOUBLE_HEADER_MAGIC 0x00051607
+#define GM_APPLE_DOUBLE_HEADER_VERSION 0x00020000
+
+typedef struct {
+ UInt32 magicNumber; // Should be 0x00051607
+ UInt32 versionNumber; // Should be 0x00020000
+ char filler[16]; // Zero-filled bytes.
+ UInt16 numberOfEntries; // Number of entries.
+} __attribute__((packed)) DoubleHeader;
+
+typedef struct {
+ UInt32 entryID; // Defines what entry is (0 is invalid)
+ UInt32 offset; // Offset from beginning of file to entry data.
+ UInt32 length; // Length of entry data in bytes.
+} __attribute__((packed)) DoubleEntryHeader;
+
+@implementation GMAppleDoubleEntry
+
++ (GMAppleDoubleEntry *)entryWithID:(GMAppleDoubleEntryID)entryID
+ data:(NSData *)data {
+ return [[[GMAppleDoubleEntry alloc]
+ initWithEntryID:entryID data:data] autorelease];
+}
+
+- (id)initWithEntryID:(GMAppleDoubleEntryID)entryID
+ data:(NSData *)data {
+ if ((self = [super init])) {
+ if (entryID == DoubleEntryInvalid || data == nil) {
+ [self release];
+ return nil;
+ }
+ entryID_ = entryID;
+ data_ = [data retain];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [data_ release];
+ [super dealloc];
+}
+
+- (GMAppleDoubleEntryID)entryID {
+ return entryID_;
+}
+- (NSData *)data {
+ return data_;
+}
+
+@end
+
+@implementation GMAppleDouble
+
++ (GMAppleDouble *)appleDouble {
+ return [[[GMAppleDouble alloc] init] autorelease];
+}
+
++ (GMAppleDouble *)appleDoubleWithData:(NSData *)data {
+ GMAppleDouble* appleDouble = [[[GMAppleDouble alloc] init] autorelease];
+ if ([appleDouble addEntriesFromAppleDoubleData:data]) {
+ return appleDouble;
+ }
+ return nil;
+}
+
+- (id)init {
+ if ((self = [super init])) {
+ entries_ = [[NSMutableArray alloc] init];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [entries_ release];
+ [super dealloc];
+}
+
+- (void)addEntry:(GMAppleDoubleEntry *)entry {
+ [entries_ addObject:entry];
+}
+
+- (void)addEntryWithID:(GMAppleDoubleEntryID)entryID data:(NSData *)data {
+ GMAppleDoubleEntry* entry = [GMAppleDoubleEntry entryWithID:entryID data:data];
+ [self addEntry:entry];
+}
+
+- (BOOL)addEntriesFromAppleDoubleData:(NSData *)data {
+ const int len = [data length];
+ DoubleHeader header;
+ if (len < sizeof(header)) {
+ return NO; // To small to even fit our header.
+ }
+ [data getBytes:&header length:sizeof(header)];
+ if (OSSwapBigToHostInt32(header.magicNumber) != GM_APPLE_DOUBLE_HEADER_MAGIC ||
+ OSSwapBigToHostInt32(header.versionNumber) != GM_APPLE_DOUBLE_HEADER_VERSION) {
+ return NO; // Invalid header.
+ }
+ int count = OSSwapBigToHostInt16(header.numberOfEntries);
+ int offset = sizeof(DoubleHeader);
+ if (len < (offset + (count * sizeof(DoubleEntryHeader)))) {
+ return NO; // Not enough data to hold all the DoubleEntryHeader.
+ }
+ for (int i = 0; i < count; ++i, offset += sizeof(DoubleEntryHeader)) {
+ // Extract header
+ DoubleEntryHeader entryHeader;
+ NSRange range = NSMakeRange(offset, sizeof(entryHeader));
+ [data getBytes:&entryHeader range:range];
+
+ // Extract data
+ range = NSMakeRange(OSSwapBigToHostInt32(entryHeader.offset),
+ OSSwapBigToHostInt32(entryHeader.length));
+ if (len < (range.location + range.length)) {
+ return NO; // Given data too small to contain this entry.
+ }
+ NSData* entryData = [data subdataWithRange:range];
+ [self addEntryWithID:OSSwapBigToHostInt32(entryHeader.entryID) data:entryData];
+ }
+
+ return YES;
+}
+
+- (NSArray *)entries {
+ return entries_;
+}
+
+- (NSData *)data {
+ NSMutableData* entryListData = [NSMutableData data];
+ NSMutableData* entryData = [NSMutableData data];
+ int dataStartOffset =
+ sizeof(DoubleHeader) + [entries_ count] * sizeof(DoubleEntryHeader);
+ for (int i = 0; i < [entries_ count]; ++i) {
+ GMAppleDoubleEntry* entry = [entries_ objectAtIndex:i];
+
+ DoubleEntryHeader entryHeader;
+ memset(&entryHeader, 0, sizeof(entryHeader));
+ entryHeader.entryID = OSSwapHostToBigInt32((UInt32)[entry entryID]);
+ entryHeader.offset =
+ OSSwapHostToBigInt32((UInt32)(dataStartOffset + [entryData length]));
+ entryHeader.length = OSSwapHostToBigInt32((UInt32)[[entry data] length]);
+ [entryListData appendBytes:&entryHeader length:sizeof(entryHeader)];
+ [entryData appendData:[entry data]];
+ }
+
+ NSMutableData* data = [NSMutableData data];
+
+ DoubleHeader header;
+ memset(&header, 0, sizeof(header));
+ header.magicNumber = OSSwapHostToBigConstInt32(GM_APPLE_DOUBLE_HEADER_MAGIC);
+ header.versionNumber = OSSwapHostToBigConstInt32(GM_APPLE_DOUBLE_HEADER_VERSION);
+ header.numberOfEntries = OSSwapHostToBigInt16((UInt16)[entries_ count]);
+ [data appendBytes:&header length:sizeof(header)];
+ [data appendData:entryListData];
+ [data appendData:entryData];
+ return data;
+}
+
+@end
View
36 External/ZipKit/NSData+ZKAdditions.h
@@ -0,0 +1,36 @@
+//
+// NSData+ZKAdditions.h
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSData (ZKAdditions)
+
+- (UInt16) zk_hostInt16OffsetBy:(NSUInteger *)offset;
+- (UInt32) zk_hostInt32OffsetBy:(NSUInteger *)offset;
+- (UInt64) zk_hostInt64OffsetBy:(NSUInteger *)offset;
+- (BOOL) zk_hostBoolOffsetBy:(NSUInteger *) offset;
+- (NSString *) zk_stringOffsetBy:(NSUInteger *)offset length:(NSUInteger)length;
+- (NSUInteger) zk_crc32;
+- (NSUInteger) zk_crc32:(NSUInteger)crc;
+- (NSData *) zk_inflate;
+- (NSData *) zk_deflate;
+
+@end
+
+@interface NSMutableData (ZKAdditions)
+
++ (NSMutableData *) zk_dataWithLittleInt16:(UInt16)value;
++ (NSMutableData *) zk_dataWithLittleInt32:(UInt32)value;
++ (NSMutableData *) zk_dataWithLittleInt64:(UInt64)value;
+
+- (void) zk_appendLittleInt16:(UInt16)value;
+- (void) zk_appendLittleInt32:(UInt32)value;
+- (void) zk_appendLittleInt64:(UInt64)value;
+- (void) zk_appendLittleBool:(BOOL) value;
+- (void) zk_appendPrecomposedUTF8String:(NSString *)value;
+
+@end
View
178 External/ZipKit/NSData+ZKAdditions.m
@@ -0,0 +1,178 @@
+//
+// NSData+ZKAdditions.m
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import "NSData+ZKAdditions.h"
+#import "NSFileManager+ZKAdditions.h"
+#import "ZKCDHeader.h"
+#import "ZKCDTrailer.h"
+#import "ZKLFHeader.h"
+#import "zlib.h"
+
+@implementation NSData (ZKAdditions)
+
+- (UInt16) zk_hostInt16OffsetBy:(NSUInteger *)offset {
+ UInt16 value;
+ NSUInteger length = sizeof(value);
+ [self getBytes:&value range:NSMakeRange(*offset, length)];
+ *offset += length;
+ return CFSwapInt16LittleToHost(value);
+}
+
+- (UInt32) zk_hostInt32OffsetBy:(NSUInteger *)offset {
+ UInt32 value;
+ NSUInteger length = sizeof(value);
+ [self getBytes:&value range:NSMakeRange(*offset, length)];
+ *offset += length;
+ return CFSwapInt32LittleToHost(value);
+}
+
+- (UInt64) zk_hostInt64OffsetBy:(NSUInteger *)offset {
+ UInt64 value;
+ NSUInteger length = sizeof(value);
+ [self getBytes:&value range:NSMakeRange(*offset, length)];
+ *offset += length;
+ return CFSwapInt64LittleToHost(value);
+}
+
+- (BOOL) zk_hostBoolOffsetBy:(NSUInteger *)offset {
+ UInt32 value = [self zk_hostInt32OffsetBy:offset];
+ return value != 0;
+}
+
+- (NSString *) zk_stringOffsetBy:(NSUInteger *)offset length:(NSUInteger)length {
+ NSString *value = nil;
+ NSData *subData = [self subdataWithRange:NSMakeRange(*offset, length)];
+ if (length > 0)
+ value = [[[NSString alloc] initWithData:subData encoding:NSUTF8StringEncoding] autorelease];
+ if (!value) {
+ // No valid utf8 encoding, replace everything non-ascii with '?'
+ NSMutableData *md = [subData mutableCopyWithZone:nil];
+ unsigned char *mdd = [md mutableBytes];
+ if ([md length] > 0) {
+ for (unsigned int i = 0; i < [md length]; i++)
+ if (mdd[i] > 127)
+ mdd[i] = '?';
+ value = [[[NSString alloc] initWithData:md encoding:NSUTF8StringEncoding] autorelease];
+ }
+ [md release];
+ }
+ *offset += length;
+ return value;
+}
+
+- (NSUInteger) zk_crc32 {
+ return [self zk_crc32:0];
+}
+
+- (NSUInteger) zk_crc32:(NSUInteger)crc {
+ return crc32(crc, [self bytes], [self length]);
+}
+
+- (NSData *) zk_inflate {
+ NSUInteger full_length = [self length];
+ NSUInteger half_length = full_length / 2;
+
+ NSMutableData *inflatedData = [NSMutableData dataWithLength:full_length + half_length];
+ BOOL done = NO;
+ int status;
+
+ z_stream strm;
+
+ strm.next_in = (Bytef *)[self bytes];
+ strm.avail_in = [self length];
+ strm.total_out = 0;
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+
+ if (inflateInit2(&strm, -MAX_WBITS) != Z_OK) return nil;
+ while (!done) {
+ if (strm.total_out >= [inflatedData length])
+ [inflatedData increaseLengthBy:half_length];
+ strm.next_out = [inflatedData mutableBytes] + strm.total_out;
+ strm.avail_out = [inflatedData length] - strm.total_out;
+ status = inflate(&strm, Z_SYNC_FLUSH);
+ if (status == Z_STREAM_END) done = YES;
+ else if (status != Z_OK) break;
+ }
+ if (inflateEnd(&strm) == Z_OK && done)
+ [inflatedData setLength:strm.total_out];
+ else
+ inflatedData = nil;
+ return inflatedData;
+}
+
+- (NSData *) zk_deflate {
+ z_stream strm;
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ strm.total_out = 0;
+ strm.next_in = (Bytef *)[self bytes];
+ strm.avail_in = [self length];
+
+ NSMutableData *deflatedData = [NSMutableData dataWithLength:16384];
+ if (deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK) return nil;
+ do {
+ if (strm.total_out >= [deflatedData length])
+ [deflatedData increaseLengthBy:16384];
+ strm.next_out = [deflatedData mutableBytes] + strm.total_out;
+ strm.avail_out = [deflatedData length] - strm.total_out;
+ deflate(&strm, Z_FINISH);
+ } while (strm.avail_out == 0);
+ deflateEnd(&strm);
+ [deflatedData setLength:strm.total_out];
+
+ return deflatedData;
+}
+
+@end
+
+@implementation NSMutableData (ZKAdditions)
+
++ (NSMutableData *) zk_dataWithLittleInt16:(UInt16)value {
+ NSMutableData *data = [self data];
+ [data zk_appendLittleInt16:value];
+ return data;
+}
+
++ (NSMutableData *) zk_dataWithLittleInt32:(UInt32)value {
+ NSMutableData *data = [self data];
+ [data zk_appendLittleInt32:value];
+ return data;
+}
+
++ (NSMutableData *) zk_dataWithLittleInt64:(UInt64)value {
+ NSMutableData *data = [self data];
+ [data zk_appendLittleInt64:value];
+ return data;
+}
+
+- (void) zk_appendLittleInt16:(UInt16)value {
+ UInt16 swappedValue = CFSwapInt16HostToLittle(value);
+ [self appendBytes:&swappedValue length:sizeof(swappedValue)];
+}
+
+- (void) zk_appendLittleInt32:(UInt32)value {
+ UInt32 swappedValue = CFSwapInt32HostToLittle(value);
+ [self appendBytes:&swappedValue length:sizeof(swappedValue)];
+}
+
+- (void) zk_appendLittleInt64:(UInt64)value {
+ UInt64 swappedValue = CFSwapInt64HostToLittle(value);
+ [self appendBytes:&swappedValue length:sizeof(swappedValue)];
+}
+
+- (void) zk_appendLittleBool:(BOOL)value {
+ return [self zk_appendLittleInt32:(value ? 1:0)];
+}
+
+- (void) zk_appendPrecomposedUTF8String:(NSString *)value {
+ return [self appendData:[[value precomposedStringWithCanonicalMapping] dataUsingEncoding:NSUTF8StringEncoding]];
+}
+
+@end
View
15 External/ZipKit/NSDate+ZKAdditions.h
@@ -0,0 +1,15 @@
+//
+// NSDate+ZKAdditions.h
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSDate (ZKAdditions)
+
++ (NSDate *) zk_dateWithDosDate:(NSUInteger) dosDate;
+- (NSUInteger) zk_dosDate;
+
+@end
View
31 External/ZipKit/NSDate+ZKAdditions.m
@@ -0,0 +1,31 @@
+//
+// NSDate+ZKAdditions.m
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import "NSDate+ZKAdditions.h"
+
+@implementation NSDate (ZKAdditions)
+
++ (NSDate *)zk_dateWithDosDate : (NSUInteger)dosDate {
+ NSUInteger date = (NSUInteger)(dosDate >> 16);
+ NSDateComponents *comps = [[NSDateComponents new] autorelease];
+ comps.year = ((date & 0x0FE00) / 0x0200) + 1980;
+ comps.month = (date & 0x1E0) / 0x20;
+ comps.day = date & 0x1f;
+ comps.hour = (dosDate & 0xF800) / 0x800;
+ comps.minute = (dosDate & 0x7E0) / 0x20;
+ comps.second = 2 * (dosDate & 0x1f);
+ return [[NSCalendar currentCalendar] dateFromComponents:comps];
+}
+
+- (NSUInteger) zk_dosDate {
+ NSUInteger options = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit |
+ NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
+ NSDateComponents *comps = [[NSCalendar currentCalendar] components:options fromDate:self];
+ return ((comps.day + 32 * comps.month + 512 * (comps.year - 1980)) << 16) | (comps.second / 2 + 32 * comps.minute + 2048 * comps.hour);
+}
+
+@end
View
16 External/ZipKit/NSDictionary+ZKAdditions.h
@@ -0,0 +1,16 @@
+//
+// NSDictionary+ZKAdditions.h
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSDictionary (ZKAdditions)
+
++ (NSDictionary *) zk_totalSizeAndCountDictionaryWithSize:(unsigned long long) size andItemCount:(unsigned long long) count;
+- (unsigned long long) zk_totalFileSize;
+- (unsigned long long) zk_itemCount;
+
+@end
View
29 External/ZipKit/NSDictionary+ZKAdditions.m
@@ -0,0 +1,29 @@
+//
+// NSDictionary+ZKAdditions.m
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import "NSDictionary+ZKAdditions.h"
+
+NSString* const ZKTotalFileSize = @"ZKTotalFileSize";
+NSString* const ZKItemCount = @"ZKItemCount";
+
+@implementation NSDictionary (ZKAdditions)
+
++ (NSDictionary *) zk_totalSizeAndCountDictionaryWithSize:(unsigned long long) size andItemCount:(unsigned long long) count {
+ return [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithUnsignedLongLong:size], ZKTotalFileSize,
+ [NSNumber numberWithUnsignedLongLong:count], ZKItemCount, nil];
+}
+
+- (unsigned long long) zk_totalFileSize {
+ return [[self objectForKey:ZKTotalFileSize] unsignedLongLongValue];
+}
+
+- (unsigned long long) zk_itemCount {
+ return [[self objectForKey:ZKItemCount] unsignedLongLongValue];
+}
+
+@end
View
14 External/ZipKit/NSFileHandle+ZKAdditions.h
@@ -0,0 +1,14 @@
+//
+// NSFileHandle+ZKAdditions.h
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSFileHandle (ZKAdditions)
+
++ (NSFileHandle *) zk_newFileHandleForWritingAtPath:(NSString *)path;
+
+@end
View
23 External/ZipKit/NSFileHandle+ZKAdditions.m
@@ -0,0 +1,23 @@
+//
+// NSFileHandle+ZKAdditions.m
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import "NSFileHandle+ZKAdditions.h"
+
+@implementation NSFileHandle (ZKAdditions)
+
++ (NSFileHandle *)zk_newFileHandleForWritingAtPath:(NSString *)path {
+ NSFileManager *fm = [NSFileManager new];
+ if (![fm fileExistsAtPath:path]) {
+ [fm createDirectoryAtPath:[path stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil];
+ [fm createFileAtPath:path contents:nil attributes:nil];
+ }
+ NSFileHandle *fileHandle = [self fileHandleForWritingAtPath:path];
+ [fm release];
+ return fileHandle;
+}
+
+@end
View
32 External/ZipKit/NSFileManager+ZKAdditions.h
@@ -0,0 +1,32 @@
+//
+// NSFileManager+ZKAdditions.h
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import <Foundation/Foundation.h>
+#import "ZKDefs.h"
+
+@interface NSFileManager (ZKAdditions)
+
+- (BOOL) zk_isSymLinkAtPath:(NSString *) path;
+- (BOOL) zk_isDirAtPath:(NSString *) path;
+
+- (unsigned long long) zk_dataSizeAtFilePath:(NSString *) path;
+- (NSDictionary *) zkTotalSizeAndItemCountAtPath:(NSString *) path usingResourceFork:(BOOL) rfFlag;
+#if ZK_TARGET_OS_MAC
+- (void) zk_combineAppleDoubleInDirectory:(NSString *) path;
+#endif
+
+- (NSDate *) zk_modificationDateForPath:(NSString *) path;
+- (NSUInteger) zk_posixPermissionsAtPath:(NSString *) path;
+- (NSUInteger) zk_externalFileAttributesAtPath:(NSString *) path;
+- (NSUInteger) zk_externalFileAttributesFor:(NSDictionary *) fileAttributes;
+
+- (NSUInteger) zk_crcForPath:(NSString *) path;
+- (NSUInteger) zk_crcForPath:(NSString *) path invoker:(id) invoker;
+- (NSUInteger) zk_crcForPath:(NSString *) path invoker:(id)invoker;
+- (NSUInteger) zk_crcForPath:(NSString *)path invoker:(id)invoker throttleThreadSleepTime:(NSTimeInterval) throttleThreadSleepTime;
+
+@end
View
185 External/ZipKit/NSFileManager+ZKAdditions.m
@@ -0,0 +1,185 @@
+//
+// NSFileManager+ZKAdditions.m
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import "NSFileManager+ZKAdditions.h"
+#import "NSData+ZKAdditions.h"
+#import "NSDictionary+ZKAdditions.h"
+
+#if ZK_TARGET_OS_MAC
+#import "GMAppleDouble+ZKAdditions.h"
+#endif
+
+const NSUInteger ZKMaxEntriesPerFetch = 40;
+
+@implementation NSFileManager (ZKAdditions)
+
+- (BOOL) zk_isSymLinkAtPath:(NSString *) path {
+ return [[[self attributesOfItemAtPath:path error:nil] fileType] isEqualToString:NSFileTypeSymbolicLink];
+}
+
+- (BOOL) zk_isDirAtPath:(NSString *) path {
+ BOOL isDir;
+ BOOL pathExists = [self fileExistsAtPath:path isDirectory:&isDir];
+ return pathExists && isDir;
+}
+
+- (unsigned long long) zk_dataSizeAtFilePath:(NSString *) path {
+ return [[self attributesOfItemAtPath:path error:nil] fileSize];
+}
+
+#if ZK_TARGET_OS_MAC
+- (void) totalsAtDirectoryFSRef:(FSRef*) fsRef usingResourceFork:(BOOL) rfFlag
+ totalSize:(unsigned long long *) size
+ itemCount:(unsigned long long *) count {
+ FSIterator iterator;
+ OSErr fsErr = FSOpenIterator(fsRef, kFSIterateFlat, &iterator);
+ if (fsErr == noErr) {
+ ItemCount actualFetched;
+ FSRef fetchedRefs[ZKMaxEntriesPerFetch];
+ FSCatalogInfo fetchedInfos[ZKMaxEntriesPerFetch];
+ while (fsErr == noErr) {
+ fsErr = FSGetCatalogInfoBulk(iterator, ZKMaxEntriesPerFetch, &actualFetched, NULL,
+ kFSCatInfoDataSizes | kFSCatInfoRsrcSizes | kFSCatInfoNodeFlags,
+ fetchedInfos, fetchedRefs, NULL, NULL);
+ if ((fsErr == noErr) || (fsErr == errFSNoMoreItems)) {
+ (*count) += actualFetched;
+ for (ItemCount i = 0; i < actualFetched; i++) {
+ if (fetchedInfos[i].nodeFlags & kFSNodeIsDirectoryMask)
+ [self totalsAtDirectoryFSRef:&fetchedRefs[i] usingResourceFork:rfFlag totalSize:size itemCount:count];
+ else
+ (*size) += fetchedInfos [i].dataLogicalSize + (rfFlag ? fetchedInfos [i].rsrcLogicalSize : 0);
+ }
+ }
+ }
+ FSCloseIterator(iterator);
+ }
+ return ;
+}
+#endif
+
+- (NSDictionary *) zkTotalSizeAndItemCountAtPath:(NSString *) path usingResourceFork:(BOOL) rfFlag {
+ unsigned long long size = 0;
+ unsigned long long count = 0;
+#if ZK_TARGET_OS_MAC
+ FSRef fsRef;
+ Boolean isDirectory;
+ OSStatus status = FSPathMakeRef((const unsigned char*)[path fileSystemRepresentation], &fsRef, &isDirectory);
+ if (status != noErr)
+ return nil;
+ if (isDirectory) {
+ [self totalsAtDirectoryFSRef:&fsRef usingResourceFork:rfFlag totalSize:&size itemCount:&count];
+ } else {
+ count = 1;
+ FSCatalogInfo info;
+ OSErr fsErr = FSGetCatalogInfo(&fsRef, kFSCatInfoDataSizes | kFSCatInfoRsrcSizes, &info, NULL, NULL, NULL);
+ if (fsErr == noErr)
+ size = info.dataLogicalSize + (rfFlag ? info.rsrcLogicalSize : 0);
+ }
+#else
+ // TODO: maybe fix this for non-Mac targets
+ size = 0;
+ count = 0;
+#endif
+ return [NSDictionary zk_totalSizeAndCountDictionaryWithSize:size andItemCount:count];
+}
+
+#if ZK_TARGET_OS_MAC
+- (void) zk_combineAppleDoubleInDirectory:(NSString *) path {
+ if (![self zk_isDirAtPath:path])
+ return;
+ NSArray *dirContents = [self contentsOfDirectoryAtPath:path error:nil];
+ for (NSString *entry in dirContents) {
+ NSString *subPath = [path stringByAppendingPathComponent:entry];
+ if (![self zk_isSymLinkAtPath:subPath]) {
+ if ([self zk_isDirAtPath:subPath])
+ [self zk_combineAppleDoubleInDirectory:subPath];
+ else {
+ // if the file is an AppleDouble file (i.e., it begins with "._") in the __MACOSX hierarchy,
+ // find its corresponding data fork and combine them
+ if ([subPath rangeOfString:ZKMacOSXDirectory].location != NSNotFound) {
+ NSString *fileName = [subPath lastPathComponent];
+ NSRange ZKDotUnderscoreRange = [fileName rangeOfString:ZKDotUnderscore];
+ if (ZKDotUnderscoreRange.location == 0 && ZKDotUnderscoreRange.length == 2) {
+ NSMutableArray *pathComponents =
+ (NSMutableArray *)[[[subPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:
+ [fileName substringFromIndex:2]] pathComponents];
+ for (NSString *pathComponent in pathComponents) {
+ if ([ZKMacOSXDirectory isEqualToString:pathComponent]) {
+ [pathComponents removeObject:pathComponent];
+ break;
+ }
+ }
+ NSData *appleDoubleData = [NSData dataWithContentsOfFile:subPath];
+ [GMAppleDouble zk_restoreAppleDoubleData:appleDoubleData toPath:[NSString pathWithComponents:pathComponents]];
+ }
+ }
+ }
+ }
+ }
+}
+#endif
+
+- (NSDate *) zk_modificationDateForPath:(NSString *) path {
+ return [[self attributesOfItemAtPath:path error:nil] fileModificationDate];
+}
+
+- (NSUInteger) zk_posixPermissionsAtPath:(NSString *) path {
+ return [[self attributesOfItemAtPath:path error:nil] filePosixPermissions];
+}
+
+- (NSUInteger) zk_externalFileAttributesAtPath:(NSString *) path {
+ return [self zk_externalFileAttributesFor:[self attributesOfItemAtPath:path error:nil]];
+}
+
+- (NSUInteger) zk_externalFileAttributesFor:(NSDictionary *) fileAttributes {
+ NSUInteger externalFileAttributes = 0;
+ @try {
+ BOOL isSymLink = [[fileAttributes fileType] isEqualToString:NSFileTypeSymbolicLink];
+ BOOL isDir = [[fileAttributes fileType] isEqualToString:NSFileTypeDirectory];
+ NSUInteger posixPermissions = [fileAttributes filePosixPermissions];
+ externalFileAttributes = posixPermissions << 16 | (isSymLink ? 0xA0004000 : (isDir ? 0x40004000 : 0x80004000));
+ } @catch(NSException * e) {
+ externalFileAttributes = 0;
+ }
+ return externalFileAttributes;
+}
+
+- (NSUInteger) zk_crcForPath:(NSString *) path {
+ return [self zk_crcForPath:path invoker:nil throttleThreadSleepTime:0.0];
+}
+
+- (NSUInteger) zk_crcForPath:(NSString *) path invoker:(id)invoker {
+ return [self zk_crcForPath:path invoker:invoker throttleThreadSleepTime:0.0];
+}
+
+- (NSUInteger) zk_crcForPath:(NSString *)path invoker:(id)invoker throttleThreadSleepTime:(NSTimeInterval) throttleThreadSleepTime {
+ NSUInteger crc32 = 0;
+ path = [path stringByExpandingTildeInPath];
+ BOOL isDirectory;
+ if ([self fileExistsAtPath:path isDirectory:&isDirectory] && !isDirectory) {
+ BOOL irtsIsCancelled = [invoker respondsToSelector:@selector(isCancelled)];
+ const NSUInteger crcBlockSize = 1048576;
+ NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
+ NSData *block = [fileHandle readDataOfLength:crcBlockSize] ;
+ while ([block length] > 0) {
+ crc32 = [block zk_crc32:crc32];
+ if (irtsIsCancelled) {
+ if ([invoker isCancelled]) {
+ [fileHandle closeFile];
+ return 0;
+ }
+ }
+ block = [fileHandle readDataOfLength:crcBlockSize];
+ [NSThread sleepForTimeInterval:throttleThreadSleepTime];
+ }
+ [fileHandle closeFile];
+ } else
+ crc32 = 0;
+ return crc32;
+}
+
+@end
View
15 External/ZipKit/NSString+ZKAdditions.h
@@ -0,0 +1,15 @@
+//
+// NSString+ZKAdditions.h
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSString (ZKAdditions)
+
+- (NSUInteger) zk_precomposedUTF8Length;
+- (BOOL) zk_isResourceForkPath;
+
+@end
View
22 External/ZipKit/NSString+ZKAdditions.m
@@ -0,0 +1,22 @@
+//
+// NSString+ZKAdditions.m
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import "NSString+ZKAdditions.h"
+#import "ZKDefs.h"
+
+@implementation NSString (ZKAdditions)
+
+- (NSUInteger) zk_precomposedUTF8Length {
+ return [[self precomposedStringWithCanonicalMapping] lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+}
+
+- (BOOL) zk_isResourceForkPath {
+ return [[[self pathComponents] objectAtIndex:0] isEqualToString:ZKMacOSXDirectory];
+}
+
+
+@end
View
70 External/ZipKit/ZKArchive.h
@@ -0,0 +1,70 @@
+//
+// ZKArchive.h
+// ZipKit
+//
+// Created by Karl Moskowski on 08/05/09.
+//
+
+#import <Foundation/Foundation.h>
+
+@class ZKCDTrailer;
+
+@interface ZKArchive : NSObject {
+@private
+ // invoker should be an NSOperation or NSThread; if [invoker isCancelled], inflation or deflation will be aborted
+ id __weak _invoker;
+ id __weak _delegate;
+ NSString *_archivePath;
+ NSMutableArray *_centralDirectory;
+ NSFileManager *_fileManager;
+ ZKCDTrailer *_cdTrailer;
+ NSTimeInterval _throttleThreadSleepTime;
+
+@protected
+ // cached respondsToSelector: checks
+ BOOL drtsDelegateWantsSizes;
+ BOOL drtsDidBeginZip;
+ BOOL drtsDidBeginUnzip;
+ BOOL drtsWillZipPath;
+ BOOL drtsWillUnzipPath;
+ BOOL drtsDidEndZip;
+ BOOL drtsDidEndUnzip;
+ BOOL drtsDidCancel;
+ BOOL drtsDidFail;
+ BOOL drtsDidUpdateTotalSize;
+ BOOL drtsDidUpdateTotalCount;
+ BOOL drtsDidUpdateBytesWritten;
+
+ BOOL irtsIsCancelled;
+}
+
++ (BOOL) validArchiveAtPath:(NSString *) path;
++ (NSString *) uniquify:(NSString *) path;
+- (void) calculateSizeAndItemCount:(NSDictionary *) userInfo;
+- (NSString *) uniqueExpansionDirectoryIn:(NSString *) enclosingFolder;
+- (void) cleanUpExpansionDirectory:(NSString *) expansionDirectory;
+
+- (BOOL) delegateWantsSizes;
+
+- (void) didBeginZip;
+- (void) didBeginUnzip;
+- (void) willZipPath:(NSString *)path;
+- (void) willUnzipPath:(NSString *)path;
+- (void) didEndZip;
+- (void) didEndUnzip;
+- (void) didCancel;
+- (void) didFail;
+- (void) didUpdateTotalSize:(NSNumber *) size;
+- (void) didUpdateTotalCount:(NSNumber *) count;
+- (void) didUpdateBytesWritten:(NSNumber *) byteCount;
+
+@property (assign, nonatomic) id __weak invoker;
+@property (assign, nonatomic) id __weak delegate;
+@property (copy) NSString *archivePath;
+@property (retain) NSMutableArray *centralDirectory;
+@property (retain) NSFileManager *fileManager;
+@property (retain) ZKCDTrailer *cdTrailer;
+@property (assign) NSTimeInterval throttleThreadSleepTime;
+@property (copy) NSString *comment;
+
+@end
View
261 External/ZipKit/ZKArchive.m
@@ -0,0 +1,261 @@
+//
+// ZKArchive.m
+// ZipKit
+//
+// Created by Karl Moskowski on 08/05/09.
+//
+
+#import "ZKArchive.h"
+#import "NSDictionary+ZKAdditions.h"
+#import "NSFileManager+ZKAdditions.h"
+#import "ZKCDTrailer.h"
+#import "ZKDefs.h"
+
+@interface NSObject (ZipKitDelegate)
+- (void) onZKArchiveDidBeginZip:(ZKArchive *) archive;
+- (void) onZKArchiveDidBeginUnzip:(ZKArchive *) archive;
+- (void) onZKArchive:(ZKArchive *) archive willZipPath:(NSString *) path;
+- (void) onZKArchive:(ZKArchive *) archive willUnzipPath:(NSString *) path;
+- (void) onZKArchive:(ZKArchive *) archive didUpdateTotalSize:(unsigned long long) size;
+- (void) onZKArchive:(ZKArchive *) archive didUpdateTotalCount:(unsigned long long) count;
+- (void) onZKArchive:(ZKArchive *) archive didUpdateBytesWritten:(unsigned long long) byteCount;
+- (void) onZKArchiveDidEndZip:(ZKArchive *) archive;
+- (void) onZKArchiveDidEndUnzip:(ZKArchive *) archive;
+- (void) onZKArchiveDidCancel:(ZKArchive *) archive;
+- (void) onZKArchiveDidFail:(ZKArchive *) archive;
+- (BOOL) zkDelegateWantsSizes;
+@end
+
+#pragma mark -
+
+@implementation ZKArchive
+
+#pragma mark -
+#pragma mark Utility
+
++ (BOOL) validArchiveAtPath:(NSString *) path {
+ // check that the first few bytes of the file are a local file header
+ NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
+ NSData *fileHeader = [fileHandle readDataOfLength:4];
+ [fileHandle closeFile];
+ UInt32 headerValue;
+ [fileHeader getBytes:&headerValue];
+ return (CFSwapInt32LittleToHost(headerValue) == ZKLFHeaderMagicNumber);
+}
+
++ (NSString *) uniquify:(NSString *) path {
+ // avoid name collisions by adding a sequence number if needed
+ NSString * uniquePath = [NSString stringWithString:path];
+ NSString *dir = [path stringByDeletingLastPathComponent];
+ NSString *fileNameBase = [[path lastPathComponent] stringByDeletingPathExtension];
+ NSString *ext = [path pathExtension];
+ NSUInteger i = 2;
+ NSFileManager *fm = [[NSFileManager new] autorelease];
+ while ([fm fileExistsAtPath:uniquePath]) {
+ uniquePath = [dir stringByAppendingPathComponent:[NSString stringWithFormat:@"%@ %u", fileNameBase, i++]];
+ if (ext && [ext length] > 0)
+ uniquePath = [uniquePath stringByAppendingPathExtension:ext];
+ }
+ return uniquePath;
+}
+
+- (void) calculateSizeAndItemCount:(NSDictionary *) userInfo {
+ NSArray *paths = [userInfo objectForKey:ZKPathsKey];
+ BOOL rfFlag = [[userInfo objectForKey:ZKusingResourceForkKey] boolValue];
+ unsigned long long size = 0;
+ unsigned long long count = 0;
+ NSFileManager *fmgr = [[NSFileManager new] autorelease];
+ NSDictionary *dict = nil;
+ for (NSString *path in paths) {
+ dict = [fmgr zkTotalSizeAndItemCountAtPath:path usingResourceFork:rfFlag];
+ size += [dict zk_totalFileSize];
+ count += [dict zk_itemCount];
+ }
+ [self performSelectorOnMainThread:@selector(didUpdateTotalSize:)
+ withObject:[NSNumber numberWithUnsignedLongLong:size] waitUntilDone:NO];
+ [self performSelectorOnMainThread:@selector(didUpdateTotalCount:)
+ withObject:[NSNumber numberWithUnsignedLongLong:count] waitUntilDone:NO];
+}
+
+- (NSString *) uniqueExpansionDirectoryIn:(NSString *) enclosingFolder {
+ NSString *expansionDirectory = [enclosingFolder stringByAppendingPathComponent:ZKExpansionDirectoryName];
+ NSUInteger i = 1;
+ while ([self.fileManager fileExistsAtPath:expansionDirectory]) {
+ expansionDirectory = [enclosingFolder stringByAppendingPathComponent:
+ [NSString stringWithFormat:@"%@ %u", ZKExpansionDirectoryName, i++]];
+ }
+ return expansionDirectory;
+}
+
+- (void) cleanUpExpansionDirectory:(NSString *) expansionDirectory {
+ NSString *enclosingFolder = [expansionDirectory stringByDeletingLastPathComponent];
+ NSArray *dirContents = [self.fileManager contentsOfDirectoryAtPath:expansionDirectory error:nil];
+ for (NSString *item in dirContents) {
+ if (![item isEqualToString:ZKMacOSXDirectory]) {
+ NSString *subPath = [expansionDirectory stringByAppendingPathComponent:item];
+ NSString *dest = [enclosingFolder stringByAppendingPathComponent:item];
+ NSUInteger i = 2;
+ while ([self.fileManager fileExistsAtPath:dest]) {
+ NSString *ext = [item pathExtension];
+ dest = [enclosingFolder stringByAppendingPathComponent:[NSString stringWithFormat:@"%@ %u",
+ [item stringByDeletingPathExtension], i++]];
+ if (ext && [ext length] > 0)
+ dest = [dest stringByAppendingPathExtension:ext];
+ }
+ [self.fileManager moveItemAtPath:subPath toPath:dest error:nil];
+ }
+ }
+ [self.fileManager removeItemAtPath:expansionDirectory error:nil];
+
+}
+
+#pragma mark -
+#pragma mark Accessors
+
+- (NSString *) comment {
+ return self.cdTrailer.comment;
+}
+- (void) setComment:(NSString *)comment {
+ self.cdTrailer.comment = comment;
+}
+
+#pragma mark -
+#pragma mark Delegate
+
+- (void) setInvoker:(id)i {
+ _invoker = i;
+ if (_invoker) {
+ irtsIsCancelled = [self.invoker respondsToSelector:@selector(isCancelled)];
+ } else {
+ irtsIsCancelled = NO;
+ }
+}
+
+- (void) setDelegate:(id)d {
+ _delegate = d;
+ if (_delegate) {
+ drtsDelegateWantsSizes = [_delegate respondsToSelector:@selector(zkDelegateWantsSizes)];
+ drtsDidBeginZip = [_delegate respondsToSelector:@selector(onZKArchiveDidBeginZip:)];
+ drtsDidBeginUnzip = [_delegate respondsToSelector:@selector(onZKArchiveDidBeginUnzip:)];
+ drtsWillZipPath = [_delegate respondsToSelector:@selector(onZKArchive:willZipPath:)];
+ drtsWillUnzipPath = [_delegate respondsToSelector:@selector(onZKArchive:willUnzipPath:)];
+ drtsDidEndZip = [_delegate respondsToSelector:@selector(onZKArchiveDidEndZip:)];
+ drtsDidEndUnzip = [_delegate respondsToSelector:@selector(onZKArchiveDidEndUnzip:)];
+ drtsDidCancel = [_delegate respondsToSelector:@selector(onZKArchiveDidCancel:)];
+ drtsDidFail = [_delegate respondsToSelector:@selector(onZKArchiveDidFail:)];
+ drtsDidUpdateTotalSize = [_delegate respondsToSelector:@selector(onZKArchive:didUpdateTotalSize:)];
+ drtsDidUpdateTotalCount = [_delegate respondsToSelector:@selector(onZKArchive:didUpdateTotalCount:)];
+ drtsDidUpdateBytesWritten = [_delegate respondsToSelector:@selector(onZKArchive:didUpdateBytesWritten:)];
+ } else {
+ drtsDelegateWantsSizes = NO;
+ drtsDidBeginZip = NO;
+ drtsDidBeginUnzip = NO;
+ drtsWillZipPath = NO;
+ drtsWillUnzipPath = NO;
+ drtsDidEndZip = NO;
+ drtsDidEndUnzip = NO;
+ drtsDidCancel = NO;
+ drtsDidFail = NO;
+ drtsDidUpdateTotalSize = NO;
+ drtsDidUpdateTotalCount = NO;
+ drtsDidUpdateBytesWritten = NO;
+ }
+}
+
+- (BOOL) delegateWantsSizes {
+ BOOL delegateWantsSizes = NO;
+ if (drtsDelegateWantsSizes) {
+ delegateWantsSizes = [self.delegate zkDelegateWantsSizes];
+ }
+ return delegateWantsSizes;
+}
+
+- (void) didBeginZip {
+ if (drtsDidBeginZip)
+ [self.delegate onZKArchiveDidBeginZip:self];
+}
+
+- (void) didBeginUnzip {
+ if (drtsDidBeginUnzip)
+ [self.delegate onZKArchiveDidBeginUnzip:self];
+}
+
+- (void) willZipPath:(NSString *) path {
+ if (drtsWillZipPath)
+ [self.delegate onZKArchive:self willZipPath:path];
+}
+
+- (void) willUnzipPath:(NSString *) path {
+ if (drtsWillUnzipPath)
+ [self.delegate onZKArchive:self willUnzipPath:path];
+}
+
+- (void) didEndZip {
+ if (drtsDidEndZip)
+ [self.delegate onZKArchiveDidEndZip:self];
+}
+
+- (void) didEndUnzip {
+ if (drtsDidEndUnzip)
+ [self.delegate onZKArchiveDidEndUnzip:self];
+}
+
+- (void) didCancel {
+ if (drtsDidCancel)
+ [self.delegate onZKArchiveDidCancel:self];
+}
+
+- (void) didFail {
+ if (drtsDidFail)
+ [self.delegate onZKArchiveDidFail:self];
+}
+
+- (void) didUpdateTotalSize:(NSNumber *) size {
+ if (drtsDidUpdateTotalSize)
+ [self.delegate onZKArchive:self didUpdateTotalSize:[size unsignedLongLongValue]];
+}
+
+- (void) didUpdateTotalCount:(NSNumber *) count {
+ if (drtsDidUpdateTotalCount)
+ [self.delegate onZKArchive:self didUpdateTotalCount:[count unsignedLongLongValue]];
+}
+
+- (void) didUpdateBytesWritten:(NSNumber *) byteCount {
+ if (drtsDidUpdateBytesWritten)
+ [self.delegate onZKArchive:self didUpdateBytesWritten:[byteCount unsignedLongLongValue]];
+}
+
+#pragma mark -
+#pragma mark Setup
+
+- (id) init {
+ if (self = [super init]) {
+ self.invoker = nil;
+ self.delegate = nil;
+ self.archivePath = nil;
+ self.centralDirectory = [NSMutableArray array];
+ self.fileManager = [[NSFileManager new] autorelease];
+ self.cdTrailer = [[ZKCDTrailer new] autorelease];
+ self.throttleThreadSleepTime = 0.0;
+ }
+ return self;
+}
+
+- (void) dealloc {
+ self.invoker = nil;
+ self.delegate = nil;
+ self.archivePath = nil;
+ self.centralDirectory = nil;
+ self.fileManager = nil;
+ self.cdTrailer = nil;
+ [super dealloc];
+}
+
+- (NSString *) description {
+ return [NSString stringWithFormat: @"%@\n\ttrailer:%@\n\tcentral directory:%@", self.archivePath, self.cdTrailer, self.centralDirectory];
+}
+
+@synthesize invoker = _invoker, delegate = _delegate, archivePath = _archivePath, centralDirectory = _centralDirectory, fileManager = _fileManager, cdTrailer = _cdTrailer, throttleThreadSleepTime = _throttleThreadSleepTime;
+@dynamic comment;
+
+@end
View
67 External/ZipKit/ZKCDHeader.h
@@ -0,0 +1,67 @@
+//
+// ZKCDHeader.h
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface ZKCDHeader : NSObject {
+@private
+ NSUInteger magicNumber;
+ NSUInteger versionMadeBy;
+ NSUInteger versionNeededToExtract;
+ NSUInteger generalPurposeBitFlag;
+ NSUInteger compressionMethod;
+ NSDate *lastModDate;
+ NSUInteger crc;
+ unsigned long long compressedSize;
+ unsigned long long uncompressedSize;
+ NSUInteger filenameLength;
+ NSUInteger extraFieldLength;
+ NSUInteger commentLength;
+ NSUInteger diskNumberStart;
+ NSUInteger internalFileAttributes;
+ NSUInteger externalFileAttributes;
+ unsigned long long localHeaderOffset;
+ NSString *filename;
+ NSData *extraField;
+ NSString *comment;
+ NSMutableData *cachedData;
+}
+
++ (ZKCDHeader *) recordWithData:(NSData *)data atOffset:(NSUInteger)offset;
++ (ZKCDHeader *) recordWithArchivePath:(NSString *)path atOffset:(unsigned long long)offset;
+- (void) parseZip64ExtraField;
+- (NSData *) zip64ExtraField;
+- (NSData *) data;
+- (NSUInteger) length;
+- (BOOL) useZip64Extensions;
+- (NSNumber *) posixPermissions;
+- (BOOL) isDirectory;
+- (BOOL) isSymLink;
+- (BOOL) isResourceFork;
+
+@property (assign) NSUInteger magicNumber;
+@property (assign) NSUInteger versionMadeBy;
+@property (assign) NSUInteger versionNeededToExtract;
+@property (assign) NSUInteger generalPurposeBitFlag;
+@property (assign) NSUInteger compressionMethod;
+@property (retain) NSDate *lastModDate;
+@property (assign) NSUInteger crc;
+@property (assign) unsigned long long compressedSize;
+@property (assign) unsigned long long uncompressedSize;
+@property (assign) NSUInteger filenameLength;
+@property (assign) NSUInteger extraFieldLength;
+@property (assign) NSUInteger commentLength;
+@property (assign) NSUInteger diskNumberStart;
+@property (assign) NSUInteger internalFileAttributes;
+@property (assign) NSUInteger externalFileAttributes;
+@property (assign) unsigned long long localHeaderOffset;
+@property (copy) NSString *filename;
+@property (retain) NSData *extraField;
+@property (copy) NSString *comment;
+@property (retain) NSMutableData *cachedData;
+
+@end
View
247 External/ZipKit/ZKCDHeader.m
@@ -0,0 +1,247 @@
+//
+// ZKCDHeader.m
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import "ZKCDHeader.h"
+#import "NSDate+ZKAdditions.h"
+#import "NSData+ZKAdditions.h"
+#import "NSString+ZKAdditions.h"
+#import "ZKDefs.h"
+#import "zlib.h"
+
+@implementation ZKCDHeader
+
+- (id) init {
+ if (self = [super init]) {
+ self.magicNumber = ZKCDHeaderMagicNumber;
+ self.versionNeededToExtract = 20;
+ self.versionMadeBy = 789;
+ self.generalPurposeBitFlag = 0;
+ self.compressionMethod = Z_DEFLATED;
+ self.lastModDate = [NSDate date];
+ self.crc = 0;
+ self.compressedSize = 0;
+ self.uncompressedSize = 0;
+ self.filenameLength = 0;
+ self.extraFieldLength = 0;
+ self.commentLength = 0;
+ self.diskNumberStart = 0;
+ self.internalFileAttributes = 0;
+ self.externalFileAttributes = 0;
+ self.localHeaderOffset = 0;
+ self.extraField = nil;
+ self.comment = nil;
+
+ [self addObserver:self forKeyPath:@"compressedSize" options:NSKeyValueObservingOptionNew context:nil];
+ [self addObserver:self forKeyPath:@"uncompressedSize" options:NSKeyValueObservingOptionNew context:nil];
+ [self addObserver:self forKeyPath:@"localHeaderOffset" options:NSKeyValueObservingOptionNew context:nil];
+ [self addObserver:self forKeyPath:@"extraField" options:NSKeyValueObservingOptionNew context:nil];
+ [self addObserver:self forKeyPath:@"filename" options:NSKeyValueObservingOptionNew context:nil];
+ [self addObserver:self forKeyPath:@"comment" options:NSKeyValueObservingOptionNew context:nil];
+ }
+ return self;
+}
+
+- (void) removeObservers {
+ [self removeObserver:self forKeyPath:@"compressedSize"];
+ [self removeObserver:self forKeyPath:@"uncompressedSize"];
+ [self removeObserver:self forKeyPath:@"localHeaderOffset"];
+ [self removeObserver:self forKeyPath:@"extraField"];
+ [self removeObserver:self forKeyPath:@"filename"];
+ [self removeObserver:self forKeyPath:@"comment"];
+}
+
+- (void) dealloc {
+ [self removeObservers];
+ self.cachedData = nil;
+ self.lastModDate = nil;
+ self.filename = nil;
+ self.extraField = nil;
+ self.comment = nil;
+ [super dealloc];
+}
+
+- (void) finalize {
+ self.cachedData = nil;
+ [self removeObservers];
+ [super finalize];
+}
+
+- (void) observeValueForKeyPath:(NSString *) keyPath ofObject:(id) object change:(NSDictionary *) change context:(void *) context {
+ if ([keyPath isEqualToString:@"compressedSize"]
+ || [keyPath isEqualToString:@"uncompressedSize"]
+ || [keyPath isEqualToString:@"localHeaderOffset"]) {
+ self.versionNeededToExtract = ([self useZip64Extensions] ? 45 : 20);
+ } else if ([keyPath isEqualToString:@"extraField"] && self.extraFieldLength < 1) {
+ self.extraFieldLength = [self.extraField length];
+ } else if ([keyPath isEqualToString:@"filename"] && self.filenameLength < 1) {
+ self.filenameLength = [self.filename zk_precomposedUTF8Length];
+ } else if ([keyPath isEqualToString:@"comment"] && self.commentLength < 1) {
+ self.commentLength = [self.comment zk_precomposedUTF8Length];
+ }
+}
+
++ (ZKCDHeader *) recordWithData:(NSData *)data atOffset:(NSUInteger)offset {
+ if (!data) return nil;
+ NSUInteger mn = [data zk_hostInt32OffsetBy:&offset];
+ if (mn != ZKCDHeaderMagicNumber) return nil;
+ ZKCDHeader *record = [[ZKCDHeader new] autorelease];
+ record.magicNumber = mn;
+ record.versionMadeBy = [data zk_hostInt16OffsetBy:&offset];
+ record.versionNeededToExtract = [data zk_hostInt16OffsetBy:&offset];
+ record.generalPurposeBitFlag = [data zk_hostInt16OffsetBy:&offset];
+ record.compressionMethod = [data zk_hostInt16OffsetBy:&offset];
+ record.lastModDate = [NSDate zk_dateWithDosDate:[data zk_hostInt32OffsetBy:&offset]];
+ record.crc = [data zk_hostInt32OffsetBy:&offset];
+ record.compressedSize = [data zk_hostInt32OffsetBy:&offset];
+ record.uncompressedSize = [data zk_hostInt32OffsetBy:&offset];
+ record.filenameLength = [data zk_hostInt16OffsetBy:&offset];
+ record.extraFieldLength = [data zk_hostInt16OffsetBy:&offset];
+ record.commentLength = [data zk_hostInt16OffsetBy:&offset];
+ record.diskNumberStart = [data zk_hostInt16OffsetBy:&offset];
+ record.internalFileAttributes = [data zk_hostInt16OffsetBy:&offset];
+ record.externalFileAttributes = [data zk_hostInt32OffsetBy:&offset];
+ record.localHeaderOffset = [data zk_hostInt32OffsetBy:&offset];
+ if ([data length] > ZKCDHeaderFixedDataLength) {
+ if (record.filenameLength)
+ record.filename = [data zk_stringOffsetBy:&offset length:record.filenameLength];
+ if (record.extraFieldLength) {
+ record.extraField = [data subdataWithRange:NSMakeRange(offset, record.extraFieldLength)];
+ offset += record.extraFieldLength;
+ [record parseZip64ExtraField];
+ }
+ if (record.commentLength)
+ record.comment = [data zk_stringOffsetBy:&offset length:record.commentLength];
+ }
+ return record;
+}
+
++ (ZKCDHeader *) recordWithArchivePath:(NSString *)path atOffset:(unsigned long long)offset {
+ NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
+ [file seekToFileOffset:offset];
+ NSData *fixedData = [file readDataOfLength:ZKCDHeaderFixedDataLength];
+ ZKCDHeader *record = [self recordWithData:fixedData atOffset:0];
+ if (record.filenameLength > 0) {
+ NSData *data = [file readDataOfLength:record.filenameLength];
+ record.filename = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
+ }
+ if (record.extraFieldLength > 0) {
+ record.extraField = [file readDataOfLength:record.extraFieldLength];
+ [record parseZip64ExtraField];
+ }
+ if (record.commentLength > 0) {
+ NSData *data = [file readDataOfLength:record.commentLength];
+ record.comment = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
+ } else
+ record.comment = nil;
+
+ [file closeFile];
+ return record;
+}
+
+- (NSData *) data {
+ if (!self.cachedData || ([self.cachedData length] < ZKCDHeaderFixedDataLength)) {
+ self.extraField = [self zip64ExtraField];
+
+ self.cachedData = [NSMutableData zk_dataWithLittleInt32:self.magicNumber];
+ [self.cachedData zk_appendLittleInt16:self.versionMadeBy];
+ [self.cachedData zk_appendLittleInt16:self.versionNeededToExtract];
+ [self.cachedData zk_appendLittleInt16:self.generalPurposeBitFlag];
+ [self.cachedData zk_appendLittleInt16:self.compressionMethod];
+ [self.cachedData zk_appendLittleInt32:[self.lastModDate zk_dosDate]];
+ [self.cachedData zk_appendLittleInt32:self.crc];
+ if ([self useZip64Extensions]) {
+ [self.cachedData zk_appendLittleInt32:0xFFFFFFFF];
+ [self.cachedData zk_appendLittleInt32:0xFFFFFFFF];
+ } else {
+ [self.cachedData zk_appendLittleInt32:self.compressedSize];
+ [self.cachedData zk_appendLittleInt32:self.uncompressedSize];
+ }
+ [self.cachedData zk_appendLittleInt16:[self.filename zk_precomposedUTF8Length]];
+ [self.cachedData zk_appendLittleInt16:[self.extraField length]];
+ [self.cachedData zk_appendLittleInt16:[self.comment zk_precomposedUTF8Length]];
+ [self.cachedData zk_appendLittleInt16:self.diskNumberStart];
+ [self.cachedData zk_appendLittleInt16:self.internalFileAttributes];
+ [self.cachedData zk_appendLittleInt32:self.externalFileAttributes];
+ if ([self useZip64Extensions])
+ [self.cachedData zk_appendLittleInt32:0xFFFFFFFF];
+ else
+ [self.cachedData zk_appendLittleInt32:self.localHeaderOffset];
+ [self.cachedData zk_appendPrecomposedUTF8String:self.filename];
+ [self.cachedData appendData:self.extraField];
+ [self.cachedData zk_appendPrecomposedUTF8String:self.comment];
+ }
+ return self.cachedData;
+}
+
+- (void) parseZip64ExtraField {
+ NSUInteger offset = 0, tag, length;
+ while (offset < self.extraFieldLength) {
+ tag = [self.extraField zk_hostInt16OffsetBy:&offset];
+ length = [self.extraField zk_hostInt16OffsetBy:&offset];
+ if (tag == 0x0001) {
+ if (length >= 8)
+ self.uncompressedSize = [self.extraField zk_hostInt64OffsetBy:&offset];
+ if (length >= 16)
+ self.compressedSize = [self.extraField zk_hostInt64OffsetBy:&offset];
+ if (length >= 24)
+ self.localHeaderOffset = [self.extraField zk_hostInt64OffsetBy:&offset];
+ break;
+ } else {
+ offset += length;
+ }
+ }
+}
+
+- (NSData *) zip64ExtraField {
+ NSMutableData *zip64ExtraField = nil;
+ if ([self useZip64Extensions]) {
+ zip64ExtraField = [NSMutableData zk_dataWithLittleInt16:0x0001];
+ [zip64ExtraField zk_appendLittleInt16:24];
+ [zip64ExtraField zk_appendLittleInt64:self.uncompressedSize];
+ [zip64ExtraField zk_appendLittleInt64:self.compressedSize];
+ [zip64ExtraField zk_appendLittleInt64:self.localHeaderOffset];
+ }
+ return zip64ExtraField;
+}
+
+- (NSUInteger) length {
+ if (!self.extraField || [self.extraField length] == 0)
+ self.extraField = [self zip64ExtraField];
+ return ZKCDHeaderFixedDataLength + self.filenameLength + self.commentLength + [self.extraField length];
+}
+
+- (BOOL) useZip64Extensions {
+ return (self.uncompressedSize >= 0xFFFFFFFF) || (self.compressedSize >= 0xFFFFFFFF) || (self.localHeaderOffset >= 0xFFFFFFFF);
+}
+
+- (NSString *) description {
+ return [NSString stringWithFormat:@"%@ modified %@, %qu bytes (%qu compressed), @ %qu",
+ self.filename, self.lastModDate, self.uncompressedSize, self.compressedSize, self.localHeaderOffset];
+}
+
+- (NSNumber *) posixPermissions {
+ // if posixPermissions are 0, e.g. on Windows-produced archives, then default them to rwxr-wr-w a la Archive Utility
+ return [NSNumber numberWithUnsignedInteger:(self.externalFileAttributes >> 16 & 0x1FF) ?: 0755U];
+}
+
+- (BOOL) isDirectory {
+ uLong type = self.externalFileAttributes >> 29 & 0x1F;
+ return (0x02 == type) && ![self isSymLink];
+}
+
+- (BOOL) isSymLink {
+ uLong type = self.externalFileAttributes >> 29 & 0x1F;
+ return (0x05 == type);
+}
+
+- (BOOL) isResourceFork {
+ return [self.filename zk_isResourceForkPath];
+}
+
+@synthesize magicNumber, versionNeededToExtract, versionMadeBy, generalPurposeBitFlag, compressionMethod, lastModDate, crc, compressedSize, uncompressedSize, filenameLength, extraFieldLength, commentLength, diskNumberStart, internalFileAttributes, externalFileAttributes, localHeaderOffset, filename, extraField, comment, cachedData;
+
+@end
View
40 External/ZipKit/ZKCDTrailer.h
@@ -0,0 +1,40 @@
+//
+// ZKCDTrailer.h
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface ZKCDTrailer : NSObject {
+@private
+ NSUInteger magicNumber;
+ NSUInteger thisDiskNumber;
+ NSUInteger diskNumberWithStartOfCentralDirectory;
+ NSUInteger numberOfCentralDirectoryEntriesOnThisDisk;
+ NSUInteger totalNumberOfCentralDirectoryEntries;
+ unsigned long long sizeOfCentralDirectory;
+ unsigned long long offsetOfStartOfCentralDirectory;
+ NSUInteger commentLength;
+ NSString *comment;
+}
+
++ (ZKCDTrailer *) recordWithData:(NSData *)data atOffset:(NSUInteger) offset;
++ (ZKCDTrailer *) recordWithData:(NSData *)data;
++ (ZKCDTrailer *) recordWithArchivePath:(NSString *) path;
+- (NSData *) data;
+- (NSUInteger) length;
+- (BOOL) useZip64Extensions;
+
+@property (assign) NSUInteger magicNumber;
+@property (assign) NSUInteger thisDiskNumber;
+@property (assign) NSUInteger diskNumberWithStartOfCentralDirectory;
+@property (assign) NSUInteger numberOfCentralDirectoryEntriesOnThisDisk;
+@property (assign) NSUInteger totalNumberOfCentralDirectoryEntries;
+@property (assign) unsigned long long sizeOfCentralDirectory;
+@property (assign) unsigned long long offsetOfStartOfCentralDirectory;
+@property (assign) NSUInteger commentLength;
+@property (copy) NSString *comment;
+
+@end
View
142 External/ZipKit/ZKCDTrailer.m
@@ -0,0 +1,142 @@
+//
+// ZKCDTrailer.m
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import "ZKCDTrailer.h"
+#import "NSData+ZKAdditions.h"
+#import "NSString+ZKAdditions.h"
+#import "ZKDefs.h"
+#import "zlib.h"
+
+@implementation ZKCDTrailer
+
+- (id) init {
+ if (self = [super init]) {
+ [self addObserver:self forKeyPath:@"comment" options:NSKeyValueObservingOptionNew context:nil];
+
+ self.magicNumber = ZKCDTrailerMagicNumber;
+ self.thisDiskNumber = 0;
+ self.diskNumberWithStartOfCentralDirectory = 0;
+ self.numberOfCentralDirectoryEntriesOnThisDisk = 0;
+ self.totalNumberOfCentralDirectoryEntries = 0;
+ self.sizeOfCentralDirectory = 0;
+ self.offsetOfStartOfCentralDirectory = 0;
+ self.comment = @"Archive created with ZipKit";
+ }
+ return self;
+}
+
+- (void) removeObservers {
+ [self removeObserver:self forKeyPath:@"comment"];
+}
+
+- (void) finalize {
+ [self removeObservers];
+ [super finalize];
+}
+
+- (void) dealloc {
+ [self removeObservers];
+ self.comment = nil;
+ [super dealloc];
+}
+
+
+- (void) observeValueForKeyPath:(NSString *) keyPath ofObject:(id) object change:(NSDictionary *) change context:(void *) context {
+ if ([keyPath isEqualToString:@"comment"] && self.commentLength < 1) {
+ self.commentLength = [self.comment zk_precomposedUTF8Length];
+ }
+}
+
++ (ZKCDTrailer *) recordWithData:(NSData *)data atOffset:(NSUInteger) offset {
+ NSUInteger mn = [data zk_hostInt32OffsetBy:&offset];
+ if (mn != ZKCDTrailerMagicNumber) return nil;
+ ZKCDTrailer *record = [[ZKCDTrailer new] autorelease];
+ record.magicNumber = mn;
+ record.thisDiskNumber = [data zk_hostInt16OffsetBy:&offset];
+ record.diskNumberWithStartOfCentralDirectory = [data zk_hostInt16OffsetBy:&offset];
+ record.numberOfCentralDirectoryEntriesOnThisDisk = [data zk_hostInt16OffsetBy:&offset];
+ record.totalNumberOfCentralDirectoryEntries = [data zk_hostInt16OffsetBy:&offset];
+ record.sizeOfCentralDirectory = [data zk_hostInt32OffsetBy:&offset];
+ record.offsetOfStartOfCentralDirectory = [data zk_hostInt32OffsetBy:&offset];
+ record.commentLength = [data zk_hostInt16OffsetBy:&offset];
+ if (record.commentLength > 0)
+ record.comment = [data zk_stringOffsetBy:&offset length:record.commentLength];
+ else
+ record.comment = nil;
+ return record;
+}
+
++ (ZKCDTrailer *) recordWithData:(NSData *)data {
+ UInt32 trailerCheck = 0;
+ NSInteger offset = [data length] - sizeof(trailerCheck);
+ while (trailerCheck != ZKCDTrailerMagicNumber && offset > 0) {
+ NSUInteger o = offset;
+ trailerCheck = [data zk_hostInt32OffsetBy:&o];
+ offset--;
+ }
+ if (offset < 1)
+ return nil;
+ ZKCDTrailer *record = [self recordWithData:data atOffset:++offset];
+ return record;
+}
+
++ (ZKCDTrailer *) recordWithArchivePath:(NSString *)path {
+ NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
+ unsigned long long fileOffset = [file seekToEndOfFile];
+ for (UInt32 trailerCheck = 0; trailerCheck != ZKCDTrailerMagicNumber && fileOffset > 0; fileOffset--) {
+ [file seekToFileOffset:fileOffset];
+ NSData *data = [file readDataOfLength:sizeof(UInt32)];
+ [data getBytes:&trailerCheck length:sizeof(UInt32)];
+ }
+ if (fileOffset < 1) {
+ [file closeFile];
+ return nil;
+ }
+ fileOffset++;
+ [file seekToFileOffset:fileOffset];
+ NSData *data = [file readDataToEndOfFile];
+ [file closeFile];
+ ZKCDTrailer *record = [self recordWithData:data atOffset:(NSUInteger) 0];
+ return record;
+}
+
+- (NSData *) data {
+ NSMutableData *data = [NSMutableData zk_dataWithLittleInt32:self.magicNumber];
+ [data zk_appendLittleInt16:self.thisDiskNumber];
+ [data zk_appendLittleInt16:self.diskNumberWithStartOfCentralDirectory];
+ [data zk_appendLittleInt16:self.numberOfCentralDirectoryEntriesOnThisDisk];
+ [data zk_appendLittleInt16:self.totalNumberOfCentralDirectoryEntries];
+ if ([self useZip64Extensions]) {
+ [data zk_appendLittleInt32:0xFFFFFFFF];
+ [data zk_appendLittleInt32:0xFFFFFFFF];
+ } else {
+ [data zk_appendLittleInt32:self.sizeOfCentralDirectory];
+ [data zk_appendLittleInt32:self.offsetOfStartOfCentralDirectory];
+ }
+ [data zk_appendLittleInt16:[self.comment zk_precomposedUTF8Length]];
+ [data zk_appendPrecomposedUTF8String:self.comment];
+ return data;
+}
+
+- (NSUInteger) length {
+ return ZKCDTrailerFixedDataLength + [self.comment length];
+}
+
+- (BOOL) useZip64Extensions {
+ return (self.sizeOfCentralDirectory >= 0xFFFFFFFF) || (self.offsetOfStartOfCentralDirectory >= 0xFFFFFFFF);
+}
+
+- (NSString *) description {
+ return [NSString stringWithFormat:@"%u entries (%qu bytes) @: %qu",
+ self.totalNumberOfCentralDirectoryEntries,
+ self.sizeOfCentralDirectory,
+ self.offsetOfStartOfCentralDirectory];
+}
+
+@synthesize magicNumber, thisDiskNumber, diskNumberWithStartOfCentralDirectory, numberOfCentralDirectoryEntriesOnThisDisk, totalNumberOfCentralDirectoryEntries, sizeOfCentralDirectory, offsetOfStartOfCentralDirectory, commentLength, comment;
+
+@end
View
41 External/ZipKit/ZKCDTrailer64.h
@@ -0,0 +1,41 @@
+//
+// ZKCDTrailer64.h
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface ZKCDTrailer64 : NSObject {
+@private
+ NSUInteger magicNumber;
+ unsigned long long sizeOfTrailer;
+ NSUInteger versionMadeBy;
+ NSUInteger versionNeededToExtract;
+ NSUInteger thisDiskNumber;
+ NSUInteger diskNumberWithStartOfCentralDirectory;
+ unsigned long long numberOfCentralDirectoryEntriesOnThisDisk;
+ unsigned long long totalNumberOfCentralDirectoryEntries;
+ unsigned long long sizeOfCentralDirectory;
+ unsigned long long offsetOfStartOfCentralDirectory;
+}
+
++ (ZKCDTrailer64 *) recordWithData:(NSData *)data atOffset:(NSUInteger)offset;
++ (ZKCDTrailer64 *) recordWithArchivePath:(NSString *)path atOffset:(unsigned long long)offset;
+
+- (NSData *) data;
+- (NSUInteger) length;
+
+@property (assign) NSUInteger magicNumber;
+@property (assign) unsigned long long sizeOfTrailer;
+@property (assign) NSUInteger versionMadeBy;
+@property (assign) NSUInteger versionNeededToExtract;
+@property (assign) NSUInteger thisDiskNumber;
+@property (assign) NSUInteger diskNumberWithStartOfCentralDirectory;
+@property (assign) unsigned long long numberOfCentralDirectoryEntriesOnThisDisk;
+@property (assign) unsigned long long totalNumberOfCentralDirectoryEntries;
+@property (assign) unsigned long long sizeOfCentralDirectory;
+@property (assign) unsigned long long offsetOfStartOfCentralDirectory;
+
+@end
View
80 External/ZipKit/ZKCDTrailer64.m
@@ -0,0 +1,80 @@
+//
+// ZKCDTrailer64.m
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import "ZKCDTrailer64.h"
+#import "NSData+ZKAdditions.h"
+#import "ZKDefs.h"
+
+@implementation ZKCDTrailer64
+
+- (id) init {
+ if (self = [super init]) {
+ self.magicNumber = ZKCDTrailer64MagicNumber;
+ self.sizeOfTrailer = 44;
+ self.versionMadeBy = 789;
+ self.versionNeededToExtract = 45;
+ self.thisDiskNumber = 0;
+ self.diskNumberWithStartOfCentralDirectory = 0;
+ }
+ return self;
+}
+
++ (ZKCDTrailer64 *) recordWithData:(NSData *)data atOffset:(NSUInteger)offset {
+ if (!data) return nil;
+ NSUInteger mn = [data zk_hostInt32OffsetBy:&offset];
+ if (mn != ZKCDTrailer64MagicNumber) return nil;
+ ZKCDTrailer64 *record = [[ZKCDTrailer64 new] autorelease];
+ record.magicNumber = mn;
+ record.sizeOfTrailer = [data zk_hostInt64OffsetBy:&offset];
+ record.versionMadeBy = [data zk_hostInt16OffsetBy:&offset];
+ record.versionNeededToExtract = [data zk_hostInt16OffsetBy:&offset];
+ record.thisDiskNumber = [data zk_hostInt32OffsetBy:&offset];
+ record.diskNumberWithStartOfCentralDirectory = [data zk_hostInt32OffsetBy:&offset];
+ record.numberOfCentralDirectoryEntriesOnThisDisk = [data zk_hostInt64OffsetBy:&offset];
+ record.totalNumberOfCentralDirectoryEntries = [data zk_hostInt64OffsetBy:&offset];
+ record.sizeOfCentralDirectory = [data zk_hostInt64OffsetBy:&offset];
+ record.offsetOfStartOfCentralDirectory = [data zk_hostInt64OffsetBy:&offset];
+ return record;
+}
+
++ (ZKCDTrailer64 *) recordWithArchivePath:(NSString *)path atOffset:(unsigned long long)offset {
+ NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
+ [file seekToFileOffset:offset];
+ NSData *data = [file readDataOfLength:ZKCDTrailer64FixedDataLength];
+ [file closeFile];
+ ZKCDTrailer64 *record = [self recordWithData:data atOffset:0];
+ return record;
+}
+
+- (NSData *) data {
+ NSMutableData *data = [NSMutableData zk_dataWithLittleInt32:self.magicNumber];
+ [data zk_appendLittleInt64:self.sizeOfTrailer];
+ [data zk_appendLittleInt16:self.versionMadeBy];
+ [data zk_appendLittleInt16:self.versionNeededToExtract];
+ [data zk_appendLittleInt32:self.thisDiskNumber];
+ [data zk_appendLittleInt32:self.diskNumberWithStartOfCentralDirectory];
+ [data zk_appendLittleInt64:self.numberOfCentralDirectoryEntriesOnThisDisk];
+ [data zk_appendLittleInt64:self.totalNumberOfCentralDirectoryEntries];
+ [data zk_appendLittleInt64:self.sizeOfCentralDirectory];
+ [data zk_appendLittleInt64:self.offsetOfStartOfCentralDirectory];
+ return data;
+}
+
+- (NSUInteger) length {
+ return ZKCDTrailer64FixedDataLength;
+}
+
+- (NSString *) description {
+ return [NSString stringWithFormat:@"%qu entries @ offset of CD: %qu (%qu bytes)",
+ self.numberOfCentralDirectoryEntriesOnThisDisk,
+ self.offsetOfStartOfCentralDirectory,
+ self.sizeOfCentralDirectory];
+}
+
+@synthesize magicNumber, sizeOfTrailer, versionMadeBy, versionNeededToExtract, thisDiskNumber, diskNumberWithStartOfCentralDirectory, numberOfCentralDirectoryEntriesOnThisDisk, totalNumberOfCentralDirectoryEntries, sizeOfCentralDirectory, offsetOfStartOfCentralDirectory;
+
+@end
View
29 External/ZipKit/ZKCDTrailer64Locator.h
@@ -0,0 +1,29 @@
+//
+// ZKCDTrailer64Locator.h
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface ZKCDTrailer64Locator : NSObject {
+@private
+ NSUInteger magicNumber;
+ NSUInteger diskNumberWithStartOfCentralDirectory;
+ unsigned long long offsetOfStartOfCentralDirectoryTrailer64;
+ NSUInteger numberOfDisks;
+}
+
++ (ZKCDTrailer64Locator *) recordWithData:(NSData *)data atOffset:(NSUInteger) offset;
++ (ZKCDTrailer64Locator *) recordWithArchivePath:(NSString *)path andCDTrailerLength:(NSUInteger)cdTrailerLength;
+
+- (NSData *) data;
+- (NSUInteger) length;
+
+@property (assign) NSUInteger magicNumber;
+@property (assign) NSUInteger diskNumberWithStartOfCentralDirectory;
+@property (assign) unsigned long long offsetOfStartOfCentralDirectoryTrailer64;
+@property (assign) NSUInteger numberOfDisks;
+
+@end
View
62 External/ZipKit/ZKCDTrailer64Locator.m
@@ -0,0 +1,62 @@
+//
+// ZKCDTrailer64Locator.m
+// ZipKit
+//
+// Created by Karl Moskowski on 01/04/09.
+//
+
+#import "ZKCDTrailer64Locator.h"
+#import "NSData+ZKAdditions.h"
+#import "ZKDefs.h"
+
+@implementation ZKCDTrailer64Locator
+
+- (id) init {
+ if (self = [super init]) {
+ self.magicNumber = ZKCDTrailer64LocatorMagicNumber;
+ self.diskNumberWithStartOfCentralDirectory = 0;
+ self.numberOfDisks = 1;
+ }
+ return self;
+}
+
++ (ZKCDTrailer64Locator *) recordWithData:(NSData *)data atOffset:(NSUInteger) offset {
+ NSUInteger mn = [data zk_hostInt32OffsetBy:&offset];
+ if (mn != ZKCDTrailer64LocatorMagicNumber) return nil;
+ ZKCDTrailer64Locator *record = [[ZKCDTrailer64Locator new] autorelease];
+ record.magicNumber = mn;
+ record.diskNumberWithStartOfCentralDirectory = [data zk_hostInt32OffsetBy:&offset];
+ record.offsetOfStartOfCentralDirectoryTrailer64 = [data zk_hostInt64OffsetBy:&offset];
+ record.numberOfDisks = [data zk_hostInt32OffsetBy:&offset];
+ return record;
+}
+
++ (ZKCDTrailer64Locator *) recordWithArchivePath:(NSString *)path andCDTrailerLength:(NSUInteger)cdTrailerLength {
+ NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
+ unsigned long long fileOffset = [file seekToEndOfFile] - cdTrailerLength - ZKCDTrailer64LocatorFixedDataLength;
+ [file seekToFileOffset:fileOffset];
+ NSData *data = [file readDataOfLength:ZKCDTrailer64LocatorFixedDataLength];
+ [file closeFile];
+ ZKCDTrailer64Locator *record = [self recordWithData:data atOffset:0];
+ return record;
+}
+
+- (NSData *) data {
+ NSMutableData *data = [NSMutableData zk_dataWithLittleInt32:self.magicNumber];
+ [data zk_appendLittleInt32:self.diskNumberWithStartOfCentralDirectory];
+ [data zk_appendLittleInt64:self.offsetOfStartOfCentralDirectoryTrailer64];
+ [data zk_appendLittleInt32:self.numberOfDisks];
+ return data;
+}
+
+- (NSUInteger) length {
+ return ZKCDTrailer64LocatorFixedDataLength;
+}
+
+- (NSString *) description {
+ return [NSString stringWithFormat:@"offset of CD64: %qu", self.offsetOfStartOfCentralDirectoryTrailer64];
+}
+
+@synthesize magicNumber, diskNumberWithStartOfCentralDirectory, offsetOfStartOfCentralDirectoryTrailer64, numberOfDisks;
+
+@end
View
32 External/ZipKit/ZKDataArchive.h
@@ -0,0 +1,32 @@
+//
+// ZKDataArchive.h
+// ZipKit
+//
+// Created by Karl Moskowski on 07/05/09.
+//
+
+#import <Foundation/Foundation.h>
+#import "ZKArchive.h"
+
+@class ZKCDHeader;
+
+@interface ZKDataArchive : ZKArchive {
+ NSMutableData *_data;
+ NSMutableArray *_inflatedFiles;
+}
+
++ (ZKDataArchive *) archiveWithArchivePath:(NSString *) path;
++ (ZKDataArchive *) archiveWithArchiveData:(NSMutableData *) archiveData;
+- (NSUInteger) inflateAll;
+- (NSData *) inflateFile:(ZKCDHeader *) cdHeader attributes:(NSDictionary **) fileAttributes;
+- (NSUInteger) inflateInFolder:(NSString *)enclosingFolder withFolderName:(NSString *)folderName usingResourceFork:(BOOL) rfFlag;
+
+- (NSInteger) deflateFiles:(NSArray *) paths relativeToPath:(NSString *) basePath usingResourceFork:(BOOL) flag;
</