mirror of
https://github.com/SabreTools/SabreTools.IO.git
synced 2026-09-22 14:45:58 +00:00
Add narrow and wide reading helpers
This commit is contained in:
@@ -352,16 +352,8 @@ namespace SabreTools.IO.Extensions
|
||||
if (reader.BaseStream.Position >= reader.BaseStream.Length)
|
||||
return null;
|
||||
|
||||
List<byte> buffer = [];
|
||||
while (reader.BaseStream.Position < reader.BaseStream.Length)
|
||||
{
|
||||
byte ch = reader.ReadByte();
|
||||
buffer.Add(ch);
|
||||
if (ch == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.ASCII.GetString([.. buffer]);
|
||||
byte[] buffer = ReadUntilNullNarrow(reader);
|
||||
return Encoding.ASCII.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -372,16 +364,8 @@ namespace SabreTools.IO.Extensions
|
||||
if (reader.BaseStream.Position >= reader.BaseStream.Length)
|
||||
return null;
|
||||
|
||||
List<byte> buffer = [];
|
||||
while (reader.BaseStream.Position < reader.BaseStream.Length)
|
||||
{
|
||||
byte[] ch = reader.ReadBytes(2);
|
||||
buffer.AddRange(ch);
|
||||
if (ch[0] == '\0' && ch[1] == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.Unicode.GetString([.. buffer]);
|
||||
byte[] buffer = ReadUntilNullWide(reader);
|
||||
return Encoding.Unicode.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -635,59 +619,59 @@ namespace SabreTools.IO.Extensions
|
||||
case UnmanagedType.LPStr:
|
||||
case UnmanagedType.LPTStr: // Technically distinct; possibly not null-terminated
|
||||
case null:
|
||||
var lpstrBytes = new List<byte>();
|
||||
while (true)
|
||||
{
|
||||
byte next = reader.ReadByte();
|
||||
if (next == 0x00)
|
||||
break;
|
||||
|
||||
lpstrBytes.Add(next);
|
||||
|
||||
if (reader.BaseStream.Position >= reader.BaseStream.Length)
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.ASCII.GetString([.. lpstrBytes]);
|
||||
var lpstrBytes = ReadUntilNullNarrow(reader);
|
||||
return Encoding.ASCII.GetString(lpstrBytes);
|
||||
|
||||
#if NET472_OR_GREATER || NETCOREAPP
|
||||
case UnmanagedType.LPUTF8Str:
|
||||
var lputf8Str = new List<byte>();
|
||||
while (true)
|
||||
{
|
||||
byte next = reader.ReadByte();
|
||||
if (next == 0x00)
|
||||
break;
|
||||
|
||||
lputf8Str.Add(next);
|
||||
|
||||
if (reader.BaseStream.Position >= reader.BaseStream.Length)
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.UTF8.GetString([.. lputf8Str]);
|
||||
var lputf8Str = ReadUntilNullNarrow(reader);
|
||||
return Encoding.UTF8.GetString(lputf8Str);
|
||||
#endif
|
||||
|
||||
case UnmanagedType.LPWStr:
|
||||
var lpwstrBytes = new List<byte>();
|
||||
while (true)
|
||||
{
|
||||
ushort next = reader.ReadUInt16();
|
||||
if (next == 0x0000)
|
||||
break;
|
||||
|
||||
lpwstrBytes.AddRange(BitConverter.GetBytes(next));
|
||||
|
||||
if (reader.BaseStream.Position >= reader.BaseStream.Length)
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.Unicode.GetString([.. lpwstrBytes]);
|
||||
var lpwstrBytes = ReadUntilNullWide(reader);
|
||||
return Encoding.Unicode.GetString(lpwstrBytes);
|
||||
|
||||
// No other string types are recognized
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read bytes until a 1-byte null terminator is found
|
||||
/// </summary>
|
||||
private static byte[] ReadUntilNullNarrow(BinaryReader reader)
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
while (reader.BaseStream.Position < reader.BaseStream.Length)
|
||||
{
|
||||
byte next = reader.ReadByte();
|
||||
if (next == 0x00)
|
||||
break;
|
||||
|
||||
bytes.Add(next);
|
||||
}
|
||||
|
||||
return [.. bytes];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read bytes until a 2-byte null terminator is found
|
||||
/// </summary>
|
||||
private static byte[] ReadUntilNullWide(BinaryReader reader)
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
while (reader.BaseStream.Position < reader.BaseStream.Length)
|
||||
{
|
||||
ushort next = reader.ReadUInt16();
|
||||
if (next == 0x0000)
|
||||
break;
|
||||
|
||||
bytes.AddRange(BitConverter.GetBytes(next));
|
||||
}
|
||||
|
||||
return [.. bytes];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,16 +480,8 @@ namespace SabreTools.IO.Extensions
|
||||
if (offset >= content.Length)
|
||||
return null;
|
||||
|
||||
List<byte> buffer = [];
|
||||
while (offset < content.Length)
|
||||
{
|
||||
byte ch = content.ReadByteValue(ref offset);
|
||||
buffer.Add(ch);
|
||||
if (ch == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.ASCII.GetString([.. buffer]);
|
||||
byte[] buffer = ReadUntilNullNarrow(content, ref offset);
|
||||
return Encoding.ASCII.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -500,16 +492,8 @@ namespace SabreTools.IO.Extensions
|
||||
if (offset >= content.Length)
|
||||
return null;
|
||||
|
||||
List<byte> buffer = [];
|
||||
while (offset < content.Length)
|
||||
{
|
||||
byte[] ch = content.ReadBytes(ref offset, 2);
|
||||
buffer.AddRange(ch);
|
||||
if (ch[0] == '\0' && ch[1] == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.Unicode.GetString([.. buffer]);
|
||||
byte[] buffer = ReadUntilNullWide(content, ref offset);
|
||||
return Encoding.Unicode.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -763,54 +747,18 @@ namespace SabreTools.IO.Extensions
|
||||
case UnmanagedType.LPStr:
|
||||
case UnmanagedType.LPTStr: // Technically distinct; possibly not null-terminated
|
||||
case null:
|
||||
var lpstrBytes = new List<byte>();
|
||||
while (true)
|
||||
{
|
||||
byte next = content.ReadByteValue(ref offset);
|
||||
if (next == 0x00)
|
||||
break;
|
||||
|
||||
lpstrBytes.Add(next);
|
||||
|
||||
if (offset >= content.Length)
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.ASCII.GetString([.. lpstrBytes]);
|
||||
var lpstrBytes = ReadUntilNullNarrow(content, ref offset);
|
||||
return Encoding.ASCII.GetString(lpstrBytes);
|
||||
|
||||
#if NET472_OR_GREATER || NETCOREAPP
|
||||
case UnmanagedType.LPUTF8Str:
|
||||
var lputf8Str = new List<byte>();
|
||||
while (true)
|
||||
{
|
||||
byte next = content.ReadByteValue(ref offset);
|
||||
if (next == 0x00)
|
||||
break;
|
||||
|
||||
lputf8Str.Add(next);
|
||||
|
||||
if (offset >= content.Length)
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.UTF8.GetString([.. lputf8Str]);
|
||||
var lputf8Str = ReadUntilNullNarrow(content, ref offset);
|
||||
return Encoding.UTF8.GetString(lputf8Str);
|
||||
#endif
|
||||
|
||||
case UnmanagedType.LPWStr:
|
||||
var lpwstrBytes = new List<byte>();
|
||||
while (true)
|
||||
{
|
||||
ushort next = content.ReadUInt16(ref offset);
|
||||
if (next == 0x0000)
|
||||
break;
|
||||
|
||||
lpwstrBytes.AddRange(BitConverter.GetBytes(next));
|
||||
|
||||
if (offset >= content.Length)
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.Unicode.GetString([.. lpwstrBytes]);
|
||||
var lpwstrBytes = ReadUntilNullWide(content, ref offset);
|
||||
return Encoding.Unicode.GetString(lpwstrBytes);
|
||||
|
||||
// No other string types are recognized
|
||||
default:
|
||||
@@ -818,6 +766,42 @@ 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)
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
while (offset < content.Length)
|
||||
{
|
||||
byte next = content.ReadByte(ref offset);
|
||||
if (next == 0x00)
|
||||
break;
|
||||
|
||||
bytes.Add(next);
|
||||
}
|
||||
|
||||
return [.. bytes];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read bytes until a 2-byte null terminator is found
|
||||
/// </summary>
|
||||
private static byte[] ReadUntilNullWide(byte[] content, ref int offset)
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
while (offset < content.Length)
|
||||
{
|
||||
ushort next = content.ReadUInt16(ref offset);
|
||||
if (next == 0x0000)
|
||||
break;
|
||||
|
||||
bytes.AddRange(BitConverter.GetBytes(next));
|
||||
}
|
||||
|
||||
return [.. bytes];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a number of bytes from the byte array to a buffer
|
||||
/// </summary>
|
||||
|
||||
@@ -464,16 +464,8 @@ namespace SabreTools.IO.Extensions
|
||||
if (stream.Position >= stream.Length)
|
||||
return null;
|
||||
|
||||
List<byte> buffer = [];
|
||||
while (stream.Position < stream.Length)
|
||||
{
|
||||
byte ch = stream.ReadByteValue();
|
||||
buffer.Add(ch);
|
||||
if (ch == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.ASCII.GetString([.. buffer]);
|
||||
byte[] buffer = ReadUntilNullNarrow(stream);
|
||||
return Encoding.ASCII.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -484,16 +476,8 @@ namespace SabreTools.IO.Extensions
|
||||
if (stream.Position >= stream.Length)
|
||||
return null;
|
||||
|
||||
List<byte> buffer = [];
|
||||
while (stream.Position < stream.Length)
|
||||
{
|
||||
byte[] ch = stream.ReadBytes(2);
|
||||
buffer.AddRange(ch);
|
||||
if (ch[0] == '\0' && ch[1] == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.Unicode.GetString([.. buffer]);
|
||||
byte[] buffer = ReadUntilNullWide(stream);
|
||||
return Encoding.Unicode.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -747,54 +731,18 @@ namespace SabreTools.IO.Extensions
|
||||
case UnmanagedType.LPStr:
|
||||
case UnmanagedType.LPTStr: // Technically distinct; possibly not null-terminated
|
||||
case null:
|
||||
var lpstrBytes = new List<byte>();
|
||||
while (true)
|
||||
{
|
||||
byte next = stream.ReadByteValue();
|
||||
if (next == 0x00)
|
||||
break;
|
||||
|
||||
lpstrBytes.Add(next);
|
||||
|
||||
if (stream.Position >= stream.Length)
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.ASCII.GetString([.. lpstrBytes]);
|
||||
var lpstrBytes = ReadUntilNullNarrow(stream);
|
||||
return Encoding.ASCII.GetString(lpstrBytes);
|
||||
|
||||
#if NET472_OR_GREATER || NETCOREAPP
|
||||
case UnmanagedType.LPUTF8Str:
|
||||
var lputf8Str = new List<byte>();
|
||||
while (true)
|
||||
{
|
||||
byte next = stream.ReadByteValue();
|
||||
if (next == 0x00)
|
||||
break;
|
||||
|
||||
lputf8Str.Add(next);
|
||||
|
||||
if (stream.Position >= stream.Length)
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.UTF8.GetString([.. lputf8Str]);
|
||||
var lputf8Str = ReadUntilNullNarrow(stream);
|
||||
return Encoding.UTF8.GetString(lputf8Str);
|
||||
#endif
|
||||
|
||||
case UnmanagedType.LPWStr:
|
||||
var lpwstrBytes = new List<byte>();
|
||||
while (true)
|
||||
{
|
||||
ushort next = stream.ReadUInt16();
|
||||
if (next == 0x0000)
|
||||
break;
|
||||
|
||||
lpwstrBytes.AddRange(BitConverter.GetBytes(next));
|
||||
|
||||
if (stream.Position >= stream.Length)
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.Unicode.GetString([.. lpwstrBytes]);
|
||||
var lpwstrBytes = ReadUntilNullWide(stream);
|
||||
return Encoding.Unicode.GetString(lpwstrBytes);
|
||||
|
||||
// No other string types are recognized
|
||||
default:
|
||||
@@ -802,6 +750,42 @@ namespace SabreTools.IO.Extensions
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read bytes until a 1-byte null terminator is found
|
||||
/// </summary>
|
||||
private static byte[] ReadUntilNullNarrow(Stream stream)
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
while (stream.Position < stream.Length)
|
||||
{
|
||||
byte next = stream.ReadByteValue();
|
||||
if (next == 0x00)
|
||||
break;
|
||||
|
||||
bytes.Add(next);
|
||||
}
|
||||
|
||||
return [.. bytes];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read bytes until a 2-byte null terminator is found
|
||||
/// </summary>
|
||||
private static byte[] ReadUntilNullWide(Stream stream)
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
while (stream.Position < stream.Length)
|
||||
{
|
||||
ushort next = stream.ReadUInt16();
|
||||
if (next == 0x0000)
|
||||
break;
|
||||
|
||||
bytes.AddRange(BitConverter.GetBytes(next));
|
||||
}
|
||||
|
||||
return [.. bytes];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a number of bytes from the stream to a buffer
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user