/rust/registry/src/index.crates.io-1949cf8c6b5b557f/mesa3d_util-0.1.75/bytestream/mod.rs
Line | Count | Source |
1 | | // Copyright 2025 Google |
2 | | // SPDX-License-Identifier: MIT |
3 | | |
4 | | use std::io::BufRead; |
5 | | use std::io::Error; |
6 | | use std::io::ErrorKind; |
7 | | use std::io::Read; |
8 | | use std::io::Result; |
9 | | use std::mem::size_of; |
10 | | |
11 | | use zerocopy::FromBytes; |
12 | | use zerocopy::Immutable; |
13 | | use zerocopy::IntoBytes; |
14 | | |
15 | | pub struct Reader<'slice> { |
16 | | data: &'slice [u8], |
17 | | } |
18 | | |
19 | | impl<'slice> Reader<'slice> { |
20 | | /// Construct a new Reader wrapper over `data`. |
21 | 0 | pub fn new(data: &[u8]) -> Reader<'_> { |
22 | 0 | Reader { data } |
23 | 0 | } |
24 | | |
25 | | /// Reads and consumes an object from the buffer. |
26 | 0 | pub fn read_obj<T: FromBytes>(&mut self) -> Result<T> { |
27 | 0 | let obj = <T>::read_from_prefix(self.data.as_bytes()) |
28 | 0 | .map_err(|_e| Error::from(ErrorKind::UnexpectedEof))?; |
29 | 0 | self.consume(size_of::<T>()); |
30 | 0 | Ok(obj.0) |
31 | 0 | } |
32 | | |
33 | | #[allow(dead_code)] |
34 | 0 | fn read(&mut self, buf: &mut [u8]) -> Result<usize> { |
35 | 0 | self.data.read(buf) |
36 | 0 | } |
37 | | |
38 | 0 | pub fn available_bytes(&self) -> usize { |
39 | 0 | self.data.len() |
40 | 0 | } |
41 | | |
42 | | /// Reads an object from the buffer without consuming it. |
43 | 0 | pub fn peek_obj<T: FromBytes>(&self) -> Result<T> { |
44 | 0 | let obj = <T>::read_from_prefix(self.data.as_bytes()) |
45 | 0 | .map_err(|_e| Error::from(ErrorKind::UnexpectedEof))?; |
46 | 0 | Ok(obj.0) |
47 | 0 | } |
48 | | |
49 | 0 | pub fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { |
50 | 0 | self.data.read_exact(buf) |
51 | 0 | } |
52 | | |
53 | | /// Consumes `amt` bytes from the underlying buffer. If `amt` is larger than the |
54 | | /// remaining data left in this `Reader`, then all remaining data will be consumed. |
55 | 0 | pub fn consume(&mut self, amt: usize) { |
56 | 0 | self.data.consume(amt); |
57 | 0 | } |
58 | | } |
59 | | |
60 | | pub struct Writer<'slice> { |
61 | | data: &'slice mut [u8], |
62 | | index: usize, |
63 | | } |
64 | | |
65 | | impl<'slice> Writer<'slice> { |
66 | 0 | pub fn new(data: &mut [u8]) -> Writer<'_> { |
67 | 0 | Writer { data, index: 0 } |
68 | 0 | } |
69 | | |
70 | | /// Writes an object to the buffer. |
71 | 0 | pub fn write_obj<T: FromBytes + IntoBytes + Immutable>(&mut self, val: T) -> Result<()> { |
72 | 0 | self.write_all(val.as_bytes()) |
73 | 0 | } |
74 | | |
75 | 0 | pub fn write_all(&mut self, buf: &[u8]) -> Result<()> { |
76 | 0 | let new_index = self.index + buf.len(); |
77 | | |
78 | 0 | let Some(data) = self.data.get_mut(self.index..new_index) else { |
79 | 0 | return Err(Error::from(ErrorKind::UnexpectedEof)); |
80 | | }; |
81 | | |
82 | 0 | data.copy_from_slice(buf); |
83 | 0 | self.index = new_index; |
84 | 0 | Ok(()) |
85 | 0 | } |
86 | | |
87 | 0 | pub fn bytes_written(&self) -> usize { |
88 | 0 | self.index |
89 | 0 | } |
90 | | } |