///|
/// Binary writer for serialization - single buffer with grow-on-demand
pub struct BinaryWriter {
  mut buf : FixedArray[Byte]
  mut len : Int
}

///|
/// Create a new binary writer with initial capacity
pub fn BinaryWriter::new(capacity? : Int = 256) -> BinaryWriter {
  { buf: FixedArray::make(capacity, b'\x00'), len: 0 }
}

///|
/// Ensure capacity for additional bytes
fn BinaryWriter::ensure(self : BinaryWriter, extra : Int) -> Unit {
  let needed = self.len + extra
  if needed <= self.buf.length() {
    return
  }
  let mut new_cap = self.buf.length()
  while new_cap < needed {
    new_cap = new_cap * 2
  }
  let new_buf = FixedArray::make(new_cap, b'\x00')
  for i in 0.. Unit {
  self.ensure(4)
  write_u32_le(self.buf, self.len, value)
  self.len = self.len + 4
}

///|
/// Push an i32 value (little-endian)
pub fn BinaryWriter::push_i32(self : BinaryWriter, value : Int) -> Unit {
  self.push_u32(value.reinterpret_as_uint())
}

///|
/// Push a u64 value (little-endian)
pub fn BinaryWriter::push_u64(self : BinaryWriter, value : UInt64) -> Unit {
  self.ensure(8)
  write_u64_le(self.buf, self.len, value)
  self.len = self.len + 8
}

///|
/// Push an i64 value (little-endian)
pub fn BinaryWriter::push_i64(self : BinaryWriter, value : Int64) -> Unit {
  self.push_u64(value.reinterpret_as_uint64())
}

///|
/// Push a f64 value
pub fn BinaryWriter::push_f64(self : BinaryWriter, value : Double) -> Unit {
  self.push_u64(value.reinterpret_as_uint64())
}

///|
/// Push a f32 value (little-endian)
pub fn BinaryWriter::push_f32(self : BinaryWriter, value : Float) -> Unit {
  self.push_u32(value.reinterpret_as_uint())
}

///|
/// Push a single byte
pub fn BinaryWriter::push_byte(self : BinaryWriter, value : Byte) -> Unit {
  self.ensure(1)
  self.buf[self.len] = value
  self.len = self.len + 1
}

///|
/// Push raw bytes
pub fn BinaryWriter::push_bytes(self : BinaryWriter, data : Bytes) -> Unit {
  let n = data.length()
  self.ensure(n)
  for i in 0.. Bytes {
  Bytes::from_array(self.buf[:self.len])
}