From f666781a5dc24b7f27979682ff0849bd8cf5bd3b Mon Sep 17 00:00:00 2001 From: Brant Burnett Date: Sun, 15 Dec 2024 19:10:26 -0500 Subject: [PATCH] Add some tweaks to SnappyStream (#113) - Slightly more performant ReadByte/WriteByte overloads - Include DisposeAsync in test coverage Co-authored-by: Brant Burnett --- .gitignore | 1 + Snappier.Tests/SnappyStreamTests.cs | 39 +++++++++++++++++++++++++++++ Snappier/SnappyStream.cs | 16 ++++++++++++ 3 files changed, 56 insertions(+) diff --git a/.gitignore b/.gitignore index 8839678..30cf935 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ Couchbase.snk BenchmarkDotNet.Artifacts/ test-results/ TestResults/ +.DS_Store diff --git a/Snappier.Tests/SnappyStreamTests.cs b/Snappier.Tests/SnappyStreamTests.cs index d3b857a..830fde0 100644 --- a/Snappier.Tests/SnappyStreamTests.cs +++ b/Snappier.Tests/SnappyStreamTests.cs @@ -60,6 +60,39 @@ public void CompressAndDecompress(string filename) Assert.Equal(sourceText, decompressedText); } + [Fact] + public void CompressAndDecompress_SingleByte() + { + using var resource = + typeof(SnappyStreamTests).Assembly.GetManifestResourceStream($"Snappier.Tests.TestData.alice29.txt"); + Assert.NotNull(resource); + + var inBuffer = new byte[128]; + var readBytes = resource.Read(inBuffer, 0, inBuffer.Length); + + using var output = new MemoryStream(); + + using (var compressor = new SnappyStream(output, CompressionMode.Compress, true)) + { + for (var i = 0; i < readBytes; i++) + { + compressor.WriteByte(inBuffer[i]); + } + } + + output.Position = 0; + + using var decompressor = new SnappyStream(output, CompressionMode.Decompress, true); + + var outBuffer = new byte[128]; + for (var i = 0; i < readBytes; i++) + { + outBuffer[i] = (byte)decompressor.ReadByte(); + } + + Assert.Equal(inBuffer, outBuffer); + } + [Theory] [InlineData("alice29.txt")] [InlineData("asyoulik.txt")] @@ -80,6 +113,9 @@ public async Task CompressAndDecompressAsync(string filename) using var output = new MemoryStream(); +#if NET6_0_OR_GREATER + await +#endif using (var compressor = new SnappyStream(output, CompressionMode.Compress, true)) { await resource.CopyToAsync(compressor); @@ -87,6 +123,9 @@ public async Task CompressAndDecompressAsync(string filename) output.Position = 0; +#if NET6_0_OR_GREATER + await +#endif using var decompressor = new SnappyStream(output, CompressionMode.Decompress, true); using var streamReader = new StreamReader(decompressor, Encoding.UTF8); diff --git a/Snappier/SnappyStream.cs b/Snappier/SnappyStream.cs index 37367a4..8e8a8f8 100644 --- a/Snappier/SnappyStream.cs +++ b/Snappier/SnappyStream.cs @@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.IO.Compression; +using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Snappier.Internal; @@ -180,8 +181,18 @@ public override long Seek(long offset, SeekOrigin origin) public override int Read(byte[] buffer, int offset, int count) => ReadCore(buffer.AsSpan(offset, count)); #if !NETSTANDARD2_0 + /// public override int Read(Span buffer) => ReadCore(buffer); + + /// + public override int ReadByte() + { + byte b = 0; + int r = ReadCore(MemoryMarshal.CreateSpan(ref b, 1)); + return r == 0 ? -1 : b; + } + #endif private int ReadCore(Span buffer) @@ -350,8 +361,13 @@ public override void Write(byte[] buffer, int offset, int count) => WriteCore(buffer.AsSpan(offset, count)); #if !NETSTANDARD2_0 + /// public override void Write(ReadOnlySpan buffer) => WriteCore(buffer); + + /// + public override void WriteByte(byte value) => WriteCore(MemoryMarshal.CreateReadOnlySpan(ref value, 1)); + #endif private void WriteCore(ReadOnlySpan buffer)