Overview
Comment: | OFLHAArchive: Add support for files > 4 GB |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
9d9fa168aacf06ac46883f90e4aec444 |
User & Date: | js on 2024-02-26 21:46:56 |
Other Links: | manifest | tags |
Context
2024-02-27
| ||
00:57 | OFStream: Minor documentation fix check-in: ed4319fab0 user: js tags: trunk | |
2024-02-26
| ||
21:46 | OFLHAArchive: Add support for files > 4 GB check-in: 9d9fa168aa user: js tags: trunk | |
20:32 | Use <cet.h> and _CET_ENDBR macro check-in: 0b441e52d6 user: js tags: trunk | |
Changes
Modified src/OFLHAArchive.m from [7a342795be] to [ac15e6d468].
︙ | ︙ | |||
67 68 69 70 71 72 73 | @interface OFLHAArchiveFileWriteStream: OFStream <OFReadyForWritingObserving> { OFLHAArchive *_archive; OFMutableLHAArchiveEntry *_entry; OFStringEncoding _encoding; OFSeekableStream *_stream; OFStreamOffset _headerOffset; | | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | @interface OFLHAArchiveFileWriteStream: OFStream <OFReadyForWritingObserving> { OFLHAArchive *_archive; OFMutableLHAArchiveEntry *_entry; OFStringEncoding _encoding; OFSeekableStream *_stream; OFStreamOffset _headerOffset; uint64_t _bytesWritten; uint16_t _CRC16; } - (instancetype)of_initWithArchive: (OFLHAArchive *)archive stream: (OFSeekableStream *)stream entry: (OFLHAArchiveEntry *)entry encoding: (OFStringEncoding)encoding; |
︙ | ︙ | |||
550 551 552 553 554 555 556 | } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; | | | | | 550 551 552 553 554 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 | } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (UINT64_MAX - _bytesWritten < length) @throw [OFOutOfRangeException exception]; @try { [_stream writeBuffer: buffer length: length]; } @catch (OFWriteFailedException *e) { OFEnsure(e.bytesWritten <= length); _bytesWritten += (uint64_t)e.bytesWritten; _CRC16 = OFCRC16(_CRC16, buffer, e.bytesWritten); if (e.errNo == EWOULDBLOCK || e.errNo == EAGAIN) return e.bytesWritten; @throw e; } _bytesWritten += (uint64_t)length; _CRC16 = OFCRC16(_CRC16, buffer, length); return length; } - (bool)lowlevelIsAtEndOfStream { |
︙ | ︙ |
Modified src/OFLHAArchiveEntry.m from [fa0ccd29a1] to [2adb105405].
︙ | ︙ | |||
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 | [entry->_modificationDate release]; entry->_modificationDate = nil; entry->_modificationDate = [[OFDate alloc] initWithTimeIntervalSince1970: modificationDate]; } static bool parseExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding, bool allowFileName) { void (*function)(OFLHAArchiveEntry *, OFData *, OFStringEncoding) = NULL; switch (*(char *)[extension itemAtIndex: 0]) { case 0x01: if (allowFileName) function = parseFileNameExtension; break; case 0x02: function = parseDirectoryNameExtension; break; case 0x3F: function = parseCommentExtension; break; case 0x50: function = parsePermissionsExtension; break; case 0x51: function = parseGIDUIDExtension; break; case 0x52: | > > > > > > > > > > > > > > > > > > > | 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 241 242 243 244 245 246 247 | [entry->_modificationDate release]; entry->_modificationDate = nil; entry->_modificationDate = [[OFDate alloc] initWithTimeIntervalSince1970: modificationDate]; } static void parseFileSizeExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { uint64_t tmp; if (extension.count != 17) @throw [OFInvalidFormatException exception]; memcpy(&tmp, (char *)extension.items + 1, 8); entry->_compressedSize = OFFromLittleEndian64(tmp); memcpy(&tmp, (char *)extension.items + 9, 8); entry->_uncompressedSize = OFFromLittleEndian64(tmp); } static bool parseExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding, bool allowFileName) { void (*function)(OFLHAArchiveEntry *, OFData *, OFStringEncoding) = NULL; switch (*(char *)[extension itemAtIndex: 0]) { case 0x01: if (allowFileName) function = parseFileNameExtension; break; case 0x02: function = parseDirectoryNameExtension; break; case 0x3F: function = parseCommentExtension; break; case 0x42: function = parseFileSizeExtension; break; case 0x50: function = parsePermissionsExtension; break; case 0x51: function = parseGIDUIDExtension; break; case 0x52: |
︙ | ︙ | |||
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 | { void *pool = objc_autoreleasePoolPush(); OFMutableData *data = [OFMutableData dataWithCapacity: 24]; const char *fileName, *directoryName; size_t fileNameLength, directoryNameLength; uint16_t tmp16; uint32_t tmp32; size_t headerSize; if ([_compressionMethod cStringLengthWithEncoding: OFStringEncodingASCII] != 5) @throw [OFInvalidArgumentException exception]; getFileNameAndDirectoryName(self, encoding, &fileName, &fileNameLength, &directoryName, &directoryNameLength); if (fileNameLength > UINT16_MAX - 3 || directoryNameLength > UINT16_MAX - 3 || | > | | 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 | { void *pool = objc_autoreleasePoolPush(); OFMutableData *data = [OFMutableData dataWithCapacity: 24]; const char *fileName, *directoryName; size_t fileNameLength, directoryNameLength; uint16_t tmp16; uint32_t tmp32; uint64_t tmp64; size_t headerSize; if ([_compressionMethod cStringLengthWithEncoding: OFStringEncodingASCII] != 5) @throw [OFInvalidArgumentException exception]; getFileNameAndDirectoryName(self, encoding, &fileName, &fileNameLength, &directoryName, &directoryNameLength); if (fileNameLength > UINT16_MAX - 3 || directoryNameLength > UINT16_MAX - 3 || _compressedSize > UINT64_MAX || _uncompressedSize > UINT64_MAX) @throw [OFOutOfRangeException exception]; /* Length. Filled in after we're done. */ [data increaseCountBy: 2]; [data addItems: [_compressionMethod cStringWithEncoding: OFStringEncodingASCII] |
︙ | ︙ | |||
673 674 675 676 677 678 679 680 681 682 683 684 685 686 | tmp16 = OFToLittleEndian16((uint16_t)fileCommentLength + 3); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x3F"]; [data addItems: [_fileComment cStringWithEncoding: encoding] count: fileCommentLength]; } if (_POSIXPermissions != nil) { tmp16 = OFToLittleEndian16(5); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x50"]; tmp16 = OFToLittleEndian16(_POSIXPermissions.unsignedShortValue); | > > > > > > > > > > > > > > | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 | tmp16 = OFToLittleEndian16((uint16_t)fileCommentLength + 3); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x3F"]; [data addItems: [_fileComment cStringWithEncoding: encoding] count: fileCommentLength]; } /* * Always include the file size extension, as the header can be written * with size 0 initially and then rewritten with the actual size in * case the data to be archived is being streamed - but for that we * need to make sure we always have the space. */ tmp16 = OFToLittleEndian16(19); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x42"]; tmp64 = OFToLittleEndian64(_compressedSize); [data addItems: &tmp64 count: sizeof(tmp64)]; tmp64 = OFToLittleEndian64(_uncompressedSize); [data addItems: &tmp64 count: sizeof(tmp64)]; if (_POSIXPermissions != nil) { tmp16 = OFToLittleEndian16(5); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x50"]; tmp16 = OFToLittleEndian16(_POSIXPermissions.unsignedShortValue); |
︙ | ︙ |