///|
priv struct BitWriter {
mut buf : FixedArray[Byte]
mut size : Int
mut pos : Int
mut bits : Int
mut nbits : Int
}
///|
fn BitWriter::new(capacity : Int) -> BitWriter {
{
buf: FixedArray::make(capacity, b'\x00'),
size: capacity,
pos: 0,
bits: 0,
nbits: 0,
}
}
///|
fn BitWriter::ensure_capacity(self : BitWriter, needed : Int) -> Unit {
if self.pos + needed >= self.size {
let new_size = (self.pos + needed) * 2
let new_buf : FixedArray[Byte] = FixedArray::make(new_size, b'\x00')
for i in 0.. Unit {
self.bits = self.bits | (value << self.nbits)
self.nbits += nbits
if self.nbits >= 8 {
if self.pos + 4 >= self.size {
self.ensure_capacity(4)
}
while self.nbits >= 8 {
self.buf[self.pos] = (self.bits & 0xff).to_byte()
self.pos += 1
self.bits = self.bits >> 8
self.nbits -= 8
}
}
}
///|
fn BitWriter::write_byte(self : BitWriter, b : Int) -> Unit {
self.write_bits(8, b & 0xff)
}
///|
fn BitWriter::align_byte(self : BitWriter) -> Unit {
if self.nbits > 0 {
self.ensure_capacity(1)
self.buf[self.pos] = (self.bits & 0xff).to_byte()
self.pos += 1
self.bits = 0
self.nbits = 0
}
}
///|
fn BitWriter::finish(self : BitWriter) -> Bytes {
self.align_byte()
Bytes::makei(self.pos, fn(i) { self.buf[i] })
}