internal void WriteCore(ReadOnlySpan <byte> buffer, bool isFinalBlock = false) { if (_mode != CompressionMode.Compress) { throw new InvalidOperationException(SR.BrotliStream_Decompress_UnsupportedOperation); } EnsureNotDisposed(); OperationStatus lastResult = OperationStatus.DestinationTooSmall; Span <byte> output = new Span <byte>(_buffer); while (lastResult == OperationStatus.DestinationTooSmall) { int bytesConsumed; int bytesWritten; lastResult = _encoder.Compress(buffer, output, out bytesConsumed, out bytesWritten, isFinalBlock); if (lastResult == OperationStatus.InvalidData) { throw new InvalidOperationException(SR.BrotliStream_Compress_InvalidData); } if (bytesWritten > 0) { _stream.Write(output.Slice(0, bytesWritten)); } if (bytesConsumed > 0) { buffer = buffer.Slice(bytesConsumed); } } }
public void Compress_Canterbury_WithState(int innerIterations, string uncompressedFileName, CompressionLevel compressLevel) { byte[] bytes = File.ReadAllBytes(uncompressedFileName); ReadOnlySpan <byte> uncompressedData = new ReadOnlySpan <byte>(bytes); int maxCompressedSize = BrotliEncoder.GetMaxCompressedLength(bytes.Length); List <byte[]> compressedDataArrays = new List <byte[]>(innerIterations); foreach (var iteration in Benchmark.Iterations) { for (int i = 0; i < innerIterations; i++) { compressedDataArrays.Add(new byte[maxCompressedSize]); } using (iteration.StartMeasurement()) { for (int i = 0; i < innerIterations; i++) { using (BrotliEncoder encoder = new BrotliEncoder()) { Span <byte> output = new Span <byte>(compressedDataArrays[i]); ReadOnlySpan <byte> input = uncompressedData; while (!input.IsEmpty && !output.IsEmpty) { encoder.Compress(input, output, out int bytesConsumed, out int written, isFinalBlock: false); input = input.Slice(bytesConsumed); output = output.Slice(written); } encoder.Compress(input, output, out int bytesConsumed2, out int written2, isFinalBlock: true); } } } } }
public void Compress_Canterbury_WithState(string uncompressedFileName, CompressionLevel compressLevel) { byte[] bytes = File.ReadAllBytes(uncompressedFileName); ReadOnlySpan <byte> uncompressedData = new ReadOnlySpan <byte>(bytes); int maxCompressedSize = BrotliEncoder.GetMaxCompressedLength(bytes.Length); byte[] compressedDataArray = new byte[maxCompressedSize]; int compressLevelBrotli = compressLevel == CompressionLevel.Optimal ? 11 : compressLevel == CompressionLevel.Fastest ? 1 : 0; foreach (var iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) using (BrotliEncoder encoder = new BrotliEncoder(compressLevelBrotli, 22)) { Span <byte> output = new Span <byte>(compressedDataArray); ReadOnlySpan <byte> input = uncompressedData; while (!input.IsEmpty && !output.IsEmpty) { encoder.Compress(input, output, out int bytesConsumed, out int written, isFinalBlock: false); input = input.Slice(bytesConsumed); output = output.Slice(written); } encoder.Compress(input, output, out int bytesConsumed2, out int written2, isFinalBlock: true); } } }
private static void Compress_WithState(ReadOnlySpan <byte> input, Span <byte> output) { BrotliEncoder encoder = default; while (!input.IsEmpty && !output.IsEmpty) { encoder.Compress(input, output, out int bytesConsumed, out int written, isFinalBlock: false); input = input.Slice(bytesConsumed); output = output.Slice(written); } encoder.Compress(ReadOnlySpan <byte> .Empty, output, out int bytesConsumed2, out int bytesWritten, isFinalBlock: true); }
public void RoundTrip_Chunks() { int chunkSize = 100; int totalSize = 20000; BrotliEncoder encoder = default; BrotliDecoder decoder = default; for (int i = 0; i < totalSize; i += chunkSize) { byte[] uncompressed = new byte[chunkSize]; new Random().NextBytes(uncompressed); byte[] compressed = new byte[BrotliEncoder.GetMaxCompressedLength(chunkSize)]; byte[] decompressed = new byte[chunkSize]; var uncompressedSpan = new ReadOnlySpan <byte>(uncompressed); var compressedSpan = new Span <byte>(compressed); var decompressedSpan = new Span <byte>(decompressed); int totalWrittenThisIteration = 0; var compress = encoder.Compress(uncompressedSpan, compressedSpan, out int bytesConsumed, out int bytesWritten, isFinalBlock: false); totalWrittenThisIteration += bytesWritten; compress = encoder.Flush(compressedSpan.Slice(bytesWritten), out bytesWritten); totalWrittenThisIteration += bytesWritten; var res = decoder.Decompress(compressedSpan.Slice(0, totalWrittenThisIteration), decompressedSpan, out int decompressbytesConsumed, out int decompressbytesWritten); Assert.Equal(totalWrittenThisIteration, decompressbytesConsumed); Assert.Equal(bytesConsumed, decompressbytesWritten); Assert.Equal <byte>(uncompressed, decompressedSpan.ToArray()); } }
public Span <byte> Compress_WithState() { using (BrotliEncoder encoder = new BrotliEncoder(GetQuality(level), Window)) { Span <byte> output = new Span <byte>(CompressedFile.UncompressedData); ReadOnlySpan <byte> input = CompressedFile.CompressedData; while (!input.IsEmpty && !output.IsEmpty) { encoder.Compress(input, output, out int bytesConsumed, out int written, isFinalBlock: false); input = input.Slice(bytesConsumed); output = output.Slice(written); } encoder.Compress(input, output, out int bytesConsumed2, out int written2, isFinalBlock: true); return(output); } }
public void Compress_WithEmptySource() { byte[] sourceBytes = new byte[0]; byte[] destinationBytes = new byte[100000]; ReadOnlySpan <byte> source = new ReadOnlySpan <byte>(sourceBytes); Span <byte> destination = new Span <byte>(destinationBytes); Assert.True(BrotliEncoder.TryCompress(source, destination, out int bytesWritten)); // The only byte written should be the Brotli end of stream byte which varies based on the window/quality Assert.Equal(1, bytesWritten); BrotliEncoder encoder = default; var result = encoder.Compress(source, destination, out int bytesConsumed, out bytesWritten, false); Assert.Equal(0, bytesWritten); Assert.Equal(0, bytesConsumed); Assert.Equal(OperationStatus.Done, result); result = encoder.Compress(source, destination, out bytesConsumed, out bytesWritten, isFinalBlock: true); Assert.Equal(1, bytesWritten); Assert.Equal(0, bytesConsumed); Assert.Equal(OperationStatus.Done, result); }
public void Compress_WithEmptyDestination() { string testFile = UncompressedTestFile(); byte[] correctUncompressedBytes = File.ReadAllBytes(testFile); byte[] empty = new byte[0]; ReadOnlySpan <byte> source = new ReadOnlySpan <byte>(correctUncompressedBytes); Span <byte> destination = new Span <byte>(empty); Assert.False(BrotliEncoder.TryCompress(source, destination, out int bytesWritten), "TryCompress completed successfully but should have failed due to too short of a destination array"); Assert.Equal(0, bytesWritten); BrotliEncoder encoder = default; var result = encoder.Compress(source, destination, out int bytesConsumed, out bytesWritten, false); Assert.Equal(0, bytesWritten); Assert.Equal(0, bytesConsumed); Assert.Equal(OperationStatus.DestinationTooSmall, result); result = encoder.Compress(source, destination, out bytesConsumed, out bytesWritten, isFinalBlock: true); Assert.Equal(0, bytesWritten); Assert.Equal(0, bytesConsumed); Assert.Equal(OperationStatus.DestinationTooSmall, result); }