public static void Main()
var bufferData = NetBuffer.Create(32);
NetBuffer.AddUShort(ref bufferData, 23);
var val = NetBuffer.ReadUShort(ref bufferData);
public struct NetBufferData
private const int defaultCapacity = 375;
private const int stringLengthBits = 8;
private const int stringLengthMax = (1 << stringLengthBits) - 1;
private const int bitsASCII = 7;
private const int growFactor = 2;
private const int minGrow = 1;
public static NetBufferData Create(ushort id, int capacity = defaultCapacity)
return new NetBufferData()
chunks = new uint[capacity]
public static void AddUShort(ref NetBufferData data, ushort value)
AddUInt(ref data, value);
public static void AddUInt(ref NetBufferData data, uint value)
Add(ref data, 8, buffer);
public static void Add(ref NetBufferData data, int numBits, uint value)
int index = data.nextPosition >> 5;
int used = data.nextPosition & 0x0000001F;
ulong chunkMask = ((1UL << used) - 1);
ulong scratch = data.chunks[index] & chunkMask;
ulong result = scratch | ((ulong)value << used);
data.chunks[index] = (uint)result;
data.chunks[index + 1] = (uint)(result >> 32);
data.nextPosition += numBits;
public static ushort ReadUShort(ref NetBufferData data)
return (ushort)ReadUInt(ref data);
public static uint ReadUInt(ref NetBufferData data)
buffer = Read(ref data, 8);
value |= (buffer & 0x7Fu) << shift;
while ((buffer & 0x80u) > 0);
public static uint Read(ref NetBufferData data, int numBits)
uint result = Peek(ref data, numBits);
data.readPosition += numBits;
public static uint Peek(ref NetBufferData data, int numBits)
int index = data.readPosition >> 5;
int used = data.readPosition & 0x0000001F;
ulong chunkMask = ((1UL << numBits) - 1) << used;
ulong scratch = (ulong)data.chunks[index];
if ((index + 1) < data.chunks.Length)
scratch |= (ulong)data.chunks[index + 1] << 32;
ulong result = (scratch & chunkMask) >> used;