A different implementation of endian swap
I'd suggest a different approach to handling swapped endianness, not the usual shifting one. This could be considered a micro-optimization in many places but in a package like yours where it could be called really many times, it might pay off:
[StructLayout(LayoutKind.Explicit)]
private unsafe struct ENDIAN_SWAP {
[FieldOffset(0)]
public ushort @ushort;
[FieldOffset(0)]
public short @short;
[FieldOffset(0)]
public uint @uint;
[FieldOffset(0)]
public int @int;
[FieldOffset(0)]
public ulong @ulong;
[FieldOffset(0)]
public long @long;
[FieldOffset(0)]
public fixed byte b[8];
};
public static unsafe short Short(short x) {
var swap = new ENDIAN_SWAP { @short = x };
(swap.b[0], swap.b[1]) = (swap.b[1], swap.b[0]);
return swap.@short;
}
public static unsafe ushort Short(ushort x) {
var swap = new ENDIAN_SWAP { @ushort = x };
(swap.b[0], swap.b[1]) = (swap.b[1], swap.b[0]);
return swap.@ushort;
}
public static unsafe int Int(int x) {
var swap = new ENDIAN_SWAP { @int = x };
(swap.b[0], swap.b[1], swap.b[2], swap.b[3]) = (swap.b[3], swap.b[2], swap.b[1], swap.b[0]);
return swap.@int;
}
public static unsafe uint Int(uint x) {
var swap = new ENDIAN_SWAP { @uint = x };
(swap.b[0], swap.b[1], swap.b[2], swap.b[3]) = (swap.b[3], swap.b[2], swap.b[1], swap.b[0]);
return swap.@uint;
}
public static unsafe long Long(long x) {
var swap = new ENDIAN_SWAP { @long = x };
(swap.b[0], swap.b[1], swap.b[2], swap.b[3], swap.b[4], swap.b[5], swap.b[6], swap.b[7]) = (swap.b[7], swap.b[6], swap.b[5], swap.b[4], swap.b[3], swap.b[2], swap.b[1], swap.b[0]);
return swap.@long;
}
public static unsafe ulong Long(ulong x) {
var swap = new ENDIAN_SWAP { @ulong = x };
(swap.b[0], swap.b[1], swap.b[2], swap.b[3], swap.b[4], swap.b[5], swap.b[6], swap.b[7]) = (swap.b[7], swap.b[6], swap.b[5], swap.b[4], swap.b[3], swap.b[2], swap.b[1], swap.b[0]);
return swap.@ulong;
}
Of course, some benchmarking first...
Edited by deakjahn