simple_bytes/
cursor.rs

1
2use crate::{
3	BytesRead, ReadError,
4	BytesWrite, WriteError,
5	BytesSeek, SeekError, Bytes
6};
7use crate::util::{io_eof, seek_from_to_n_pos, write_or_alloc};
8
9use std::io;
10
11/// A generic struct implementing BytesRead, BytesWrite and BytesSeek
12/// for different types.
13/// 
14/// In the background Bytes, BytesMut and
15/// BytesOwned use this.
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17pub struct Cursor<T> {
18	/// always points to the next position
19	position: usize,
20	inner: T
21}
22
23impl<T> Cursor<T> {
24	/// Creates a new Cursor.
25	pub fn new(inner: T) -> Self {
26		Self {
27			position: 0,
28			inner
29		}
30	}
31
32	/// Returns the inner value as a reference.
33	pub fn inner(&self) -> &T {
34		&self.inner
35	}
36
37	/// Returns the inner value as a mutable reference.
38	/// Shrinking the inner len may lead to panics when reading
39	/// or writing.
40	pub fn inner_mut(&mut self) -> &mut T {
41		&mut self.inner
42	}
43
44	/// Returns the inner value, discarding how many bytes
45	/// were read or written.
46	pub fn into_inner(self) -> T {
47		self.inner
48	}
49}
50
51impl<T> BytesRead for Cursor<T>
52where T: AsRef<[u8]> {
53	#[inline]
54	fn as_slice(&self) -> &[u8] {
55		self.inner.as_ref()
56	}
57
58	#[inline]
59	fn remaining(&self) -> &[u8] {
60		&self.as_slice()[self.position..]
61	}
62
63	#[inline]
64	fn try_read(&mut self, len: usize) -> Result<&[u8], ReadError> {
65		let slice = &self.inner.as_ref()[self.position..].get(..len)
66			.ok_or(ReadError)?;
67		self.position += len;
68
69		Ok(slice)
70	}
71
72	fn peek(&self, len: usize) -> Option<&[u8]> {
73		self.remaining().get(..len)
74	}
75}
76
77impl<T> io::Read for Cursor<T>
78where T: AsRef<[u8]> {
79	fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
80		let len = buf.len().min(self.remaining().len());
81		buf[..len].copy_from_slice(BytesRead::read(self, len));
82
83		Ok(len)
84	}
85}
86
87impl<'a> BytesSeek for Cursor<&'a [u8]> {
88	#[inline]
89	fn position(&self) -> usize {
90		self.position
91	}
92
93	/// Sets the internal position.
94	/// 
95	/// ## Fails
96	/// If the position exceeds the slice.
97	fn try_seek(&mut self, pos: usize) -> Result<(), SeekError> {
98		let len = self.inner.len();
99		if self.position + len >= pos {
100			self.position = pos;
101			Ok(())
102		} else {
103			Err(SeekError(len))
104		}
105	}
106}
107
108
109
110impl<'a> io::Seek for Cursor<&'a [u8]> {
111	fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
112		let n_pos = seek_from_to_n_pos(self.inner.len(), self.position, pos)?;
113
114		self.try_seek(n_pos)
115			.map(|_| n_pos as u64)
116			.map_err(io_eof)
117	}
118}
119
120
121impl<'a> BytesWrite for Cursor<&'a mut [u8]> {
122	fn as_mut(&mut self) -> &mut [u8] {
123		self.inner
124	}
125
126	fn as_bytes(&self) -> Bytes<'_> {
127		Bytes::new(0, &*self.inner)
128	}
129
130	fn remaining_mut(&mut self) -> &mut [u8] {
131		&mut self.inner[self.position..]
132	}
133
134	fn try_write(&mut self, slice: impl AsRef<[u8]>) -> Result<(), WriteError> {
135		let slice = slice.as_ref();
136		self.remaining_mut().get_mut(..slice.len())
137			.ok_or(WriteError)?
138			.copy_from_slice(slice);
139		self.position += slice.len();
140
141		Ok(())
142	}
143}
144
145impl<'a> io::Write for Cursor<&'a mut [u8]> {
146	fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
147		self.try_write(buf)
148			.map_err(io_eof)?;
149		Ok(buf.len())
150	}
151
152	fn flush(&mut self) -> io::Result<()> {
153		Ok(())
154	}
155}
156
157impl<'a> BytesSeek for Cursor<&'a mut [u8]> {
158	fn position(&self) -> usize {
159		self.position
160	}
161
162	/// Sets the internal position.
163	/// 
164	/// ## Fails
165	/// If the position exceeds the slice.
166	fn try_seek(&mut self, pos: usize) -> Result<(), SeekError> {
167		let len = self.inner.len();
168		if self.position + len >= pos {
169			self.position = pos;
170			Ok(())
171		} else {
172			Err(SeekError(len))
173		}
174	}
175}
176
177impl<'a> io::Seek for Cursor<&'a mut [u8]> {
178	fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
179		let n_pos = seek_from_to_n_pos(self.inner.len(), self.position, pos)?;
180
181		self.try_seek(n_pos)
182			.map(|_| n_pos as u64)
183			.map_err(io_eof)
184	}
185}
186
187
188impl<const L: usize> BytesWrite for Cursor<[u8; L]> {
189	fn as_mut(&mut self) -> &mut [u8] {
190		&mut self.inner
191	}
192
193	fn as_bytes(&self) -> Bytes<'_> {
194		Bytes::new(0, &self.inner)
195	}
196
197	fn remaining_mut(&mut self) -> &mut [u8] {
198		&mut self.inner[self.position..]
199	}
200
201	fn try_write(&mut self, slice: impl AsRef<[u8]>) -> Result<(), WriteError> {
202		let slice = slice.as_ref();
203		self.remaining_mut().get_mut(..slice.len())
204			.ok_or(WriteError)?
205			.copy_from_slice(slice);
206		self.position += slice.len();
207
208		Ok(())
209	}
210}
211
212impl<const L: usize> io::Write for Cursor<[u8; L]> {
213	fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
214		self.try_write(buf)
215			.map_err(io_eof)?;
216		Ok(buf.len())
217	}
218
219	fn flush(&mut self) -> io::Result<()> {
220		Ok(())
221	}
222}
223
224impl<const L: usize> BytesSeek for Cursor<[u8; L]> {
225	fn position(&self) -> usize {
226		self.position
227	}
228
229	/// Sets the internal position.
230	/// 
231	/// ## Fails
232	/// If the position exceeds the slice.
233	fn try_seek(&mut self, pos: usize) -> Result<(), SeekError> {
234		let len = self.inner.len();
235		if self.position + len >= pos {
236			self.position = pos;
237			Ok(())
238		} else {
239			Err(SeekError(len))
240		}
241	}
242}
243
244impl<const L: usize> io::Seek for Cursor<[u8; L]> {
245	fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
246		let n_pos = seek_from_to_n_pos(self.inner.len(), self.position, pos)?;
247
248		self.try_seek(n_pos)
249			.map(|_| n_pos as u64)
250			.map_err(io_eof)
251	}
252}
253
254
255impl BytesWrite for Cursor<&mut Vec<u8>> {
256	fn as_mut(&mut self) -> &mut [u8] {
257		&mut self.inner
258	}
259
260	fn as_bytes(&self) -> Bytes<'_> {
261		Bytes::new(0, &self.inner)
262	}
263
264	/// Returns the remaining mutable slice.
265	/// 
266	/// If an empty slice is returned, this does not mean
267	/// you can't write anymore.
268	fn remaining_mut(&mut self) -> &mut [u8] {
269		&mut self.inner[self.position..]
270	}
271
272	/// Write a slice. Allocates more space if the slice is
273	/// bigger than the `Vec`.
274	fn try_write(&mut self, slice: impl AsRef<[u8]>) -> Result<(), WriteError> {
275		self.position = write_or_alloc(
276			self.inner,
277			self.position,
278			slice.as_ref()
279		);
280
281		Ok(())
282	}
283}
284
285impl io::Write for Cursor<&mut Vec<u8>> {
286	fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
287		self.try_write(buf)
288			.map_err(io_eof)?;
289		Ok(buf.len())
290	}
291
292	fn flush(&mut self) -> io::Result<()> {
293		Ok(())
294	}
295}
296
297impl BytesSeek for Cursor<&mut Vec<u8>> {
298	fn position(&self) -> usize {
299		self.position
300	}
301
302	/// Sets the internal position, allocating more space
303	/// if the position is bigger than the `Vec`.
304	fn try_seek(&mut self, pos: usize) -> Result<(), SeekError> {
305		self.position = pos;
306		let n_len = self.position;
307		if self.inner.len() < n_len {
308			self.inner.resize(n_len, 0u8);
309		}
310
311		Ok(())
312	}
313}
314
315impl io::Seek for Cursor<&mut Vec<u8>> {
316	fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
317		let n_pos = seek_from_to_n_pos(self.inner.len(), self.position, pos)?;
318
319		self.try_seek(n_pos)
320			.map(|_| n_pos as u64)
321			.map_err(io_eof)
322	}
323}
324
325
326impl BytesWrite for Cursor<Vec<u8>> {
327	fn as_mut(&mut self) -> &mut [u8] {
328		&mut self.inner
329	}
330
331	fn as_bytes(&self) -> Bytes<'_> {
332		Bytes::new(0, &self.inner)
333	}
334
335	/// Returns the remaining mutable slice.
336	/// 
337	/// If an empty slice is returned, this does not mean
338	/// you can't write anymore.
339	fn remaining_mut(&mut self) -> &mut [u8] {
340		&mut self.inner[self.position..]
341	}
342
343	/// Write a slice. Allocates more space if the slice is
344	/// bigger than the `Vec`.
345	fn try_write(&mut self, slice: impl AsRef<[u8]>) -> Result<(), WriteError> {
346		self.position = write_or_alloc(
347			&mut self.inner,
348			self.position,
349			slice.as_ref()
350		);
351
352		Ok(())
353	}
354}
355
356impl io::Write for Cursor<Vec<u8>> {
357	fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
358		self.try_write(buf)
359			.map_err(io_eof)?;
360		Ok(buf.len())
361	}
362
363	fn flush(&mut self) -> io::Result<()> {
364		Ok(())
365	}
366}
367
368impl BytesSeek for Cursor<Vec<u8>> {
369	fn position(&self) -> usize {
370		self.position
371	}
372
373	/// Sets the internal position, allocating more space
374	/// if the position is bigger than the `Vec`.
375	fn try_seek(&mut self, pos: usize) -> Result<(), SeekError> {
376		self.position = pos;
377		let n_len = self.position;
378		if self.inner.len() < n_len {
379			self.inner.resize(n_len, 0u8);
380		}
381
382		Ok(())
383	}
384}
385
386impl io::Seek for Cursor<Vec<u8>> {
387	fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
388		let n_pos = seek_from_to_n_pos(self.inner.len(), self.position, pos)?;
389
390		self.try_seek(n_pos)
391			.map(|_| n_pos as u64)
392			.map_err(io_eof)
393	}
394}