Add parsing for binary floats

This commit is contained in:
Nathan McRae 2024-02-16 21:26:35 -08:00
parent 53e87e2f7f
commit bb750fac58
2 changed files with 69 additions and 14 deletions

View File

@ -33,6 +33,18 @@ public class SaneTsv
public Type[] ColumnTypes { get; protected set; }
public List<SaneTsvRecord> Records { get; protected set; }
public string FileComment { get; protected set; } = null;
protected static bool? _littleEndian = null;
public static bool LittleEndian
{
get
{
if (_littleEndian == null)
{
_littleEndian = BitConverter.GetBytes(double.NegativeInfinity)[7] == 255;
}
return _littleEndian.Value;
}
}
public static SaneTsv ParseSimpleTsv(byte[] inputBuffer)
{
@ -303,6 +315,44 @@ public class SaneTsv
parsedFields[j] = fields[j];
continue;
}
else if (parsed.ColumnTypes[j] == typeof(Float32LEType))
{
byte[] floatBytes;
if (!LittleEndian)
{
floatBytes = new byte[sizeof(float)];
for (int k = 0; k < sizeof(float); k++)
{
floatBytes[k] = fields[j][sizeof(float) - 1 - k];
}
}
else
{
floatBytes = fields[j];
}
parsedFields[j] = BitConverter.ToSingle(floatBytes, 0);
continue;
}
else if (parsed.ColumnTypes[j] == typeof(Float64LEType))
{
byte[] floatBytes;
if (!LittleEndian)
{
floatBytes = new byte[sizeof(double)];
for (int k = 0; k < sizeof(double); k++)
{
floatBytes[k] = fields[j][sizeof(double) - 1 - k];
}
}
else
{
floatBytes = fields[j];
}
parsedFields[j] = BitConverter.ToDouble(floatBytes, 0);
continue;
}
string fieldString;
try
@ -347,13 +397,6 @@ public class SaneTsv
parsedFields[j] = parsedFloat;
}
else if (parsed.ColumnTypes[j] == typeof(Float32LEType))
{
throw new NotImplementedException();
// TODO: Implement and do byte-swapping if necessary
//parsedFields[j] = parsedFloat;
}
else if (parsed.ColumnTypes[j] == typeof(Float64Type))
{
if (!double.TryParse(fieldString, out double parsedDouble))
@ -363,13 +406,6 @@ public class SaneTsv
parsedFields[j] = parsedDouble;
}
else if (parsed.ColumnTypes[j] == typeof(Float64LEType))
{
throw new NotImplementedException();
// TODO: Implement and do byte-swapping if necessary
//parsedFields[j] = parsedFloat;
}
else if (parsed.ColumnTypes[j] == typeof(UInt32Type))
{
if (!UInt32.TryParse(fieldString, out UInt32 parsedUInt32))

View File

@ -1,4 +1,5 @@
using NathanMcRae;
using System.Linq;
using System.Text;
{
@ -68,6 +69,24 @@ using System.Text;
}
}
{
string testName = "Float binary test";
var bytes = new List<byte>();
bytes.AddRange(Encoding.UTF8.GetBytes("somefloat:float64\tbinfloat:float64-le" +
"\n1.5\t")); bytes.AddRange(BitConverter.GetBytes(1.5));
bytes.AddRange(Encoding.UTF8.GetBytes("\n-8.0000005E-14\t")); bytes.AddRange(BitConverter.GetBytes(-8.0000005E-14));
SaneTsv parsed = SaneTsv.ParseTypedTsv(bytes.ToArray());
if ((double)parsed.Records[0]["binfloat"] == (double)parsed.Records[0]["somefloat"])
{
Console.WriteLine($"Passed {testName}");
}
else
{
Console.WriteLine($"Failed {testName}");
}
}
Console.WriteLine("Done with tests");