Skip to main content

zune_core/bytestream/reader/
no_std_readers.rs

1#![allow(dead_code)]
2
3use crate::bytestream::{ZByteIoError, ZByteReaderTrait, ZSeekFrom};
4/// Wraps an in memory buffer providing it with a `Seek` method
5/// but works in `no_std` environments
6///
7/// `std::io::Cursor` is available in std environments, but we also need support
8/// for `no_std` environments so this serves as a drop in replacement
9pub struct ZCursor<T> {
10    pub(crate) stream:   T,
11    pub(crate) position: usize
12}
13
14impl<T: AsRef<[u8]>> ZCursor<T> {
15    pub fn new(buffer: T) -> ZCursor<T> {
16        ZCursor {
17            stream:   buffer,
18            position: 0
19        }
20    }
21}
22
23impl<T: AsRef<[u8]>> ZCursor<T> {
24    /// Move forward `num` bytes  from
25    /// the current position.
26    ///
27    /// It doesn't check that position overflowed, new position
28    /// may point past the internal buffer, all subsequent reads will
29    /// either return an error or zero depending on the method called
30    #[inline]
31    pub fn skip(&mut self, num: usize) {
32        // Can this overflow ??
33        self.position = self.position.wrapping_add(num);
34    }
35    /// Move back `num` bytes from the current position
36    ///
37    ///
38    /// This saturates at zero, it can never be negative or wraparound
39    /// when the value becomes too small
40    #[inline]
41    pub fn rewind(&mut self, num: usize) {
42        self.position = self.position.saturating_sub(num);
43    }
44
45    pub fn split(&self) -> (&[u8], &[u8]) {
46        let slice = self.stream.as_ref();
47        let pos = self.position.min(slice.len());
48        slice.split_at(pos)
49    }
50}
51
52impl<T: AsRef<[u8]>>  ZCursor<T> {
53    #[inline(always)]
54    pub (crate) fn read_byte_no_error_impl(&mut self) -> u8 {
55        let byte = self.stream.as_ref().get(self.position).unwrap_or(&0);
56        self.position += 1;
57        *byte
58    }
59    #[inline(always)]
60    pub (crate) fn read_exact_bytes_impl(&mut self, buf: &mut [u8]) -> Result<(), ZByteIoError> {
61        let bytes_read = self.read_bytes(buf)?;
62        if bytes_read != buf.len() {
63            // restore read to initial position it was in.
64            self.rewind(bytes_read);
65            // not all bytes were read.
66            return Err(ZByteIoError::NotEnoughBytes(bytes_read, buf.len()));
67        }
68        Ok(())
69    }
70
71    pub (crate) fn read_const_bytes_impl<const N: usize>(&mut self, buf: &mut [u8; N]) -> Result<(), ZByteIoError> {
72        if self.position + N <= self.stream.as_ref().len() {
73            // we are in bounds
74            let reference = self.stream.as_ref();
75            let position = self.position;
76            if let Some(buf_ref) = reference.get(position..position + N) {
77                self.position += N;
78                buf.copy_from_slice(buf_ref);
79                return Ok(());
80            }
81        }
82        Err(ZByteIoError::Generic("Cannot satisfy read"))
83    }
84
85    pub (crate) fn read_const_bytes_no_error_impl<const N: usize>(&mut self, buf: &mut [u8; N]) {
86        if self.position + N <= self.stream.as_ref().len() {
87            // we are in bounds
88            let reference = self.stream.as_ref();
89            let position = self.position;
90            if let Some(buf_ref) = reference.get(position..position + N) {
91                self.position += N;
92                buf.copy_from_slice(buf_ref);
93            }
94        }
95    }
96
97    #[inline(always)]
98  pub (crate) fn read_bytes_impl(&mut self, buf: &mut [u8]) -> Result<usize, ZByteIoError> {
99        let len = self.peek_bytes_impl(buf)?;
100        self.skip(len);
101        Ok(len)
102    }
103
104    #[inline(always)]
105    pub (crate) fn peek_bytes_impl(&mut self, buf: &mut [u8]) -> Result<usize, ZByteIoError> {
106        let stream_end = self.stream.as_ref().len();
107
108        let start = core::cmp::min(self.position, stream_end);
109        let end = core::cmp::min(self.position + buf.len(), stream_end);
110
111        let slice = self.stream.as_ref().get(start..end).unwrap();
112        buf[..slice.len()].copy_from_slice(slice);
113        let len = slice.len();
114
115        Ok(len)
116    }
117
118    #[inline(always)]
119    pub (crate) fn peek_exact_bytes_impl(&mut self, buf: &mut [u8]) -> Result<(), ZByteIoError> {
120        self.read_exact_bytes_impl(buf)?;
121        self.rewind(buf.len());
122        Ok(())
123    }
124
125    #[inline(always)]
126    pub (crate) fn z_seek_impl(&mut self, from: ZSeekFrom) -> Result<u64, ZByteIoError> {
127        let (base_pos, offset) = match from {
128            ZSeekFrom::Start(n) => {
129                self.position = n as usize;
130                return Ok(n);
131            }
132            ZSeekFrom::End(n) => (self.stream.as_ref().len(), n as isize),
133            ZSeekFrom::Current(n) => (self.position, n as isize)
134        };
135        match base_pos.checked_add_signed(offset) {
136            Some(n) => {
137                self.position = n;
138                Ok(self.position as u64)
139            }
140            None => Err(ZByteIoError::SeekError("Negative seek"))
141        }
142    }
143
144    #[inline(always)]
145    pub (crate) fn is_eof_impl(&mut self) -> Result<bool, ZByteIoError> {
146        Ok(self.position >= self.stream.as_ref().len())
147    }
148    #[inline(always)]
149    pub (crate) fn z_position_impl(&mut self) -> Result<u64, ZByteIoError> {
150        Ok(self.position as u64)
151    }
152
153    pub (crate) fn read_remaining_impl(&mut self, sink: &mut alloc::vec::Vec<u8>) -> Result<usize, ZByteIoError> {
154        let start = self.position;
155        let end = self.stream.as_ref().len();
156        match self.stream.as_ref().get(start..end) {
157            None => {
158                return Err(ZByteIoError::Generic(
159                    "Somehow read remaining couldn't satisfy it's invariants"
160                ))
161            }
162            Some(e) => {
163                sink.extend_from_slice(e);
164            }
165        }
166        self.skip(end - start);
167        Ok(end - start)
168    }
169}
170
171impl<T: AsRef<[u8]>> From<T> for ZCursor<T> {
172    fn from(value: T) -> Self {
173        ZCursor::new(value)
174    }
175}