add Crc32Stream write async

This commit is contained in:
Adam Hathcock
2026-04-30 13:07:34 +01:00
parent 2aec75a3bc
commit 29f06b753a
2 changed files with 76 additions and 0 deletions

View File

@@ -1,5 +1,7 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace SharpCompress.Crypto;
@@ -34,9 +36,26 @@ public sealed class Crc32Stream : Stream
public override void Flush() => stream.Flush();
public override async Task FlushAsync(CancellationToken cancellationToken) =>
await stream.FlushAsync(cancellationToken).ConfigureAwait(false);
public override int Read(byte[] buffer, int offset, int count) =>
throw new NotSupportedException();
public override Task<int> ReadAsync(
byte[] buffer,
int offset,
int count,
CancellationToken cancellationToken
) => throw new NotSupportedException();
#if !LEGACY_DOTNET
public override ValueTask<int> ReadAsync(
Memory<byte> buffer,
CancellationToken cancellationToken = default
) => throw new NotSupportedException();
#endif
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
public override void SetLength(long value) => throw new NotSupportedException();
@@ -57,6 +76,28 @@ public sealed class Crc32Stream : Stream
seed = CalculateCrc(_table, seed, buffer.AsSpan(offset, count));
}
public override async Task WriteAsync(
byte[] buffer,
int offset,
int count,
CancellationToken cancellationToken
)
{
await stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
seed = CalculateCrc(_table, seed, buffer.AsSpan(offset, count));
}
#if !LEGACY_DOTNET
public override async ValueTask WriteAsync(
ReadOnlyMemory<byte> buffer,
CancellationToken cancellationToken = default
)
{
await stream.WriteAsync(buffer, cancellationToken).ConfigureAwait(false);
seed = CalculateCrc(_table, seed, buffer.Span);
}
#endif
public override void WriteByte(byte value)
{
stream.WriteByte(value);

View File

@@ -23,7 +23,10 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Compressors.ADC;
using SharpCompress.Compressors.Deflate;
using SharpCompress.Crypto;
@@ -121,4 +124,36 @@ public class AdcTest : TestBase
Assert.Equal(crc32, crc32A);
Assert.Equal(crc32, crc32B);
}
[Fact]
public async Task TestCrc32StreamWriteAsync()
{
var buffer = File.ReadAllBytes(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar"));
var crc32 = Crc32Stream.Compute(buffer);
using var memory = new MemoryStream();
using var crcStream = new Crc32Stream(memory, 0xEDB88320, 0xFFFFFFFF);
await crcStream.WriteAsync(buffer, 0, buffer.Length, CancellationToken.None);
Assert.Equal(buffer, memory.ToArray());
Assert.Equal(crc32, crcStream.Crc);
}
#if !LEGACY_DOTNET
[Fact]
public async Task TestCrc32StreamWriteMemoryAsync()
{
var buffer = File.ReadAllBytes(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar"));
var crc32 = Crc32Stream.Compute(buffer);
using var memory = new MemoryStream();
using var crcStream = new Crc32Stream(memory, 0xEDB88320, 0xFFFFFFFF);
await crcStream.WriteAsync(buffer.AsMemory(), CancellationToken.None);
Assert.Equal(buffer, memory.ToArray());
Assert.Equal(crc32, crcStream.Crc);
}
#endif
}