Update writer extensions and add tests

This commit is contained in:
Matt Nadareski
2024-11-25 16:15:12 -05:00
parent 3b7f910a98
commit ae3a27eee1
6 changed files with 434 additions and 77 deletions

View File

@@ -10,8 +10,6 @@ using Xunit;
namespace SabreTools.IO.Test.Extensions
{
// TODO: Add byte[], char[] tests
// TODO: Add string writing tests
public class BinaryWriterExtensionsTests
{
/// <summary>
@@ -52,6 +50,16 @@ namespace SabreTools.IO.Test.Extensions
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteBytesBigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = _bytes.Take(4).ToArray();
bw.WriteBigEndian([0x03, 0x02, 0x01, 0x00]);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteSByteTest()
{
@@ -446,6 +454,121 @@ namespace SabreTools.IO.Test.Extensions
}
#endif
[Fact]
public void WriteNullTerminatedAnsiStringTest()
{
var stream = new MemoryStream(new byte[4], 0, 4, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = [0x41, 0x42, 0x43, 0x00];
bool write = bw.WriteNullTerminatedAnsiString("ABC");
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteNullTerminatedUTF8StringTest()
{
var stream = new MemoryStream(new byte[4], 0, 4, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = [0x41, 0x42, 0x43, 0x00];
bool write = bw.WriteNullTerminatedUTF8String("ABC");
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteNullTerminatedUnicodeStringTest()
{
var stream = new MemoryStream(new byte[8], 0, 8, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = [0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x00];
bool write = bw.WriteNullTerminatedUnicodeString("ABC");
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteNullTerminatedUTF32StringTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = [0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
bool write = bw.WriteNullTerminatedUTF32String("ABC");
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WritePrefixedAnsiStringTest()
{
var stream = new MemoryStream(new byte[4], 0, 4, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = [0x03, 0x41, 0x42, 0x43];
bool write = bw.WritePrefixedAnsiString("ABC");
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WritePrefixedUnicodeStringTest()
{
var stream = new MemoryStream(new byte[8], 0, 8, true, true);
var bw = new BinaryWriter(stream);
byte[] expected = [0x03, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00];
bool write = bw.WritePrefixedUnicodeString("ABC");
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteTypeTest()
{
// Guid
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
var bw = new BinaryWriter(stream);
bool actual = bw.WriteType<Guid>(new Guid(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, stream.GetBuffer());
#if NET6_0_OR_GREATER
// Half
stream = new MemoryStream(new byte[2], 0, 2, true, true);
bw = new BinaryWriter(stream);
actual = bw.WriteType<Half>(BitConverter.Int16BitsToHalf(0x0100));
Assert.True(actual);
ValidateBytes([.. _bytes.Take(2)], stream.GetBuffer());
#endif
#if NET7_0_OR_GREATER
// Int128
stream = new MemoryStream(new byte[16], 0, 16, true, true);
bw = new BinaryWriter(stream);
actual = bw.WriteType<Int128>((Int128)new BigInteger(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, stream.GetBuffer());
// UInt128
stream = new MemoryStream(new byte[16], 0, 16, true, true);
bw = new BinaryWriter(stream);
actual = bw.WriteType<UInt128>((UInt128)new BigInteger(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, stream.GetBuffer());
#endif
// Enum
stream = new MemoryStream(new byte[4], 0, 4, true, true);
bw = new BinaryWriter(stream);
actual = bw.WriteType<TestEnum>((TestEnum)0x03020100);
Assert.True(actual);
ValidateBytes([.. _bytes.Take(4)], stream.GetBuffer());
}
[Fact]
public void WriteTypeExplicitTest()
{

View File

@@ -3,12 +3,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 writing tests
public class ByteArrayWriterExtensionsTests
{
/// <summary>
@@ -51,6 +51,17 @@ namespace SabreTools.IO.Test.Extensions
ValidateBytes(expected, buffer);
}
[Fact]
public void WriteBytesBigEndianTest()
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(4).ToArray();
bool write = buffer.WriteBigEndian(ref offset, [0x03, 0x02, 0x01, 0x00]);
Assert.True(write);
ValidateBytes(expected, buffer);
}
[Fact]
public void WriteSByteTest()
{
@@ -73,6 +84,17 @@ namespace SabreTools.IO.Test.Extensions
ValidateBytes(expected, buffer);
}
[Fact]
public void WriteCharEncodingTest()
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = [0x00, 0x00];
bool write = buffer.Write(ref offset, '\0', Encoding.Unicode);
Assert.True(write);
ValidateBytes(expected, buffer);
}
[Fact]
public void WriteInt16Test()
{
@@ -339,6 +361,28 @@ namespace SabreTools.IO.Test.Extensions
ValidateBytes(expected, buffer);
}
[Fact]
public void WriteDoubleTest()
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(8).ToArray();
bool write = buffer.Write(ref offset, BitConverter.Int64BitsToDouble(0x0706050403020100));
Assert.True(write);
ValidateBytes(expected, buffer);
}
[Fact]
public void WriteDoubleBigEndianTest()
{
byte[] buffer = new byte[16];
int offset = 0;
byte[] expected = _bytes.Take(8).ToArray();
bool write = buffer.WriteBigEndian(ref offset, BitConverter.Int64BitsToDouble(0x0001020304050607));
Assert.True(write);
ValidateBytes(expected, buffer);
}
[Fact]
public void WriteDecimalTest()
{
@@ -429,6 +473,121 @@ namespace SabreTools.IO.Test.Extensions
}
#endif
[Fact]
public void WriteNullTerminatedAnsiStringTest()
{
int offset = 0;
byte[] buffer = new byte[4];
byte[] expected = [0x41, 0x42, 0x43, 0x00];
bool write = buffer.WriteNullTerminatedAnsiString(ref offset, "ABC");
Assert.True(write);
ValidateBytes(expected, buffer);
}
[Fact]
public void WriteNullTerminatedUTF8StringTest()
{
int offset = 0;
byte[] buffer = new byte[4];
byte[] expected = [0x41, 0x42, 0x43, 0x00];
bool write = buffer.WriteNullTerminatedUTF8String(ref offset, "ABC");
Assert.True(write);
ValidateBytes(expected, buffer);
}
[Fact]
public void WriteNullTerminatedUnicodeStringTest()
{
int offset = 0;
byte[] buffer = new byte[8];
byte[] expected = [0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x00];
bool write = buffer.WriteNullTerminatedUnicodeString(ref offset, "ABC");
Assert.True(write);
ValidateBytes(expected, buffer);
}
[Fact]
public void WriteNullTerminatedUTF32StringTest()
{
int offset = 0;
byte[] buffer = new byte[16];
byte[] expected = [0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
bool write = buffer.WriteNullTerminatedUTF32String(ref offset, "ABC");
Assert.True(write);
ValidateBytes(expected, buffer);
}
[Fact]
public void WritePrefixedAnsiStringTest()
{
int offset = 0;
byte[] buffer = new byte[4];
byte[] expected = [0x03, 0x41, 0x42, 0x43];
bool write = buffer.WritePrefixedAnsiString(ref offset, "ABC");
Assert.True(write);
ValidateBytes(expected, buffer);
}
[Fact]
public void WritePrefixedUnicodeStringTest()
{
int offset = 0;
byte[] buffer = new byte[8];
byte[] expected = [0x03, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00];
bool write = buffer.WritePrefixedUnicodeString(ref offset, "ABC");
Assert.True(write);
ValidateBytes(expected, buffer);
}
[Fact]
public void WriteTypeTest()
{
// Guid
int offset = 0;
byte[] buffer = new byte[16];
bool actual = buffer.WriteType<Guid>(ref offset, new Guid(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, buffer);
#if NET6_0_OR_GREATER
// Half
offset = 0;
buffer = new byte[2];
actual = buffer.WriteType<Half>(ref offset, BitConverter.Int16BitsToHalf(0x0100));
Assert.True(actual);
ValidateBytes([.. _bytes.Take(2)], buffer);
#endif
#if NET7_0_OR_GREATER
// Int128
offset = 0;
buffer = new byte[16];
actual = buffer.WriteType<Int128>(ref offset, (Int128)new BigInteger(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, buffer);
// UInt128
offset = 0;
buffer = new byte[16];
actual = buffer.WriteType<UInt128>(ref offset, (UInt128)new BigInteger(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, buffer);
#endif
// Enum
offset = 0;
buffer = new byte[4];
actual = buffer.WriteType<TestEnum>(ref offset, (TestEnum)0x03020100);
Assert.True(actual);
ValidateBytes([.. _bytes.Take(4)], buffer);
}
[Fact]
public void WriteTypeExplicitTest()
{

View File

@@ -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 writing tests
public class StreamWriterExtensionsTests
{
/// <summary>
@@ -50,6 +50,15 @@ namespace SabreTools.IO.Test.Extensions
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteBytesBigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(4).ToArray();
stream.WriteBigEndian([0x03, 0x02, 0x01, 0x00]);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteSByteTest()
{
@@ -70,6 +79,15 @@ namespace SabreTools.IO.Test.Extensions
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteCharEncodingTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = [0x00, 0x00];
stream.Write('\0', Encoding.Unicode);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteInt16Test()
{
@@ -312,6 +330,26 @@ namespace SabreTools.IO.Test.Extensions
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteDoubleTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(8).ToArray();
bool write = stream.Write(BitConverter.Int64BitsToDouble(0x0706050403020100));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteDoubleBigEndianTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = _bytes.Take(8).ToArray();
bool write = stream.WriteBigEndian(BitConverter.Int64BitsToDouble(0x0001020304050607));
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteDecimalTest()
{
@@ -394,6 +432,110 @@ namespace SabreTools.IO.Test.Extensions
}
#endif
[Fact]
public void WriteNullTerminatedAnsiStringTest()
{
var stream = new MemoryStream(new byte[4], 0, 4, true, true);
byte[] expected = [0x41, 0x42, 0x43, 0x00];
bool write = stream.WriteNullTerminatedAnsiString("ABC");
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteNullTerminatedUTF8StringTest()
{
var stream = new MemoryStream(new byte[4], 0, 4, true, true);
byte[] expected = [0x41, 0x42, 0x43, 0x00];
bool write = stream.WriteNullTerminatedUTF8String("ABC");
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteNullTerminatedUnicodeStringTest()
{
var stream = new MemoryStream(new byte[8], 0, 8, true, true);
byte[] expected = [0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x00];
bool write = stream.WriteNullTerminatedUnicodeString("ABC");
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteNullTerminatedUTF32StringTest()
{
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
byte[] expected = [0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
bool write = stream.WriteNullTerminatedUTF32String("ABC");
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WritePrefixedAnsiStringTest()
{
var stream = new MemoryStream(new byte[4], 0, 4, true, true);
byte[] expected = [0x03, 0x41, 0x42, 0x43];
bool write = stream.WritePrefixedAnsiString("ABC");
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WritePrefixedUnicodeStringTest()
{
var stream = new MemoryStream(new byte[8], 0, 8, true, true);
byte[] expected = [0x03, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00];
bool write = stream.WritePrefixedUnicodeString("ABC");
Assert.True(write);
ValidateBytes(expected, stream.GetBuffer());
}
[Fact]
public void WriteTypeTest()
{
// Guid
var stream = new MemoryStream(new byte[16], 0, 16, true, true);
bool actual = stream.WriteType<Guid>(new Guid(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, stream.GetBuffer());
#if NET6_0_OR_GREATER
// Half
stream = new MemoryStream(new byte[2], 0, 2, true, true);
actual = stream.WriteType<Half>(BitConverter.Int16BitsToHalf(0x0100));
Assert.True(actual);
ValidateBytes([.. _bytes.Take(2)], stream.GetBuffer());
#endif
#if NET7_0_OR_GREATER
// Int128
stream = new MemoryStream(new byte[16], 0, 16, true, true);
actual = stream.WriteType<Int128>((Int128)new BigInteger(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, stream.GetBuffer());
// UInt128
stream = new MemoryStream(new byte[16], 0, 16, true, true);
actual = stream.WriteType<UInt128>((UInt128)new BigInteger(_bytes));
Assert.True(actual);
ValidateBytes(_bytes, stream.GetBuffer());
#endif
// Enum
stream = new MemoryStream(new byte[4], 0, 4, true, true);
actual = stream.WriteType<TestEnum>((TestEnum)0x03020100);
Assert.True(actual);
ValidateBytes([.. _bytes.Take(4)], stream.GetBuffer());
}
[Fact]
public void WriteTypeExplicitTest()
{

View File

@@ -12,7 +12,6 @@ namespace SabreTools.IO.Extensions
/// <summary>
/// Extensions for BinaryWriter
/// </summary>
/// <remarks>TODO: Add WriteDecimal methods</remarks>
/// TODO: Handle proper negative values for Int24 and Int48
public static class BinaryWriterExtensions
{
@@ -374,7 +373,7 @@ namespace SabreTools.IO.Extensions
byte[] buffer = Encoding.ASCII.GetBytes(value);
// Write the length as a byte
writer.Write((byte)buffer.Length);
writer.Write((byte)value.Length);
// Write the buffer
return WriteFromBuffer(writer, buffer);
@@ -393,34 +392,12 @@ namespace SabreTools.IO.Extensions
byte[] buffer = Encoding.Unicode.GetBytes(value);
// Write the length as a ushort
writer.Write((ushort)buffer.Length);
writer.Write((ushort)value.Length);
// Write the buffer
return WriteFromBuffer(writer, buffer);
}
/// <summary>
/// Write a string that is terminated by a newline but contains a quoted portion that
/// may also contain a newline to the underlying stream
/// </summary>
public static bool WriteQuotedString(this BinaryWriter writer, string? value)
=> writer.WriteQuotedString(value, Encoding.UTF8);
/// <summary>
/// Write a string that is terminated by a newline but contains a quoted portion that
/// may also contain a newline to the underlying stream
/// </summary>
public static bool WriteQuotedString(this BinaryWriter writer, string? value, Encoding encoding)
{
// If the value is null
if (value == null)
return false;
// Write without the null terminator
byte[] buffer = encoding.GetBytes(value);
return WriteFromBuffer(writer, buffer);
}
/// <summary>
/// Write a <typeparamref name="T"/> to the underlying stream
/// </summary>

View File

@@ -525,7 +525,7 @@ namespace SabreTools.IO.Extensions
byte[] buffer = Encoding.ASCII.GetBytes(value);
// Write the length as a byte
if (!content.Write(ref offset, (byte)buffer.Length))
if (!content.Write(ref offset, (byte)value.Length))
return false;
// Write the buffer
@@ -545,35 +545,13 @@ namespace SabreTools.IO.Extensions
byte[] buffer = Encoding.Unicode.GetBytes(value);
// Write the length as a ushort
if (!content.Write(ref offset, (ushort)buffer.Length))
if (!content.Write(ref offset, (ushort)value.Length))
return false;
// Write the buffer
return WriteFromBuffer(content, ref offset, buffer);
}
/// <summary>
/// Write a string that is terminated by a newline but contains a quoted portion that
/// may also contain a newline to the byte array
/// </summary>
public static bool WriteQuotedString(this byte[] content, ref int offset, string? value)
=> content.WriteQuotedString(ref offset, value, Encoding.UTF8);
/// <summary>
/// Write a string that is terminated by a newline but contains a quoted portion that
/// may also contain a newline to the byte array
/// </summary>
public static bool WriteQuotedString(this byte[] content, ref int offset, string? value, Encoding encoding)
{
// If the value is null
if (value == null)
return false;
// Write without the null terminator
byte[] buffer = encoding.GetBytes(value);
return WriteFromBuffer(content, ref offset, buffer);
}
/// <summary>
/// Write a <typeparamref name="T"/> to the byte array
/// </summary>

View File

@@ -526,7 +526,7 @@ namespace SabreTools.IO.Extensions
byte[] buffer = Encoding.ASCII.GetBytes(value);
// Write the length as a byte
if (!stream.Write((byte)buffer.Length))
if (!stream.Write((byte)value.Length))
return false;
// Write the buffer
@@ -546,35 +546,13 @@ namespace SabreTools.IO.Extensions
byte[] buffer = Encoding.Unicode.GetBytes(value);
// Write the length as a ushort
if (!stream.Write((ushort)buffer.Length))
if (!stream.Write((ushort)value.Length))
return false;
// Write the buffer
return WriteFromBuffer(stream, buffer);
}
/// <summary>
/// Write a string that is terminated by a newline but contains a quoted portion that
/// may also contain a newline to the stream
/// </summary>
public static bool WriteQuotedString(this Stream stream, string? value)
=> stream.WriteQuotedString(value, Encoding.UTF8);
/// <summary>
/// Write a string that is terminated by a newline but contains a quoted portion that
/// may also contain a newline to the stream
/// </summary>
public static bool WriteQuotedString(this Stream stream, string? value, Encoding encoding)
{
// If the value is null
if (value == null)
return false;
// Write without the null terminator
byte[] buffer = encoding.GetBytes(value);
return WriteFromBuffer(stream, buffer);
}
/// <summary>
/// Write a <typeparamref name="T"/> to the stream
/// </summary>