︙ | | | ︙ | |
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
- (bool)matchesEntry: (OFZIPArchiveEntry *)entry;
@end
OF_DIRECT_MEMBERS
@interface OFZIPArchiveFileReadStream: OFStream
{
OFZIPArchive *_archive;
OFStream *_stream, *_decompressedStream;
OFZIPArchiveEntry *_entry;
unsigned long long _toRead;
uint32_t _CRC32;
bool _atEndOfStream;
}
- (instancetype)of_initWithArchive: (OFZIPArchive *)archive
|
>
|
|
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
- (bool)matchesEntry: (OFZIPArchiveEntry *)entry;
@end
OF_DIRECT_MEMBERS
@interface OFZIPArchiveFileReadStream: OFStream
{
OFZIPArchive *_archive;
OFZIPArchiveEntryCompressionMethod _compressionMethod;
OF_KINDOF(OFStream *) _decompressedStream;
OFZIPArchiveEntry *_entry;
unsigned long long _toRead;
uint32_t _CRC32;
bool _atEndOfStream;
}
- (instancetype)of_initWithArchive: (OFZIPArchive *)archive
|
︙ | | | ︙ | |
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
seekOrThrowInvalidFormat(OFZIPArchive *archive, const uint32_t *diskNumber,
OFStreamOffset offset, OFSeekWhence whence)
{
if (diskNumber != NULL && *diskNumber != archive->_diskNumber) {
OFStream *oldStream;
OFSeekableStream *stream;
if (archive->_mode != modeRead)
@throw [OFInvalidFormatException exception];
oldStream = archive->_stream;
stream = [archive->_delegate archive: archive
wantsPartNumbered: *diskNumber
totalNumberOfParts: archive->_numDisks];
if (stream == nil)
@throw [OFInvalidFormatException exception];
archive->_diskNumber = *diskNumber;
archive->_stream = [stream retain];
[oldStream release];
|
|
>
|
|
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
seekOrThrowInvalidFormat(OFZIPArchive *archive, const uint32_t *diskNumber,
OFStreamOffset offset, OFSeekWhence whence)
{
if (diskNumber != NULL && *diskNumber != archive->_diskNumber) {
OFStream *oldStream;
OFSeekableStream *stream;
if (archive->_mode != modeRead ||
*diskNumber > archive->_lastDiskNumber)
@throw [OFInvalidFormatException exception];
oldStream = archive->_stream;
stream = [archive->_delegate archive: archive
wantsPartNumbered: *diskNumber
lastPartNumber: archive->_lastDiskNumber];
if (stream == nil)
@throw [OFInvalidFormatException exception];
archive->_diskNumber = *diskNumber;
archive->_stream = [stream retain];
[oldStream release];
|
︙ | | | ︙ | |
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
|
break;
}
} while (--offset >= -65557);
if (!valid)
@throw [OFInvalidFormatException exception];
_diskNumber = _numDisks = [_stream readLittleEndianInt16];
_centralDirectoryDisk = [_stream readLittleEndianInt16];
_centralDirectoryEntriesInDisk = [_stream readLittleEndianInt16];
_centralDirectoryEntries = [_stream readLittleEndianInt16];
_centralDirectorySize = [_stream readLittleEndianInt32];
_centralDirectoryOffset = [_stream readLittleEndianInt32];
commentLength = [_stream readLittleEndianInt16];
_archiveComment = [[_stream
readStringWithLength: commentLength
encoding: OFStringEncodingCodepage437] copy];
if (_numDisks == 0xFFFF ||
_centralDirectoryDisk == 0xFFFF ||
_centralDirectoryEntriesInDisk == 0xFFFF ||
_centralDirectoryEntries == 0xFFFF ||
_centralDirectorySize == 0xFFFFFFFF ||
_centralDirectoryOffset == 0xFFFFFFFF) {
uint32_t diskNumber;
int64_t offset64;
|
|
|
|
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
|
break;
}
} while (--offset >= -65557);
if (!valid)
@throw [OFInvalidFormatException exception];
_diskNumber = _lastDiskNumber = [_stream readLittleEndianInt16];
_centralDirectoryDisk = [_stream readLittleEndianInt16];
_centralDirectoryEntriesInDisk = [_stream readLittleEndianInt16];
_centralDirectoryEntries = [_stream readLittleEndianInt16];
_centralDirectorySize = [_stream readLittleEndianInt32];
_centralDirectoryOffset = [_stream readLittleEndianInt32];
commentLength = [_stream readLittleEndianInt16];
_archiveComment = [[_stream
readStringWithLength: commentLength
encoding: OFStringEncodingCodepage437] copy];
if (_lastDiskNumber == 0xFFFF ||
_centralDirectoryDisk == 0xFFFF ||
_centralDirectoryEntriesInDisk == 0xFFFF ||
_centralDirectoryEntries == 0xFFFF ||
_centralDirectorySize == 0xFFFFFFFF ||
_centralDirectoryOffset == 0xFFFFFFFF) {
uint32_t diskNumber;
int64_t offset64;
|
︙ | | | ︙ | |
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
|
/*
* FIXME: Handle number of the disk containing ZIP64 end of
* central directory record.
*/
diskNumber = [_stream readLittleEndianInt32];
offset64 = [_stream readLittleEndianInt64];
_numDisks = [_stream readLittleEndianInt32];
if (offset64 < 0 || (OFStreamOffset)offset64 != offset64)
@throw [OFOutOfRangeException exception];
seekOrThrowInvalidFormat(self, &diskNumber,
(OFStreamOffset)offset64, OFSeekSet);
|
|
>
>
>
|
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
|
/*
* FIXME: Handle number of the disk containing ZIP64 end of
* central directory record.
*/
diskNumber = [_stream readLittleEndianInt32];
offset64 = [_stream readLittleEndianInt64];
_lastDiskNumber = [_stream readLittleEndianInt32];
if (_lastDiskNumber == 0)
@throw [OFInvalidFormatException exception];
_lastDiskNumber--;
if (offset64 < 0 || (OFStreamOffset)offset64 != offset64)
@throw [OFOutOfRangeException exception];
seekOrThrowInvalidFormat(self, &diskNumber,
(OFStreamOffset)offset64, OFSeekSet);
|
︙ | | | ︙ | |
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
|
stream: (OFStream *)stream
entry: (OFZIPArchiveEntry *)entry
{
self = [super init];
@try {
_archive = [archive retain];
_stream = [stream retain];
switch (entry.compressionMethod) {
case OFZIPArchiveEntryCompressionMethodNone:
_decompressedStream = [stream retain];
break;
case OFZIPArchiveEntryCompressionMethodDeflate:
_decompressedStream = [[OFInflateStream alloc]
initWithStream: stream];
break;
case OFZIPArchiveEntryCompressionMethodDeflate64:
_decompressedStream = [[OFInflate64Stream alloc]
initWithStream: stream];
break;
default:
@throw [OFNotImplementedException
exceptionWithSelector: _cmd
object: nil];
}
_entry = [entry copy];
_toRead = entry.uncompressedSize;
_CRC32 = ~0;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
if (_stream != nil || _decompressedStream != nil)
[self close];
[_entry release];
if (_archive->_lastReturnedStream == self)
_archive->_lastReturnedStream = nil;
[_archive release];
[super dealloc];
}
- (bool)lowlevelIsAtEndOfStream
{
if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
return _atEndOfStream;
}
- (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length
{
size_t ret;
if (_stream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
if (_atEndOfStream)
return 0;
if (_stream.atEndOfStream && !_decompressedStream.hasDataInReadBuffer)
@throw [OFTruncatedDataException exception];
#if SIZE_MAX >= UINT64_MAX
if (length > UINT64_MAX)
@throw [OFOutOfRangeException exception];
#endif
if (length > _toRead)
|
|
|
|
|
|
|
|
|
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
|
stream: (OFStream *)stream
entry: (OFZIPArchiveEntry *)entry
{
self = [super init];
@try {
_archive = [archive retain];
_compressionMethod = entry.compressionMethod;
switch (_compressionMethod) {
case OFZIPArchiveEntryCompressionMethodNone:
_decompressedStream = [_archive->_stream retain];
break;
case OFZIPArchiveEntryCompressionMethodDeflate:
_decompressedStream = [[OFInflateStream alloc]
initWithStream: _archive->_stream];
break;
case OFZIPArchiveEntryCompressionMethodDeflate64:
_decompressedStream = [[OFInflate64Stream alloc]
initWithStream: _archive->_stream];
break;
default:
@throw [OFNotImplementedException
exceptionWithSelector: _cmd
object: nil];
}
_entry = [entry copy];
_toRead = entry.uncompressedSize;
_CRC32 = ~0;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
if (_decompressedStream != nil)
[self close];
[_entry release];
if (_archive->_lastReturnedStream == self)
_archive->_lastReturnedStream = nil;
[_archive release];
[super dealloc];
}
- (bool)lowlevelIsAtEndOfStream
{
if (_decompressedStream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
return _atEndOfStream;
}
- (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length
{
size_t ret;
if (_decompressedStream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
if (_atEndOfStream)
return 0;
if (_archive->_stream.atEndOfStream &&
!_decompressedStream.hasDataInReadBuffer) {
OFStream *oldStream, *oldDecompressedStream;
OFSeekableStream *stream;
if (_archive->_diskNumber >= _archive->_lastDiskNumber)
@throw [OFTruncatedDataException exception];
oldStream = _archive->_stream;
stream = [_archive->_delegate
archive: _archive
wantsPartNumbered: _archive->_diskNumber + 1
lastPartNumber: _archive->_lastDiskNumber];
if (stream == nil)
@throw [OFInvalidFormatException exception];
_archive->_diskNumber++;
_archive->_stream = [stream retain];
[oldStream release];
switch (_compressionMethod) {
case OFZIPArchiveEntryCompressionMethodNone:
oldDecompressedStream = _decompressedStream;
_decompressedStream = [_archive->_stream retain];
[oldDecompressedStream release];
break;
case OFZIPArchiveEntryCompressionMethodDeflate:
case OFZIPArchiveEntryCompressionMethodDeflate64:
[_decompressedStream
setUnderlyingStream: _archive->_stream];
break;
default:
@throw [OFNotImplementedException
exceptionWithSelector: _cmd
object: nil];
}
}
#if SIZE_MAX >= UINT64_MAX
if (length > UINT64_MAX)
@throw [OFOutOfRangeException exception];
#endif
if (length > _toRead)
|
︙ | | | ︙ | |
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
|
{
return ((id <OFReadyForReadingObserving>)_decompressedStream)
.fileDescriptorForReading;
}
- (void)close
{
if (_stream == nil || _decompressedStream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
[_stream release];
_stream = nil;
[_decompressedStream release];
_decompressedStream = nil;
[super close];
}
@end
|
|
<
<
<
|
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
|
{
return ((id <OFReadyForReadingObserving>)_decompressedStream)
.fileDescriptorForReading;
}
- (void)close
{
if (_decompressedStream == nil)
@throw [OFNotOpenException exceptionWithObject: self];
[_decompressedStream release];
_decompressedStream = nil;
[super close];
}
@end
|
︙ | | | ︙ | |