ObjFW  Check-in [6f13f74134]

Overview
Comment:OFLHAArchiveEntry: Make (un)compressedSize ull

There's newer, less common LHA versions that allow 64 bit for the size.
However, for consistency with OFTarArchiveEntry, use unsigned long long
instead of uint64_t.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 6f13f741344ec40aaef45867a64fd67fdcf1fad3a2df79f6201aa65ea1b8abc2
User & Date: js on 2022-08-27 20:23:24
Other Links: manifest | tags
Context
2022-08-27
20:33
OFZIPArchiveEntry: Make (un)compressedSize ull check-in: 94c326ab78 user: js tags: trunk
20:23
OFLHAArchiveEntry: Make (un)compressedSize ull check-in: 6f13f74134 user: js tags: trunk
2022-08-25
19:56
OFLHAArchiveEntry: Merge date and modificationDate check-in: 327e67021e user: js tags: trunk
Changes

Modified src/OFLHAArchive.m from [3c453bb2f0] to [39715cb197].

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

OF_DIRECT_MEMBERS
@interface OFLHAArchiveFileReadStream: OFStream <OFReadyForReadingObserving>
{
	OFStream *_stream, *_decompressedStream;
	OFLHAArchiveEntry *_entry;
	uint32_t _toRead, _bytesConsumed;
	uint16_t _CRC16;
	bool _atEndOfStream, _skipped;
}

- (instancetype)of_initWithStream: (OFStream *)stream
			    entry: (OFLHAArchiveEntry *)entry;
- (void)of_skip;







|







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

OF_DIRECT_MEMBERS
@interface OFLHAArchiveFileReadStream: OFStream <OFReadyForReadingObserving>
{
	OFStream *_stream, *_decompressedStream;
	OFLHAArchiveEntry *_entry;
	unsigned long long _toRead;
	uint16_t _CRC16;
	bool _atEndOfStream, _skipped;
}

- (instancetype)of_initWithStream: (OFStream *)stream
			    entry: (OFLHAArchiveEntry *)entry;
- (void)of_skip;
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
	if (_atEndOfStream)
		return 0;

	if (_stream.atEndOfStream && !_decompressedStream.hasDataInReadBuffer)
		@throw [OFTruncatedDataException exception];

	if (length > _toRead)
		length = _toRead;

	ret = [_decompressedStream readIntoBuffer: buffer length: length];

	_toRead -= ret;
	_CRC16 = OFCRC16(_CRC16, buffer, ret);

	if (_toRead == 0) {







|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
	if (_atEndOfStream)
		return 0;

	if (_stream.atEndOfStream && !_decompressedStream.hasDataInReadBuffer)
		@throw [OFTruncatedDataException exception];

	if (length > _toRead)
		length = (size_t)_toRead;

	ret = [_decompressedStream readIntoBuffer: buffer length: length];

	_toRead -= ret;
	_CRC16 = OFCRC16(_CRC16, buffer, ret);

	if (_toRead == 0) {
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
	return ((id <OFReadyForReadingObserving>)_decompressedStream)
	    .fileDescriptorForReading;
}

- (void)of_skip
{
	OFStream *stream;
	uint32_t toRead;

	if (_stream == nil || _skipped)
		return;

	stream = _stream;
	toRead = _toRead;








|







369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
	return ((id <OFReadyForReadingObserving>)_decompressedStream)
	    .fileDescriptorForReading;
}

- (void)of_skip
{
	OFStream *stream;
	unsigned long long toRead;

	if (_stream == nil || _skipped)
		return;

	stream = _stream;
	toRead = _toRead;

394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

413
414
415
416
417
418
419
		toRead =
		    _entry.compressedSize - decompressingStream.bytesConsumed;

		stream = _stream;
	}

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

			if (min > 512)
				min = 512;

			toRead -= [stream readIntoBuffer: buffer length: min];

		}
	}

	_toRead = 0;
	_skipped = true;
}








|





|




|
>







394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
		toRead =
		    _entry.compressedSize - decompressingStream.bytesConsumed;

		stream = _stream;
	}

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

			if (min > 512)
				min = 512;

			toRead -= [stream readIntoBuffer: buffer
						  length: (size_t)min];
		}
	}

	_toRead = 0;
	_skipped = true;
}

Modified src/OFLHAArchiveEntry.h from [667eea830b] to [1b1edad7fa].

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 * @class OFLHAArchiveEntry OFLHAArchiveEntry.h ObjFW/OFLHAArchiveEntry.h
 *
 * @brief A class which represents an entry in an LHA archive.
 */
@interface OFLHAArchiveEntry: OFObject <OFCopying, OFMutableCopying>
{
	OFString *_fileName, *_Nullable _directoryName, *_compressionMethod;
	uint32_t _compressedSize, _uncompressedSize;
	OFDate *_modificationDate;
	uint8_t _headerLevel;
	uint16_t _CRC16;
	uint8_t _operatingSystemIdentifier;
	OFString *_Nullable _fileComment;
	OFNumber *_Nullable _mode, *_Nullable _UID, *_Nullable _GID;
	OFString *_Nullable _owner, *_Nullable _group;







|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 * @class OFLHAArchiveEntry OFLHAArchiveEntry.h ObjFW/OFLHAArchiveEntry.h
 *
 * @brief A class which represents an entry in an LHA archive.
 */
@interface OFLHAArchiveEntry: OFObject <OFCopying, OFMutableCopying>
{
	OFString *_fileName, *_Nullable _directoryName, *_compressionMethod;
	unsigned long long _compressedSize, _uncompressedSize;
	OFDate *_modificationDate;
	uint8_t _headerLevel;
	uint16_t _CRC16;
	uint8_t _operatingSystemIdentifier;
	OFString *_Nullable _fileComment;
	OFNumber *_Nullable _mode, *_Nullable _UID, *_Nullable _GID;
	OFString *_Nullable _owner, *_Nullable _group;
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
 * @brief The compression method of the entry.
 */
@property (readonly, copy, nonatomic) OFString *compressionMethod;

/**
 * @brief The compressed size of the entry's file.
 */
@property (readonly, nonatomic) uint32_t compressedSize;

/**
 * @brief The uncompressed size of the entry's file.
 */
@property (readonly, nonatomic) uint32_t uncompressedSize;

/**
 * @brief The modification date of the file.
 */
@property (readonly, retain, nonatomic) OFDate *modificationDate;

/**







|




|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
 * @brief The compression method of the entry.
 */
@property (readonly, copy, nonatomic) OFString *compressionMethod;

/**
 * @brief The compressed size of the entry's file.
 */
@property (readonly, nonatomic) unsigned long long compressedSize;

/**
 * @brief The uncompressed size of the entry's file.
 */
@property (readonly, nonatomic) unsigned long long uncompressedSize;

/**
 * @brief The modification date of the file.
 */
@property (readonly, retain, nonatomic) OFDate *modificationDate;

/**

Modified src/OFLHAArchiveEntry.m from [027838e133] to [c71c080e0a].

333
334
335
336
337
338
339




340
341

342
343
344

345
346
347
348
349
350
351
		uint32_t date;

		_compressionMethod = [[OFString alloc]
		    initWithCString: header + 2
			   encoding: OFStringEncodingASCII
			     length: 5];





		memcpy(&_compressedSize, header + 7, 4);
		_compressedSize = OFFromLittleEndian32(_compressedSize);


		memcpy(&_uncompressedSize, header + 11, 4);
		_uncompressedSize = OFFromLittleEndian32(_uncompressedSize);


		memcpy(&date, header + 15, 4);
		date = OFFromLittleEndian32(date);

		_headerLevel = header[20];
		_extensions = [[OFMutableArray alloc] init];








>
>
>
>

|
>


|
>







333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
		uint32_t date;

		_compressionMethod = [[OFString alloc]
		    initWithCString: header + 2
			   encoding: OFStringEncodingASCII
			     length: 5];

		if (_compressedSize > UINT32_MAX ||
		    _uncompressedSize > UINT32_MAX)
			@throw [OFOutOfRangeException exception];

		memcpy(&_compressedSize, header + 7, 4);
		_compressedSize =
		    OFFromLittleEndian32((uint32_t)_compressedSize);

		memcpy(&_uncompressedSize, header + 11, 4);
		_uncompressedSize =
		    OFFromLittleEndian32((uint32_t)_uncompressedSize);

		memcpy(&date, header + 15, 4);
		date = OFFromLittleEndian32(date);

		_headerLevel = header[20];
		_extensions = [[OFMutableArray alloc] init];

471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
}

- (OFString *)compressionMethod
{
	return _compressionMethod;
}

- (uint32_t)compressedSize
{
	return _compressedSize;
}

- (uint32_t)uncompressedSize
{
	return _uncompressedSize;
}

- (OFDate *)modificationDate
{
	return _modificationDate;







|




|







477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
}

- (OFString *)compressionMethod
{
	return _compressionMethod;
}

- (unsigned long long)compressedSize
{
	return _compressedSize;
}

- (unsigned long long)uncompressedSize
{
	return _uncompressedSize;
}

- (OFDate *)modificationDate
{
	return _modificationDate;
555
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
	    OFStringEncodingASCII] != 5)
		@throw [OFInvalidArgumentException exception];

	getFileNameAndDirectoryName(self, encoding, &fileName, &fileNameLength,
	    &directoryName, &directoryNameLength);

	if (fileNameLength > UINT16_MAX - 3 ||
	    directoryNameLength > UINT16_MAX - 3)

		@throw [OFOutOfRangeException exception];

	/* Length. Filled in after we're done. */
	[data increaseCountBy: 2];

	[data addItems: [_compressionMethod
			    cStringWithEncoding: OFStringEncodingASCII]
		 count: 5];

	tmp32 = OFToLittleEndian32(_compressedSize);
	[data addItems: &tmp32 count: sizeof(tmp32)];

	tmp32 = OFToLittleEndian32(_uncompressedSize);
	[data addItems: &tmp32 count: sizeof(tmp32)];

	tmp32 = OFToLittleEndian32(
	    (uint32_t)_modificationDate.timeIntervalSince1970);
	[data addItems: &tmp32 count: sizeof(tmp32)];

	/* Reserved */







|
>









|


|







561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
	    OFStringEncodingASCII] != 5)
		@throw [OFInvalidArgumentException exception];

	getFileNameAndDirectoryName(self, encoding, &fileName, &fileNameLength,
	    &directoryName, &directoryNameLength);

	if (fileNameLength > UINT16_MAX - 3 ||
	    directoryNameLength > UINT16_MAX - 3 ||
	    _compressedSize > UINT32_MAX || _uncompressedSize > UINT32_MAX)
		@throw [OFOutOfRangeException exception];

	/* Length. Filled in after we're done. */
	[data increaseCountBy: 2];

	[data addItems: [_compressionMethod
			    cStringWithEncoding: OFStringEncodingASCII]
		 count: 5];

	tmp32 = OFToLittleEndian32((uint32_t)_compressedSize);
	[data addItems: &tmp32 count: sizeof(tmp32)];

	tmp32 = OFToLittleEndian32((uint32_t)_uncompressedSize);
	[data addItems: &tmp32 count: sizeof(tmp32)];

	tmp32 = OFToLittleEndian32(
	    (uint32_t)_modificationDate.timeIntervalSince1970);
	[data addItems: &tmp32 count: sizeof(tmp32)];

	/* Reserved */
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
	OFString *extensions = [_extensions.description
	    stringByReplacingOccurrencesOfString: @"\n"
				      withString: @"\n\t"];
	OFString *ret = [OFString stringWithFormat:
	    @"<%@:\n"
	    @"\tFile name = %@\n"
	    @"\tCompression method = %@\n"
	    @"\tCompressed size = %" @PRIu32 "\n"
	    @"\tUncompressed size = %" @PRIu32 "\n"
	    @"\tModification date = %@\n"
	    @"\tHeader level = %u\n"
	    @"\tCRC16 = %04" @PRIX16 @"\n"
	    @"\tOperating system identifier = %c\n"
	    @"\tComment = %@\n"
	    @"\tMode = %@\n"
	    @"\tUID = %@\n"







|
|







726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
	OFString *extensions = [_extensions.description
	    stringByReplacingOccurrencesOfString: @"\n"
				      withString: @"\n\t"];
	OFString *ret = [OFString stringWithFormat:
	    @"<%@:\n"
	    @"\tFile name = %@\n"
	    @"\tCompression method = %@\n"
	    @"\tCompressed size = %llu\n"
	    @"\tUncompressed size = %llu\n"
	    @"\tModification date = %@\n"
	    @"\tHeader level = %u\n"
	    @"\tCRC16 = %04" @PRIX16 @"\n"
	    @"\tOperating system identifier = %c\n"
	    @"\tComment = %@\n"
	    @"\tMode = %@\n"
	    @"\tUID = %@\n"

Modified src/OFMutableLHAArchiveEntry.h from [eae4b7cde4] to [14f294b208].

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 * @brief The compression method of the entry.
 */
@property (readwrite, copy, nonatomic) OFString *compressionMethod;

/**
 * @brief The compressed size of the entry's file.
 */
@property (readwrite, nonatomic) uint32_t compressedSize;

/**
 * @brief The uncompressed size of the entry's file.
 */
@property (readwrite, nonatomic) uint32_t uncompressedSize;

/**
 * @brief The modification date of the file.
 */
@property (readwrite, retain, nonatomic) OFDate *modificationDate;

/**







|




|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 * @brief The compression method of the entry.
 */
@property (readwrite, copy, nonatomic) OFString *compressionMethod;

/**
 * @brief The compressed size of the entry's file.
 */
@property (readwrite, nonatomic) unsigned long long compressedSize;

/**
 * @brief The uncompressed size of the entry's file.
 */
@property (readwrite, nonatomic) unsigned long long uncompressedSize;

/**
 * @brief The modification date of the file.
 */
@property (readwrite, retain, nonatomic) OFDate *modificationDate;

/**

Modified src/OFMutableLHAArchiveEntry.m from [c791dddd21] to [423181bd19].

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
- (void)setCompressionMethod: (OFString *)compressionMethod
{
	OFString *old = _compressionMethod;
	_compressionMethod = [compressionMethod copy];
	[old release];
}

- (void)setCompressedSize: (uint32_t)compressedSize
{
	_compressedSize = compressedSize;
}

- (void)setUncompressedSize: (uint32_t)uncompressedSize
{
	_uncompressedSize = uncompressedSize;
}

- (void)setModificationDate: (OFDate *)modificationDate
{
	OFDate *old = _modificationDate;







|




|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
- (void)setCompressionMethod: (OFString *)compressionMethod
{
	OFString *old = _compressionMethod;
	_compressionMethod = [compressionMethod copy];
	[old release];
}

- (void)setCompressedSize: (unsigned long long)compressedSize
{
	_compressedSize = compressedSize;
}

- (void)setUncompressedSize: (unsigned long long)uncompressedSize
{
	_uncompressedSize = uncompressedSize;
}

- (void)setModificationDate: (OFDate *)modificationDate
{
	OFDate *old = _modificationDate;

Modified utils/ofarc/LHAArchive.m from [5f83697ea8] to [a1e8c6e072].

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

		[OFStdOut writeLine: entry.fileName];

		if (app->_outputLevel >= 1) {
			OFString *modificationDate = [entry.modificationDate
			    localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"];
			OFString *compressedSize = [OFString stringWithFormat:
			    @"%" PRIu32, entry.compressedSize];
			OFString *uncompressedSize = [OFString stringWithFormat:
			    @"%" PRIu32, entry.uncompressedSize];
			OFString *CRC16 = [OFString stringWithFormat:
			    @"%04" PRIX16, entry.CRC16];

			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"list_compressed_size",
			    @"["







|

|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

		[OFStdOut writeLine: entry.fileName];

		if (app->_outputLevel >= 1) {
			OFString *modificationDate = [entry.modificationDate
			    localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"];
			OFString *compressedSize = [OFString stringWithFormat:
			    @"%llu", entry.compressedSize];
			OFString *uncompressedSize = [OFString stringWithFormat:
			    @"%llu", entry.uncompressedSize];
			OFString *CRC16 = [OFString stringWithFormat:
			    @"%04" PRIX16, entry.CRC16];

			[OFStdOut writeString: @"\t"];
			[OFStdOut writeLine: OF_LOCALIZED(
			    @"list_compressed_size",
			    @"["
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268

	while ((entry = [_archive nextEntry]) != nil) {
		void *pool = objc_autoreleasePoolPush();
		OFString *fileName = entry.fileName;
		OFString *outFileName, *directory;
		OFFile *output;
		OFStream *stream;
		uint64_t written = 0, size = entry.uncompressedSize;
		int8_t percent = -1, newPercent;

		if (!all && ![files containsObject: fileName])
			continue;

		[missing removeObject: fileName];








|







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

	while ((entry = [_archive nextEntry]) != nil) {
		void *pool = objc_autoreleasePoolPush();
		OFString *fileName = entry.fileName;
		OFString *outFileName, *directory;
		OFFile *output;
		OFStream *stream;
		unsigned long long written = 0, size = entry.uncompressedSize;
		int8_t percent = -1, newPercent;

		if (!all && ![files containsObject: fileName])
			continue;

		[missing removeObject: fileName];