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