public void Should_return_defaults_when_try_to_extract_first_header() { var(firstBlock, afterHeader) = defaultInstance.CutFirstBlock(); firstBlock.Array.Should().BeNull(); afterHeader.Should().Be(defaultInstance); }
public override int Read(byte[] buffer, int offset, int count) { CheckStreamPosition(); if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (offset < 0) { throw new ArgumentOutOfRangeException(nameof(offset), "Need non negative number"); } if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), "Need non negative number"); } if (buffer.Length - offset < count) { throw new ArgumentException($"Buffer have smaller elements {buffer.Length - offset} from given offset {offset} than requested in count {count}", nameof(count)); } if (count == 0) { throw new ArgumentException("Requested zero elements", nameof(count)); } if (count < GzipHeader.Length) { throw new ArgumentException("Buffer element count can't be less than Gzip header length", nameof(count)); } if (buffer.Length - offset == 0) { throw new ArgumentException("Buffer has no elements from requested offset", nameof(offset)); } var currentGzipBuffer = leftBuffer; var isEnd = streamEnded; var read = 0; if (currentGzipBuffer.IsEmpty && !streamEnded) { (read, isEnd, currentGzipBuffer) = ReadGzipBufferFromStream(); } if (!currentGzipBuffer.IsEmpty) { ArraySegment <byte> readBlock; (readBlock, currentGzipBuffer) = ReadFirstBockFromBuffer(currentGzipBuffer, count); read = readBlock.Count; if (readBlock.Array != null && readBlock.Count > 0) { Buffer.BlockCopy(readBlock.Array, readBlock.Offset, buffer, offset, readBlock.Count); } } leftBuffer = currentGzipBuffer; position += read; streamEnded = isEnd; return(read); (int Read, bool StreamIsEnd, GzipBuffer gzipBuffer) ReadGzipBufferFromStream() { GzipBuffer gzipBuffer = default; var(readBuffer, endOfStream) = stream.ReadExactBuffer(buffer, offset, count); if (readBuffer.Count > 0) { var readGzipBuffer = new GzipBuffer(readBuffer); gzipBuffer = readGzipBuffer.NoHeadersOrParts || readGzipBuffer.ContainsOnlyOneCompressedBlockFromStart ? default : readGzipBuffer.ToOwnedBuffer(); } return(readBuffer.Count, endOfStream, gzipBuffer); } (ArraySegment <byte> Block, GzipBuffer LeftGzipBuffer) ReadFirstBockFromBuffer(GzipBuffer gzipBuffer, int requestedCount) { var(block, left) = gzipBuffer.CutFirstBlock(); if (block.Array == null || block.Count == 0) { if (left.ContainsOnlyPart) { block = gzipBuffer.GetPossiblePart(); } left = default; } else if (block.Count > requestedCount) { block = block.Slice(block.Offset, requestedCount); var returnBlock = block.Slice(block.Offset + requestedCount, block.Count - requestedCount); left = left.ReturnToStart(returnBlock); } return(block, left); } }