diff --git a/PowerKit.Tests/BinaryReaderExtensionsTests.cs b/PowerKit.Tests/BinaryReaderExtensionsTests.cs new file mode 100644 index 0000000..aa68c42 --- /dev/null +++ b/PowerKit.Tests/BinaryReaderExtensionsTests.cs @@ -0,0 +1,87 @@ +using System.IO; +using System.Text; +using FluentAssertions; +using PowerKit.Extensions; +using Xunit; + +namespace PowerKit.Tests; + +public class BinaryReaderExtensionsTests +{ + [Fact] + public void SkipZeroes_Test() + { + // Arrange + var data = new byte[] { 0, 0, 0, 1, 2, 3 }; + using var stream = new MemoryStream(data); + using var reader = new BinaryReader(stream); + + // Act + reader.SkipZeroes(); + + // Assert + stream.Position.Should().Be(3); + reader.ReadByte().Should().Be(1); + } + + [Fact] + public void SkipZeroes_WithMaxLength_Test() + { + // Arrange + var data = new byte[] { 0, 0, 0, 0, 1, 2, 3 }; + using var stream = new MemoryStream(data); + using var reader = new BinaryReader(stream); + + // Act + reader.SkipZeroes(maxSkipLength: 2); + + // Assert + stream.Position.Should().Be(2); + reader.ReadByte().Should().Be(0); + } + + [Fact] + public void SkipZeroes_AllZeroes_Test() + { + // Arrange + var data = new byte[] { 0, 0, 0 }; + using var stream = new MemoryStream(data); + using var reader = new BinaryReader(stream); + + // Act + reader.SkipZeroes(); + + // Assert + stream.Position.Should().Be(3); + } + + [Fact] + public void ReadNullTerminatedString_Test() + { + // Arrange + var data = Encoding.ASCII.GetBytes("hello\0"); + using var stream = new MemoryStream(data); + using var reader = new BinaryReader(stream, Encoding.ASCII); + + // Act + var result = reader.ReadNullTerminatedString(); + + // Assert + result.Should().Be("hello"); + } + + [Fact] + public void ReadNullTerminatedString_Empty_Test() + { + // Arrange + var data = new byte[] { 0 }; + using var stream = new MemoryStream(data); + using var reader = new BinaryReader(stream, Encoding.ASCII); + + // Act + var result = reader.ReadNullTerminatedString(); + + // Assert + result.Should().Be(""); + } +} diff --git a/PowerKit.Tests/BinaryWriterExtensionsTests.cs b/PowerKit.Tests/BinaryWriterExtensionsTests.cs new file mode 100644 index 0000000..537338c --- /dev/null +++ b/PowerKit.Tests/BinaryWriterExtensionsTests.cs @@ -0,0 +1,38 @@ +using System.IO; +using System.Text; +using FluentAssertions; +using PowerKit.Extensions; +using Xunit; + +namespace PowerKit.Tests; + +public class BinaryWriterExtensionsTests +{ + [Fact] + public void WriteNullTerminatedString_Test() + { + // Arrange + using var stream = new MemoryStream(); + using var writer = new BinaryWriter(stream, Encoding.ASCII); + + // Act + writer.WriteNullTerminatedString("hello"); + + // Assert + stream.ToArray().Should().Equal("hello\0"u8.ToArray()); + } + + [Fact] + public void WriteNullTerminatedString_Empty_Test() + { + // Arrange + using var stream = new MemoryStream(); + using var writer = new BinaryWriter(stream, Encoding.ASCII); + + // Act + writer.WriteNullTerminatedString(""); + + // Assert + stream.ToArray().Should().Equal(0); + } +} diff --git a/PowerKit/Extensions/BinaryReaderExtensions.cs b/PowerKit/Extensions/BinaryReaderExtensions.cs new file mode 100644 index 0000000..1920df0 --- /dev/null +++ b/PowerKit/Extensions/BinaryReaderExtensions.cs @@ -0,0 +1,49 @@ +using System.IO; +using System.Text; + +namespace PowerKit.Extensions; + +internal static class BinaryReaderExtensions +{ + extension(BinaryReader reader) + { + /// + /// Skips zero bytes in the stream, up to the specified maximum length. + /// + public void SkipZeroes(long? maxSkipLength = null) + { + var skipped = 0L; + while (maxSkipLength is null || skipped < maxSkipLength) + { + if (reader.PeekChar() != 0) + { + break; + } + + reader.ReadByte(); + skipped++; + } + } + + /// + /// Reads a null-terminated string from the binary reader. + /// + public string ReadNullTerminatedString() + { + var buffer = new StringBuilder(); + + while (true) + { + var ch = reader.ReadChar(); + if (ch == '\0') + { + break; + } + + buffer.Append(ch); + } + + return buffer.ToString(); + } + } +} diff --git a/PowerKit/Extensions/BinaryWriterExtensions.cs b/PowerKit/Extensions/BinaryWriterExtensions.cs new file mode 100644 index 0000000..fa7b159 --- /dev/null +++ b/PowerKit/Extensions/BinaryWriterExtensions.cs @@ -0,0 +1,22 @@ +using System.IO; + +namespace PowerKit.Extensions; + +internal static class BinaryWriterExtensions +{ + extension(BinaryWriter writer) + { + /// + /// Writes a null-terminated string to the binary writer. + /// + public void WriteNullTerminatedString(string value) + { + foreach (var ch in value) + { + writer.Write(ch); + } + + writer.Write('\0'); + } + } +}