using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; #nullable enable namespace MemoryPack { // VarInt, first sbyte is value or typeCode // 0~127 = unsigned byte value // -1~-120 = signed byte value // -121 = byte // -122 = sbyte // -123 = ushort // -124 = short // -125 = uint // -126 = int // -127 = ulong // -128 = long internal static class VarIntCodes { public const byte MaxSingleValue = 127; public const sbyte MinSingleValue = -120; public const sbyte Byte = -121; public const sbyte SByte = -122; public const sbyte UInt16 = -123; public const sbyte Int16 = -124; public const sbyte UInt32 = -125; public const sbyte Int32 = -126; public const sbyte UInt64 = -127; public const sbyte Int64 = -128; } public ref partial struct MemoryPackWriter { public void WriteVarInt(byte x) { if (x <= VarIntCodes.MaxSingleValue) { WriteUnmanaged((sbyte)x); } else { WriteUnmanaged(VarIntCodes.Byte, x); } } public void WriteVarInt(sbyte x) { if (VarIntCodes.MinSingleValue <= x) { WriteUnmanaged(x); } else { WriteUnmanaged(VarIntCodes.SByte, x); } } public void WriteVarInt(ushort x) { if (x <= VarIntCodes.MaxSingleValue) { WriteUnmanaged((sbyte)x); } else { WriteUnmanaged(VarIntCodes.UInt16, (UInt16)x); } } public void WriteVarInt(short x) { if (0 <= x) { if (x <= VarIntCodes.MaxSingleValue) // same as sbyte.MaxValue { WriteUnmanaged((sbyte)x); } else { WriteUnmanaged(VarIntCodes.Int16, (Int16)x); } } else { if (VarIntCodes.MinSingleValue <= x) { WriteUnmanaged((sbyte)x); } else if (sbyte.MinValue <= x) { WriteUnmanaged(VarIntCodes.SByte, (SByte)x); } else { WriteUnmanaged(VarIntCodes.Int16, (Int16)x); } } } public void WriteVarInt(uint x) { if (x <= VarIntCodes.MaxSingleValue) { WriteUnmanaged((sbyte)x); } else if (x <= ushort.MaxValue) { WriteUnmanaged(VarIntCodes.UInt16, (UInt16)x); } else { WriteUnmanaged(VarIntCodes.UInt32, (UInt32)x); } } public void WriteVarInt(int x) { if (0 <= x) { if (x <= VarIntCodes.MaxSingleValue) // same as sbyte.MaxValue { WriteUnmanaged((sbyte)x); } else if (x <= short.MaxValue) { WriteUnmanaged(VarIntCodes.Int16, (Int16)x); } else { WriteUnmanaged(VarIntCodes.Int32, (Int32)x); } } else { if (VarIntCodes.MinSingleValue <= x) { WriteUnmanaged((sbyte)x); } else if (sbyte.MinValue <= x) { WriteUnmanaged(VarIntCodes.SByte, (SByte)x); } else if (short.MinValue <= x) { WriteUnmanaged(VarIntCodes.Int16, (Int16)x); } else { WriteUnmanaged(VarIntCodes.Int32, (Int32)x); } } } public void WriteVarInt(ulong x) { if (x <= VarIntCodes.MaxSingleValue) { WriteUnmanaged((sbyte)x); } else if (x <= ushort.MaxValue) { WriteUnmanaged(VarIntCodes.UInt16, (UInt16)x); } else if (x <= uint.MaxValue) { WriteUnmanaged(VarIntCodes.UInt32, (UInt32)x); } else { WriteUnmanaged(VarIntCodes.UInt64, (UInt64)x); } } public void WriteVarInt(long x) { if (0 <= x) { if (x <= VarIntCodes.MaxSingleValue) // same as sbyte.MaxValue { WriteUnmanaged((sbyte)x); } else if (x <= short.MaxValue) { WriteUnmanaged(VarIntCodes.Int16, (Int16)x); } else if (x <= int.MaxValue) { WriteUnmanaged(VarIntCodes.Int32, (Int32)x); } else { WriteUnmanaged(VarIntCodes.Int64, (Int64)x); } } else { if (VarIntCodes.MinSingleValue <= x) { WriteUnmanaged((sbyte)x); } else if (sbyte.MinValue <= x) { WriteUnmanaged(VarIntCodes.SByte, (SByte)x); } else if (short.MinValue <= x) { WriteUnmanaged(VarIntCodes.Int16, (Int16)x); } else if (int.MinValue <= x) { WriteUnmanaged(VarIntCodes.Int32, (Int32)x); } else { WriteUnmanaged(VarIntCodes.Int64, (Int64)x); } } } } public ref partial struct MemoryPackReader { public byte ReadVarIntByte() { ReadUnmanaged(out sbyte typeCode); switch (typeCode) { case VarIntCodes.Byte: return ReadUnmanaged(); case VarIntCodes.SByte: return checked((byte)ReadUnmanaged()); case VarIntCodes.UInt16: return checked((byte)ReadUnmanaged()); case VarIntCodes.Int16: return checked((byte)ReadUnmanaged()); case VarIntCodes.UInt32: return checked((byte)ReadUnmanaged()); case VarIntCodes.Int32: return checked((byte)ReadUnmanaged()); case VarIntCodes.UInt64: return checked((byte)ReadUnmanaged()); case VarIntCodes.Int64: return checked((byte)ReadUnmanaged()); default: return checked((byte)typeCode); } } public sbyte ReadVarIntSByte() { ReadUnmanaged(out sbyte typeCode); switch (typeCode) { case VarIntCodes.Byte: return checked((sbyte)ReadUnmanaged()); case VarIntCodes.SByte: return ReadUnmanaged(); case VarIntCodes.UInt16: return checked((sbyte)ReadUnmanaged()); case VarIntCodes.Int16: return checked((sbyte)ReadUnmanaged()); case VarIntCodes.UInt32: return checked((sbyte)ReadUnmanaged()); case VarIntCodes.Int32: return checked((sbyte)ReadUnmanaged()); case VarIntCodes.UInt64: return checked((sbyte)ReadUnmanaged()); case VarIntCodes.Int64: return checked((sbyte)ReadUnmanaged()); default: return typeCode; } } public ushort ReadVarIntUInt16() { ReadUnmanaged(out sbyte typeCode); switch (typeCode) { case VarIntCodes.Byte: return ReadUnmanaged(); case VarIntCodes.SByte: return checked((ushort)ReadUnmanaged()); case VarIntCodes.UInt16: return ReadUnmanaged(); case VarIntCodes.Int16: return checked((ushort)ReadUnmanaged()); case VarIntCodes.UInt32: return checked((ushort)ReadUnmanaged()); case VarIntCodes.Int32: return checked((ushort)ReadUnmanaged()); case VarIntCodes.UInt64: return checked((ushort)ReadUnmanaged()); case VarIntCodes.Int64: return checked((ushort)ReadUnmanaged()); default: return checked((ushort)typeCode); } } public short ReadVarIntInt16() { ReadUnmanaged(out sbyte typeCode); switch (typeCode) { case VarIntCodes.Byte: return ReadUnmanaged(); case VarIntCodes.SByte: return ReadUnmanaged(); case VarIntCodes.UInt16: return checked((short)ReadUnmanaged()); case VarIntCodes.Int16: return ReadUnmanaged(); case VarIntCodes.UInt32: return checked((short)ReadUnmanaged()); case VarIntCodes.Int32: return checked((short)ReadUnmanaged()); case VarIntCodes.UInt64: return checked((short)ReadUnmanaged()); case VarIntCodes.Int64: return checked((short)ReadUnmanaged()); default: return typeCode; } } public uint ReadVarIntUInt32() { ReadUnmanaged(out sbyte typeCode); switch (typeCode) { case VarIntCodes.Byte: return ReadUnmanaged(); case VarIntCodes.SByte: return checked((uint)ReadUnmanaged()); case VarIntCodes.UInt16: return ReadUnmanaged(); case VarIntCodes.Int16: return checked((uint)ReadUnmanaged()); case VarIntCodes.UInt32: return ReadUnmanaged(); case VarIntCodes.Int32: return checked((uint)ReadUnmanaged()); case VarIntCodes.UInt64: return checked((uint)ReadUnmanaged()); case VarIntCodes.Int64: return checked((uint)ReadUnmanaged()); default: return checked((uint)typeCode); } } public int ReadVarIntInt32() { ReadUnmanaged(out sbyte typeCode); switch (typeCode) { case VarIntCodes.Byte: return ReadUnmanaged(); case VarIntCodes.SByte: return ReadUnmanaged(); case VarIntCodes.UInt16: return ReadUnmanaged(); case VarIntCodes.Int16: return ReadUnmanaged(); case VarIntCodes.UInt32: return checked((int)ReadUnmanaged()); case VarIntCodes.Int32: return ReadUnmanaged(); case VarIntCodes.UInt64: return checked((int)ReadUnmanaged()); case VarIntCodes.Int64: return checked((int)ReadUnmanaged()); default: return typeCode; } } public ulong ReadVarIntUInt64() { ReadUnmanaged(out sbyte typeCode); switch (typeCode) { case VarIntCodes.Byte: return ReadUnmanaged(); case VarIntCodes.SByte: return checked((ulong)ReadUnmanaged()); case VarIntCodes.UInt16: return ReadUnmanaged(); case VarIntCodes.Int16: return checked((ulong)ReadUnmanaged()); case VarIntCodes.UInt32: return ReadUnmanaged(); case VarIntCodes.Int32: return checked((ulong)ReadUnmanaged()); case VarIntCodes.UInt64: return ReadUnmanaged(); case VarIntCodes.Int64: return checked((ulong)ReadUnmanaged()); default: return checked((ulong)typeCode); } } public long ReadVarIntInt64() { ReadUnmanaged(out sbyte typeCode); switch (typeCode) { case VarIntCodes.Byte: return ReadUnmanaged(); case VarIntCodes.SByte: return ReadUnmanaged(); case VarIntCodes.UInt16: return ReadUnmanaged(); case VarIntCodes.Int16: return ReadUnmanaged(); case VarIntCodes.UInt32: return ReadUnmanaged(); case VarIntCodes.Int32: return ReadUnmanaged(); case VarIntCodes.UInt64: return checked((long)ReadUnmanaged()); case VarIntCodes.Int64: return ReadUnmanaged(); default: return typeCode; } } } }