Add default UTF-32 null-terminated string reading

This commit is contained in:
Matt Nadareski
2024-04-29 12:57:37 -04:00
parent f0033af712
commit 9beb2177aa
3 changed files with 111 additions and 15 deletions

View File

@@ -330,6 +330,8 @@ namespace SabreTools.IO.Extensions
return reader.ReadNullTerminatedUTF8String();
else if (encoding.Equals(Encoding.Unicode))
return reader.ReadNullTerminatedUnicodeString();
else if (encoding.Equals(Encoding.UTF32))
return reader.ReadNullTerminatedUTF32String();
if (reader.BaseStream.Position >= reader.BaseStream.Length)
return null;
@@ -354,7 +356,7 @@ namespace SabreTools.IO.Extensions
if (reader.BaseStream.Position >= reader.BaseStream.Length)
return null;
byte[] buffer = ReadUntilNullNarrow(reader);
byte[] buffer = ReadUntilNull1Byte(reader);
return Encoding.ASCII.GetString(buffer);
}
@@ -366,7 +368,7 @@ namespace SabreTools.IO.Extensions
if (reader.BaseStream.Position >= reader.BaseStream.Length)
return null;
byte[] buffer = ReadUntilNullNarrow(reader);
byte[] buffer = ReadUntilNull1Byte(reader);
return Encoding.ASCII.GetString(buffer);
}
@@ -378,7 +380,19 @@ namespace SabreTools.IO.Extensions
if (reader.BaseStream.Position >= reader.BaseStream.Length)
return null;
byte[] buffer = ReadUntilNullWide(reader);
byte[] buffer = ReadUntilNull2Byte(reader);
return Encoding.Unicode.GetString(buffer);
}
/// <summary>
/// Read a null-terminated UTF-32 string from the underlying stream
/// </summary>
public static string? ReadNullTerminatedUTF32String(this BinaryReader reader)
{
if (reader.BaseStream.Position >= reader.BaseStream.Length)
return null;
byte[] buffer = ReadUntilNull4Byte(reader);
return Encoding.Unicode.GetString(buffer);
}
@@ -648,7 +662,7 @@ namespace SabreTools.IO.Extensions
/// <summary>
/// Read bytes until a 1-byte null terminator is found
/// </summary>
private static byte[] ReadUntilNullNarrow(BinaryReader reader)
private static byte[] ReadUntilNull1Byte(BinaryReader reader)
{
var bytes = new List<byte>();
while (reader.BaseStream.Position < reader.BaseStream.Length)
@@ -666,7 +680,7 @@ namespace SabreTools.IO.Extensions
/// <summary>
/// Read bytes until a 2-byte null terminator is found
/// </summary>
private static byte[] ReadUntilNullWide(BinaryReader reader)
private static byte[] ReadUntilNull2Byte(BinaryReader reader)
{
var bytes = new List<byte>();
while (reader.BaseStream.Position < reader.BaseStream.Length)
@@ -680,5 +694,23 @@ namespace SabreTools.IO.Extensions
return [.. bytes];
}
/// <summary>
/// Read bytes until a 4-byte null terminator is found
/// </summary>
private static byte[] ReadUntilNull4Byte(BinaryReader reader)
{
var bytes = new List<byte>();
while (reader.BaseStream.Position < reader.BaseStream.Length)
{
uint next = reader.ReadUInt32();
if (next == 0x00000000)
break;
bytes.AddRange(BitConverter.GetBytes(next));
}
return [.. bytes];
}
}
}

View File

@@ -458,6 +458,8 @@ namespace SabreTools.IO.Extensions
return content.ReadNullTerminatedUTF8String(ref offset);
else if (encoding.Equals(Encoding.Unicode))
return content.ReadNullTerminatedUnicodeString(ref offset);
else if (encoding.Equals(Encoding.UTF32))
return content.ReadNullTerminatedUTF32String(ref offset);
if (offset >= content.Length)
return null;
@@ -482,7 +484,7 @@ namespace SabreTools.IO.Extensions
if (offset >= content.Length)
return null;
byte[] buffer = ReadUntilNullNarrow(content, ref offset);
byte[] buffer = ReadUntilNull1Byte(content, ref offset);
return Encoding.ASCII.GetString(buffer);
}
@@ -494,7 +496,7 @@ namespace SabreTools.IO.Extensions
if (offset >= content.Length)
return null;
byte[] buffer = ReadUntilNullNarrow(content, ref offset);
byte[] buffer = ReadUntilNull1Byte(content, ref offset);
return Encoding.UTF8.GetString(buffer);
}
@@ -506,7 +508,19 @@ namespace SabreTools.IO.Extensions
if (offset >= content.Length)
return null;
byte[] buffer = ReadUntilNullWide(content, ref offset);
byte[] buffer = ReadUntilNull2Byte(content, ref offset);
return Encoding.Unicode.GetString(buffer);
}
/// <summary>
/// Read a null-terminated UTF-32 string from the byte array
/// </summary>
public static string? ReadNullTerminatedUTF32String(this byte[] content, ref int offset)
{
if (offset >= content.Length)
return null;
byte[] buffer = ReadUntilNull4Byte(content, ref offset);
return Encoding.Unicode.GetString(buffer);
}
@@ -776,7 +790,7 @@ namespace SabreTools.IO.Extensions
/// <summary>
/// Read bytes until a 1-byte null terminator is found
/// </summary>
private static byte[] ReadUntilNullNarrow(byte[] content, ref int offset)
private static byte[] ReadUntilNull1Byte(byte[] content, ref int offset)
{
var bytes = new List<byte>();
while (offset < content.Length)
@@ -794,7 +808,7 @@ namespace SabreTools.IO.Extensions
/// <summary>
/// Read bytes until a 2-byte null terminator is found
/// </summary>
private static byte[] ReadUntilNullWide(byte[] content, ref int offset)
private static byte[] ReadUntilNull2Byte(byte[] content, ref int offset)
{
var bytes = new List<byte>();
while (offset < content.Length)
@@ -809,6 +823,24 @@ namespace SabreTools.IO.Extensions
return [.. bytes];
}
/// <summary>
/// Read bytes until a 4-byte null terminator is found
/// </summary>
private static byte[] ReadUntilNull4Byte(byte[] content, ref int offset)
{
var bytes = new List<byte>();
while (offset < content.Length)
{
uint next = content.ReadUInt32(ref offset);
if (next == 0x00000000)
break;
bytes.AddRange(BitConverter.GetBytes(next));
}
return [.. bytes];
}
/// <summary>
/// Read a number of bytes from the byte array to a buffer
/// </summary>

View File

@@ -442,6 +442,8 @@ namespace SabreTools.IO.Extensions
return stream.ReadNullTerminatedUTF8String();
else if (encoding.Equals(Encoding.Unicode))
return stream.ReadNullTerminatedUnicodeString();
else if (encoding.Equals(Encoding.UTF32))
return stream.ReadNullTerminatedUTF32String();
if (stream.Position >= stream.Length)
return null;
@@ -466,7 +468,7 @@ namespace SabreTools.IO.Extensions
if (stream.Position >= stream.Length)
return null;
byte[] buffer = ReadUntilNullNarrow(stream);
byte[] buffer = ReadUntilNull1Byte(stream);
return Encoding.ASCII.GetString(buffer);
}
@@ -478,7 +480,7 @@ namespace SabreTools.IO.Extensions
if (stream.Position >= stream.Length)
return null;
byte[] buffer = ReadUntilNullNarrow(stream);
byte[] buffer = ReadUntilNull1Byte(stream);
return Encoding.UTF8.GetString(buffer);
}
@@ -490,7 +492,19 @@ namespace SabreTools.IO.Extensions
if (stream.Position >= stream.Length)
return null;
byte[] buffer = ReadUntilNullWide(stream);
byte[] buffer = ReadUntilNull2Byte(stream);
return Encoding.Unicode.GetString(buffer);
}
/// <summary>
/// Read a null-terminated UTF-32 string from the stream
/// </summary>
public static string? ReadNullTerminatedUTF32String(this Stream stream)
{
if (stream.Position >= stream.Length)
return null;
byte[] buffer = ReadUntilNull4Byte(stream);
return Encoding.Unicode.GetString(buffer);
}
@@ -760,7 +774,7 @@ namespace SabreTools.IO.Extensions
/// <summary>
/// Read bytes until a 1-byte null terminator is found
/// </summary>
private static byte[] ReadUntilNullNarrow(Stream stream)
private static byte[] ReadUntilNull1Byte(Stream stream)
{
var bytes = new List<byte>();
while (stream.Position < stream.Length)
@@ -778,7 +792,7 @@ namespace SabreTools.IO.Extensions
/// <summary>
/// Read bytes until a 2-byte null terminator is found
/// </summary>
private static byte[] ReadUntilNullWide(Stream stream)
private static byte[] ReadUntilNull2Byte(Stream stream)
{
var bytes = new List<byte>();
while (stream.Position < stream.Length)
@@ -814,5 +828,23 @@ namespace SabreTools.IO.Extensions
return buffer;
}
/// <summary>
/// Read bytes until a 4-byte null terminator is found
/// </summary>
private static byte[] ReadUntilNull4Byte(Stream stream)
{
var bytes = new List<byte>();
while (stream.Position < stream.Length)
{
uint next = stream.ReadUInt32();
if (next == 0x00000000)
break;
bytes.AddRange(BitConverter.GetBytes(next));
}
return [.. bytes];
}
}
}