use std::io;
use std::io::Write;
pub struct BinaryWriter<T: Write> {
output: T,
num_bytes_written: u64
}
impl<T> BinaryWriter<T>
where T: Write {
pub fn new(output: T) -> Self {
Self {
output,
num_bytes_written: 0
}
}
pub fn num_bytes_written(&self) -> u64 {
self.num_bytes_written
}
pub fn write_byte(&mut self, data: u8) -> io::Result<usize> {
self.write_bytes(&[data])
}
pub fn write_bytes(&mut self, data: &[u8]) -> io::Result<usize> {
self.num_bytes_written += data.len() as u64;
self.output.write(data)
}
pub fn write_7_bit_encoded_int(&mut self, data: i32) -> io::Result<usize> {
let mut value = data as u32;
let mut out_bytes: Vec<u8> = Vec::new();
while value > 0x7F {
let low_bits_and_flag: u8 = (value | !0x7F).to_le_bytes()[0];
value >>= 7;
out_bytes.push(low_bits_and_flag);
}
out_bytes.push(value.to_le_bytes()[0]);
self.write_bytes(&out_bytes)
}
pub fn write_7_bit_encoded_int64(&mut self, data: i64) -> io::Result<usize> {
let mut value = data as u64;
let mut out_bytes: Vec<u8> = Vec::new();
while value > 0x7F {
let low_bits_and_flag: u8 = (value | !0x7F).to_le_bytes()[0];
value >>= 7;
out_bytes.push(low_bits_and_flag);
}
out_bytes.push(value.to_le_bytes()[0]);
self.write_bytes(&out_bytes)
}
pub fn write_boolean(&mut self, data: bool) -> io::Result<usize> {
if data {
self.write_byte(1)
} else {
self.write_byte(0)
}
}
pub fn write_f32(&mut self, data: f32) -> io::Result<usize> {
self.write_bytes(&data.to_le_bytes())
}
pub fn write_f64(&mut self, data: f64) -> io::Result<usize> {
self.write_bytes(&data.to_le_bytes())
}
#[cfg_attr(docsrs, doc(cfg(feature = "f16")))]
#[cfg(feature = "f16")]
pub fn write_f16(&mut self, data: f16) -> io::Result<usize> {
self.write_bytes(&data.to_le_bytes())
}
pub fn write_string(&mut self, data: &str) -> io::Result<usize> {
if let Err(e) = self.write_7_bit_encoded_int(data.len().try_into().unwrap()) {
return Err(e)
}
self.write_bytes(data.as_bytes())
}
pub fn write_i8(&mut self, data: i8) -> io::Result<usize> {
self.write_bytes(&data.to_le_bytes())
}
pub fn write_i16(&mut self, data: i16) -> io::Result<usize> {
self.write_bytes(&data.to_le_bytes())
}
pub fn write_i32(&mut self, data: i32) -> io::Result<usize> {
self.write_bytes(&data.to_le_bytes())
}
pub fn write_i64(&mut self, data: i64) -> io::Result<usize> {
self.write_bytes(&data.to_le_bytes())
}
pub fn write_u16(&mut self, data: u16) -> io::Result<usize> {
self.write_bytes(&data.to_le_bytes())
}
pub fn write_u32(&mut self, data: u32) -> io::Result<usize> {
self.write_bytes(&data.to_le_bytes())
}
pub fn write_u64(&mut self, data: u64) -> io::Result<usize> {
self.write_bytes(&data.to_le_bytes())
}
pub fn write_char(&mut self, data: char) -> io::Result<usize> {
let mut buf: [u8; 4] = [0; 4];
self.write_bytes(data.encode_utf8(buf.as_mut_slice()).as_bytes())
}
}