xref: /aosp_15_r20/external/crosvm/rutabaga_gfx/src/bytestream/mod.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2024 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker use std::io::BufRead;
6*bb4ee6a4SAndroid Build Coastguard Worker use std::io::Error as IoError;
7*bb4ee6a4SAndroid Build Coastguard Worker use std::io::ErrorKind as IoErrorKind;
8*bb4ee6a4SAndroid Build Coastguard Worker use std::io::Read;
9*bb4ee6a4SAndroid Build Coastguard Worker use std::io::Result as IoResult;
10*bb4ee6a4SAndroid Build Coastguard Worker use std::mem::size_of;
11*bb4ee6a4SAndroid Build Coastguard Worker 
12*bb4ee6a4SAndroid Build Coastguard Worker use zerocopy::AsBytes;
13*bb4ee6a4SAndroid Build Coastguard Worker use zerocopy::FromBytes;
14*bb4ee6a4SAndroid Build Coastguard Worker 
15*bb4ee6a4SAndroid Build Coastguard Worker pub struct Reader<'slice> {
16*bb4ee6a4SAndroid Build Coastguard Worker     data: &'slice [u8],
17*bb4ee6a4SAndroid Build Coastguard Worker }
18*bb4ee6a4SAndroid Build Coastguard Worker 
19*bb4ee6a4SAndroid Build Coastguard Worker impl<'slice> Reader<'slice> {
20*bb4ee6a4SAndroid Build Coastguard Worker     /// Construct a new Reader wrapper over `data`.
new(data: &[u8]) -> Reader21*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new(data: &[u8]) -> Reader {
22*bb4ee6a4SAndroid Build Coastguard Worker         Reader { data }
23*bb4ee6a4SAndroid Build Coastguard Worker     }
24*bb4ee6a4SAndroid Build Coastguard Worker 
25*bb4ee6a4SAndroid Build Coastguard Worker     /// Reads and consumes an object from the buffer.
read_obj<T: FromBytes>(&mut self) -> IoResult<T>26*bb4ee6a4SAndroid Build Coastguard Worker     pub fn read_obj<T: FromBytes>(&mut self) -> IoResult<T> {
27*bb4ee6a4SAndroid Build Coastguard Worker         let obj = <T>::read_from_prefix(self.data.as_bytes())
28*bb4ee6a4SAndroid Build Coastguard Worker             .ok_or(IoError::from(IoErrorKind::UnexpectedEof))?;
29*bb4ee6a4SAndroid Build Coastguard Worker         self.consume(size_of::<T>());
30*bb4ee6a4SAndroid Build Coastguard Worker         Ok(obj)
31*bb4ee6a4SAndroid Build Coastguard Worker     }
32*bb4ee6a4SAndroid Build Coastguard Worker 
33*bb4ee6a4SAndroid Build Coastguard Worker     #[allow(dead_code)]
read(&mut self, buf: &mut [u8]) -> IoResult<usize>34*bb4ee6a4SAndroid Build Coastguard Worker     fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
35*bb4ee6a4SAndroid Build Coastguard Worker         self.data.read(buf)
36*bb4ee6a4SAndroid Build Coastguard Worker     }
37*bb4ee6a4SAndroid Build Coastguard Worker 
available_bytes(&self) -> usize38*bb4ee6a4SAndroid Build Coastguard Worker     pub fn available_bytes(&self) -> usize {
39*bb4ee6a4SAndroid Build Coastguard Worker         self.data.len()
40*bb4ee6a4SAndroid Build Coastguard Worker     }
41*bb4ee6a4SAndroid Build Coastguard Worker 
42*bb4ee6a4SAndroid Build Coastguard Worker     /// Reads an object from the buffer without consuming it.
peek_obj<T: FromBytes>(&self) -> IoResult<T>43*bb4ee6a4SAndroid Build Coastguard Worker     pub fn peek_obj<T: FromBytes>(&self) -> IoResult<T> {
44*bb4ee6a4SAndroid Build Coastguard Worker         let obj = <T>::read_from_prefix(self.data.as_bytes())
45*bb4ee6a4SAndroid Build Coastguard Worker             .ok_or(IoError::from(IoErrorKind::UnexpectedEof))?;
46*bb4ee6a4SAndroid Build Coastguard Worker         Ok(obj)
47*bb4ee6a4SAndroid Build Coastguard Worker     }
48*bb4ee6a4SAndroid Build Coastguard Worker 
read_exact(&mut self, buf: &mut [u8]) -> IoResult<()>49*bb4ee6a4SAndroid Build Coastguard Worker     pub fn read_exact(&mut self, buf: &mut [u8]) -> IoResult<()> {
50*bb4ee6a4SAndroid Build Coastguard Worker         self.data.read_exact(buf)
51*bb4ee6a4SAndroid Build Coastguard Worker     }
52*bb4ee6a4SAndroid Build Coastguard Worker 
53*bb4ee6a4SAndroid Build Coastguard Worker     /// Consumes `amt` bytes from the underlying buffer. If `amt` is larger than the
54*bb4ee6a4SAndroid Build Coastguard Worker     /// remaining data left in this `Reader`, then all remaining data will be consumed.
consume(&mut self, amt: usize)55*bb4ee6a4SAndroid Build Coastguard Worker     pub fn consume(&mut self, amt: usize) {
56*bb4ee6a4SAndroid Build Coastguard Worker         self.data.consume(amt);
57*bb4ee6a4SAndroid Build Coastguard Worker     }
58*bb4ee6a4SAndroid Build Coastguard Worker }
59*bb4ee6a4SAndroid Build Coastguard Worker 
60*bb4ee6a4SAndroid Build Coastguard Worker pub struct Writer<'slice> {
61*bb4ee6a4SAndroid Build Coastguard Worker     data: &'slice mut [u8],
62*bb4ee6a4SAndroid Build Coastguard Worker     index: usize,
63*bb4ee6a4SAndroid Build Coastguard Worker }
64*bb4ee6a4SAndroid Build Coastguard Worker 
65*bb4ee6a4SAndroid Build Coastguard Worker impl<'slice> Writer<'slice> {
new(data: &mut [u8]) -> Writer66*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new(data: &mut [u8]) -> Writer {
67*bb4ee6a4SAndroid Build Coastguard Worker         Writer { data, index: 0 }
68*bb4ee6a4SAndroid Build Coastguard Worker     }
69*bb4ee6a4SAndroid Build Coastguard Worker 
70*bb4ee6a4SAndroid Build Coastguard Worker     /// Writes an object to the buffer.
write_obj<T: FromBytes + AsBytes>(&mut self, val: T) -> IoResult<()>71*bb4ee6a4SAndroid Build Coastguard Worker     pub fn write_obj<T: FromBytes + AsBytes>(&mut self, val: T) -> IoResult<()> {
72*bb4ee6a4SAndroid Build Coastguard Worker         self.write_all(val.as_bytes())
73*bb4ee6a4SAndroid Build Coastguard Worker     }
74*bb4ee6a4SAndroid Build Coastguard Worker 
write_all(&mut self, buf: &[u8]) -> IoResult<()>75*bb4ee6a4SAndroid Build Coastguard Worker     pub fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
76*bb4ee6a4SAndroid Build Coastguard Worker         let new_index = self.index + buf.len();
77*bb4ee6a4SAndroid Build Coastguard Worker 
78*bb4ee6a4SAndroid Build Coastguard Worker         if new_index >= self.data.len() {
79*bb4ee6a4SAndroid Build Coastguard Worker             return Err(IoError::from(IoErrorKind::UnexpectedEof));
80*bb4ee6a4SAndroid Build Coastguard Worker         }
81*bb4ee6a4SAndroid Build Coastguard Worker 
82*bb4ee6a4SAndroid Build Coastguard Worker         self.data[self.index..new_index].copy_from_slice(buf);
83*bb4ee6a4SAndroid Build Coastguard Worker         self.index = new_index;
84*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
85*bb4ee6a4SAndroid Build Coastguard Worker     }
86*bb4ee6a4SAndroid Build Coastguard Worker 
bytes_written(&self) -> usize87*bb4ee6a4SAndroid Build Coastguard Worker     pub fn bytes_written(&self) -> usize {
88*bb4ee6a4SAndroid Build Coastguard Worker         self.index
89*bb4ee6a4SAndroid Build Coastguard Worker     }
90*bb4ee6a4SAndroid Build Coastguard Worker }
91