mirror of
https://github.com/SabreTools/SabreTools.IO.git
synced 2026-09-22 22:56:13 +00:00
Update reader extensions and add tests
This commit is contained in:
@@ -4,12 +4,12 @@ using System.Linq;
|
||||
#if NET7_0_OR_GREATER
|
||||
using System.Numerics;
|
||||
#endif
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.IO.Test.Extensions
|
||||
{
|
||||
// TODO: Add string reading tests
|
||||
public class BinaryReaderExtensionsTests
|
||||
{
|
||||
/// <summary>
|
||||
@@ -30,6 +30,50 @@ namespace SabreTools.IO.Test.Extensions
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00,
|
||||
];
|
||||
|
||||
[Fact]
|
||||
public void ReadByteArrayTest()
|
||||
{
|
||||
byte[] arr = new byte[4];
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
int read = br.Read(arr, 0, 4);
|
||||
Assert.Equal(4, read);
|
||||
Assert.True(arr.SequenceEqual(_bytes.Take(4)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadByteArrayBigEndianTest()
|
||||
{
|
||||
byte[] arr = new byte[4];
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
int read = br.ReadBigEndian(arr, 0, 4);
|
||||
Assert.Equal(4, read);
|
||||
Assert.True(arr.SequenceEqual(_bytes.Take(4).Reverse()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadCharArrayTest()
|
||||
{
|
||||
char[] arr = new char[4];
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
int read = br.Read(arr, 0, 4);
|
||||
Assert.Equal(4, read);
|
||||
Assert.True(arr.SequenceEqual(_bytes.Take(4).Select(b => (char)b)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadCharArrayBigEndianTest()
|
||||
{
|
||||
char[] arr = new char[4];
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
int read = br.ReadBigEndian(arr, 0, 4);
|
||||
Assert.Equal(4, read);
|
||||
Assert.True(arr.SequenceEqual(_bytes.Take(4).Select(b => (char)b).Reverse()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadByteTest()
|
||||
{
|
||||
@@ -50,6 +94,39 @@ namespace SabreTools.IO.Test.Extensions
|
||||
Assert.True(read.SequenceEqual(_bytes.Take(length)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadBytesBigEndianTest()
|
||||
{
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
int length = 4;
|
||||
byte[] read = br.ReadBytesBigEndian(length);
|
||||
Assert.Equal(length, read.Length);
|
||||
Assert.True(read.SequenceEqual(_bytes.Take(length).Reverse()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadCharsTest()
|
||||
{
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
int length = 4;
|
||||
char[] read = br.ReadChars(length);
|
||||
Assert.Equal(length, read.Length);
|
||||
Assert.True(read.SequenceEqual(_bytes.Take(length).Select(b => (char)b)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadCharsBigEndianTest()
|
||||
{
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
int length = 4;
|
||||
char[] read = br.ReadCharsBigEndian(length);
|
||||
Assert.Equal(length, read.Length);
|
||||
Assert.True(read.SequenceEqual(_bytes.Take(length).Select(b => (char)b).Reverse()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadSByteTest()
|
||||
{
|
||||
@@ -104,6 +181,24 @@ namespace SabreTools.IO.Test.Extensions
|
||||
Assert.Equal(0x0001, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadWORDTest()
|
||||
{
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
ushort read = br.ReadWORD();
|
||||
Assert.Equal(0x0100, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadWORDBigEndianTest()
|
||||
{
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
ushort read = br.ReadWORDBigEndian();
|
||||
Assert.Equal(0x0001, read);
|
||||
}
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
[Fact]
|
||||
public void ReadHalfTest()
|
||||
@@ -198,6 +293,24 @@ namespace SabreTools.IO.Test.Extensions
|
||||
Assert.Equal((uint)0x00010203, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadDWORDTest()
|
||||
{
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
uint read = br.ReadDWORD();
|
||||
Assert.Equal((uint)0x03020100, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadDWORDBigEndianTest()
|
||||
{
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
uint read = br.ReadDWORDBigEndian();
|
||||
Assert.Equal((uint)0x00010203, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadSingleTest()
|
||||
{
|
||||
@@ -394,6 +507,88 @@ namespace SabreTools.IO.Test.Extensions
|
||||
}
|
||||
#endif
|
||||
|
||||
[Fact]
|
||||
public void ReadNullTerminatedStringTest()
|
||||
{
|
||||
// Encoding.ASCII
|
||||
byte[] bytes = [0x41, 0x42, 0x43, 0x00];
|
||||
var stream = new MemoryStream(bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
string? actual = br.ReadNullTerminatedString(Encoding.ASCII);
|
||||
Assert.Equal("ABC", actual);
|
||||
|
||||
// Encoding.UTF8
|
||||
bytes = [0x41, 0x42, 0x43, 0x00];
|
||||
stream = new MemoryStream(bytes);
|
||||
br = new BinaryReader(stream);
|
||||
actual = br.ReadNullTerminatedString(Encoding.UTF8);
|
||||
Assert.Equal("ABC", actual);
|
||||
|
||||
// Encoding.Unicode
|
||||
bytes = [0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x00, 0x00];
|
||||
stream = new MemoryStream(bytes);
|
||||
br = new BinaryReader(stream);
|
||||
actual = br.ReadNullTerminatedString(Encoding.Unicode);
|
||||
Assert.Equal("ABC", actual);
|
||||
|
||||
// Encoding.UTF32
|
||||
bytes = [0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
|
||||
stream = new MemoryStream(bytes);
|
||||
br = new BinaryReader(stream);
|
||||
actual = br.ReadNullTerminatedString(Encoding.UTF32);
|
||||
Assert.Equal("ABC", actual);
|
||||
|
||||
// Encoding.Latin1
|
||||
bytes = [0x41, 0x42, 0x43, 0x00];
|
||||
stream = new MemoryStream(bytes);
|
||||
br = new BinaryReader(stream);
|
||||
actual = br.ReadNullTerminatedString(Encoding.Latin1);
|
||||
Assert.Equal("ABC", actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadTypeTest()
|
||||
{
|
||||
// Guid
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var br = new BinaryReader(stream);
|
||||
var expectedGuid = new Guid(_bytes);
|
||||
Guid actualGuid = br.ReadType<Guid>();
|
||||
Assert.Equal(expectedGuid, actualGuid);
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
// Half
|
||||
stream = new MemoryStream(_bytes);
|
||||
br = new BinaryReader(stream);
|
||||
Half expectedHalf = BitConverter.Int16BitsToHalf(0x0100);
|
||||
Half actualHalf = br.ReadType<Half>();
|
||||
Assert.Equal(expectedHalf, actualHalf);
|
||||
#endif
|
||||
|
||||
#if NET7_0_OR_GREATER
|
||||
// Int128
|
||||
stream = new MemoryStream(_bytes);
|
||||
br = new BinaryReader(stream);
|
||||
Int128 expectedInt128 = (Int128)new BigInteger(_bytes);
|
||||
Int128 actualInt128 = br.ReadType<Int128>();
|
||||
Assert.Equal(expectedHalf, actualHalf);
|
||||
|
||||
// UInt128
|
||||
stream = new MemoryStream(_bytes);
|
||||
br = new BinaryReader(stream);
|
||||
UInt128 expectedUInt128 = (UInt128)new BigInteger(_bytes);
|
||||
UInt128 actualUInt128 = br.ReadType<UInt128>();
|
||||
Assert.Equal(expectedHalf, actualHalf);
|
||||
#endif
|
||||
|
||||
// Enum
|
||||
stream = new MemoryStream(_bytes);
|
||||
br = new BinaryReader(stream);
|
||||
TestEnum expectedTestEnum = (TestEnum)0x03020100;
|
||||
TestEnum actualTestEnum = br.ReadType<TestEnum>();
|
||||
Assert.Equal(expectedTestEnum, actualTestEnum);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadTypeExplicitTest()
|
||||
{
|
||||
@@ -492,6 +687,12 @@ namespace SabreTools.IO.Test.Extensions
|
||||
0x05, 0x04, 0x03, 0x02,
|
||||
0x06, 0x05, 0x04, 0x03,
|
||||
|
||||
// Enum Array
|
||||
0x03, 0x02, 0x01, 0x00,
|
||||
0x04, 0x03, 0x02, 0x01,
|
||||
0x05, 0x04, 0x03, 0x02,
|
||||
0x06, 0x05, 0x04, 0x03,
|
||||
|
||||
// Struct Array (X, Y)
|
||||
0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0xFF, 0xFF, 0x00,
|
||||
@@ -509,6 +710,13 @@ namespace SabreTools.IO.Test.Extensions
|
||||
{
|
||||
ByteArray = [0x00, 0x01, 0x02, 0x03],
|
||||
IntArray = [0x00010203, 0x01020304, 0x02030405, 0x03040506],
|
||||
EnumArray =
|
||||
[
|
||||
(TestEnum)0x00010203,
|
||||
(TestEnum)0x01020304,
|
||||
(TestEnum)0x02030405,
|
||||
(TestEnum)0x03040506,
|
||||
],
|
||||
StructArray =
|
||||
[
|
||||
new TestStructPoint { X = 0x00FF, Y = 0xFF00 },
|
||||
@@ -524,6 +732,8 @@ namespace SabreTools.IO.Test.Extensions
|
||||
Assert.True(expected.ByteArray.SequenceEqual(read.ByteArray));
|
||||
Assert.NotNull(read.IntArray);
|
||||
Assert.True(expected.IntArray.SequenceEqual(read.IntArray));
|
||||
Assert.NotNull(read.EnumArray);
|
||||
Assert.True(expected.EnumArray.SequenceEqual(read.EnumArray));
|
||||
Assert.NotNull(read.StructArray);
|
||||
Assert.True(expected.StructArray.SequenceEqual(read.StructArray));
|
||||
Assert.Equal(expected.LPByteArrayLength, read.LPByteArrayLength);
|
||||
|
||||
@@ -3,13 +3,13 @@ using System.Linq;
|
||||
#if NET7_0_OR_GREATER
|
||||
using System.Numerics;
|
||||
#endif
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.IO.Test.Extensions
|
||||
{
|
||||
// TODO: Add string reading tests
|
||||
public class ByteArrayExtensionsReadTests
|
||||
public class ByteArrayReaderExtensionsTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Test pattern from 0x00-0x0F
|
||||
@@ -102,6 +102,22 @@ namespace SabreTools.IO.Test.Extensions
|
||||
Assert.Equal(0x0001, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadWORDTest()
|
||||
{
|
||||
int offset = 0;
|
||||
ushort read = _bytes.ReadWORD(ref offset);
|
||||
Assert.Equal(0x0100, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadWORDBigEndianTest()
|
||||
{
|
||||
int offset = 0;
|
||||
ushort read = _bytes.ReadWORDBigEndian(ref offset);
|
||||
Assert.Equal(0x0001, read);
|
||||
}
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
[Fact]
|
||||
public void ReadHalfTest()
|
||||
@@ -186,6 +202,22 @@ namespace SabreTools.IO.Test.Extensions
|
||||
Assert.Equal((uint)0x00010203, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadDWORDTest()
|
||||
{
|
||||
int offset = 0;
|
||||
uint read = _bytes.ReadDWORD(ref offset);
|
||||
Assert.Equal((uint)0x03020100, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadDWORDBigEndianTest()
|
||||
{
|
||||
int offset = 0;
|
||||
uint read = _bytes.ReadDWORDBigEndian(ref offset);
|
||||
Assert.Equal((uint)0x00010203, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadSingleTest()
|
||||
{
|
||||
@@ -362,6 +394,78 @@ namespace SabreTools.IO.Test.Extensions
|
||||
}
|
||||
#endif
|
||||
|
||||
[Fact]
|
||||
public void ReadNullTerminatedStringTest()
|
||||
{
|
||||
// Encoding.ASCII
|
||||
int offset = 0;
|
||||
byte[] bytes = [0x41, 0x42, 0x43, 0x00];
|
||||
string? actual = bytes.ReadNullTerminatedString(ref offset, Encoding.ASCII);
|
||||
Assert.Equal("ABC", actual);
|
||||
|
||||
// Encoding.UTF8
|
||||
offset = 0;
|
||||
bytes = [0x41, 0x42, 0x43, 0x00];
|
||||
actual = bytes.ReadNullTerminatedString(ref offset, Encoding.UTF8);
|
||||
Assert.Equal("ABC", actual);
|
||||
|
||||
// Encoding.Unicode
|
||||
offset = 0;
|
||||
bytes = [0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x00, 0x00];
|
||||
actual = bytes.ReadNullTerminatedString(ref offset, Encoding.Unicode);
|
||||
Assert.Equal("ABC", actual);
|
||||
|
||||
// Encoding.UTF32
|
||||
offset = 0;
|
||||
bytes = [0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
|
||||
actual = bytes.ReadNullTerminatedString(ref offset, Encoding.UTF32);
|
||||
Assert.Equal("ABC", actual);
|
||||
|
||||
// Encoding.Latin1
|
||||
offset = 0;
|
||||
bytes = [0x41, 0x42, 0x43, 0x00];
|
||||
actual = bytes.ReadNullTerminatedString(ref offset, Encoding.Latin1);
|
||||
Assert.Equal("ABC", actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadTypeTest()
|
||||
{
|
||||
// Guid
|
||||
int offset = 0;
|
||||
var expectedGuid = new Guid(_bytes);
|
||||
Guid actualGuid = _bytes.ReadType<Guid>(ref offset);
|
||||
Assert.Equal(expectedGuid, actualGuid);
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
// Half
|
||||
offset = 0;
|
||||
Half expectedHalf = BitConverter.Int16BitsToHalf(0x0100);
|
||||
Half actualHalf = _bytes.ReadType<Half>(ref offset);
|
||||
Assert.Equal(expectedHalf, actualHalf);
|
||||
#endif
|
||||
|
||||
#if NET7_0_OR_GREATER
|
||||
// Int128
|
||||
offset = 0;
|
||||
Int128 expectedInt128 = (Int128)new BigInteger(_bytes);
|
||||
Int128 actualInt128 = _bytes.ReadType<Int128>(ref offset);
|
||||
Assert.Equal(expectedHalf, actualHalf);
|
||||
|
||||
// UInt128
|
||||
offset = 0;
|
||||
UInt128 expectedUInt128 = (UInt128)new BigInteger(_bytes);
|
||||
UInt128 actualUInt128 = _bytes.ReadType<UInt128>(ref offset);
|
||||
Assert.Equal(expectedHalf, actualHalf);
|
||||
#endif
|
||||
|
||||
// Enum
|
||||
offset = 0;
|
||||
TestEnum expectedTestEnum = (TestEnum)0x03020100;
|
||||
TestEnum actualTestEnum = _bytes.ReadType<TestEnum>(ref offset);
|
||||
Assert.Equal(expectedTestEnum, actualTestEnum);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadTypeExplicitTest()
|
||||
{
|
||||
@@ -456,6 +560,12 @@ namespace SabreTools.IO.Test.Extensions
|
||||
0x05, 0x04, 0x03, 0x02,
|
||||
0x06, 0x05, 0x04, 0x03,
|
||||
|
||||
// Enum Array
|
||||
0x03, 0x02, 0x01, 0x00,
|
||||
0x04, 0x03, 0x02, 0x01,
|
||||
0x05, 0x04, 0x03, 0x02,
|
||||
0x06, 0x05, 0x04, 0x03,
|
||||
|
||||
// Struct Array (X, Y)
|
||||
0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0xFF, 0xFF, 0x00,
|
||||
@@ -472,6 +582,13 @@ namespace SabreTools.IO.Test.Extensions
|
||||
{
|
||||
ByteArray = [0x00, 0x01, 0x02, 0x03],
|
||||
IntArray = [0x00010203, 0x01020304, 0x02030405, 0x03040506],
|
||||
EnumArray =
|
||||
[
|
||||
(TestEnum)0x00010203,
|
||||
(TestEnum)0x01020304,
|
||||
(TestEnum)0x02030405,
|
||||
(TestEnum)0x03040506,
|
||||
],
|
||||
StructArray =
|
||||
[
|
||||
new TestStructPoint { X = 0x00FF, Y = 0xFF00 },
|
||||
@@ -487,6 +604,8 @@ namespace SabreTools.IO.Test.Extensions
|
||||
Assert.True(expected.ByteArray.SequenceEqual(read.ByteArray));
|
||||
Assert.NotNull(read.IntArray);
|
||||
Assert.True(expected.IntArray.SequenceEqual(read.IntArray));
|
||||
Assert.NotNull(read.EnumArray);
|
||||
Assert.True(expected.EnumArray.SequenceEqual(read.EnumArray));
|
||||
Assert.NotNull(read.StructArray);
|
||||
Assert.True(expected.StructArray.SequenceEqual(read.StructArray));
|
||||
Assert.Equal(expected.LPByteArrayLength, read.LPByteArrayLength);
|
||||
@@ -9,7 +9,7 @@ using Xunit;
|
||||
namespace SabreTools.IO.Test.Extensions
|
||||
{
|
||||
// TODO: Add string writing tests
|
||||
public class ByteArrayExtensionsWriteTests
|
||||
public class ByteArrayWriterExtensionsTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Test pattern from 0x00-0x0F
|
||||
@@ -4,13 +4,13 @@ using System.Linq;
|
||||
#if NET7_0_OR_GREATER
|
||||
using System.Numerics;
|
||||
#endif
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using Xunit;
|
||||
|
||||
namespace SabreTools.IO.Test.Extensions
|
||||
{
|
||||
// TODO: Add string reading tests
|
||||
public class StreamExtensionsReadTests
|
||||
public class StreamReaderExtensionsTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Test pattern from 0x00-0x0F
|
||||
@@ -30,6 +30,16 @@ namespace SabreTools.IO.Test.Extensions
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00,
|
||||
];
|
||||
|
||||
[Fact]
|
||||
public void ReadByteArrayTest()
|
||||
{
|
||||
byte[] arr = new byte[4];
|
||||
var stream = new MemoryStream(_bytes);
|
||||
int read = stream.Read(arr, 0, 4);
|
||||
Assert.Equal(4, read);
|
||||
Assert.True(arr.SequenceEqual(_bytes.Take(4)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadByteValueTest()
|
||||
{
|
||||
@@ -96,6 +106,22 @@ namespace SabreTools.IO.Test.Extensions
|
||||
Assert.Equal(0x0001, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadWORDTest()
|
||||
{
|
||||
var stream = new MemoryStream(_bytes);
|
||||
ushort read = stream.ReadWORD();
|
||||
Assert.Equal(0x0100, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadWORDBigEndianTest()
|
||||
{
|
||||
var stream = new MemoryStream(_bytes);
|
||||
ushort read = stream.ReadWORDBigEndian();
|
||||
Assert.Equal(0x0001, read);
|
||||
}
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
[Fact]
|
||||
public void ReadHalfTest()
|
||||
@@ -180,6 +206,22 @@ namespace SabreTools.IO.Test.Extensions
|
||||
Assert.Equal((uint)0x00010203, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadDWORDTest()
|
||||
{
|
||||
var stream = new MemoryStream(_bytes);
|
||||
uint read = stream.ReadDWORD();
|
||||
Assert.Equal((uint)0x03020100, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadDWORDBigEndianTest()
|
||||
{
|
||||
var stream = new MemoryStream(_bytes);
|
||||
uint read = stream.ReadDWORDBigEndian();
|
||||
Assert.Equal((uint)0x00010203, read);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadSingleTest()
|
||||
{
|
||||
@@ -356,6 +398,78 @@ namespace SabreTools.IO.Test.Extensions
|
||||
}
|
||||
#endif
|
||||
|
||||
[Fact]
|
||||
public void ReadNullTerminatedStringTest()
|
||||
{
|
||||
// Encoding.ASCII
|
||||
byte[] bytes = [0x41, 0x42, 0x43, 0x00];
|
||||
var stream = new MemoryStream(bytes);
|
||||
string? actual = stream.ReadNullTerminatedString(Encoding.ASCII);
|
||||
Assert.Equal("ABC", actual);
|
||||
|
||||
// Encoding.UTF8
|
||||
bytes = [0x41, 0x42, 0x43, 0x00];
|
||||
stream = new MemoryStream(bytes);
|
||||
actual = stream.ReadNullTerminatedString(Encoding.UTF8);
|
||||
Assert.Equal("ABC", actual);
|
||||
|
||||
// Encoding.Unicode
|
||||
bytes = [0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x00, 0x00];
|
||||
stream = new MemoryStream(bytes);
|
||||
actual = stream.ReadNullTerminatedString(Encoding.Unicode);
|
||||
Assert.Equal("ABC", actual);
|
||||
|
||||
// Encoding.UTF32
|
||||
bytes = [0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
|
||||
stream = new MemoryStream(bytes);
|
||||
actual = stream.ReadNullTerminatedString(Encoding.UTF32);
|
||||
Assert.Equal("ABC", actual);
|
||||
|
||||
// Encoding.Latin1
|
||||
bytes = [0x41, 0x42, 0x43, 0x00];
|
||||
stream = new MemoryStream(bytes);
|
||||
actual = stream.ReadNullTerminatedString(Encoding.Latin1);
|
||||
Assert.Equal("ABC", actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadTypeTest()
|
||||
{
|
||||
// Guid
|
||||
var stream = new MemoryStream(_bytes);
|
||||
var expectedGuid = new Guid(_bytes);
|
||||
Guid actualGuid = stream.ReadType<Guid>();
|
||||
Assert.Equal(expectedGuid, actualGuid);
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
// Half
|
||||
stream = new MemoryStream(_bytes);
|
||||
Half expectedHalf = BitConverter.Int16BitsToHalf(0x0100);
|
||||
Half actualHalf = stream.ReadType<Half>();
|
||||
Assert.Equal(expectedHalf, actualHalf);
|
||||
#endif
|
||||
|
||||
#if NET7_0_OR_GREATER
|
||||
// Int128
|
||||
stream = new MemoryStream(_bytes);
|
||||
Int128 expectedInt128 = (Int128)new BigInteger(_bytes);
|
||||
Int128 actualInt128 = stream.ReadType<Int128>();
|
||||
Assert.Equal(expectedHalf, actualHalf);
|
||||
|
||||
// UInt128
|
||||
stream = new MemoryStream(_bytes);
|
||||
UInt128 expectedUInt128 = (UInt128)new BigInteger(_bytes);
|
||||
UInt128 actualUInt128 = stream.ReadType<UInt128>();
|
||||
Assert.Equal(expectedHalf, actualHalf);
|
||||
#endif
|
||||
|
||||
// Enum
|
||||
stream = new MemoryStream(_bytes);
|
||||
TestEnum expectedTestEnum = (TestEnum)0x03020100;
|
||||
TestEnum actualTestEnum = stream.ReadType<TestEnum>();
|
||||
Assert.Equal(expectedTestEnum, actualTestEnum);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadTypeExplicitTest()
|
||||
{
|
||||
@@ -450,6 +564,12 @@ namespace SabreTools.IO.Test.Extensions
|
||||
0x05, 0x04, 0x03, 0x02,
|
||||
0x06, 0x05, 0x04, 0x03,
|
||||
|
||||
// Enum Array
|
||||
0x03, 0x02, 0x01, 0x00,
|
||||
0x04, 0x03, 0x02, 0x01,
|
||||
0x05, 0x04, 0x03, 0x02,
|
||||
0x06, 0x05, 0x04, 0x03,
|
||||
|
||||
// Struct Array (X, Y)
|
||||
0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0xFF, 0xFF, 0x00,
|
||||
@@ -466,6 +586,13 @@ namespace SabreTools.IO.Test.Extensions
|
||||
{
|
||||
ByteArray = [0x00, 0x01, 0x02, 0x03],
|
||||
IntArray = [0x00010203, 0x01020304, 0x02030405, 0x03040506],
|
||||
EnumArray =
|
||||
[
|
||||
(TestEnum)0x00010203,
|
||||
(TestEnum)0x01020304,
|
||||
(TestEnum)0x02030405,
|
||||
(TestEnum)0x03040506,
|
||||
],
|
||||
StructArray =
|
||||
[
|
||||
new TestStructPoint { X = 0x00FF, Y = 0xFF00 },
|
||||
@@ -481,6 +608,8 @@ namespace SabreTools.IO.Test.Extensions
|
||||
Assert.True(expected.ByteArray.SequenceEqual(read.ByteArray));
|
||||
Assert.NotNull(read.IntArray);
|
||||
Assert.True(expected.IntArray.SequenceEqual(read.IntArray));
|
||||
Assert.NotNull(read.EnumArray);
|
||||
Assert.True(expected.EnumArray.SequenceEqual(read.EnumArray));
|
||||
Assert.NotNull(read.StructArray);
|
||||
Assert.True(expected.StructArray.SequenceEqual(read.StructArray));
|
||||
Assert.Equal(expected.LPByteArrayLength, read.LPByteArrayLength);
|
||||
@@ -10,7 +10,7 @@ using Xunit;
|
||||
namespace SabreTools.IO.Test.Extensions
|
||||
{
|
||||
// TODO: Add string writing tests
|
||||
public class StreamExtensionsWriteTests
|
||||
public class StreamWriterExtensionsTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Test pattern from 0x00-0x0F
|
||||
@@ -17,6 +17,12 @@ namespace SabreTools.IO.Test.Extensions
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public int[]? IntArray;
|
||||
|
||||
/// <summary>
|
||||
/// 4 entry int array
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public TestEnum[]? EnumArray;
|
||||
|
||||
/// <summary>
|
||||
/// 4 entry struct array
|
||||
/// </summary>
|
||||
@@ -31,7 +37,7 @@ namespace SabreTools.IO.Test.Extensions
|
||||
/// <summary>
|
||||
/// 4 entry byte array whose length is defined by <see cref="LPByteArrayLength"/>
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]
|
||||
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]
|
||||
public byte[]? LPByteArray;
|
||||
|
||||
// /// <summary>
|
||||
|
||||
@@ -365,9 +365,10 @@ namespace SabreTools.IO.Extensions
|
||||
while (reader.BaseStream.Position < reader.BaseStream.Length)
|
||||
{
|
||||
byte ch = reader.ReadByte();
|
||||
buffer.Add(ch);
|
||||
if (ch == '\0')
|
||||
break;
|
||||
|
||||
buffer.Add(ch);
|
||||
}
|
||||
|
||||
return encoding.GetString([.. buffer]);
|
||||
@@ -418,7 +419,7 @@ namespace SabreTools.IO.Extensions
|
||||
return null;
|
||||
|
||||
byte[] buffer = ReadUntilNull4Byte(reader);
|
||||
return Encoding.Unicode.GetString(buffer);
|
||||
return Encoding.UTF32.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -453,45 +454,6 @@ namespace SabreTools.IO.Extensions
|
||||
return Encoding.Unicode.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a string that is terminated by a newline but contains a quoted portion that
|
||||
/// may also contain a newline from the underlying stream
|
||||
/// </summary>
|
||||
public static string? ReadQuotedString(this BinaryReader reader)
|
||||
=> reader.ReadQuotedString(Encoding.Default);
|
||||
|
||||
/// <summary>
|
||||
/// Read a string that is terminated by a newline but contains a quoted portion that
|
||||
/// may also contain a newline from the underlying stream
|
||||
/// </summary>
|
||||
public static string? ReadQuotedString(this BinaryReader reader, Encoding encoding)
|
||||
{
|
||||
if (reader.BaseStream.Position >= reader.BaseStream.Length)
|
||||
return null;
|
||||
|
||||
var bytes = new List<byte>();
|
||||
bool openQuote = false;
|
||||
while (reader.BaseStream.Position < reader.BaseStream.Length)
|
||||
{
|
||||
// Read the byte value
|
||||
byte b = reader.ReadByte();
|
||||
|
||||
// If we have a quote, flip the flag
|
||||
if (b == (byte)'"')
|
||||
openQuote = !openQuote;
|
||||
|
||||
// If we have a newline not in a quoted string, exit the loop
|
||||
else if (b == (byte)'\n' && !openQuote)
|
||||
break;
|
||||
|
||||
// Add the byte to the set
|
||||
bytes.Add(b);
|
||||
}
|
||||
|
||||
var line = encoding.GetString([.. bytes]);
|
||||
return line.TrimEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a <typeparamref name="T"/> from the underlying stream
|
||||
/// </summary>
|
||||
@@ -620,7 +582,10 @@ namespace SabreTools.IO.Extensions
|
||||
else if (fi.FieldType.IsArray)
|
||||
{
|
||||
var value = ReadArrayType(reader, fields, instance, fi);
|
||||
fi.SetValue(instance, Convert.ChangeType(value, fi.FieldType));
|
||||
if (value.GetType() == fi.FieldType)
|
||||
fi.SetValue(instance, value);
|
||||
else
|
||||
fi.SetValue(instance, Convert.ChangeType(value, fi.FieldType));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -651,7 +616,10 @@ namespace SabreTools.IO.Extensions
|
||||
for (int i = 0; i < elementCount; i++)
|
||||
{
|
||||
var value = ReadType(reader, elementType);
|
||||
arr.SetValue(value, i);
|
||||
if (value != null && elementType.IsEnum)
|
||||
arr.SetValue(Enum.ToObject(elementType, value), i);
|
||||
else
|
||||
arr.SetValue(value, i);
|
||||
}
|
||||
|
||||
// Return the built array
|
||||
|
||||
@@ -494,9 +494,10 @@ namespace SabreTools.IO.Extensions
|
||||
while (offset < content.Length)
|
||||
{
|
||||
byte ch = content.ReadByteValue(ref offset);
|
||||
buffer.Add(ch);
|
||||
if (ch == '\0')
|
||||
break;
|
||||
|
||||
buffer.Add(ch);
|
||||
}
|
||||
|
||||
return encoding.GetString([.. buffer]);
|
||||
@@ -547,7 +548,7 @@ namespace SabreTools.IO.Extensions
|
||||
return null;
|
||||
|
||||
byte[] buffer = ReadUntilNull4Byte(content, ref offset);
|
||||
return Encoding.Unicode.GetString(buffer);
|
||||
return Encoding.UTF32.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -582,45 +583,6 @@ namespace SabreTools.IO.Extensions
|
||||
return Encoding.Unicode.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a string that is terminated by a newline but contains a quoted portion that
|
||||
/// may also contain a newline from the byte array
|
||||
/// </summary>
|
||||
public static string? ReadQuotedString(this byte[] content, ref int offset)
|
||||
=> content.ReadQuotedString(ref offset, Encoding.Default);
|
||||
|
||||
/// <summary>
|
||||
/// Read a string that is terminated by a newline but contains a quoted portion that
|
||||
/// may also contain a newline from the byte array
|
||||
/// </summary>
|
||||
public static string? ReadQuotedString(this byte[] content, ref int offset, Encoding encoding)
|
||||
{
|
||||
if (offset >= content.Length)
|
||||
return null;
|
||||
|
||||
byte[] nullTerminator = encoding.GetBytes("\0");
|
||||
int charWidth = nullTerminator.Length;
|
||||
|
||||
var keyChars = new List<char>();
|
||||
bool openQuote = false;
|
||||
while (offset < content.Length)
|
||||
{
|
||||
char c = encoding.GetChars(content, offset, charWidth)[0];
|
||||
keyChars.Add(c);
|
||||
offset += charWidth;
|
||||
|
||||
// If we have a quote, flip the flag
|
||||
if (c == '"')
|
||||
openQuote = !openQuote;
|
||||
|
||||
// If we have a newline not in a quoted string, exit the loop
|
||||
else if (c == (byte)'\n' && !openQuote)
|
||||
break;
|
||||
}
|
||||
|
||||
return new string([.. keyChars]).TrimEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a <typeparamref name="T"/> from the stream
|
||||
/// </summary>
|
||||
@@ -749,7 +711,10 @@ namespace SabreTools.IO.Extensions
|
||||
else if (fi.FieldType.IsArray)
|
||||
{
|
||||
var value = ReadArrayType(content, ref offset, fields, instance, fi);
|
||||
fi.SetValue(instance, Convert.ChangeType(value, fi.FieldType));
|
||||
if (value.GetType() == fi.FieldType)
|
||||
fi.SetValue(instance, value);
|
||||
else
|
||||
fi.SetValue(instance, Convert.ChangeType(value, fi.FieldType));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -780,7 +745,10 @@ namespace SabreTools.IO.Extensions
|
||||
for (int i = 0; i < elementCount; i++)
|
||||
{
|
||||
var value = ReadType(content, ref offset, elementType);
|
||||
arr.SetValue(value, i);
|
||||
if (value != null && elementType.IsEnum)
|
||||
arr.SetValue(Enum.ToObject(elementType, value), i);
|
||||
else
|
||||
arr.SetValue(value, i);
|
||||
}
|
||||
|
||||
// Return the built array
|
||||
|
||||
@@ -478,9 +478,10 @@ namespace SabreTools.IO.Extensions
|
||||
while (stream.Position < stream.Length)
|
||||
{
|
||||
byte ch = stream.ReadByteValue();
|
||||
buffer.Add(ch);
|
||||
if (ch == '\0')
|
||||
break;
|
||||
|
||||
buffer.Add(ch);
|
||||
}
|
||||
|
||||
return encoding.GetString([.. buffer]);
|
||||
@@ -531,7 +532,7 @@ namespace SabreTools.IO.Extensions
|
||||
return null;
|
||||
|
||||
byte[] buffer = ReadUntilNull4Byte(stream);
|
||||
return Encoding.Unicode.GetString(buffer);
|
||||
return Encoding.UTF32.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -566,45 +567,6 @@ namespace SabreTools.IO.Extensions
|
||||
return Encoding.Unicode.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a string that is terminated by a newline but contains a quoted portion that
|
||||
/// may also contain a newline from the stream
|
||||
/// </summary>
|
||||
public static string? ReadQuotedString(this Stream stream)
|
||||
=> stream.ReadQuotedString(Encoding.Default);
|
||||
|
||||
/// <summary>
|
||||
/// Read a string that is terminated by a newline but contains a quoted portion that
|
||||
/// may also contain a newline from the stream
|
||||
/// </summary>
|
||||
public static string? ReadQuotedString(this Stream stream, Encoding encoding)
|
||||
{
|
||||
if (stream.Position >= stream.Length)
|
||||
return null;
|
||||
|
||||
var bytes = new List<byte>();
|
||||
bool openQuote = false;
|
||||
while (stream.Position < stream.Length)
|
||||
{
|
||||
// Read the byte value
|
||||
byte b = stream.ReadByteValue();
|
||||
|
||||
// If we have a quote, flip the flag
|
||||
if (b == (byte)'"')
|
||||
openQuote = !openQuote;
|
||||
|
||||
// If we have a newline not in a quoted string, exit the loop
|
||||
else if (b == (byte)'\n' && !openQuote)
|
||||
break;
|
||||
|
||||
// Add the byte to the set
|
||||
bytes.Add(b);
|
||||
}
|
||||
|
||||
var line = encoding.GetString([.. bytes]);
|
||||
return line.TrimEnd();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a <typeparamref name="T"/> from the stream
|
||||
/// </summary>
|
||||
@@ -733,7 +695,10 @@ namespace SabreTools.IO.Extensions
|
||||
else if (fi.FieldType.IsArray)
|
||||
{
|
||||
var value = ReadArrayType(stream, fields, instance, fi);
|
||||
fi.SetValue(instance, Convert.ChangeType(value, fi.FieldType));
|
||||
if (value.GetType() == fi.FieldType)
|
||||
fi.SetValue(instance, value);
|
||||
else
|
||||
fi.SetValue(instance, Convert.ChangeType(value, fi.FieldType));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -764,7 +729,10 @@ namespace SabreTools.IO.Extensions
|
||||
for (int i = 0; i < elementCount; i++)
|
||||
{
|
||||
var value = ReadType(stream, elementType);
|
||||
arr.SetValue(value, i);
|
||||
if (value != null && elementType.IsEnum)
|
||||
arr.SetValue(Enum.ToObject(elementType, value), i);
|
||||
else
|
||||
arr.SetValue(value, i);
|
||||
}
|
||||
|
||||
// Return the built array
|
||||
|
||||
Reference in New Issue
Block a user