ObjFW  Check-in [51589c6496]

Overview
Comment:Rename OFFileOffset -> OFStreamOffset
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 51589c64965b371beecd2e326eaedb0d71901dd6ac29e2f797b67981280bc9e7
User & Date: js on 2022-08-27 20:39:50
Other Links: manifest | tags
Context
2022-08-27
20:42
OFTarArchive: Clean up types check-in: fc63341028 user: js tags: trunk
20:39
Rename OFFileOffset -> OFStreamOffset check-in: 51589c6496 user: js tags: trunk
20:33
OFZIPArchiveEntry: Make (un)compressedSize ull check-in: 94c326ab78 user: js tags: trunk
Changes

Modified src/OFFile.m from [6bda5c55f7] to [8cbc43a8f0].

446
447
448
449
450
451
452
453


454
455

456
457
458
459
460
461
462
446
447
448
449
450
451
452

453
454
455

456
457
458
459
460
461
462
463







-
+
+

-
+







						      bytesWritten: 0
							     errNo: errno];
#endif

	return (size_t)bytesWritten;
}

- (OFFileOffset)lowlevelSeekToOffset: (OFFileOffset)offset whence: (int)whence
- (OFStreamOffset)lowlevelSeekToOffset: (OFStreamOffset)offset
				whence: (int)whence
{
	OFFileOffset ret;
	OFStreamOffset ret;

	if (_handle == OFInvalidFileHandle)
		@throw [OFNotOpenException exceptionWithObject: self];

#ifndef OF_AMIGAOS
# if defined(OF_WINDOWS)
	ret = _lseeki64(_handle, offset, whence);

Modified src/OFFileURLHandler.m from [50a5ea9a56] to [9f18f4fcb5].

83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97







-
+







# ifdef OF_AMIGAOS4
#  define DeleteFile(path) Delete(path)
# endif
#endif

#if defined(OF_WINDOWS) || defined(OF_AMIGAOS)
typedef struct {
	OFFileOffset st_size;
	OFStreamOffset st_size;
	unsigned int st_mode;
	OFTimeInterval st_atime, st_mtime, st_ctime;
# ifdef OF_WINDOWS
#  define HAVE_STRUCT_STAT_ST_BIRTHTIME
	OFTimeInterval st_birthtime;
	DWORD fileAttributes;
# endif

Modified src/OFLHAArchive.m from [39715cb197] to [16be8d0f67].

58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72







-
+








OF_DIRECT_MEMBERS
@interface OFLHAArchiveFileWriteStream: OFStream <OFReadyForWritingObserving>
{
	OFMutableLHAArchiveEntry *_entry;
	OFStringEncoding _encoding;
	OFSeekableStream *_stream;
	OFFileOffset _headerOffset;
	OFStreamOffset _headerOffset;
	uint32_t _bytesWritten;
	uint16_t _CRC16;
}

- (instancetype)of_initWithStream: (OFSeekableStream *)stream
			    entry: (OFLHAArchiveEntry *)entry
			 encoding: (OFStringEncoding)encoding;
394
395
396
397
398
399
400
401
402


403
404
405
406
407
408
409
394
395
396
397
398
399
400


401
402
403
404
405
406
407
408
409







-
-
+
+







		toRead =
		    _entry.compressedSize - decompressingStream.bytesConsumed;

		stream = _stream;
	}

	if ([stream isKindOfClass: [OFSeekableStream class]] &&
	    (sizeof(OFFileOffset) > 4 || toRead != (OFFileOffset)toRead))
		[(OFSeekableStream *)stream seekToOffset: (OFFileOffset)toRead
	    (sizeof(OFStreamOffset) > 4 || toRead != (OFStreamOffset)toRead))
		[(OFSeekableStream *)stream seekToOffset: (OFStreamOffset)toRead
						  whence: SEEK_CUR];
	else {
		while (toRead > 0) {
			char buffer[512];
			unsigned long long min = toRead;

			if (min > 512)
512
513
514
515
516
517
518
519

520
521
522
523
524
525
526
512
513
514
515
516
517
518

519
520
521
522
523
524
525
526







-
+







{
	return ((id <OFReadyForWritingObserving>)_stream)
	    .fileDescriptorForWriting;
}

- (void)close
{
	OFFileOffset offset;
	OFStreamOffset offset;

	if (_stream == nil)
		@throw [OFNotOpenException exceptionWithObject: self];

	_entry.uncompressedSize = _bytesWritten;
	_entry.compressedSize = _bytesWritten;
	_entry.CRC16 = _CRC16;

Modified src/OFMemoryStream.m from [1697ea3e2b] to [0ce810b341].

42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56







-
+







- (instancetype)initWithMemoryAddress: (void *)address
				 size: (size_t)size
			     writable: (bool)writable
{
	self = [super init];

	@try {
		if (size > SSIZE_MAX || (ssize_t)size != (OFFileOffset)size)
		if (size > SSIZE_MAX || (ssize_t)size != (OFStreamOffset)size)
			@throw [OFOutOfRangeException exception];

		_address = address;
		_size = size;
		_writable = writable;
	} @catch (id e) {
		[self release];
97
98
99
100
101
102
103
104


105
106

107
108
109
110
111
112
113

114
115
116

117
118
119
120
121
122

123
124
125
126
127
128
129
130
97
98
99
100
101
102
103

104
105
106

107
108
109
110
111
112
113

114
115
116

117
118
119
120
121
122

123
124
125
126
127
128
129
130
131







-
+
+

-
+






-
+


-
+





-
+








}

- (bool)lowlevelIsAtEndOfStream
{
	return (_position == _size);
}

- (OFFileOffset)lowlevelSeekToOffset: (OFFileOffset)offset whence: (int)whence
- (OFStreamOffset)lowlevelSeekToOffset: (OFStreamOffset)offset
				whence: (int)whence
{
	OFFileOffset new;
	OFStreamOffset new;

	switch (whence) {
	case SEEK_SET:
		new = offset;
		break;
	case SEEK_CUR:
		new = (OFFileOffset)_position + offset;
		new = (OFStreamOffset)_position + offset;
		break;
	case SEEK_END:
		new = (OFFileOffset)_size + offset;
		new = (OFStreamOffset)_size + offset;
		break;
	default:
		@throw [OFInvalidArgumentException exception];
	}

	if (new < 0 || new > (OFFileOffset)_size)
	if (new < 0 || new > (OFStreamOffset)_size)
		@throw [OFSeekFailedException exceptionWithStream: self
							   offset: offset
							   whence: whence
							    errNo: EINVAL];

	return (_position = (size_t)new);
}
@end

Modified src/OFSeekableStream.h from [dfe5585e9c] to [7f5f12c98e].

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
81
82
83
84
85
86
87
88
89
90
91
92
93
94


95
96
97
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
81
82
83
84
85
86
87
88
89
90
91
92
93

94
95
96
97
98







-
+

-
+

-
+

-
+

-
+



















-
+











-
+



















-
+
+



#endif

#import "OFStream.h"

OF_ASSUME_NONNULL_BEGIN

#if defined(OF_WINDOWS)
typedef __int64 OFFileOffset;
typedef __int64 OFStreamOffset;
#elif defined(OF_ANDROID)
typedef long long OFFileOffset;
typedef long long OFStreamOffset;
#elif defined(OF_MORPHOS)
typedef signed long long OFFileOffset;
typedef signed long long OFStreamOffset;
#elif defined(OF_HAVE_OFF64_T)
typedef off64_t OFFileOffset;
typedef off64_t OFStreamOffset;
#else
typedef off_t OFFileOffset;
typedef off_t OFStreamOffset;
#endif

/**
 * @class OFSeekableStream OFSeekableStream.h ObjFW/OFSeekableStream.h
 *
 * @brief A stream that supports seeking.
 *
 * @note If you want to subclass this, override
 *	 @ref lowlevelSeekToOffset:whence:. OFSeekableStream uses this method
 *	 and makes it work together with the caching of OFStream. If you
 *	 override this methods without the `lowlevel` prefix, you *will* break
 *	 caching, get broken results and seek to the wrong position!
 */
@interface OFSeekableStream: OFStream
{
	OF_RESERVE_IVARS(OFSeekableStream, 4)
}

/**
 * @brief Seeks to the specified absolute offset.
 * @brief Seeks to the specified offset.
 *
 * @param offset The offset in bytes
 * @param whence From where to seek.@n
 *		 Possible values are:
 *		 Value      | Description
 *		 -----------|---------------------------------------
 *		 `SEEK_SET` | Seek to the specified byte
 *		 `SEEK_CUR` | Seek to the current location + offset
 *		 `SEEK_END` | Seek to the end of the stream + offset
 * @return The new offset form the start of the file
 */
- (OFFileOffset)seekToOffset: (OFFileOffset)offset whence: (int)whence;
- (OFStreamOffset)seekToOffset: (OFStreamOffset)offset whence: (int)whence;

/**
 * @brief Seek the stream on the lowlevel.
 *
 * @warning Do not call this directly!
 *
 * @note Override this method with your actual seek implementation when
 *	 subclassing!
 *
 * @param offset The offset to seek to
 * @param whence From where to seek.@n
 *		 Possible values are:
 *		 Value      | Description
 *		 -----------|---------------------------------------
 *		 `SEEK_SET` | Seek to the specified byte
 *		 `SEEK_CUR` | Seek to the current location + offset
 *		 `SEEK_END` | Seek to the end of the stream + offset
 * @return The new offset from the start of the file
 */
- (OFFileOffset)lowlevelSeekToOffset: (OFFileOffset)offset whence: (int)whence;
- (OFStreamOffset)lowlevelSeekToOffset: (OFStreamOffset)offset
				whence: (int)whence;
@end

OF_ASSUME_NONNULL_END

Modified src/OFSeekableStream.m from [9e766aeca1] to [562c4a07bd].

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







-
+
+




-
+













			@throw e;
		}
	}

	return [super init];
}

- (OFFileOffset)lowlevelSeekToOffset: (OFFileOffset)offset whence: (int)whence
- (OFStreamOffset)lowlevelSeekToOffset: (OFStreamOffset)offset
				whence: (int)whence
{
	OF_UNRECOGNIZED_SELECTOR
}

- (OFFileOffset)seekToOffset: (OFFileOffset)offset whence: (int)whence
- (OFStreamOffset)seekToOffset: (OFStreamOffset)offset whence: (int)whence
{
	if (whence == SEEK_CUR)
		offset -= _readBufferLength;

	offset = [self lowlevelSeekToOffset: offset whence: whence];

	OFFreeMemory(_readBufferMemory);
	_readBuffer = _readBufferMemory = NULL;
	_readBufferLength = 0;

	return offset;
}
@end

Modified src/OFTarArchive.m from [90c0fe7151] to [d41a5109d6].

355
356
357
358
359
360
361
362


363
364
365
366



367
368
369
370
371
372
373
355
356
357
358
359
360
361

362
363
364
365


366
367
368
369
370
371
372
373
374
375







-
+
+


-
-
+
+
+








- (void)of_skip
{
	if (_stream == nil || _skipped)
		return;

	if ([_stream isKindOfClass: [OFSeekableStream class]] &&
	    _toRead <= INT64_MAX && (OFFileOffset)_toRead == (int64_t)_toRead) {
	    _toRead <= INT64_MAX &&
	    (OFStreamOffset)_toRead == (int64_t)_toRead) {
		uint64_t size;

		[(OFSeekableStream *)_stream seekToOffset: (OFFileOffset)_toRead
						   whence: SEEK_CUR];
		[(OFSeekableStream *)_stream
		    seekToOffset: (OFStreamOffset)_toRead
			  whence: SEEK_CUR];

		_toRead = 0;

		size = _entry.size;

		if (size % 512 != 0)
			[(OFSeekableStream *)_stream

Modified src/OFZIPArchive.m from [e9a337a52f] to [6a0897ace1].

138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152







-
+







	*size -= 8;

	return field;
}

static void
seekOrThrowInvalidFormat(OFSeekableStream *stream,
    OFFileOffset offset, int whence)
    OFStreamOffset offset, int whence)
{
	@try {
		[stream seekToOffset: offset whence: whence];
	} @catch (OFSeekFailedException *e) {
		if (e.errNo == EINVAL)
			@throw [OFInvalidFormatException exception];

197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
197
198
199
200
201
202
203

204
205
206
207
208
209
210
211







-
+







			[self of_readZIPInfo];
			[self of_readEntries];
		}

		if (_mode == modeAppend) {
			_offset = _centralDirectoryOffset;
			seekOrThrowInvalidFormat((OFSeekableStream *)_stream,
			    (OFFileOffset)_offset, SEEK_SET);
			    (OFStreamOffset)_offset, SEEK_SET);
		}
	} @catch (id e) {
		/*
		 * If we are in write or append mode, we do not want -[close]
		 * to write anything to it on error - after all, it might not
		 * be a ZIP file which we would destroy otherwise.
		 */
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269







-
+







	[super dealloc];
}

- (void)of_readZIPInfo
{
	void *pool = objc_autoreleasePoolPush();
	uint16_t commentLength;
	OFFileOffset offset = -22;
	OFStreamOffset offset = -22;
	bool valid = false;

	do {
		seekOrThrowInvalidFormat((OFSeekableStream *)_stream,
		    offset, SEEK_END);

		if ([_stream readLittleEndianInt32] == 0x06054B50) {
307
308
309
310
311
312
313
314

315
316
317
318

319
320
321
322
323
324
325
307
308
309
310
311
312
313

314
315
316
317

318
319
320
321
322
323
324
325







-
+



-
+







		/*
		 * FIXME: Handle number of the disk containing ZIP64 end of
		 * central directory record.
		 */
		[_stream readLittleEndianInt32];
		offset64 = [_stream readLittleEndianInt64];

		if (offset64 < 0 || (OFFileOffset)offset64 != offset64)
		if (offset64 < 0 || (OFStreamOffset)offset64 != offset64)
			@throw [OFOutOfRangeException exception];

		seekOrThrowInvalidFormat((OFSeekableStream *)_stream,
		    (OFFileOffset)offset64, SEEK_SET);
		    (OFStreamOffset)offset64, SEEK_SET);

		if ([_stream readLittleEndianInt32] != 0x06064B50)
			@throw [OFInvalidFormatException exception];

		size = [_stream readLittleEndianInt64];
		if (size < 44)
			@throw [OFInvalidFormatException exception];
334
335
336
337
338
339
340
341

342
343
344
345
346
347
348
349
350
351
352
353
354

355
356
357
358

359
360
361
362
363
364
365
334
335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
351
352
353

354
355
356
357

358
359
360
361
362
363
364
365







-
+












-
+



-
+







		_centralDirectoryEntriesInDisk =
		    [_stream readLittleEndianInt64];
		_centralDirectoryEntries = [_stream readLittleEndianInt64];
		_centralDirectorySize = [_stream readLittleEndianInt64];
		_centralDirectoryOffset = [_stream readLittleEndianInt64];

		if (_centralDirectoryOffset < 0 ||
		    (OFFileOffset)_centralDirectoryOffset !=
		    (OFStreamOffset)_centralDirectoryOffset !=
		    _centralDirectoryOffset)
			@throw [OFOutOfRangeException exception];
	}

	objc_autoreleasePoolPop(pool);
}

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

	if (_centralDirectoryOffset < 0 ||
	    (OFFileOffset)_centralDirectoryOffset != _centralDirectoryOffset)
	    (OFStreamOffset)_centralDirectoryOffset != _centralDirectoryOffset)
		@throw [OFOutOfRangeException exception];

	seekOrThrowInvalidFormat((OFSeekableStream *)_stream,
	    (OFFileOffset)_centralDirectoryOffset, SEEK_SET);
	    (OFStreamOffset)_centralDirectoryOffset, SEEK_SET);

	for (size_t i = 0; i < _centralDirectoryEntries; i++) {
		OFZIPArchiveEntry *entry = [[[OFZIPArchiveEntry alloc]
		    of_initWithStream: _stream] autorelease];

		if ([_pathToEntryMap objectForKey: entry.fileName] != nil)
			@throw [OFInvalidFormatException exception];
443
444
445
446
447
448
449
450

451
452
453
454

455
456
457
458
459
460
461
443
444
445
446
447
448
449

450
451
452
453

454
455
456
457
458
459
460
461







-
+



-
+







		@throw [OFOpenItemFailedException exceptionWithPath: path
							       mode: @"r"
							      errNo: ENOENT];

	[self of_closeLastReturnedStream];

	offset64 = entry.of_localFileHeaderOffset;
	if (offset64 < 0 || (OFFileOffset)offset64 != offset64)
	if (offset64 < 0 || (OFStreamOffset)offset64 != offset64)
		@throw [OFOutOfRangeException exception];

	seekOrThrowInvalidFormat((OFSeekableStream *)_stream,
	    (OFFileOffset)offset64, SEEK_SET);
	    (OFStreamOffset)offset64, SEEK_SET);
	localFileHeader = [[[OFZIPArchiveLocalFileHeader alloc]
	    initWithStream: _stream] autorelease];

	if (![localFileHeader matchesEntry: entry])
		@throw [OFInvalidFormatException exception];

	if ((localFileHeader->_minVersionNeeded & 0xFF) > 45) {

Modified src/exceptions/OFSeekFailedException.h from [f6a3b56229] to [f1d3a39ff6].

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







-
+











-
+







 *	  OFSeekFailedException.h ObjFW/OFSeekFailedException.h
 *
 * @brief An exception indicating that seeking in a stream failed.
 */
@interface OFSeekFailedException: OFException
{
	OFSeekableStream *_stream;
	OFFileOffset _offset;
	OFStreamOffset _offset;
	int _whence, _errNo;
}

/**
 * @brief The stream for which seeking failed.
 */
@property (readonly, nonatomic) OFSeekableStream *stream;

/**
 * @brief The offset to which seeking failed.
 */
@property (readonly, nonatomic) OFFileOffset offset;
@property (readonly, nonatomic) OFStreamOffset offset;

/**
 * @brief To what the offset is relative.
 */
@property (readonly, nonatomic) int whence;

/**
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87







-
+















-
+







 * @param stream The stream for which seeking failed
 * @param offset The offset to which seeking failed
 * @param whence To what the offset is relative
 * @param errNo The errno of the error that occurred
 * @return A new, autoreleased seek failed exception
 */
+ (instancetype)exceptionWithStream: (OFSeekableStream *)stream
			     offset: (OFFileOffset)offset
			     offset: (OFStreamOffset)offset
			     whence: (int)whence
			      errNo: (int)errNo;

+ (instancetype)exception OF_UNAVAILABLE;

/**
 * @brief Initializes an already allocated seek failed exception.
 *
 * @param stream The stream for which seeking failed
 * @param offset The offset to which seeking failed
 * @param whence To what the offset is relative
 * @param errNo The errno of the error that occurred
 * @return An initialized seek failed exception
 */
- (instancetype)initWithStream: (OFSeekableStream *)stream
			offset: (OFFileOffset)offset
			offset: (OFStreamOffset)offset
			whence: (int)whence
			 errNo: (int)errNo OF_DESIGNATED_INITIALIZER;

- (instancetype)init OF_UNAVAILABLE;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/OFSeekFailedException.m from [8afbb45d54] to [1550412068].

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







-
+















-
+








+ (instancetype)exception
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)exceptionWithStream: (OFSeekableStream *)stream
			     offset: (OFFileOffset)offset
			     offset: (OFStreamOffset)offset
			     whence: (int)whence
			      errNo: (int)errNo
{
	return [[[self alloc] initWithStream: stream
				      offset: offset
				      whence: whence
				       errNo: errNo] autorelease];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithStream: (OFSeekableStream *)stream
			offset: (OFFileOffset)offset
			offset: (OFStreamOffset)offset
			whence: (int)whence
			 errNo: (int)errNo
{
	self = [super init];

	_stream = [stream retain];
	_offset = offset;