Skip to content

Instantly share code, notes, and snippets.

@ArvidSilverlock
Created March 22, 2024 08:30
Show Gist options
  • Select an option

  • Save ArvidSilverlock/4b8137b6d7268da14941e50c8b2528a6 to your computer and use it in GitHub Desktop.

Select an option

Save ArvidSilverlock/4b8137b6d7268da14941e50c8b2528a6 to your computer and use it in GitHub Desktop.
Runtime Fast Bitbuffer
local Reader = {}
Reader.__index = Reader
local function nextChunk(reader, width)
local value
if width > 24 then
reader._chunk += buffer.readu32(reader._buffer, reader._byte) * 2^reader._bit
reader._byte += 4
reader._bit += 32
elseif width > 16 then
reader._chunk += ( buffer.readu8(reader._buffer, reader._byte)
+ buffer.readu16(reader._buffer, reader._byte + 1) * 2^8 ) * 2^reader._bit
reader._byte += 3
reader._bit += 24
elseif width > 8 then
reader._chunk += buffer.readu16(reader._buffer, reader._byte) * 2^reader._bit
reader._byte += 2
reader._bit += 16
else
reader._chunk += buffer.readu8(reader._buffer, reader._byte) * 2^reader._bit
reader._byte += 1
reader._bit += 8
end
end
function Reader.new(b: buffer)
return setmetatable({
_buffer = b,
_byte = 0,
_bit = 0,
_chunk = 0
}, Reader)
end
function Reader:UInt(width: number): number
if self._bit < width then
nextChunk(self, width - self._bit)
end
local value = self._chunk % 2^width
self._chunk //= 2^width
self._bit -= width
return value
end
return Reader
local Writer = {}
Writer.__index = Writer
local function depositChunk32(writer)
buffer.writeu32(writer._buffer, writer._byte, writer._chunk)
writer._chunk //= 2^32
writer._byte += 4
writer._bit -= 32
end
local function depositChunk(writer)
if writer._bit > 32 then
depositChunk32(writer)
elseif writer._bit > 24 then
buffer.writeu8(writer._buffer, writer._byte, writer._chunk)
buffer.writeu16(writer._buffer, writer._byte + 1, writer._chunk // 2^8)
writer._chunk //= 2^24
writer._byte += 3
writer._bit -= 24
elseif writer._bit > 16 then
buffer.writeu16(writer._buffer, writer._byte, writer._chunk)
writer._chunk //= 2^16
writer._byte += 2
writer._bit -= 16
else
buffer.writeu8(writer._buffer, writer._byte, writer._chunk)
writer._chunk //= 2^8
writer._byte += 1
writer._bit -= 8
end
end
function Writer.new(b: buffer)
return setmetatable({
_buffer = b,
_byte = 0,
_bit = 0,
_chunk = 0
}, Writer)
end
function Writer:UInt(value: number, width: number)
local nextBit = self._bit + width
if nextBit > 53 then
depositChunk(self)
nextBit = self._bit + width
end
self._chunk += value * 2^self._bit
self._bit = nextBit
end
function Writer:Close()
while self._bit > 0 do
depositChunk(self)
end
end
return Writer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment