Created
March 22, 2024 08:30
-
-
Save ArvidSilverlock/4b8137b6d7268da14941e50c8b2528a6 to your computer and use it in GitHub Desktop.
Runtime Fast Bitbuffer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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