Add both-endian numeric types

This commit is contained in:
Matt Nadareski
2025-10-27 09:09:00 -04:00
parent 2c5d7ad56b
commit 8f06bf5859
18 changed files with 1997 additions and 0 deletions

View File

@@ -73,6 +73,25 @@ Logic for a logging system, including writing to console and textfile outputs. T
Classes designed to make matching contents and paths easier. These classes allow for both grouped and single matching as well as post-processing of matched information.
### `SabreTools.IO.Numerics`
Custom numeric types and related functionality.
#### Supported Numeric Types
| Type Name | Description |
| --- | --- |
| `BothInt8` | Both-endian `Int8` value |
| `BothUInt8` | Both-endian `UInt8` value |
| `BothInt16` | Both-endian `Int16` value |
| `BothUInt16` | Both-endian `UInt16` value |
| `BothInt32` | Both-endian `Int32` value |
| `BothUInt32` | Both-endian `UInt32` value |
| `BothInt64` | Both-endian `Int64` value |
| `BothUInt64` | Both-endian `UInt64` value |
**Both-endian** or **bi-endian** numbers are represented by a little-endian value followed by a big-endian value, where both values are the same number.
### `SabreTools.IO.Readers` and `SabreTools.IO.Writers`
Reading and writing support for the following file types:

View File

@@ -0,0 +1,168 @@
using System;
using SabreTools.IO.Numerics;
using Xunit;
namespace SabreTools.IO.Test.Numerics
{
public class BothInt16Tests
{
[Theory]
[InlineData(0, 0, true)]
[InlineData(0, 1, false)]
public void IsValidTest(short le, short be, bool expected)
{
var val = new BothInt16(le, be);
Assert.Equal(le, val.LittleEndian);
Assert.Equal(be, val.BigEndian);
Assert.Equal(expected, val.IsValid);
}
[Fact]
public void ImplicitConversionTest()
{
short expected = 1;
var val = new BothInt16(expected, expected);
short to = (short)val;
Assert.Equal(expected, to);
BothInt16 back = (BothInt16)to;
Assert.Equal(expected, back.LittleEndian);
Assert.Equal(expected, back.BigEndian);
}
[Theory]
[InlineData(0, -1)]
[InlineData(1, 0)]
[InlineData(2, 1)]
public void CompareToTest(short le, int expected)
{
short compare = 1;
var val = new BothInt16(le, le);
int actual = val.CompareTo(compare);
Assert.Equal(expected, actual);
}
[Fact]
public void GetTypeCodeTest()
{
TypeCode expected = ((short)1).GetTypeCode();
var val = new BothInt16(1, 1);
Assert.Equal(expected, val.GetTypeCode());
}
[Fact]
public void ToTypesTest()
{
var val = new BothInt16(1, 1);
bool expectedBool = Convert.ToBoolean((short)1);
Assert.Equal(expectedBool, val.ToBoolean(null));
char expectedChar = Convert.ToChar((short)1);
Assert.Equal(expectedChar, val.ToChar(null));
sbyte expectedSByte = Convert.ToSByte((short)1);
Assert.Equal(expectedSByte, val.ToSByte(null));
byte expectedByte = Convert.ToByte((short)1);
Assert.Equal(expectedByte, val.ToByte(null));
short expectedInt16 = Convert.ToInt16((short)1);
Assert.Equal(expectedInt16, val.ToInt16(null));
ushort expectedUInt16 = Convert.ToUInt16((short)1);
Assert.Equal(expectedUInt16, val.ToUInt16(null));
int expectedInt32 = Convert.ToInt32((short)1);
Assert.Equal(expectedInt32, val.ToInt32(null));
uint expectedUInt32 = Convert.ToUInt32((short)1);
Assert.Equal(expectedUInt32, val.ToUInt32(null));
long expectedInt64 = Convert.ToInt64((short)1);
Assert.Equal(expectedInt64, val.ToInt64(null));
ulong expectedUInt64 = Convert.ToUInt64((short)1);
Assert.Equal(expectedUInt64, val.ToUInt64(null));
float expectedSingle = Convert.ToSingle((short)1);
Assert.Equal(expectedSingle, val.ToSingle(null));
double expectedDouble = Convert.ToDouble((short)1);
Assert.Equal(expectedDouble, val.ToDouble(null));
decimal expectedDecimal = Convert.ToDecimal((short)1);
Assert.Equal(expectedDecimal, val.ToDecimal(null));
Assert.Throws<InvalidCastException>(() => val.ToDateTime(null));
string expectedString = Convert.ToString((short)1);
Assert.Equal(expectedString, val.ToString(null));
ulong expectedObject = Convert.ToUInt64((short)1);
Assert.Equal(expectedObject, val.ToType(typeof(ulong), null));
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(0, 1, false)]
[InlineData(1, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BothEndian(short le, short be, bool expected)
{
var val = new BothInt16(le, be);
var equalTo = new BothInt16(1, 1);
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BaseType(short le, short be, bool expected)
{
var val = new BothInt16(le, be);
short equalTo = 1;
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Fact]
public void OperatorsTest()
{
var valA = new BothInt16(2, 2);
var valB = new BothInt16(1, 1);
short expected = (short)2 + (short)1;
BothInt16 actual = valA + valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (short)2 - (short)1;
actual = valA - valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (short)2 * (short)1;
actual = valA * valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (short)2 / (short)1;
actual = valA / valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (short)2 ^ (short)1;
actual = valA ^ valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
}
}
}

View File

@@ -0,0 +1,168 @@
using System;
using SabreTools.IO.Numerics;
using Xunit;
namespace SabreTools.IO.Test.Numerics
{
public class BothInt32Tests
{
[Theory]
[InlineData(0, 0, true)]
[InlineData(0, 1, false)]
public void IsValidTest(int le, int be, bool expected)
{
var val = new BothInt32(le, be);
Assert.Equal(le, val.LittleEndian);
Assert.Equal(be, val.BigEndian);
Assert.Equal(expected, val.IsValid);
}
[Fact]
public void ImplicitConversionTest()
{
int expected = 1;
var val = new BothInt32(expected, expected);
int to = (int)val;
Assert.Equal(expected, to);
BothInt32 back = (BothInt32)to;
Assert.Equal(expected, back.LittleEndian);
Assert.Equal(expected, back.BigEndian);
}
[Theory]
[InlineData(0, -1)]
[InlineData(1, 0)]
[InlineData(2, 1)]
public void CompareToTest(int le, int expected)
{
int compare = 1;
var val = new BothInt32(le, le);
int actual = val.CompareTo(compare);
Assert.Equal(expected, actual);
}
[Fact]
public void GetTypeCodeTest()
{
TypeCode expected = ((int)1).GetTypeCode();
var val = new BothInt32(1, 1);
Assert.Equal(expected, val.GetTypeCode());
}
[Fact]
public void ToTypesTest()
{
var val = new BothInt32(1, 1);
bool expectedBool = Convert.ToBoolean((int)1);
Assert.Equal(expectedBool, val.ToBoolean(null));
char expectedChar = Convert.ToChar((int)1);
Assert.Equal(expectedChar, val.ToChar(null));
sbyte expectedSByte = Convert.ToSByte((int)1);
Assert.Equal(expectedSByte, val.ToSByte(null));
byte expectedByte = Convert.ToByte((int)1);
Assert.Equal(expectedByte, val.ToByte(null));
short expectedInt16 = Convert.ToInt16((int)1);
Assert.Equal(expectedInt16, val.ToInt16(null));
ushort expectedUInt16 = Convert.ToUInt16((int)1);
Assert.Equal(expectedUInt16, val.ToUInt16(null));
int expectedInt32 = Convert.ToInt32((int)1);
Assert.Equal(expectedInt32, val.ToInt32(null));
uint expectedUInt32 = Convert.ToUInt32((int)1);
Assert.Equal(expectedUInt32, val.ToUInt32(null));
long expectedInt64 = Convert.ToInt64((int)1);
Assert.Equal(expectedInt64, val.ToInt64(null));
ulong expectedUInt64 = Convert.ToUInt64((int)1);
Assert.Equal(expectedUInt64, val.ToUInt64(null));
float expectedSingle = Convert.ToSingle((int)1);
Assert.Equal(expectedSingle, val.ToSingle(null));
double expectedDouble = Convert.ToDouble((int)1);
Assert.Equal(expectedDouble, val.ToDouble(null));
decimal expectedDecimal = Convert.ToDecimal((int)1);
Assert.Equal(expectedDecimal, val.ToDecimal(null));
Assert.Throws<InvalidCastException>(() => val.ToDateTime(null));
string expectedString = Convert.ToString((int)1);
Assert.Equal(expectedString, val.ToString(null));
ulong expectedObject = Convert.ToUInt64((int)1);
Assert.Equal(expectedObject, val.ToType(typeof(ulong), null));
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(0, 1, false)]
[InlineData(1, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BothEndian(int le, int be, bool expected)
{
var val = new BothInt32(le, be);
var equalTo = new BothInt32(1, 1);
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BaseType(int le, int be, bool expected)
{
var val = new BothInt32(le, be);
int equalTo = 1;
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Fact]
public void OperatorsTest()
{
var valA = new BothInt32(2, 2);
var valB = new BothInt32(1, 1);
int expected = (int)2 + (int)1;
BothInt32 actual = valA + valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (int)2 - (int)1;
actual = valA - valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (int)2 * (int)1;
actual = valA * valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (int)2 / (int)1;
actual = valA / valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (int)2 ^ (int)1;
actual = valA ^ valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
}
}
}

View File

@@ -0,0 +1,168 @@
using System;
using SabreTools.IO.Numerics;
using Xunit;
namespace SabreTools.IO.Test.Numerics
{
public class BothInt64Tests
{
[Theory]
[InlineData(0, 0, true)]
[InlineData(0, 1, false)]
public void IsValidTest(long le, long be, bool expected)
{
var val = new BothInt64(le, be);
Assert.Equal(le, val.LittleEndian);
Assert.Equal(be, val.BigEndian);
Assert.Equal(expected, val.IsValid);
}
[Fact]
public void ImplicitConversionTest()
{
long expected = 1;
var val = new BothInt64(expected, expected);
long to = (long)val;
Assert.Equal(expected, to);
BothInt64 back = (BothInt64)to;
Assert.Equal(expected, back.LittleEndian);
Assert.Equal(expected, back.BigEndian);
}
[Theory]
[InlineData(0, -1)]
[InlineData(1, 0)]
[InlineData(2, 1)]
public void CompareToTest(long le, int expected)
{
long compare = 1;
var val = new BothInt64(le, le);
int actual = val.CompareTo(compare);
Assert.Equal(expected, actual);
}
[Fact]
public void GetTypeCodeTest()
{
TypeCode expected = ((long)1).GetTypeCode();
var val = new BothInt64(1, 1);
Assert.Equal(expected, val.GetTypeCode());
}
[Fact]
public void ToTypesTest()
{
var val = new BothInt64(1, 1);
bool expectedBool = Convert.ToBoolean((long)1);
Assert.Equal(expectedBool, val.ToBoolean(null));
char expectedChar = Convert.ToChar((long)1);
Assert.Equal(expectedChar, val.ToChar(null));
sbyte expectedSByte = Convert.ToSByte((long)1);
Assert.Equal(expectedSByte, val.ToSByte(null));
byte expectedByte = Convert.ToByte((long)1);
Assert.Equal(expectedByte, val.ToByte(null));
short expectedInt16 = Convert.ToInt16((long)1);
Assert.Equal(expectedInt16, val.ToInt16(null));
ushort expectedUInt16 = Convert.ToUInt16((long)1);
Assert.Equal(expectedUInt16, val.ToUInt16(null));
int expectedInt32 = Convert.ToInt32((long)1);
Assert.Equal(expectedInt32, val.ToInt32(null));
uint expectedUInt32 = Convert.ToUInt32((long)1);
Assert.Equal(expectedUInt32, val.ToUInt32(null));
long expectedInt64 = Convert.ToInt64((long)1);
Assert.Equal(expectedInt64, val.ToInt64(null));
ulong expectedUInt64 = Convert.ToUInt64((long)1);
Assert.Equal(expectedUInt64, val.ToUInt64(null));
float expectedSingle = Convert.ToSingle((long)1);
Assert.Equal(expectedSingle, val.ToSingle(null));
double expectedDouble = Convert.ToDouble((long)1);
Assert.Equal(expectedDouble, val.ToDouble(null));
decimal expectedDecimal = Convert.ToDecimal((long)1);
Assert.Equal(expectedDecimal, val.ToDecimal(null));
Assert.Throws<InvalidCastException>(() => val.ToDateTime(null));
string expectedString = Convert.ToString((long)1);
Assert.Equal(expectedString, val.ToString(null));
ulong expectedObject = Convert.ToUInt64((long)1);
Assert.Equal(expectedObject, val.ToType(typeof(ulong), null));
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(0, 1, false)]
[InlineData(1, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BothEndian(long le, long be, bool expected)
{
var val = new BothInt64(le, be);
var equalTo = new BothInt64(1, 1);
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BaseType(long le, long be, bool expected)
{
var val = new BothInt64(le, be);
long equalTo = 1;
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Fact]
public void OperatorsTest()
{
var valA = new BothInt64(2, 2);
var valB = new BothInt64(1, 1);
long expected = (long)2 + (long)1;
BothInt64 actual = valA + valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (long)2 - (long)1;
actual = valA - valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (long)2 * (long)1;
actual = valA * valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (long)2 / (long)1;
actual = valA / valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (long)2 ^ (long)1;
actual = valA ^ valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
}
}
}

View File

@@ -0,0 +1,168 @@
using System;
using SabreTools.IO.Numerics;
using Xunit;
namespace SabreTools.IO.Test.Numerics
{
public class BothInt8Tests
{
[Theory]
[InlineData(0, 0, true)]
[InlineData(0, 1, false)]
public void IsValidTest(sbyte le, sbyte be, bool expected)
{
var val = new BothInt8(le, be);
Assert.Equal(le, val.LittleEndian);
Assert.Equal(be, val.BigEndian);
Assert.Equal(expected, val.IsValid);
}
[Fact]
public void ImplicitConversionTest()
{
sbyte expected = 1;
var val = new BothInt8(expected, expected);
sbyte to = (sbyte)val;
Assert.Equal(expected, to);
BothInt8 back = (BothInt8)to;
Assert.Equal(expected, back.LittleEndian);
Assert.Equal(expected, back.BigEndian);
}
[Theory]
[InlineData(0, -1)]
[InlineData(1, 0)]
[InlineData(2, 1)]
public void CompareToTest(sbyte le, int expected)
{
sbyte compare = 1;
var val = new BothInt8(le, le);
int actual = val.CompareTo(compare);
Assert.Equal(expected, actual);
}
[Fact]
public void GetTypeCodeTest()
{
TypeCode expected = ((sbyte)1).GetTypeCode();
var val = new BothInt8(1, 1);
Assert.Equal(expected, val.GetTypeCode());
}
[Fact]
public void ToTypesTest()
{
var val = new BothInt8(1, 1);
bool expectedBool = Convert.ToBoolean((sbyte)1);
Assert.Equal(expectedBool, val.ToBoolean(null));
char expectedChar = Convert.ToChar((sbyte)1);
Assert.Equal(expectedChar, val.ToChar(null));
sbyte expectedSByte = Convert.ToSByte((sbyte)1);
Assert.Equal(expectedSByte, val.ToSByte(null));
byte expectedByte = Convert.ToByte((sbyte)1);
Assert.Equal(expectedByte, val.ToByte(null));
short expectedInt16 = Convert.ToInt16((sbyte)1);
Assert.Equal(expectedInt16, val.ToInt16(null));
ushort expectedUInt16 = Convert.ToUInt16((sbyte)1);
Assert.Equal(expectedUInt16, val.ToUInt16(null));
int expectedInt32 = Convert.ToInt32((sbyte)1);
Assert.Equal(expectedInt32, val.ToInt32(null));
uint expectedUInt32 = Convert.ToUInt32((sbyte)1);
Assert.Equal(expectedUInt32, val.ToUInt32(null));
long expectedInt64 = Convert.ToInt64((sbyte)1);
Assert.Equal(expectedInt64, val.ToInt64(null));
ulong expectedUInt64 = Convert.ToUInt64((sbyte)1);
Assert.Equal(expectedUInt64, val.ToUInt64(null));
float expectedSingle = Convert.ToSingle((sbyte)1);
Assert.Equal(expectedSingle, val.ToSingle(null));
double expectedDouble = Convert.ToDouble((sbyte)1);
Assert.Equal(expectedDouble, val.ToDouble(null));
decimal expectedDecimal = Convert.ToDecimal((sbyte)1);
Assert.Equal(expectedDecimal, val.ToDecimal(null));
Assert.Throws<InvalidCastException>(() => val.ToDateTime(null));
string expectedString = Convert.ToString((sbyte)1);
Assert.Equal(expectedString, val.ToString(null));
ulong expectedObject = Convert.ToUInt64((sbyte)1);
Assert.Equal(expectedObject, val.ToType(typeof(ulong), null));
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(0, 1, false)]
[InlineData(1, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BothEndian(sbyte le, sbyte be, bool expected)
{
var val = new BothInt8(le, be);
var equalTo = new BothInt8(1, 1);
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BaseType(sbyte le, sbyte be, bool expected)
{
var val = new BothInt8(le, be);
sbyte equalTo = 1;
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Fact]
public void OperatorsTest()
{
var valA = new BothInt8(2, 2);
var valB = new BothInt8(1, 1);
sbyte expected = (sbyte)2 + (sbyte)1;
BothInt8 actual = valA + valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (sbyte)2 - (sbyte)1;
actual = valA - valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (sbyte)2 * (sbyte)1;
actual = valA * valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (sbyte)2 / (sbyte)1;
actual = valA / valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (sbyte)2 ^ (sbyte)1;
actual = valA ^ valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
}
}
}

View File

@@ -0,0 +1,168 @@
using System;
using SabreTools.IO.Numerics;
using Xunit;
namespace SabreTools.IO.Test.Numerics
{
public class BothUInt16Tests
{
[Theory]
[InlineData(0, 0, true)]
[InlineData(0, 1, false)]
public void IsValidTest(ushort le, ushort be, bool expected)
{
var val = new BothUInt16(le, be);
Assert.Equal(le, val.LittleEndian);
Assert.Equal(be, val.BigEndian);
Assert.Equal(expected, val.IsValid);
}
[Fact]
public void ImplicitConversionTest()
{
ushort expected = 1;
var val = new BothUInt16(expected, expected);
ushort to = (ushort)val;
Assert.Equal(expected, to);
BothUInt16 back = (BothUInt16)to;
Assert.Equal(expected, back.LittleEndian);
Assert.Equal(expected, back.BigEndian);
}
[Theory]
[InlineData(0, -1)]
[InlineData(1, 0)]
[InlineData(2, 1)]
public void CompareToTest(ushort le, int expected)
{
ushort compare = 1;
var val = new BothUInt16(le, le);
int actual = val.CompareTo(compare);
Assert.Equal(expected, actual);
}
[Fact]
public void GetTypeCodeTest()
{
TypeCode expected = ((ushort)1).GetTypeCode();
var val = new BothUInt16(1, 1);
Assert.Equal(expected, val.GetTypeCode());
}
[Fact]
public void ToTypesTest()
{
var val = new BothUInt16(1, 1);
bool expectedBool = Convert.ToBoolean((ushort)1);
Assert.Equal(expectedBool, val.ToBoolean(null));
char expectedChar = Convert.ToChar((ushort)1);
Assert.Equal(expectedChar, val.ToChar(null));
sbyte expectedSByte = Convert.ToSByte((ushort)1);
Assert.Equal(expectedSByte, val.ToSByte(null));
byte expectedByte = Convert.ToByte((ushort)1);
Assert.Equal(expectedByte, val.ToByte(null));
short expectedInt16 = Convert.ToInt16((ushort)1);
Assert.Equal(expectedInt16, val.ToInt16(null));
ushort expectedUInt16 = Convert.ToUInt16((ushort)1);
Assert.Equal(expectedUInt16, val.ToUInt16(null));
int expectedInt32 = Convert.ToInt32((ushort)1);
Assert.Equal(expectedInt32, val.ToInt32(null));
uint expectedUInt32 = Convert.ToUInt32((ushort)1);
Assert.Equal(expectedUInt32, val.ToUInt32(null));
long expectedInt64 = Convert.ToInt64((ushort)1);
Assert.Equal(expectedInt64, val.ToInt64(null));
ulong expectedUInt64 = Convert.ToUInt64((ushort)1);
Assert.Equal(expectedUInt64, val.ToUInt64(null));
float expectedSingle = Convert.ToSingle((ushort)1);
Assert.Equal(expectedSingle, val.ToSingle(null));
double expectedDouble = Convert.ToDouble((ushort)1);
Assert.Equal(expectedDouble, val.ToDouble(null));
decimal expectedDecimal = Convert.ToDecimal((ushort)1);
Assert.Equal(expectedDecimal, val.ToDecimal(null));
Assert.Throws<InvalidCastException>(() => val.ToDateTime(null));
string expectedString = Convert.ToString((ushort)1);
Assert.Equal(expectedString, val.ToString(null));
ulong expectedObject = Convert.ToUInt64((ushort)1);
Assert.Equal(expectedObject, val.ToType(typeof(ulong), null));
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(0, 1, false)]
[InlineData(1, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BothEndian(ushort le, ushort be, bool expected)
{
var val = new BothUInt16(le, be);
var equalTo = new BothUInt16(1, 1);
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BaseType(ushort le, ushort be, bool expected)
{
var val = new BothUInt16(le, be);
ushort equalTo = 1;
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Fact]
public void OperatorsTest()
{
var valA = new BothUInt16(2, 2);
var valB = new BothUInt16(1, 1);
ushort expected = (ushort)2 + (ushort)1;
BothUInt16 actual = valA + valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (ushort)2 - (ushort)1;
actual = valA - valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (ushort)2 * (ushort)1;
actual = valA * valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (ushort)2 / (ushort)1;
actual = valA / valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (ushort)2 ^ (ushort)1;
actual = valA ^ valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
}
}
}

View File

@@ -0,0 +1,168 @@
using System;
using SabreTools.IO.Numerics;
using Xunit;
namespace SabreTools.IO.Test.Numerics
{
public class BothUInt32Tests
{
[Theory]
[InlineData(0, 0, true)]
[InlineData(0, 1, false)]
public void IsValidTest(uint le, uint be, bool expected)
{
var val = new BothUInt32(le, be);
Assert.Equal(le, val.LittleEndian);
Assert.Equal(be, val.BigEndian);
Assert.Equal(expected, val.IsValid);
}
[Fact]
public void ImplicitConversionTest()
{
uint expected = 1;
var val = new BothUInt32(expected, expected);
uint to = (uint)val;
Assert.Equal(expected, to);
BothUInt32 back = (BothUInt32)to;
Assert.Equal(expected, back.LittleEndian);
Assert.Equal(expected, back.BigEndian);
}
[Theory]
[InlineData(0, -1)]
[InlineData(1, 0)]
[InlineData(2, 1)]
public void CompareToTest(uint le, int expected)
{
uint compare = 1;
var val = new BothUInt32(le, le);
int actual = val.CompareTo(compare);
Assert.Equal(expected, actual);
}
[Fact]
public void GetTypeCodeTest()
{
TypeCode expected = ((uint)1).GetTypeCode();
var val = new BothUInt32(1, 1);
Assert.Equal(expected, val.GetTypeCode());
}
[Fact]
public void ToTypesTest()
{
var val = new BothUInt32(1, 1);
bool expectedBool = Convert.ToBoolean((uint)1);
Assert.Equal(expectedBool, val.ToBoolean(null));
char expectedChar = Convert.ToChar((uint)1);
Assert.Equal(expectedChar, val.ToChar(null));
sbyte expectedSByte = Convert.ToSByte((uint)1);
Assert.Equal(expectedSByte, val.ToSByte(null));
byte expectedByte = Convert.ToByte((uint)1);
Assert.Equal(expectedByte, val.ToByte(null));
short expectedInt16 = Convert.ToInt16((uint)1);
Assert.Equal(expectedInt16, val.ToInt16(null));
ushort expectedUInt16 = Convert.ToUInt16((uint)1);
Assert.Equal(expectedUInt16, val.ToUInt16(null));
int expectedInt32 = Convert.ToInt32((uint)1);
Assert.Equal(expectedInt32, val.ToInt32(null));
uint expectedUInt32 = Convert.ToUInt32((uint)1);
Assert.Equal(expectedUInt32, val.ToUInt32(null));
long expectedInt64 = Convert.ToInt64((uint)1);
Assert.Equal(expectedInt64, val.ToInt64(null));
ulong expectedUInt64 = Convert.ToUInt64((uint)1);
Assert.Equal(expectedUInt64, val.ToUInt64(null));
float expectedSingle = Convert.ToSingle((uint)1);
Assert.Equal(expectedSingle, val.ToSingle(null));
double expectedDouble = Convert.ToDouble((uint)1);
Assert.Equal(expectedDouble, val.ToDouble(null));
decimal expectedDecimal = Convert.ToDecimal((uint)1);
Assert.Equal(expectedDecimal, val.ToDecimal(null));
Assert.Throws<InvalidCastException>(() => val.ToDateTime(null));
string expectedString = Convert.ToString((uint)1);
Assert.Equal(expectedString, val.ToString(null));
ulong expectedObject = Convert.ToUInt64((uint)1);
Assert.Equal(expectedObject, val.ToType(typeof(ulong), null));
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(0, 1, false)]
[InlineData(1, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BothEndian(uint le, uint be, bool expected)
{
var val = new BothUInt32(le, be);
var equalTo = new BothUInt32(1, 1);
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BaseType(uint le, uint be, bool expected)
{
var val = new BothUInt32(le, be);
uint equalTo = 1;
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Fact]
public void OperatorsTest()
{
var valA = new BothUInt32(2, 2);
var valB = new BothUInt32(1, 1);
uint expected = (uint)2 + (uint)1;
BothUInt32 actual = valA + valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (uint)2 - (uint)1;
actual = valA - valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (uint)2 * (uint)1;
actual = valA * valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (uint)2 / (uint)1;
actual = valA / valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (uint)2 ^ (uint)1;
actual = valA ^ valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
}
}
}

View File

@@ -0,0 +1,168 @@
using System;
using SabreTools.IO.Numerics;
using Xunit;
namespace SabreTools.IO.Test.Numerics
{
public class BothUInt64Tests
{
[Theory]
[InlineData(0, 0, true)]
[InlineData(0, 1, false)]
public void IsValidTest(ulong le, ulong be, bool expected)
{
var val = new BothUInt64(le, be);
Assert.Equal(le, val.LittleEndian);
Assert.Equal(be, val.BigEndian);
Assert.Equal(expected, val.IsValid);
}
[Fact]
public void ImplicitConversionTest()
{
ulong expected = 1;
var val = new BothUInt64(expected, expected);
ulong to = (ulong)val;
Assert.Equal(expected, to);
BothUInt64 back = (BothUInt64)to;
Assert.Equal(expected, back.LittleEndian);
Assert.Equal(expected, back.BigEndian);
}
[Theory]
[InlineData(0, -1)]
[InlineData(1, 0)]
[InlineData(2, 1)]
public void CompareToTest(ulong le, int expected)
{
ulong compare = 1;
var val = new BothUInt64(le, le);
int actual = val.CompareTo(compare);
Assert.Equal(expected, actual);
}
[Fact]
public void GetTypeCodeTest()
{
TypeCode expected = ((ulong)1).GetTypeCode();
var val = new BothUInt64(1, 1);
Assert.Equal(expected, val.GetTypeCode());
}
[Fact]
public void ToTypesTest()
{
var val = new BothUInt64(1, 1);
bool expectedBool = Convert.ToBoolean((ulong)1);
Assert.Equal(expectedBool, val.ToBoolean(null));
char expectedChar = Convert.ToChar((ulong)1);
Assert.Equal(expectedChar, val.ToChar(null));
sbyte expectedSByte = Convert.ToSByte((ulong)1);
Assert.Equal(expectedSByte, val.ToSByte(null));
byte expectedByte = Convert.ToByte((ulong)1);
Assert.Equal(expectedByte, val.ToByte(null));
short expectedInt16 = Convert.ToInt16((ulong)1);
Assert.Equal(expectedInt16, val.ToInt16(null));
ushort expectedUInt16 = Convert.ToUInt16((ulong)1);
Assert.Equal(expectedUInt16, val.ToUInt16(null));
int expectedInt32 = Convert.ToInt32((ulong)1);
Assert.Equal(expectedInt32, val.ToInt32(null));
uint expectedUInt32 = Convert.ToUInt32((ulong)1);
Assert.Equal(expectedUInt32, val.ToUInt32(null));
long expectedInt64 = Convert.ToInt64((ulong)1);
Assert.Equal(expectedInt64, val.ToInt64(null));
ulong expectedUInt64 = Convert.ToUInt64((ulong)1);
Assert.Equal(expectedUInt64, val.ToUInt64(null));
float expectedSingle = Convert.ToSingle((ulong)1);
Assert.Equal(expectedSingle, val.ToSingle(null));
double expectedDouble = Convert.ToDouble((ulong)1);
Assert.Equal(expectedDouble, val.ToDouble(null));
decimal expectedDecimal = Convert.ToDecimal((ulong)1);
Assert.Equal(expectedDecimal, val.ToDecimal(null));
Assert.Throws<InvalidCastException>(() => val.ToDateTime(null));
string expectedString = Convert.ToString((ulong)1);
Assert.Equal(expectedString, val.ToString(null));
ulong expectedObject = Convert.ToUInt64((ulong)1);
Assert.Equal(expectedObject, val.ToType(typeof(ulong), null));
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(0, 1, false)]
[InlineData(1, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BothEndian(ulong le, ulong be, bool expected)
{
var val = new BothUInt64(le, be);
var equalTo = new BothUInt64(1, 1);
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BaseType(ulong le, ulong be, bool expected)
{
var val = new BothUInt64(le, be);
ulong equalTo = 1;
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Fact]
public void OperatorsTest()
{
var valA = new BothUInt64(2, 2);
var valB = new BothUInt64(1, 1);
ulong expected = (ulong)2 + (ulong)1;
BothUInt64 actual = valA + valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (ulong)2 - (ulong)1;
actual = valA - valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (ulong)2 * (ulong)1;
actual = valA * valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (ulong)2 / (ulong)1;
actual = valA / valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (ulong)2 ^ (ulong)1;
actual = valA ^ valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
}
}
}

View File

@@ -0,0 +1,168 @@
using System;
using SabreTools.IO.Numerics;
using Xunit;
namespace SabreTools.IO.Test.Numerics
{
public class BothUInt8Tests
{
[Theory]
[InlineData(0, 0, true)]
[InlineData(0, 1, false)]
public void IsValidTest(byte le, byte be, bool expected)
{
var val = new BothUInt8(le, be);
Assert.Equal(le, val.LittleEndian);
Assert.Equal(be, val.BigEndian);
Assert.Equal(expected, val.IsValid);
}
[Fact]
public void ImplicitConversionTest()
{
byte expected = 1;
var val = new BothUInt8(expected, expected);
byte to = (byte)val;
Assert.Equal(expected, to);
BothUInt8 back = (BothUInt8)to;
Assert.Equal(expected, back.LittleEndian);
Assert.Equal(expected, back.BigEndian);
}
[Theory]
[InlineData(0, -1)]
[InlineData(1, 0)]
[InlineData(2, 1)]
public void CompareToTest(byte le, int expected)
{
byte compare = 1;
var val = new BothUInt8(le, le);
int actual = val.CompareTo(compare);
Assert.Equal(expected, actual);
}
[Fact]
public void GetTypeCodeTest()
{
TypeCode expected = ((byte)1).GetTypeCode();
var val = new BothUInt8(1, 1);
Assert.Equal(expected, val.GetTypeCode());
}
[Fact]
public void ToTypesTest()
{
var val = new BothUInt8(1, 1);
bool expectedBool = Convert.ToBoolean((byte)1);
Assert.Equal(expectedBool, val.ToBoolean(null));
char expectedChar = Convert.ToChar((byte)1);
Assert.Equal(expectedChar, val.ToChar(null));
sbyte expectedSByte = Convert.ToSByte((byte)1);
Assert.Equal(expectedSByte, val.ToSByte(null));
byte expectedByte = Convert.ToByte((byte)1);
Assert.Equal(expectedByte, val.ToByte(null));
short expectedInt16 = Convert.ToInt16((byte)1);
Assert.Equal(expectedInt16, val.ToInt16(null));
ushort expectedUInt16 = Convert.ToUInt16((byte)1);
Assert.Equal(expectedUInt16, val.ToUInt16(null));
int expectedInt32 = Convert.ToInt32((byte)1);
Assert.Equal(expectedInt32, val.ToInt32(null));
uint expectedUInt32 = Convert.ToUInt32((byte)1);
Assert.Equal(expectedUInt32, val.ToUInt32(null));
long expectedInt64 = Convert.ToInt64((byte)1);
Assert.Equal(expectedInt64, val.ToInt64(null));
ulong expectedUInt64 = Convert.ToUInt64((byte)1);
Assert.Equal(expectedUInt64, val.ToUInt64(null));
float expectedSingle = Convert.ToSingle((byte)1);
Assert.Equal(expectedSingle, val.ToSingle(null));
double expectedDouble = Convert.ToDouble((byte)1);
Assert.Equal(expectedDouble, val.ToDouble(null));
decimal expectedDecimal = Convert.ToDecimal((byte)1);
Assert.Equal(expectedDecimal, val.ToDecimal(null));
Assert.Throws<InvalidCastException>(() => val.ToDateTime(null));
string expectedString = Convert.ToString((byte)1);
Assert.Equal(expectedString, val.ToString(null));
ulong expectedObject = Convert.ToUInt64((byte)1);
Assert.Equal(expectedObject, val.ToType(typeof(ulong), null));
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(0, 1, false)]
[InlineData(1, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BothEndian(byte le, byte be, bool expected)
{
var val = new BothUInt8(le, be);
var equalTo = new BothUInt8(1, 1);
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(0, 0, false)]
[InlineData(1, 1, true)]
public void Equals_BaseType(byte le, byte be, bool expected)
{
var val = new BothUInt8(le, be);
byte equalTo = 1;
bool actual = val.Equals(equalTo);
Assert.Equal(expected, actual);
}
[Fact]
public void OperatorsTest()
{
var valA = new BothUInt8(2, 2);
var valB = new BothUInt8(1, 1);
byte expected = (byte)2 + (byte)1;
BothUInt8 actual = valA + valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (byte)2 - (byte)1;
actual = valA - valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (byte)2 * (byte)1;
actual = valA * valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (byte)2 / (byte)1;
actual = valA / valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
expected = (byte)2 ^ (byte)1;
actual = valA ^ valB;
Assert.Equal(expected, actual.LittleEndian);
Assert.Equal(expected, actual.BigEndian);
}
}
}

View File

@@ -0,0 +1,234 @@
using System;
namespace SabreTools.IO.Numerics
{
/// <summary>
/// Both-endian numeric value
/// </summary>
public abstract class BothEndian<T>(T le, T be) : IComparable, IConvertible, IEquatable<BothEndian<T>>, IEquatable<T>
where T : notnull, IComparable, IConvertible, IEquatable<T>
{
#region Properties
/// <summary>
/// Little-endian representation of the number
/// </summary>
/// <remarks>Value should match <see cref="BigEndian"/></remarks>
public readonly T LittleEndian = le;
/// <summary>
/// Big-endian representation of the number
/// </summary>
/// <remarks>Value should match <see cref="LittleEndian"/></remarks>
public readonly T BigEndian = be;
/// <summary>
/// Indicates if the value is valid
/// </summary>
/// <remarks>
/// Validity of a both-endian value is determined based on if both
/// endianness values match. These values should always match, based
/// on all implementations.
/// </remarks>
public bool IsValid => LittleEndian.Equals(BigEndian);
#endregion
#region Operators
/// <remarks>
/// Returns either <see cref="LittleEndian"/> or <see cref="BigEndian"/>
/// depending on the system endianness.
/// </remarks>
public static implicit operator T(BothEndian<T> val)
=> BitConverter.IsLittleEndian ? val.LittleEndian : val.BigEndian;
public static bool operator ==(BothEndian<T> a, BothEndian<T> b) => a.Equals(b);
public static bool operator !=(BothEndian<T> a, BothEndian<T> b) => !a.Equals(b);
#endregion
#region Object
#if NETCOREAPP
/// <inheritdoc/>
public override bool Equals(object? obj)
{
if (obj is BothEndian<T> be)
return Equals(be);
if (obj is T t)
return Equals(t);
return base.Equals(obj);
}
#else
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj is BothEndian<T> be)
return Equals(be);
if (obj is T t)
return Equals(t);
return base.Equals(obj);
}
#endif
/// <inheritdoc/>
public override int GetHashCode() => ((T)this).GetHashCode();
#if NETCOREAPP
/// <inheritdoc/>
public override string? ToString() => ((T)this).ToString();
#else
/// <inheritdoc/>
public override string ToString() => ((T)this).ToString();
#endif
#endregion
#region IComparable
/// <inheritdoc/>
#if NETCOREAPP
public int CompareTo(object? obj) => ((T)this).CompareTo(obj);
#else
public int CompareTo(object obj) => ((T)this).CompareTo(obj);
#endif
#endregion
#region IConvertible
/// <inheritdoc/>
public TypeCode GetTypeCode() => ((T)this).GetTypeCode();
#if NETCOREAPP
/// <inheritdoc/>
public bool ToBoolean(IFormatProvider? provider) => ((T)this).ToBoolean(provider);
/// <inheritdoc/>
public char ToChar(IFormatProvider? provider) => ((T)this).ToChar(provider);
/// <inheritdoc/>
public sbyte ToSByte(IFormatProvider? provider) => ((T)this).ToSByte(provider);
/// <inheritdoc/>
public byte ToByte(IFormatProvider? provider) => ((T)this).ToByte(provider);
/// <inheritdoc/>
public short ToInt16(IFormatProvider? provider) => ((T)this).ToInt16(provider);
/// <inheritdoc/>
public ushort ToUInt16(IFormatProvider? provider) => ((T)this).ToUInt16(provider);
/// <inheritdoc/>
public int ToInt32(IFormatProvider? provider) => ((T)this).ToInt32(provider);
/// <inheritdoc/>
public uint ToUInt32(IFormatProvider? provider) => ((T)this).ToUInt32(provider);
/// <inheritdoc/>
public long ToInt64(IFormatProvider? provider) => ((T)this).ToInt64(provider);
/// <inheritdoc/>
public ulong ToUInt64(IFormatProvider? provider) => ((T)this).ToUInt64(provider);
/// <inheritdoc/>
public float ToSingle(IFormatProvider? provider) => ((T)this).ToSingle(provider);
/// <inheritdoc/>
public double ToDouble(IFormatProvider? provider) => ((T)this).ToDouble(provider);
/// <inheritdoc/>
public decimal ToDecimal(IFormatProvider? provider) => ((T)this).ToDecimal(provider);
/// <inheritdoc/>
public DateTime ToDateTime(IFormatProvider? provider) => ((T)this).ToDateTime(provider);
/// <inheritdoc/>
public string ToString(IFormatProvider? provider) => ((T)this).ToString(provider);
/// <inheritdoc/>
public object ToType(Type conversionType, IFormatProvider? provider) => ((T)this).ToType(conversionType, provider);
#else
/// <inheritdoc/>
public bool ToBoolean(IFormatProvider provider) => ((T)this).ToBoolean(provider);
/// <inheritdoc/>
public char ToChar(IFormatProvider provider) => ((T)this).ToChar(provider);
/// <inheritdoc/>
public sbyte ToSByte(IFormatProvider provider) => ((T)this).ToSByte(provider);
/// <inheritdoc/>
public byte ToByte(IFormatProvider provider) => ((T)this).ToByte(provider);
/// <inheritdoc/>
public short ToInt16(IFormatProvider provider) => ((T)this).ToInt16(provider);
/// <inheritdoc/>
public ushort ToUInt16(IFormatProvider provider) => ((T)this).ToUInt16(provider);
/// <inheritdoc/>
public int ToInt32(IFormatProvider provider) => ((T)this).ToInt32(provider);
/// <inheritdoc/>
public uint ToUInt32(IFormatProvider provider) => ((T)this).ToUInt32(provider);
/// <inheritdoc/>
public long ToInt64(IFormatProvider provider) => ((T)this).ToInt64(provider);
/// <inheritdoc/>
public ulong ToUInt64(IFormatProvider provider) => ((T)this).ToUInt64(provider);
/// <inheritdoc/>
public float ToSingle(IFormatProvider provider) => ((T)this).ToSingle(provider);
/// <inheritdoc/>
public double ToDouble(IFormatProvider provider) => ((T)this).ToDouble(provider);
/// <inheritdoc/>
public decimal ToDecimal(IFormatProvider provider) => ((T)this).ToDecimal(provider);
/// <inheritdoc/>
public DateTime ToDateTime(IFormatProvider provider) => ((T)this).ToDateTime(provider);
/// <inheritdoc/>
public string ToString(IFormatProvider provider) => ((T)this).ToString(provider);
/// <inheritdoc/>
public object ToType(Type conversionType, IFormatProvider provider) => ((T)this).ToType(conversionType, provider);
#endif
#endregion
#region IEquatable
#if NETCOREAPP
/// <inheritdoc/>
public bool Equals(BothEndian<T>? other)
{
if (other is null)
return false;
return LittleEndian.Equals(other.LittleEndian) && BigEndian.Equals(other.BigEndian);
}
/// <inheritdoc/>
public bool Equals(T? other) => ((T)this).Equals(other);
#else
/// <inheritdoc/>
public bool Equals(BothEndian<T> other)
=> LittleEndian.Equals(other.LittleEndian) && BigEndian.Equals(other.BigEndian);
/// <inheritdoc/>
public bool Equals(T other) => ((T)this).Equals(other);
#endif
#endregion
}
}

View File

@@ -0,0 +1,50 @@
namespace SabreTools.IO.Numerics
{
/// <summary>
/// Both-endian 16-bit signed value
/// </summary>
public sealed class BothInt16(short le, short be) : BothEndian<short>(le, be)
{
#region Operators
public static BothInt16 operator +(BothInt16 a, BothInt16 b)
{
short le = (short)(a.LittleEndian + b.LittleEndian);
short be = (short)(a.BigEndian + b.BigEndian);
return new BothInt16(le, be);
}
public static BothInt16 operator -(BothInt16 a, BothInt16 b)
{
short le = (short)(a.LittleEndian - b.LittleEndian);
short be = (short)(a.BigEndian - b.BigEndian);
return new BothInt16(le, be);
}
public static BothInt16 operator *(BothInt16 a, BothInt16 b)
{
short le = (short)(a.LittleEndian * b.LittleEndian);
short be = (short)(a.BigEndian * b.BigEndian);
return new BothInt16(le, be);
}
public static BothInt16 operator /(BothInt16 a, BothInt16 b)
{
short le = (short)(a.LittleEndian / b.LittleEndian);
short be = (short)(a.BigEndian / b.BigEndian);
return new BothInt16(le, be);
}
public static BothInt16 operator ^(BothInt16 a, BothInt16 b)
{
short le = (short)(a.LittleEndian ^ b.LittleEndian);
short be = (short)(a.BigEndian ^ b.BigEndian);
return new BothInt16(le, be);
}
public static implicit operator BothInt16(short val)
=> new(val, val);
#endregion
}
}

View File

@@ -0,0 +1,50 @@
namespace SabreTools.IO.Numerics
{
/// <summary>
/// Both-endian 32-bit signed value
/// </summary>
public sealed class BothInt32(int le, int be) : BothEndian<int>(le, be)
{
#region Operators
public static BothInt32 operator +(BothInt32 a, BothInt32 b)
{
int le = (int)(a.LittleEndian + b.LittleEndian);
int be = (int)(a.BigEndian + b.BigEndian);
return new BothInt32(le, be);
}
public static BothInt32 operator -(BothInt32 a, BothInt32 b)
{
int le = (int)(a.LittleEndian - b.LittleEndian);
int be = (int)(a.BigEndian - b.BigEndian);
return new BothInt32(le, be);
}
public static BothInt32 operator *(BothInt32 a, BothInt32 b)
{
int le = (int)(a.LittleEndian * b.LittleEndian);
int be = (int)(a.BigEndian * b.BigEndian);
return new BothInt32(le, be);
}
public static BothInt32 operator /(BothInt32 a, BothInt32 b)
{
int le = (int)(a.LittleEndian / b.LittleEndian);
int be = (int)(a.BigEndian / b.BigEndian);
return new BothInt32(le, be);
}
public static BothInt32 operator ^(BothInt32 a, BothInt32 b)
{
int le = (int)(a.LittleEndian ^ b.LittleEndian);
int be = (int)(a.BigEndian ^ b.BigEndian);
return new BothInt32(le, be);
}
public static implicit operator BothInt32(int val)
=> new(val, val);
#endregion
}
}

View File

@@ -0,0 +1,50 @@
namespace SabreTools.IO.Numerics
{
/// <summary>
/// Both-endian 64-bit signed value
/// </summary>
public sealed class BothInt64(long le, long be) : BothEndian<long>(le, be)
{
#region Operators
public static BothInt64 operator +(BothInt64 a, BothInt64 b)
{
long le = (long)(a.LittleEndian + b.LittleEndian);
long be = (long)(a.BigEndian + b.BigEndian);
return new BothInt64(le, be);
}
public static BothInt64 operator -(BothInt64 a, BothInt64 b)
{
long le = (long)(a.LittleEndian - b.LittleEndian);
long be = (long)(a.BigEndian - b.BigEndian);
return new BothInt64(le, be);
}
public static BothInt64 operator *(BothInt64 a, BothInt64 b)
{
long le = (long)(a.LittleEndian * b.LittleEndian);
long be = (long)(a.BigEndian * b.BigEndian);
return new BothInt64(le, be);
}
public static BothInt64 operator /(BothInt64 a, BothInt64 b)
{
long le = (long)(a.LittleEndian / b.LittleEndian);
long be = (long)(a.BigEndian / b.BigEndian);
return new BothInt64(le, be);
}
public static BothInt64 operator ^(BothInt64 a, BothInt64 b)
{
long le = (long)(a.LittleEndian ^ b.LittleEndian);
long be = (long)(a.BigEndian ^ b.BigEndian);
return new BothInt64(le, be);
}
public static implicit operator BothInt64(long val)
=> new(val, val);
#endregion
}
}

View File

@@ -0,0 +1,50 @@
namespace SabreTools.IO.Numerics
{
/// <summary>
/// Both-endian 8-bit signed value
/// </summary>
public sealed class BothInt8(sbyte le, sbyte be) : BothEndian<sbyte>(le, be)
{
#region Operators
public static BothInt8 operator +(BothInt8 a, BothInt8 b)
{
sbyte le = (sbyte)(a.LittleEndian + b.LittleEndian);
sbyte be = (sbyte)(a.BigEndian + b.BigEndian);
return new BothInt8(le, be);
}
public static BothInt8 operator -(BothInt8 a, BothInt8 b)
{
sbyte le = (sbyte)(a.LittleEndian - b.LittleEndian);
sbyte be = (sbyte)(a.BigEndian - b.BigEndian);
return new BothInt8(le, be);
}
public static BothInt8 operator *(BothInt8 a, BothInt8 b)
{
sbyte le = (sbyte)(a.LittleEndian * b.LittleEndian);
sbyte be = (sbyte)(a.BigEndian * b.BigEndian);
return new BothInt8(le, be);
}
public static BothInt8 operator /(BothInt8 a, BothInt8 b)
{
sbyte le = (sbyte)(a.LittleEndian / b.LittleEndian);
sbyte be = (sbyte)(a.BigEndian / b.BigEndian);
return new BothInt8(le, be);
}
public static BothInt8 operator ^(BothInt8 a, BothInt8 b)
{
sbyte le = (sbyte)(a.LittleEndian ^ b.LittleEndian);
sbyte be = (sbyte)(a.BigEndian ^ b.BigEndian);
return new BothInt8(le, be);
}
public static implicit operator BothInt8(sbyte val)
=> new(val, val);
#endregion
}
}

View File

@@ -0,0 +1,50 @@
namespace SabreTools.IO.Numerics
{
/// <summary>
/// Both-endian 16-bit unsigned value
/// </summary>
public sealed class BothUInt16(ushort le, ushort be) : BothEndian<ushort>(le, be)
{
#region Operators
public static BothUInt16 operator +(BothUInt16 a, BothUInt16 b)
{
ushort le = (ushort)(a.LittleEndian + b.LittleEndian);
ushort be = (ushort)(a.BigEndian + b.BigEndian);
return new BothUInt16(le, be);
}
public static BothUInt16 operator -(BothUInt16 a, BothUInt16 b)
{
ushort le = (ushort)(a.LittleEndian - b.LittleEndian);
ushort be = (ushort)(a.BigEndian - b.BigEndian);
return new BothUInt16(le, be);
}
public static BothUInt16 operator *(BothUInt16 a, BothUInt16 b)
{
ushort le = (ushort)(a.LittleEndian * b.LittleEndian);
ushort be = (ushort)(a.BigEndian * b.BigEndian);
return new BothUInt16(le, be);
}
public static BothUInt16 operator /(BothUInt16 a, BothUInt16 b)
{
ushort le = (ushort)(a.LittleEndian / b.LittleEndian);
ushort be = (ushort)(a.BigEndian / b.BigEndian);
return new BothUInt16(le, be);
}
public static BothUInt16 operator ^(BothUInt16 a, BothUInt16 b)
{
ushort le = (ushort)(a.LittleEndian ^ b.LittleEndian);
ushort be = (ushort)(a.BigEndian ^ b.BigEndian);
return new BothUInt16(le, be);
}
public static implicit operator BothUInt16(ushort val)
=> new(val, val);
#endregion
}
}

View File

@@ -0,0 +1,50 @@
namespace SabreTools.IO.Numerics
{
/// <summary>
/// Both-endian 32-bit unsigned value
/// </summary>
public sealed class BothUInt32(uint le, uint be) : BothEndian<uint>(le, be)
{
#region Operators
public static BothUInt32 operator +(BothUInt32 a, BothUInt32 b)
{
uint le = (uint)(a.LittleEndian + b.LittleEndian);
uint be = (uint)(a.BigEndian + b.BigEndian);
return new BothUInt32(le, be);
}
public static BothUInt32 operator -(BothUInt32 a, BothUInt32 b)
{
uint le = (uint)(a.LittleEndian - b.LittleEndian);
uint be = (uint)(a.BigEndian - b.BigEndian);
return new BothUInt32(le, be);
}
public static BothUInt32 operator *(BothUInt32 a, BothUInt32 b)
{
uint le = (uint)(a.LittleEndian * b.LittleEndian);
uint be = (uint)(a.BigEndian * b.BigEndian);
return new BothUInt32(le, be);
}
public static BothUInt32 operator /(BothUInt32 a, BothUInt32 b)
{
uint le = (uint)(a.LittleEndian / b.LittleEndian);
uint be = (uint)(a.BigEndian / b.BigEndian);
return new BothUInt32(le, be);
}
public static BothUInt32 operator ^(BothUInt32 a, BothUInt32 b)
{
uint le = (uint)(a.LittleEndian ^ b.LittleEndian);
uint be = (uint)(a.BigEndian ^ b.BigEndian);
return new BothUInt32(le, be);
}
public static implicit operator BothUInt32(uint val)
=> new(val, val);
#endregion
}
}

View File

@@ -0,0 +1,50 @@
namespace SabreTools.IO.Numerics
{
/// <summary>
/// Both-endian 64-bit unsigned value
/// </summary>
public sealed class BothUInt64(ulong le, ulong be) : BothEndian<ulong>(le, be)
{
#region Operators
public static BothUInt64 operator +(BothUInt64 a, BothUInt64 b)
{
ulong le = (ulong)(a.LittleEndian + b.LittleEndian);
ulong be = (ulong)(a.BigEndian + b.BigEndian);
return new BothUInt64(le, be);
}
public static BothUInt64 operator -(BothUInt64 a, BothUInt64 b)
{
ulong le = (ulong)(a.LittleEndian - b.LittleEndian);
ulong be = (ulong)(a.BigEndian - b.BigEndian);
return new BothUInt64(le, be);
}
public static BothUInt64 operator *(BothUInt64 a, BothUInt64 b)
{
ulong le = (ulong)(a.LittleEndian * b.LittleEndian);
ulong be = (ulong)(a.BigEndian * b.BigEndian);
return new BothUInt64(le, be);
}
public static BothUInt64 operator /(BothUInt64 a, BothUInt64 b)
{
ulong le = (ulong)(a.LittleEndian / b.LittleEndian);
ulong be = (ulong)(a.BigEndian / b.BigEndian);
return new BothUInt64(le, be);
}
public static BothUInt64 operator ^(BothUInt64 a, BothUInt64 b)
{
ulong le = (ulong)(a.LittleEndian ^ b.LittleEndian);
ulong be = (ulong)(a.BigEndian ^ b.BigEndian);
return new BothUInt64(le, be);
}
public static implicit operator BothUInt64(ulong val)
=> new(val, val);
#endregion
}
}

View File

@@ -0,0 +1,50 @@
namespace SabreTools.IO.Numerics
{
/// <summary>
/// Both-endian 8-bit unsigned value
/// </summary>
public sealed class BothUInt8(byte le, byte be) : BothEndian<byte>(le, be)
{
#region Operators
public static BothUInt8 operator +(BothUInt8 a, BothUInt8 b)
{
byte le = (byte)(a.LittleEndian + b.LittleEndian);
byte be = (byte)(a.BigEndian + b.BigEndian);
return new BothUInt8(le, be);
}
public static BothUInt8 operator -(BothUInt8 a, BothUInt8 b)
{
byte le = (byte)(a.LittleEndian - b.LittleEndian);
byte be = (byte)(a.BigEndian - b.BigEndian);
return new BothUInt8(le, be);
}
public static BothUInt8 operator *(BothUInt8 a, BothUInt8 b)
{
byte le = (byte)(a.LittleEndian * b.LittleEndian);
byte be = (byte)(a.BigEndian * b.BigEndian);
return new BothUInt8(le, be);
}
public static BothUInt8 operator /(BothUInt8 a, BothUInt8 b)
{
byte le = (byte)(a.LittleEndian / b.LittleEndian);
byte be = (byte)(a.BigEndian / b.BigEndian);
return new BothUInt8(le, be);
}
public static BothUInt8 operator ^(BothUInt8 a, BothUInt8 b)
{
byte le = (byte)(a.LittleEndian ^ b.LittleEndian);
byte be = (byte)(a.BigEndian ^ b.BigEndian);
return new BothUInt8(le, be);
}
public static implicit operator BothUInt8(byte val)
=> new(val, val);
#endregion
}
}