@@ -41,10 +41,11 @@ #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfRangeException.h" #import "OFSeekFailedException.h" +#import "OFTruncatedDataException.h" #import "OFUnsupportedVersionException.h" /* * FIXME: Current limitations: * - Split archives are not supported. @@ -73,11 +74,12 @@ - (bool)matchesEntry: (OFZIPArchiveEntry *)entry; @end @interface OFZIPArchive_FileReadStream: OFStream { - OFStream *_stream, *_decompressedStream; + OF_KINDOF(OFStream *) _stream; + OF_KINDOF(OFStream *) _decompressedStream; OFZIPArchiveEntry *_entry; uint64_t _toRead; uint32_t _CRC32; bool _atEndOfStream; } @@ -776,10 +778,13 @@ [super dealloc]; } - (bool)lowlevelIsAtEndOfStream { + if (_stream == nil) + @throw [OFNotOpenException exceptionWithObject: self]; + return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length @@ -801,27 +806,41 @@ length = (size_t)_toRead; ret = [_decompressedStream readIntoBuffer: buffer length: length]; - if (ret == 0) - _atEndOfStream = true; - _toRead -= ret; _CRC32 = of_crc32(_CRC32, buffer, ret); - if (_toRead == 0) + if (_toRead == 0) { + _atEndOfStream = true; + if (~_CRC32 != [_entry CRC32]) @throw [OFChecksumFailedException exception]; + } return ret; } + +- (bool)hasDataInReadBuffer +{ + return ([super hasDataInReadBuffer] || + [_decompressedStream hasDataInReadBuffer]); +} + +- (int)fileDescriptorForReading +{ + return [_decompressedStream fileDescriptorForReading]; +} - (void)close { [_stream release]; _stream = nil; + + [_decompressedStream release]; + _decompressedStream = nil; [super close]; } @end