private async Task <bool> AcquireNextChunkAsync() { do { ulong?rawVarint = await TryReadVarIntAsync().ConfigureAwait(false); if (rawVarint == null) { return(false); } ulong varint = rawVarint.Value; var flags = (ChunkFlags)varint; var isCompressed = (flags & ChunkFlags.Compressed) != 0; var originalLength = (int) await ReadVarIntAync().ConfigureAwait(false); var compressedLength = isCompressed ? (int) await ReadVarIntAync().ConfigureAwait(false) : originalLength; if (compressedLength > originalLength) { throw EndOfStream(); // corrupted } var compressed = new byte[compressedLength]; var chunk = await ReadBlockAsync(compressed, 0, compressedLength).ConfigureAwait(false); if (chunk != compressedLength) { throw EndOfStream(); // corrupted } if (!isCompressed) { _buffer = compressed; // no compression on this chunk _bufferLength = compressedLength; } else { if (_buffer == null || _buffer.Length < originalLength) { _buffer = new byte[originalLength]; } var passes = (int)flags >> 2; if (passes != 0) { throw new NotSupportedException("Chunks with multiple passes are not supported."); } LZ4Codec.Decode(compressed, 0, compressedLength, _buffer, 0, originalLength, true); _bufferLength = originalLength; } _bufferOffset = 0; } while (_bufferLength == 0); // skip empty block (shouldn't happen but...) return(true); }
/// <summary>Reads the next chunk from stream.</summary> /// <returns><c>true</c> if next has been read, or <c>false</c> if it is legitimate end of file. /// Throws <see cref="EndOfStreamException"/> if end of stream was unexpected.</returns> private bool AcquireNextChunk() { do { if (fileHeaderInfo == null) { fileHeaderInfo = _formatReader.ReadHeader(_innerStream); } if (blockInfo != null && blockInfo.ChunkSize <= 0) { return(false); } blockInfo = _formatReader.ReadChunkHeader(_innerStream); int compressedLength = blockInfo.ChunkSize; if (compressedLength <= 0 || compressedLength > GetBufferSize(fileHeaderInfo.FrameDescriptor_BD_BlockMaxSize)) { return(false); } bool isCompressed = blockInfo.IsCompressed; var compressed = new byte[compressedLength]; var chunk = ReadBlock(compressed, 0, compressedLength); if (chunk != compressedLength) { throw EndOfStream(); // corrupted } if (!isCompressed) { _buffer = compressed; // no compression on this chunk _bufferLength = compressedLength; } else { int bSize = GetBufferSize(fileHeaderInfo.FrameDescriptor_BD_BlockMaxSize); if (_buffer == null) { _buffer = new byte[bSize]; } _bufferLength = LZ4Codec.Decode(compressed, 0, compressedLength, _buffer, 0, bSize, false); } _bufferOffset = 0; } while (_bufferLength == 0); // skip empty block (shouldn't happen but...) return(true); }