zune_core/bytestream/reader/
no_std_readers.rs1use crate::bytestream::reader::{ZByteIoError, ZSeekFrom};
2use crate::bytestream::ZByteReaderTrait;
3pub struct ZCursor<T: AsRef<[u8]>> {
9 stream: T,
10 position: usize
11}
12
13impl<T: AsRef<[u8]>> ZCursor<T> {
14 pub fn new(buffer: T) -> ZCursor<T> {
15 ZCursor {
16 stream: buffer,
17 position: 0
18 }
19 }
20}
21
22impl<T: AsRef<[u8]>> ZCursor<T> {
23 #[inline]
30 pub fn skip(&mut self, num: usize) {
31 self.position = self.position.wrapping_add(num);
33 }
34 #[inline]
40 pub fn rewind(&mut self, num: usize) {
41 self.position = self.position.saturating_sub(num);
42 }
43}
44
45impl<T: AsRef<[u8]>> ZByteReaderTrait for ZCursor<T> {
46 #[inline(always)]
47 fn read_byte_no_error(&mut self) -> u8 {
48 let byte = self.stream.as_ref().get(self.position).unwrap_or(&0);
49 self.position += 1;
50 *byte
51 }
52 #[inline(always)]
53 fn read_exact_bytes(&mut self, buf: &mut [u8]) -> Result<(), ZByteIoError> {
54 let bytes_read = self.read_bytes(buf)?;
55 if bytes_read != buf.len() {
56 self.rewind(bytes_read);
58 return Err(ZByteIoError::NotEnoughBytes(bytes_read, buf.len()));
60 }
61 Ok(())
62 }
63
64 fn read_const_bytes<const N: usize>(&mut self, buf: &mut [u8; N]) -> Result<(), ZByteIoError> {
65 if self.position + N <= self.stream.as_ref().len() {
66 let reference = self.stream.as_ref();
68 let position = self.position;
69 if let Some(buf_ref) = reference.get(position..position + N) {
70 self.position += N;
71 buf.copy_from_slice(buf_ref);
72 return Ok(());
73 }
74 }
75 Err(ZByteIoError::Generic("Cannot satisfy read"))
76 }
77
78 fn read_const_bytes_no_error<const N: usize>(&mut self, buf: &mut [u8; N]) {
79 if self.position + N <= self.stream.as_ref().len() {
80 let reference = self.stream.as_ref();
82 let position = self.position;
83 if let Some(buf_ref) = reference.get(position..position + N) {
84 self.position += N;
85 buf.copy_from_slice(buf_ref);
86 }
87 }
88 }
89
90 #[inline(always)]
91 fn read_bytes(&mut self, buf: &mut [u8]) -> Result<usize, ZByteIoError> {
92 let len = self.peek_bytes(buf)?;
93 self.skip(len);
94 Ok(len)
95 }
96
97 #[inline(always)]
98 fn peek_bytes(&mut self, buf: &mut [u8]) -> Result<usize, ZByteIoError> {
99 let stream_end = self.stream.as_ref().len();
100
101 let start = core::cmp::min(self.position, stream_end);
102 let end = core::cmp::min(self.position + buf.len(), stream_end);
103
104 let slice = self.stream.as_ref().get(start..end).unwrap();
105 buf[..slice.len()].copy_from_slice(slice);
106 let len = slice.len();
107
108 Ok(len)
109 }
110
111 #[inline(always)]
112 fn peek_exact_bytes(&mut self, buf: &mut [u8]) -> Result<(), ZByteIoError> {
113 self.read_exact_bytes(buf)?;
114 self.rewind(buf.len());
115 Ok(())
116 }
117
118 #[inline(always)]
119 fn z_seek(&mut self, from: ZSeekFrom) -> Result<u64, ZByteIoError> {
120 let (base_pos, offset) = match from {
121 ZSeekFrom::Start(n) => {
122 self.position = n as usize;
123 return Ok(n);
124 }
125 ZSeekFrom::End(n) => (self.stream.as_ref().len(), n as isize),
126 ZSeekFrom::Current(n) => (self.position, n as isize)
127 };
128 match base_pos.checked_add_signed(offset) {
129 Some(n) => {
130 self.position = n;
131 Ok(self.position as u64)
132 }
133 None => Err(ZByteIoError::SeekError("Negative seek"))
134 }
135 }
136
137 #[inline(always)]
138 fn is_eof(&mut self) -> Result<bool, ZByteIoError> {
139 Ok(self.position >= self.stream.as_ref().len())
140 }
141 #[inline(always)]
142 fn z_position(&mut self) -> Result<u64, ZByteIoError> {
143 Ok(self.position as u64)
144 }
145
146 fn read_remaining(&mut self, sink: &mut alloc::vec::Vec<u8>) -> Result<usize, ZByteIoError> {
147 let start = self.position;
148 let end = self.stream.as_ref().len();
149 match self.stream.as_ref().get(start..end) {
150 None => {
151 return Err(ZByteIoError::Generic(
152 "Somehow read remaining couldn't satisfy it's invariants"
153 ))
154 }
155 Some(e) => {
156 sink.extend_from_slice(e);
157 }
158 }
159 self.skip(end - start);
160 Ok(end - start)
161 }
162}
163
164#[cfg(feature = "std")]
165impl<T: AsRef<[u8]>> std::io::Seek for ZCursor<T> {
166 fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
167 let (base_pos, offset) = match pos {
168 std::io::SeekFrom::Start(n) => {
169 self.position = n as usize;
170 return Ok(n);
171 }
172 std::io::SeekFrom::End(n) => (self.stream.as_ref().len(), n as isize),
173 std::io::SeekFrom::Current(n) => (self.position, n as isize)
174 };
175 match base_pos.checked_add_signed(offset) {
176 Some(n) => {
177 self.position = n;
178 Ok(self.position as u64)
179 }
180 None => Err(std::io::Error::new(
181 std::io::ErrorKind::Other,
182 "Negative seek"
183 ))
184 }
185 }
186}
187impl<T: AsRef<[u8]>> From<T> for ZCursor<T> {
195 fn from(value: T) -> Self {
196 ZCursor::new(value)
197 }
198}