ObjFW  Check-in [95f6035588]

Overview
Comment:OFZIPArchive: Return entries in a sorted array.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 95f6035588171fa222be63975d5a0d634383964ad14e06f40f845c243291ea53
User & Date: js on 2013-10-30 17:06:48
Other Links: manifest | tags
Context
2013-11-06
11:36
OFZIPArchive: Add support for ZIP64. check-in: 7d11e6e4e6 user: js tags: trunk
2013-10-30
17:06
OFZIPArchive: Return entries in a sorted array. check-in: 95f6035588 user: js tags: trunk
00:09
OFStringTests: Fix a path test on Win32. check-in: 7561b9244e user: js tags: trunk
Changes

Modified src/OFZIPArchive.h from [ae45487a3e] to [71d41cfc2a].

14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65


66
67
68
69
70
71
72
73
74
75
76
 * file.
 */

#import "OFObject.h"
#import "OFString.h"

@class OFFile;
@class OFDictionary;

@class OFMutableDictionary;
@class OFStream;

/*!
 * @brief A class for accessing and manipulating ZIP files.
 */
@interface OFZIPArchive: OFObject
{
	OFFile *_file;
	OFString *_path;
	uint16_t _diskNumber, _centralDirectoryDisk;
	uint16_t _centralDirectoryEntriesInDisk, _centralDirectoryEntries;
	uint32_t _centralDirectorySize, _centralDirectoryOffset;
	OFString *_archiveComment;

	OFMutableDictionary *_entries;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy) OFString *archiveComment;
@property (readonly, copy) OFDictionary *entries;
#endif

/*!
 * @brief Creates a new OFZIPArchive object for the specified file.
 *
 * @param path The path to the ZIP file
 * @return A new, autoreleased OFZIPArchive
 */
+ (instancetype)archiveWithPath: (OFString*)path;

/*!
 * @brief Initializes an already allocated OFZIPArchive object for the
 *	  specified file.
 *
 * @param path The path to the ZIP file
 * @return An initialized OFZIPArchive
 */
- initWithPath: (OFString*)path;

/*!
 * @brief Returns the entries in the central directory of the archive as a
 * 	  dictionary.
 *
 * The dictionary maps the file name to an @ref OFZIPArchiveEntry.


 *
 * @return The entries in the central directory of the archive as a dictionary
 */
- (OFDictionary*)entries;

/*!
 * @brief Returns the archive comment.
 *
 * @return The archive comment
 */
- (OFString*)archiveComment;







|
>














>
|




|




















|
|

|
>
>

|

|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 * file.
 */

#import "OFObject.h"
#import "OFString.h"

@class OFFile;
@class OFArray;
@class OFMutableArray;
@class OFMutableDictionary;
@class OFStream;

/*!
 * @brief A class for accessing and manipulating ZIP files.
 */
@interface OFZIPArchive: OFObject
{
	OFFile *_file;
	OFString *_path;
	uint16_t _diskNumber, _centralDirectoryDisk;
	uint16_t _centralDirectoryEntriesInDisk, _centralDirectoryEntries;
	uint32_t _centralDirectorySize, _centralDirectoryOffset;
	OFString *_archiveComment;
	OFMutableArray *_entries;
	OFMutableDictionary *_pathToEntryMap;
}

#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy) OFString *archiveComment;
@property (readonly, copy) OFArray *entries;
#endif

/*!
 * @brief Creates a new OFZIPArchive object for the specified file.
 *
 * @param path The path to the ZIP file
 * @return A new, autoreleased OFZIPArchive
 */
+ (instancetype)archiveWithPath: (OFString*)path;

/*!
 * @brief Initializes an already allocated OFZIPArchive object for the
 *	  specified file.
 *
 * @param path The path to the ZIP file
 * @return An initialized OFZIPArchive
 */
- initWithPath: (OFString*)path;

/*!
 * @brief Returns the entries of the central directory of the archive as an
 * 	  array of objects of class @ref OFZIPArchiveEntry.
 *
 * The array is sorted by the offset of the local file header, smallest offset
 * to largest offset. This way, hard disk seeks are minimized when the array is
 * enumerated to extract all files of the archive.
 *
 * @return The entries of the central directory of the archive as an array
 */
- (OFArray*)entries;

/*!
 * @brief Returns the archive comment.
 *
 * @return The archive comment
 */
- (OFString*)archiveComment;

Modified src/OFZIPArchive.m from [b1f97cb82f] to [dd9b24a859].

18
19
20
21
22
23
24

25
26
27
28
29
30
31

#include <stdio.h>

#import "OFZIPArchive.h"
#import "OFZIPArchiveEntry.h"
#import "OFZIPArchiveEntry+Private.h"
#import "OFDataArray.h"

#import "OFDictionary.h"
#import "OFFile.h"
#import "OFDeflateStream.h"

#import "OFChecksumFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"







>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

#include <stdio.h>

#import "OFZIPArchive.h"
#import "OFZIPArchiveEntry.h"
#import "OFZIPArchiveEntry+Private.h"
#import "OFDataArray.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFFile.h"
#import "OFDeflateStream.h"

#import "OFChecksumFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
139
140
141
142
143
144
145

146
147
148
149
150
151
152

- (void)dealloc
{
	[_file release];
	[_path release];
	[_archiveComment release];
	[_entries release];


	[super dealloc];
}

- (void)OF_readZIPInfo
{
	void *pool = objc_autoreleasePoolPush();







>







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

- (void)dealloc
{
	[_file release];
	[_path release];
	[_archiveComment release];
	[_entries release];
	[_pathToEntryMap release];

	[super dealloc];
}

- (void)OF_readZIPInfo
{
	void *pool = objc_autoreleasePoolPush();
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202
203

204
205
206
207

208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
{
	void *pool = objc_autoreleasePoolPush();
	size_t i;

	[_file seekToOffset: _centralDirectoryOffset
		     whence: SEEK_SET];


	_entries = [[OFMutableDictionary alloc] init];

	for (i = 0; i < _centralDirectoryEntries; i++) {
		OFZIPArchiveEntry *entry = [[[OFZIPArchiveEntry alloc]
		    OF_initWithFile: _file] autorelease];

		if ([_entries objectForKey: [entry fileName]] != nil)
			@throw [OFInvalidFormatException exception];


		[_entries setObject: entry
			     forKey: [entry fileName]];
	}


	[_entries makeImmutable];


	objc_autoreleasePoolPop(pool);
}

- (OFDictionary*)entries
{
	OF_GETTER(_entries, true)
}

- (OFString*)archiveComment
{
	OF_GETTER(_archiveComment, true)
}

- (OFStream*)streamForReadingFile: (OFString*)path
{
	OFStream *ret;
	void *pool = objc_autoreleasePoolPush();
	OFZIPArchiveEntry *entry = [_entries objectForKey: path];
	OFZIPArchive_LocalFileHeader *localFileHeader;

	if (entry == nil) {
		errno = ENOENT;
		@throw [OFOpenFileFailedException exceptionWithPath: path
							       mode: @"rb"];
	}







>
|





|


>
|
|


>

>




|













|







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
{
	void *pool = objc_autoreleasePoolPush();
	size_t i;

	[_file seekToOffset: _centralDirectoryOffset
		     whence: SEEK_SET];

	_entries = [[OFMutableArray alloc] init];
	_pathToEntryMap = [[OFMutableDictionary alloc] init];

	for (i = 0; i < _centralDirectoryEntries; i++) {
		OFZIPArchiveEntry *entry = [[[OFZIPArchiveEntry alloc]
		    OF_initWithFile: _file] autorelease];

		if ([_pathToEntryMap objectForKey: [entry fileName]] != nil)
			@throw [OFInvalidFormatException exception];

		[_entries addObject: entry];
		[_pathToEntryMap setObject: entry
				    forKey: [entry fileName]];
	}

	[_entries sort];
	[_entries makeImmutable];
	[_pathToEntryMap makeImmutable];

	objc_autoreleasePoolPop(pool);
}

- (OFArray*)entries
{
	OF_GETTER(_entries, true)
}

- (OFString*)archiveComment
{
	OF_GETTER(_archiveComment, true)
}

- (OFStream*)streamForReadingFile: (OFString*)path
{
	OFStream *ret;
	void *pool = objc_autoreleasePoolPush();
	OFZIPArchiveEntry *entry = [_pathToEntryMap objectForKey: path];
	OFZIPArchive_LocalFileHeader *localFileHeader;

	if (entry == nil) {
		errno = ENOENT;
		@throw [OFOpenFileFailedException exceptionWithPath: path
							       mode: @"rb"];
	}

Modified src/OFZIPArchiveEntry.m from [45871583e7] to [8411857262].

22
23
24
25
26
27
28

29
30
31
32
33
34
35
#import "OFDataArray.h"
#import "OFFile.h"
#import "OFDate.h"

#import "autorelease.h"
#import "macros.h"


#import "OFInvalidFormatException.h"

@implementation OFZIPArchiveEntry
- (instancetype)OF_initWithFile: (OFFile*)file
{
	self = [super init];








>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#import "OFDataArray.h"
#import "OFFile.h"
#import "OFDate.h"

#import "autorelease.h"
#import "macros.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"

@implementation OFZIPArchiveEntry
- (instancetype)OF_initWithFile: (OFFile*)file
{
	self = [super init];

217
218
219
220
221
222
223

















224
	return _externalAttributes;
}

- (uint32_t)OF_localFileHeaderOffset
{
	return _localFileHeaderOffset;
}

















@end







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
	return _externalAttributes;
}

- (uint32_t)OF_localFileHeaderOffset
{
	return _localFileHeaderOffset;
}

- (of_comparison_result_t)compare: (id)object
{
	OFZIPArchiveEntry *entry;

	if (![object isKindOfClass: [OFZIPArchiveEntry class]])
		@throw [OFInvalidArgumentException exception];

	entry = object;

	if (_localFileHeaderOffset > entry->_localFileHeaderOffset)
		return OF_ORDERED_DESCENDING;
	if (_localFileHeaderOffset < entry->_localFileHeaderOffset)
		return OF_ORDERED_ASCENDING;

	return OF_ORDERED_SAME;
}
@end