rive_rs/core/
binary_reader.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::str;
6
7use crate::core::property::Writable;
8
9#[derive(Debug)]
10pub struct BinaryReader<'b> {
11    buffer: &'b [u8],
12}
13
14impl Iterator for BinaryReader<'_> {
15    type Item = u8;
16
17    fn next(&mut self) -> Option<Self::Item> {
18        let result = self.buffer.first().copied()?;
19        self.buffer = &self.buffer[1..];
20
21        Some(result)
22    }
23}
24
25impl<'b> BinaryReader<'b> {
26    pub fn new(buffer: &'b [u8]) -> Self {
27        Self { buffer }
28    }
29
30    pub fn reached_end(&self) -> bool {
31        self.buffer.is_empty()
32    }
33
34    pub fn read_bytes(&mut self, len: usize) -> Option<&[u8]> {
35        let slice = self.buffer.get(..len)?;
36        self.buffer = &self.buffer[len..];
37
38        Some(slice)
39    }
40
41    pub fn read_var_u64(&mut self) -> Option<u64> {
42        let mut result = 0;
43        let mut shift = 0;
44
45        loop {
46            let byte = self.next()?;
47
48            result |= ((byte & 0b0111_1111) as u64).checked_shl(shift)?;
49            shift += 7;
50
51            if byte & 0b1000_0000 == 0 {
52                break;
53            }
54        }
55
56        Some(result)
57    }
58
59    pub fn read_string(&mut self) -> Option<String> {
60        let len = self.read_var_u64()? as usize;
61        let slice = self.read_bytes(len)?;
62
63        str::from_utf8(slice).ok().map(str::to_string)
64    }
65
66    pub fn read_f32(&mut self) -> Option<f32> {
67        let array = self.read_bytes(4)?.try_into().ok()?;
68        Some(f32::from_le_bytes(array))
69    }
70
71    pub fn read_f64(&mut self) -> Option<f64> {
72        let array = self.read_bytes(8)?.try_into().ok()?;
73        Some(f64::from_le_bytes(array))
74    }
75
76    pub fn read_u8(&mut self) -> Option<u8> {
77        self.next()
78    }
79
80    pub fn read_u32(&mut self) -> Option<u32> {
81        let array = self.read_bytes(4)?.try_into().ok()?;
82        Some(u32::from_le_bytes(array))
83    }
84
85    pub fn write<W: Writable>(&mut self, property: &W) -> bool {
86        property.write(self).is_some()
87    }
88}