mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-07-08 18:16:30 +00:00
Fixed AsyncMarkingBinaryReader
This commit is contained in:
@@ -47,14 +47,12 @@ internal class AsyncMarkingBinaryReader
|
||||
|
||||
public async ValueTask<ushort> ReadUInt16Async(CancellationToken cancellationToken = default)
|
||||
{
|
||||
CurrentReadByteCount += 2;
|
||||
var bytes = await ReadBytesAsync(2, cancellationToken).ConfigureAwait(false);
|
||||
return BinaryPrimitives.ReadUInt16LittleEndian(bytes);
|
||||
}
|
||||
|
||||
public async ValueTask<uint> ReadUInt32Async(CancellationToken cancellationToken = default)
|
||||
{
|
||||
CurrentReadByteCount += 4;
|
||||
var bytes = await ReadBytesAsync(4, cancellationToken).ConfigureAwait(false);
|
||||
return BinaryPrimitives.ReadUInt32LittleEndian(bytes);
|
||||
}
|
||||
@@ -63,7 +61,6 @@ internal class AsyncMarkingBinaryReader
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
CurrentReadByteCount += 8;
|
||||
var bytes = await ReadBytesAsync(8, cancellationToken).ConfigureAwait(false);
|
||||
return BinaryPrimitives.ReadUInt64LittleEndian(bytes);
|
||||
}
|
||||
@@ -72,7 +69,6 @@ internal class AsyncMarkingBinaryReader
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
CurrentReadByteCount += 2;
|
||||
var bytes = await ReadBytesAsync(2, cancellationToken).ConfigureAwait(false);
|
||||
return BinaryPrimitives.ReadInt16LittleEndian(bytes);
|
||||
}
|
||||
@@ -81,7 +77,6 @@ internal class AsyncMarkingBinaryReader
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
CurrentReadByteCount += 4;
|
||||
var bytes = await ReadBytesAsync(4, cancellationToken).ConfigureAwait(false);
|
||||
return BinaryPrimitives.ReadInt32LittleEndian(bytes);
|
||||
}
|
||||
@@ -90,7 +85,6 @@ internal class AsyncMarkingBinaryReader
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
CurrentReadByteCount += 8;
|
||||
var bytes = await ReadBytesAsync(8, cancellationToken).ConfigureAwait(false);
|
||||
return BinaryPrimitives.ReadInt64LittleEndian(bytes);
|
||||
}
|
||||
|
||||
@@ -119,7 +119,9 @@ internal partial class FileHeader
|
||||
{
|
||||
case FHEXTRA_CRYPT:
|
||||
{
|
||||
Rar5CryptoInfo = await Rar5CryptoInfo.CreateAsync(reader, true);
|
||||
Rar5CryptoInfo = await Rar5CryptoInfo
|
||||
.CreateAsync(reader, true)
|
||||
.ConfigureAwait(false);
|
||||
if (Rar5CryptoInfo.PswCheck.All(singleByte => singleByte == 0))
|
||||
{
|
||||
Rar5CryptoInfo = null;
|
||||
|
||||
@@ -72,7 +72,7 @@ internal sealed partial class StreamingZipHeaderFactory
|
||||
)
|
||||
{
|
||||
_headerFactory = headerFactory;
|
||||
_rewindableStream = RewindableStream.EnsureSeekable(stream);
|
||||
_rewindableStream = new RewindableStream(stream);
|
||||
_reader = new AsyncBinaryReader(_rewindableStream, leaveOpen: true);
|
||||
_cancellationToken = cancellationToken;
|
||||
}
|
||||
|
||||
188
tests/SharpCompress.Test/BinaryReaderParityTests.cs
Normal file
188
tests/SharpCompress.Test/BinaryReaderParityTests.cs
Normal file
@@ -0,0 +1,188 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpCompress.Test;
|
||||
|
||||
public class BinaryReaderParityTests : TestBase
|
||||
{
|
||||
private readonly byte[] _testData;
|
||||
|
||||
public BinaryReaderParityTests()
|
||||
{
|
||||
// Create test data with various patterns
|
||||
_testData = new byte[256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
_testData[i] = (byte)i;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadByte_Parity()
|
||||
{
|
||||
using var syncStream = new MemoryStream(_testData);
|
||||
using var asyncStream = new MemoryStream(_testData);
|
||||
using var syncReader = new BinaryReader(syncStream);
|
||||
using var asyncReader = new AsyncBinaryReader(asyncStream);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
byte syncByte = syncReader.ReadByte();
|
||||
byte asyncByte = await asyncReader.ReadByteAsync();
|
||||
Assert.Equal(syncByte, asyncByte);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadBytes_Parity()
|
||||
{
|
||||
using var syncStream = new MemoryStream(_testData);
|
||||
using var asyncStream = new MemoryStream(_testData);
|
||||
using var syncReader = new BinaryReader(syncStream);
|
||||
using var asyncReader = new AsyncBinaryReader(asyncStream);
|
||||
|
||||
var syncBytes = syncReader.ReadBytes(32);
|
||||
var asyncBuffer = new byte[32];
|
||||
await asyncReader.ReadBytesAsync(asyncBuffer, 0, 32);
|
||||
|
||||
Assert.Equal(syncBytes, asyncBuffer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadUInt16_Parity()
|
||||
{
|
||||
using var syncStream = new MemoryStream(_testData);
|
||||
using var asyncStream = new MemoryStream(_testData);
|
||||
using var syncReader = new BinaryReader(syncStream);
|
||||
using var asyncReader = new AsyncBinaryReader(asyncStream);
|
||||
|
||||
ushort syncValue = syncReader.ReadUInt16();
|
||||
ushort asyncValue = await asyncReader.ReadUInt16Async();
|
||||
|
||||
Assert.Equal(syncValue, asyncValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadUInt32_Parity()
|
||||
{
|
||||
using var syncStream = new MemoryStream(_testData);
|
||||
using var asyncStream = new MemoryStream(_testData);
|
||||
using var syncReader = new BinaryReader(syncStream);
|
||||
using var asyncReader = new AsyncBinaryReader(asyncStream);
|
||||
|
||||
uint syncValue = syncReader.ReadUInt32();
|
||||
uint asyncValue = await asyncReader.ReadUInt32Async();
|
||||
|
||||
Assert.Equal(syncValue, asyncValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadUInt64_Parity()
|
||||
{
|
||||
using var syncStream = new MemoryStream(_testData);
|
||||
using var asyncStream = new MemoryStream(_testData);
|
||||
using var syncReader = new BinaryReader(syncStream);
|
||||
using var asyncReader = new AsyncBinaryReader(asyncStream);
|
||||
|
||||
ulong syncValue = syncReader.ReadUInt64();
|
||||
ulong asyncValue = await asyncReader.ReadUInt64Async();
|
||||
|
||||
Assert.Equal(syncValue, asyncValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Position_Parity()
|
||||
{
|
||||
using var syncStream = new MemoryStream(_testData);
|
||||
using var asyncStream = new MemoryStream(_testData);
|
||||
using var syncReader = new BinaryReader(syncStream);
|
||||
using var asyncReader = new AsyncBinaryReader(asyncStream);
|
||||
|
||||
// Read some bytes
|
||||
syncReader.ReadBytes(10);
|
||||
var asyncBuffer = new byte[10];
|
||||
asyncReader.ReadBytesAsync(asyncBuffer, 0, 10).AsTask().Wait();
|
||||
|
||||
Assert.Equal(syncStream.Position, asyncStream.Position);
|
||||
Assert.Equal(syncReader.BaseStream.Position, asyncReader.BaseStream.Position);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MultipleReads_Parity()
|
||||
{
|
||||
using var syncStream = new MemoryStream(_testData);
|
||||
using var asyncStream = new MemoryStream(_testData);
|
||||
using var syncReader = new BinaryReader(syncStream);
|
||||
using var asyncReader = new AsyncBinaryReader(asyncStream);
|
||||
|
||||
// Mix of different read operations
|
||||
Assert.Equal(syncReader.ReadByte(), await asyncReader.ReadByteAsync());
|
||||
|
||||
var syncBytes = new byte[16];
|
||||
var asyncBytes = new byte[16];
|
||||
syncStream.Read(syncBytes, 0, 16);
|
||||
await asyncReader.ReadBytesAsync(asyncBytes, 0, 16);
|
||||
Assert.Equal(syncBytes, asyncBytes);
|
||||
|
||||
Assert.Equal(syncReader.ReadUInt16(), await asyncReader.ReadUInt16Async());
|
||||
Assert.Equal(syncReader.ReadUInt32(), await asyncReader.ReadUInt32Async());
|
||||
Assert.Equal(syncReader.ReadUInt64(), await asyncReader.ReadUInt64Async());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadByte_Async_Properly_Async()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
using var reader = new AsyncBinaryReader(stream);
|
||||
|
||||
var bytes = new byte[10];
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
bytes[i] = await reader.ReadByteAsync();
|
||||
}
|
||||
|
||||
Assert.Equal(_testData.Take(10).ToArray(), bytes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadBytes_Async_Properly_Async()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
using var reader = new AsyncBinaryReader(stream);
|
||||
|
||||
var buffer = new byte[64];
|
||||
await reader.ReadBytesAsync(buffer, 0, 64);
|
||||
|
||||
Assert.Equal(_testData.Take(64).ToArray(), buffer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SkipAsync_Moves_Position_Correctly()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
using var reader = new AsyncBinaryReader(stream);
|
||||
|
||||
await reader.SkipAsync(10);
|
||||
|
||||
Assert.Equal(10, stream.Position);
|
||||
Assert.Equal(10, reader.BaseStream.Position);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SkipAsync_Then_Read_Works_Correctly()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
using var reader = new AsyncBinaryReader(stream);
|
||||
|
||||
await reader.SkipAsync(10);
|
||||
byte b = await reader.ReadByteAsync();
|
||||
|
||||
Assert.Equal(_testData[10], b);
|
||||
}
|
||||
}
|
||||
258
tests/SharpCompress.Test/MarkingBinaryReaderParityTests.cs
Normal file
258
tests/SharpCompress.Test/MarkingBinaryReaderParityTests.cs
Normal file
@@ -0,0 +1,258 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Common.Rar;
|
||||
using SharpCompress.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpCompress.Test;
|
||||
|
||||
public class MarkingBinaryReaderParityTests : TestBase
|
||||
{
|
||||
private readonly byte[] _testData;
|
||||
|
||||
public MarkingBinaryReaderParityTests()
|
||||
{
|
||||
// Create test data with various patterns
|
||||
_testData = new byte[256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
_testData[i] = (byte)i;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Mark_Resets_ByteCount()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
var reader = new MarkingBinaryReader(stream);
|
||||
|
||||
reader.ReadBytes(10);
|
||||
Assert.Equal(10, reader.CurrentReadByteCount);
|
||||
|
||||
reader.Mark();
|
||||
Assert.Equal(0, reader.CurrentReadByteCount);
|
||||
|
||||
reader.ReadBytes(5);
|
||||
Assert.Equal(5, reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Mark_Resets_ByteCount_Async()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
var reader = new AsyncMarkingBinaryReader(stream);
|
||||
|
||||
await reader.ReadBytesAsync(10);
|
||||
Assert.Equal(10, reader.CurrentReadByteCount);
|
||||
|
||||
reader.Mark();
|
||||
Assert.Equal(0, reader.CurrentReadByteCount);
|
||||
|
||||
await reader.ReadBytesAsync(5);
|
||||
Assert.Equal(5, reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadByte_Updates_ByteCount()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
var reader = new MarkingBinaryReader(stream);
|
||||
|
||||
reader.Mark();
|
||||
reader.ReadByte();
|
||||
Assert.Equal(1, reader.CurrentReadByteCount);
|
||||
|
||||
reader.ReadByte();
|
||||
Assert.Equal(2, reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadByte_Updates_ByteCount_Async()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
var reader = new AsyncMarkingBinaryReader(stream);
|
||||
|
||||
reader.Mark();
|
||||
await reader.ReadByteAsync();
|
||||
Assert.Equal(1, reader.CurrentReadByteCount);
|
||||
|
||||
await reader.ReadByteAsync();
|
||||
Assert.Equal(2, reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadBytes_Updates_ByteCount()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
var reader = new MarkingBinaryReader(stream);
|
||||
|
||||
reader.Mark();
|
||||
reader.ReadBytes(16);
|
||||
Assert.Equal(16, reader.CurrentReadByteCount);
|
||||
|
||||
reader.ReadBytes(8);
|
||||
Assert.Equal(24, reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadBytes_Updates_ByteCount_Async()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
var reader = new AsyncMarkingBinaryReader(stream);
|
||||
|
||||
reader.Mark();
|
||||
await reader.ReadBytesAsync(16);
|
||||
Assert.Equal(16, reader.CurrentReadByteCount);
|
||||
|
||||
await reader.ReadBytesAsync(8);
|
||||
Assert.Equal(24, reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadUInt16_Updates_ByteCount()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
var reader = new MarkingBinaryReader(stream);
|
||||
|
||||
reader.Mark();
|
||||
reader.ReadUInt16();
|
||||
Assert.Equal(2, reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadUInt16_Updates_ByteCount_Async()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
var reader = new AsyncMarkingBinaryReader(stream);
|
||||
|
||||
reader.Mark();
|
||||
await reader.ReadUInt16Async();
|
||||
Assert.Equal(2, reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadUInt32_Updates_ByteCount()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
var reader = new MarkingBinaryReader(stream);
|
||||
|
||||
reader.Mark();
|
||||
reader.ReadUInt32();
|
||||
Assert.Equal(4, reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadUInt32_Updates_ByteCount_Async()
|
||||
{
|
||||
using var stream = new MemoryStream(_testData);
|
||||
var reader = new AsyncMarkingBinaryReader(stream);
|
||||
|
||||
reader.Mark();
|
||||
await reader.ReadUInt32Async();
|
||||
Assert.Equal(4, reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadRarVInt_Updates_ByteCount()
|
||||
{
|
||||
// Create valid RAR v-int data: 0x05 (value 5, no continuation bit)
|
||||
var data = new byte[] { 0x05, 0x85, 0x01, 0x00 }; // 0x05, then 0x85 0x01 (value 5 + 128 = 133)
|
||||
using var stream = new MemoryStream(data);
|
||||
var reader = new MarkingBinaryReader(stream);
|
||||
|
||||
reader.Mark();
|
||||
// Read a single-byte v-int (value 5, no continuation bit)
|
||||
reader.ReadRarVInt();
|
||||
Assert.Equal(1, reader.CurrentReadByteCount);
|
||||
|
||||
reader.Mark();
|
||||
// Read a two-byte v-int (0x85 means continuation, then 0x01)
|
||||
reader.ReadRarVInt();
|
||||
Assert.Equal(2, reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadRarVInt_Updates_ByteCount_Async()
|
||||
{
|
||||
// Create valid RAR v-int data: 0x05 (value 5, no continuation bit)
|
||||
var data = new byte[] { 0x05, 0x85, 0x01, 0x00 };
|
||||
using var stream = new MemoryStream(data);
|
||||
var reader = new AsyncMarkingBinaryReader(stream);
|
||||
|
||||
reader.Mark();
|
||||
// Read a single-byte v-int (value 5, no continuation bit)
|
||||
await reader.ReadRarVIntAsync();
|
||||
Assert.Equal(1, reader.CurrentReadByteCount);
|
||||
|
||||
reader.Mark();
|
||||
// Read a two-byte v-int (0x85 means continuation, then 0x01)
|
||||
await reader.ReadRarVIntAsync();
|
||||
Assert.Equal(2, reader.CurrentReadByteCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Sync_Async_ByteCount_Parity()
|
||||
{
|
||||
using var syncStream = new MemoryStream(_testData);
|
||||
using var asyncStream = new MemoryStream(_testData);
|
||||
var syncReader = new MarkingBinaryReader(syncStream);
|
||||
var asyncReader = new AsyncMarkingBinaryReader(asyncStream);
|
||||
|
||||
syncReader.Mark();
|
||||
asyncReader.Mark();
|
||||
|
||||
// Read bytes with sync
|
||||
syncReader.ReadByte();
|
||||
syncReader.ReadByte();
|
||||
syncReader.ReadUInt16();
|
||||
syncReader.ReadUInt32();
|
||||
syncReader.ReadBytes(8);
|
||||
var syncCount = syncReader.CurrentReadByteCount;
|
||||
|
||||
// Read bytes with async
|
||||
await asyncReader.ReadByteAsync();
|
||||
await asyncReader.ReadByteAsync();
|
||||
await asyncReader.ReadUInt16Async();
|
||||
await asyncReader.ReadUInt32Async();
|
||||
await asyncReader.ReadBytesAsync(8);
|
||||
var asyncCount = asyncReader.CurrentReadByteCount;
|
||||
|
||||
Assert.Equal(syncCount, asyncCount);
|
||||
Assert.Equal(16, syncCount);
|
||||
Assert.Equal(16, asyncCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Sync_Async_ByteCount_Parity_Alt()
|
||||
{
|
||||
using var syncStream = new MemoryStream(_testData);
|
||||
using var asyncStream = new MemoryStream(_testData);
|
||||
var syncReader = new MarkingBinaryReader(syncStream);
|
||||
var asyncReader = new AsyncMarkingBinaryReader(asyncStream);
|
||||
|
||||
syncReader.Mark();
|
||||
asyncReader.Mark();
|
||||
|
||||
// Read bytes with sync
|
||||
syncReader.ReadByte();
|
||||
syncReader.ReadByte();
|
||||
syncReader.ReadUInt16();
|
||||
syncReader.ReadUInt32();
|
||||
syncReader.ReadBytes(8);
|
||||
var syncCount = syncReader.CurrentReadByteCount;
|
||||
|
||||
// Read bytes with async
|
||||
await asyncReader.ReadByteAsync();
|
||||
await asyncReader.ReadByteAsync();
|
||||
await asyncReader.ReadUInt16Async();
|
||||
await asyncReader.ReadUInt32Async();
|
||||
await asyncReader.ReadBytesAsync(8);
|
||||
var asyncCount = asyncReader.CurrentReadByteCount;
|
||||
|
||||
Assert.Equal(syncCount, asyncCount);
|
||||
Assert.Equal(16, syncCount);
|
||||
Assert.Equal(16, asyncCount);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user