diff --git a/MLAPI/NetworkingManagerComponents/Binary/BinaryCollector.cs b/MLAPI/NetworkingManagerComponents/Binary/BinaryCollector.cs index 80cb2f6..ae47506 100644 --- a/MLAPI/NetworkingManagerComponents/Binary/BinaryCollector.cs +++ b/MLAPI/NetworkingManagerComponents/Binary/BinaryCollector.cs @@ -74,7 +74,7 @@ namespace Tofvesson.Common collect = new object[bufferSize]; } - public void Push(T b) + private void Push(T b) { if (b is string || b.GetType().IsArray || IsSupportedType(b.GetType())) collect[collectCount++] = b is string ? Encoding.UTF8.GetBytes(b as string) : b as object; @@ -82,6 +82,30 @@ namespace Tofvesson.Common // Debug.LogWarning("MLAPI: The type \"" + b.GetType() + "\" is not supported by the Binary Serializer. It will be ignored"); } + + public void WriteBool(bool b) => Push(b); + public void WriteFloat(float f) => Push(f); + public void WriteDouble(double d) => Push(d); + public void WriteByte(byte b) => Push(b); + public void WriteUShort(ushort s) => Push(s); + public void WriteUInt(uint i) => Push(i); + public void WriteULong(ulong l) => Push(l); + public void WriteSByte(sbyte b) => Push(b); + public void WriteShort(short s) => Push(s); + public void WriteInt(int i) => Push(i); + public void WriteLong(long l) => Push(l); + public void WriteFloatArray(float[] f) => Push(f); + public void WriteDoubleArray(double[] d) => Push(d); + public void WriteByteArray(byte[] b) => Push(b); + public void WriteUShortArray(ushort[] s) => Push(s); + public void WriteUIntArray(uint[] i) => Push(i); + public void WriteULongArray(ulong[] l) => Push(l); + public void WriteSByteArray(sbyte[] b) => Push(b); + public void WriteShortArray(short[] s) => Push(s); + public void WriteIntArray(int[] i) => Push(i); + public void WriteLongArray(long[] l) => Push(l); + public void WriteString(string s) => Push(s); + public byte[] ToArray() { long bitCount = 0; @@ -135,18 +159,18 @@ namespace Tofvesson.Common else result_holder.SetValue(0UL, 0); type_holder.SetValue(t, 0); // Insert the value to convert into the preallocated holder array Buffer.BlockCopy(type_holder, 0, result_holder, 0, bytes); // Perform an internal copy to the byte-based holder - dynamic d = result_holder.GetValue(0); // Since floating point flag bits are seemingly the highest bytes of the floating point values // and even very small values have them, we swap the endianness in the hopes of reducing the size - Serialize(BinaryHelpers.SwapEndian(d), writeTo, ref bitOffset); + if(size) Serialize(BinaryHelpers.SwapEndian((uint)result_holder.GetValue(0)), writeTo, ref bitOffset); + else Serialize(BinaryHelpers.SwapEndian((ulong)result_holder.GetValue(0)), writeTo, ref bitOffset); } //bitOffset += offset; } else { bool signed = IsSigned(t.GetType()); - dynamic value; + ulong value; if (signed) { Type t1 = t.GetType(); @@ -155,9 +179,12 @@ namespace Tofvesson.Common else if (t1 == typeof(int)) value = (uint)ZigZagEncode(t as int? ?? 0, 4); else /*if (t1 == typeof(long))*/ value = (ulong)ZigZagEncode(t as long? ?? 0, 8); } - else value = t; + else if (t is byte) value = t as byte? ?? 0; + else if (t is ushort) value = t as ushort? ?? 0; + else if (t is uint) value = t as uint? ?? 0; + else /*if (t is ulong)*/ value = t as ulong? ?? 0; - if (value <= 240) WriteByte(writeTo, value, bitOffset); + if (value <= 240) WriteByte(writeTo, (byte)value, bitOffset); else if (value <= 2287) { WriteByte(writeTo, (value - 240) / 256 + 241, bitOffset); @@ -246,7 +273,7 @@ namespace Tofvesson.Common private static void WriteBit(byte[] b, bool bit, long index) => b[index / 8] = (byte)((b[index / 8] & ~(1 << (int)(index % 8))) | (bit ? 1 << (int)(index % 8) : 0)); - //private static void WriteByte(byte[] b, dynamic value, long index) => WriteByte(b, (byte)value, index); + private static void WriteByte(byte[] b, ulong value, long index) => WriteByte(b, (byte)value, index); private static void WriteByte(byte[] b, byte value, long index) { int byteIndex = (int)(index / 8); diff --git a/MLAPI/NetworkingManagerComponents/Binary/BinaryDistributor.cs b/MLAPI/NetworkingManagerComponents/Binary/BinaryDistributor.cs index 0ee8fc7..fa4857f 100644 --- a/MLAPI/NetworkingManagerComponents/Binary/BinaryDistributor.cs +++ b/MLAPI/NetworkingManagerComponents/Binary/BinaryDistributor.cs @@ -9,6 +9,7 @@ namespace Tofvesson.Common { public class BinaryDistributor { + private delegate T Getter(); private static readonly float[] holder_f = new float[1]; private static readonly double[] holder_d = new double[1]; private static readonly ulong[] holder_u = new ulong[1]; @@ -18,13 +19,15 @@ namespace Tofvesson.Common private long bitCount = 0; public BinaryDistributor(byte[] readFrom) => this.readFrom = readFrom; - public bool ReadBit() + public bool ReadBool() { bool result = (readFrom[bitCount / 8] & (byte)(1 << (int)(bitCount % 8))) != 0; ++bitCount; return result; } + public float ReadFloat() => ReadFloating(); + public double ReadDouble() => ReadFloating(); public byte ReadByte() { int shift = (int)(bitCount % 8); @@ -35,51 +38,55 @@ namespace Tofvesson.Common bitCount += 8; return result; } - - public float ReadFloat() => ReadFloating(); - public double ReadDouble() => ReadFloating(); - public float[] ReadFloatArray() => ReadFloatingArray(); - public double[] ReadDoubleArray() => ReadFloatingArray(); - public ushort ReadUShort() => ReadUnsigned(); - public uint ReadUInt() => ReadUnsigned(); - public ulong ReadULong() => ReadUnsigned(); + public ushort ReadUShort() => (ushort)ReadULong(); + public uint ReadUInt() => (uint)ReadULong(); public sbyte ReadSByte() => (sbyte)ZigZagDecode(ReadByte(), 1); public short ReadShort() => (short)ZigZagDecode(ReadUShort(), 2); public int ReadInt() => (int)ZigZagDecode(ReadUInt(), 4); - public long ReadLong() => (long)ZigZagDecode(ReadULong(), 8); + public long ReadLong() => ZigZagDecode(ReadULong(), 8); + public float[] ReadFloatArray() => ReadArray(ReadFloat); + public double[] ReadDoubleArray() => ReadArray(ReadDouble); + public byte[] ReadByteArray() => ReadArray(ReadByte); + public ushort[] ReadUShortArray() => ReadArray(ReadUShort); + public uint[] ReadUIntArray() => ReadArray(ReadUInt); + public ulong[] ReadULongArray() => ReadArray(ReadULong); + public sbyte[] ReadSByteArray() => ReadArray(ReadSByte); + public short[] ReadShortArray() => ReadArray(ReadShort); + public int[] ReadIntArray() => ReadArray(ReadInt); + public long[] ReadLongArray() => ReadArray(ReadLong); + public string ReadString() => Encoding.UTF8.GetString(ReadByteArray()); - private T ReadUnsigned() + private ulong ReadULong() { - dynamic header = ReadByte(); - if (header <= 240) return (T) header; - if (header <= 248) return (T) (240 + 256 * (header - 241) + ReadByte()); - if (header == 249) return (T) (header = 2288 + 256 * ReadByte() + ReadByte()); - dynamic res = ReadByte() | ((long)ReadByte() << 8) | ((long)ReadByte() << 16); + ulong header = ReadByte(); + if (header <= 240) return header; + if (header <= 248) return 240 + 256 * (header - 241) + ReadByte(); + if (header == 249) return 2288 + 256UL * ReadByte() + ReadByte(); + ulong res = ReadByte() | ((ulong)ReadByte() << 8) | ((ulong)ReadByte() << 16); if(header > 250) { - res |= (long) ReadByte() << 24; + res |= (ulong) ReadByte() << 24; if(header > 251) { - res |= (long)ReadByte() << 32; + res |= (ulong)ReadByte() << 32; if(header > 252) { - res |= (long)ReadByte() << 40; + res |= (ulong)ReadByte() << 40; if (header > 253) { - res |= (long)ReadByte() << 48; - if (header > 254) res |= (long)ReadByte() << 56; + res |= (ulong)ReadByte() << 48; + if (header > 254) res |= (ulong)ReadByte() << 56; } } } } - return (T) res; + return res; } - private T[] ReadFloatingArray() + private T[] ReadArray(Getter g) { - ushort size = ReadUShort(); - T[] result = new T[size]; - for (short s = 0; s < size; ++s) - result[s] = ReadFloating(); + T[] result = new T[ReadUShort()]; + for (ushort s = 0; s < result.Length; ++s) + result[s] = g(); return result; }