blob: 814bd48786e30b620b17dbd2a7126f5cf3386e55 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::str;
use crate::core::property::Writable;
#[derive(Debug)]
pub struct BinaryReader<'b> {
buffer: &'b [u8],
}
impl Iterator for BinaryReader<'_> {
type Item = u8;
fn next(&mut self) -> Option<Self::Item> {
let result = self.buffer.first().copied()?;
self.buffer = &self.buffer[1..];
Some(result)
}
}
impl<'b> BinaryReader<'b> {
pub fn new(buffer: &'b [u8]) -> Self {
Self { buffer }
}
pub fn reached_end(&self) -> bool {
self.buffer.is_empty()
}
pub fn read_bytes(&mut self, len: usize) -> Option<&[u8]> {
let slice = self.buffer.get(..len)?;
self.buffer = &self.buffer[len..];
Some(slice)
}
pub fn read_var_u64(&mut self) -> Option<u64> {
let mut result = 0;
let mut shift = 0;
loop {
let byte = self.next()?;
result |= ((byte & 0b0111_1111) as u64).checked_shl(shift)?;
shift += 7;
if byte & 0b1000_0000 == 0 {
break;
}
}
Some(result)
}
pub fn read_string(&mut self) -> Option<String> {
let len = self.read_var_u64()? as usize;
let slice = self.read_bytes(len)?;
str::from_utf8(slice).ok().map(str::to_string)
}
pub fn read_f32(&mut self) -> Option<f32> {
let array = self.read_bytes(4)?.try_into().ok()?;
Some(f32::from_le_bytes(array))
}
pub fn read_f64(&mut self) -> Option<f64> {
let array = self.read_bytes(8)?.try_into().ok()?;
Some(f64::from_le_bytes(array))
}
pub fn read_u8(&mut self) -> Option<u8> {
self.next()
}
pub fn read_u32(&mut self) -> Option<u32> {
let array = self.read_bytes(4)?.try_into().ok()?;
Some(u32::from_le_bytes(array))
}
pub fn write<W: Writable>(&mut self, property: &W) -> bool {
property.write(self).is_some()
}
}