1#[cfg(feature = "alloc")]
2use alloc::{boxed::Box, string::String, vec::Vec};
3use core::{cmp, io::BorrowedCursor};
4
5use crate::{BufRead, Error, IoBuf, IoBufMut, Read, Result, Seek, SeekFrom, Write};
6
7#[derive(Debug, Default, Eq, PartialEq)]
15pub struct Cursor<T> {
16 inner: T,
17 pos: u64,
18}
19
20impl<T> Cursor<T> {
21 pub const fn new(inner: T) -> Cursor<T> {
27 Cursor { pos: 0, inner }
28 }
29
30 pub fn into_inner(self) -> T {
32 self.inner
33 }
34
35 pub const fn get_ref(&self) -> &T {
37 &self.inner
38 }
39
40 pub const fn get_mut(&mut self) -> &mut T {
45 &mut self.inner
46 }
47
48 pub const fn position(&self) -> u64 {
50 self.pos
51 }
52
53 pub const fn set_position(&mut self, pos: u64) {
55 self.pos = pos;
56 }
57}
58
59impl<T> Cursor<T>
60where
61 T: AsRef<[u8]>,
62{
63 pub fn split(&self) -> (&[u8], &[u8]) {
65 let slice = self.inner.as_ref();
66 let pos = self.pos.min(slice.len() as u64);
67 slice.split_at(pos as usize)
68 }
69}
70
71impl<T> Cursor<T>
72where
73 T: AsMut<[u8]>,
74{
75 pub fn split_mut(&mut self) -> (&mut [u8], &mut [u8]) {
78 let slice = self.inner.as_mut();
79 let pos = self.pos.min(slice.len() as u64);
80 slice.split_at_mut(pos as usize)
81 }
82}
83
84impl<T> Clone for Cursor<T>
85where
86 T: Clone,
87{
88 #[inline]
89 fn clone(&self) -> Self {
90 Cursor {
91 inner: self.inner.clone(),
92 pos: self.pos,
93 }
94 }
95
96 #[inline]
97 fn clone_from(&mut self, other: &Self) {
98 self.inner.clone_from(&other.inner);
99 self.pos = other.pos;
100 }
101}
102
103impl<T> Seek for Cursor<T>
104where
105 T: AsRef<[u8]>,
106{
107 fn seek(&mut self, style: SeekFrom) -> Result<u64> {
108 let (base_pos, offset) = match style {
109 SeekFrom::Start(n) => {
110 self.pos = n;
111 return Ok(n);
112 }
113 SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n),
114 SeekFrom::Current(n) => (self.pos, n),
115 };
116 match base_pos.checked_add_signed(offset) {
117 Some(n) => {
118 self.pos = n;
119 Ok(self.pos)
120 }
121 None => Err(Error::InvalidInput),
122 }
123 }
124
125 fn stream_len(&mut self) -> Result<u64> {
126 Ok(self.inner.as_ref().len() as u64)
127 }
128
129 fn stream_position(&mut self) -> Result<u64> {
130 Ok(self.pos)
131 }
132}
133
134impl<T> Read for Cursor<T>
135where
136 T: AsRef<[u8]>,
137{
138 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
139 let n = Read::read(&mut Cursor::split(self).1, buf)?;
140 self.pos += n as u64;
141 Ok(n)
142 }
143
144 fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
145 let result = Read::read_exact(&mut Cursor::split(self).1, buf);
146
147 match result {
148 Ok(_) => self.pos += buf.len() as u64,
149 Err(_) => self.pos = self.inner.as_ref().len() as u64,
151 }
152
153 result
154 }
155
156 fn read_buf(&mut self, mut cursor: BorrowedCursor<'_, u8>) -> Result<()> {
157 let prev_written = cursor.written();
158
159 Read::read_buf(&mut Cursor::split(self).1, cursor.reborrow())?;
160
161 self.pos += (cursor.written() - prev_written) as u64;
162
163 Ok(())
164 }
165
166 fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_, u8>) -> Result<()> {
167 let prev_written = cursor.written();
168
169 let result = Read::read_buf_exact(&mut Cursor::split(self).1, cursor.reborrow());
170 self.pos += (cursor.written() - prev_written) as u64;
171
172 result
173 }
174
175 #[cfg(feature = "alloc")]
176 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
177 let content = Cursor::split(self).1;
178 let len = content.len();
179 buf.try_reserve(len).map_err(|_| Error::NoMemory)?;
180 buf.extend_from_slice(content);
181 self.pos += len as u64;
182
183 Ok(len)
184 }
185
186 #[cfg(feature = "alloc")]
187 fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
188 let content = str::from_utf8(Cursor::split(self).1).map_err(|_| Error::IllegalBytes)?;
189 let len = content.len();
190 buf.try_reserve(len).map_err(|_| Error::NoMemory)?;
191 buf.push_str(content);
192 self.pos += len as u64;
193
194 Ok(len)
195 }
196}
197
198impl<T> BufRead for Cursor<T>
199where
200 T: AsRef<[u8]>,
201{
202 fn fill_buf(&mut self) -> Result<&[u8]> {
203 Ok(Cursor::split(self).1)
204 }
205
206 fn consume(&mut self, amt: usize) {
207 self.pos += amt as u64;
208 }
209}
210
211fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> Result<usize> {
212 let pos = cmp::min(*pos_mut, slice.len() as u64);
213 let amt = (&mut slice[(pos as usize)..]).write(buf)?;
214 *pos_mut += amt as u64;
215 Ok(amt)
216}
217
218#[inline]
219fn slice_write_all(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> Result<()> {
220 let n = slice_write(pos_mut, slice, buf)?;
221 if n < buf.len() {
222 Err(Error::WriteZero)
223 } else {
224 Ok(())
225 }
226}
227
228#[cfg(feature = "alloc")]
230fn reserve_and_pad(pos_mut: &mut u64, vec: &mut Vec<u8>, buf_len: usize) -> Result<usize> {
231 let pos: usize = (*pos_mut).try_into().map_err(|_| Error::InvalidInput)?;
232
233 let desired_cap = pos.saturating_add(buf_len);
236 if desired_cap > vec.capacity() {
237 vec.reserve(desired_cap - vec.len());
242 }
243 if pos > vec.len() {
245 let diff = pos - vec.len();
246 let spare = vec.spare_capacity_mut();
250 debug_assert!(spare.len() >= diff);
251 unsafe {
254 spare
255 .get_unchecked_mut(..diff)
256 .fill(core::mem::MaybeUninit::new(0));
257 vec.set_len(pos);
258 }
259 }
260
261 Ok(pos)
262}
263
264#[cfg(feature = "alloc")]
270unsafe fn vec_write_all_unchecked(pos: usize, vec: &mut Vec<u8>, buf: &[u8]) -> usize {
271 debug_assert!(vec.capacity() >= pos + buf.len());
272 unsafe { vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()) };
273 pos + buf.len()
274}
275
276#[cfg(feature = "alloc")]
286fn vec_write_all(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> Result<usize> {
287 let buf_len = buf.len();
288 let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
289
290 unsafe {
294 pos = vec_write_all_unchecked(pos, vec, buf);
295 if pos > vec.len() {
296 vec.set_len(pos);
297 }
298 };
299
300 *pos_mut += buf_len as u64;
302 Ok(buf_len)
303}
304
305impl Write for Cursor<&mut [u8]> {
306 #[inline]
307 fn write(&mut self, buf: &[u8]) -> Result<usize> {
308 slice_write(&mut self.pos, self.inner, buf)
309 }
310
311 #[inline]
312 fn write_all(&mut self, buf: &[u8]) -> Result<()> {
313 slice_write_all(&mut self.pos, self.inner, buf)
314 }
315
316 #[inline]
317 fn flush(&mut self) -> Result<()> {
318 Ok(())
319 }
320}
321
322#[cfg(feature = "alloc")]
323impl Write for Cursor<&mut Vec<u8>> {
324 fn write(&mut self, buf: &[u8]) -> Result<usize> {
325 vec_write_all(&mut self.pos, self.inner, buf)
326 }
327
328 fn write_all(&mut self, buf: &[u8]) -> Result<()> {
329 vec_write_all(&mut self.pos, self.inner, buf)?;
330 Ok(())
331 }
332
333 #[inline]
334 fn flush(&mut self) -> Result<()> {
335 Ok(())
336 }
337}
338
339#[cfg(feature = "alloc")]
340impl Write for Cursor<Vec<u8>> {
341 fn write(&mut self, buf: &[u8]) -> Result<usize> {
342 vec_write_all(&mut self.pos, &mut self.inner, buf)
343 }
344
345 fn write_all(&mut self, buf: &[u8]) -> Result<()> {
346 vec_write_all(&mut self.pos, &mut self.inner, buf)?;
347 Ok(())
348 }
349
350 #[inline]
351 fn flush(&mut self) -> Result<()> {
352 Ok(())
353 }
354}
355
356#[cfg(feature = "alloc")]
357impl Write for Cursor<Box<[u8]>> {
358 #[inline]
359 fn write(&mut self, buf: &[u8]) -> Result<usize> {
360 slice_write(&mut self.pos, &mut self.inner, buf)
361 }
362
363 #[inline]
364 fn write_all(&mut self, buf: &[u8]) -> Result<()> {
365 slice_write_all(&mut self.pos, &mut self.inner, buf)
366 }
367
368 #[inline]
369 fn flush(&mut self) -> Result<()> {
370 Ok(())
371 }
372}
373
374impl<const N: usize> Write for Cursor<[u8; N]> {
375 #[inline]
376 fn write(&mut self, buf: &[u8]) -> Result<usize> {
377 slice_write(&mut self.pos, &mut self.inner, buf)
378 }
379
380 #[inline]
381 fn write_all(&mut self, buf: &[u8]) -> Result<()> {
382 slice_write_all(&mut self.pos, &mut self.inner, buf)
383 }
384
385 #[inline]
386 fn flush(&mut self) -> Result<()> {
387 Ok(())
388 }
389}
390
391impl<T: IoBuf> IoBuf for Cursor<T> {
392 #[inline]
393 fn remaining(&self) -> usize {
394 self.inner.remaining() - (self.pos as usize)
395 }
396}
397
398impl<T: IoBufMut> IoBufMut for Cursor<T> {
399 #[inline]
400 fn remaining_mut(&self) -> usize {
401 self.inner.remaining_mut() - (self.pos as usize)
402 }
403}
404
405#[cfg(all(test, feature = "alloc"))]
406mod tests {
407 use super::*;
408
409 #[test]
410 fn cursor_split_and_clone_hold() {
411 use alloc::vec;
412
413 let cursor = crate::Cursor::new(vec![1, 2, 3, 4, 5]);
415 let (before, after) = crate::Cursor::split(&cursor);
416 assert!(before.is_empty()); assert_eq!(after, [1, 2, 3, 4, 5]);
418
419 let mut cursor = crate::Cursor::new(vec![1, 2, 3, 4, 5]);
421 cursor.set_position(3);
422 let (before, after) = crate::Cursor::split(&cursor);
423 assert_eq!(before, [1, 2, 3]);
424 assert_eq!(after, [4, 5]);
425
426 let cursor1 = crate::Cursor::new(vec![10, 20, 30]);
428 let cursor2 = cursor1.clone();
429 assert_eq!(cursor1.position(), cursor2.position());
430 assert_eq!(*cursor1.get_ref(), *cursor2.get_ref());
431
432 let cursor: crate::Cursor<alloc::vec::Vec<u8>> = Default::default();
434 assert_eq!(cursor.position(), 0);
435 assert!(cursor.get_ref().is_empty());
436 }
437
438 #[test]
439 fn cursor_seek_from_variants_hold() {
440 use alloc::vec;
441
442 use crate::{Cursor, Seek, SeekFrom};
443
444 let mut cursor = Cursor::new(vec![1, 2, 3, 4, 5]);
445
446 let pos = cursor.seek(SeekFrom::Start(2)).unwrap();
448 assert_eq!(pos, 2);
449 assert_eq!(cursor.position(), 2);
450
451 let pos = cursor.seek(SeekFrom::Current(1)).unwrap();
453 assert_eq!(pos, 3);
454 assert_eq!(cursor.position(), 3);
455
456 let pos = cursor.seek(SeekFrom::End(-2)).unwrap();
458 assert_eq!(pos, 3); assert_eq!(cursor.position(), 3);
460
461 let len = cursor.stream_len().unwrap();
463 assert_eq!(len, 5);
464
465 let pos = cursor.stream_position().unwrap();
467 assert_eq!(pos, 3);
468 }
469
470 #[test]
471 fn cursor_split_mut_and_write_hold() {
472 use alloc::vec;
473
474 let mut cursor = crate::Cursor::new(vec![1, 2, 3, 4, 5]);
476 cursor.set_position(2);
477 let (before, after) = crate::Cursor::split_mut(&mut cursor);
478 assert_eq!(before, [1, 2]);
479 assert_eq!(after, [3, 4, 5]);
480
481 let mut buf = [0u8; 10];
483 {
484 let mut cursor = crate::Cursor::new(&mut buf[..]);
485 cursor.write_all(&[1, 2, 3]).unwrap();
486 assert_eq!(cursor.position(), 3);
487 }
488 assert_eq!(&buf[..3], [1, 2, 3]);
489
490 let mut vec = alloc::vec::Vec::new();
492 {
493 let mut cursor = crate::Cursor::new(&mut vec);
494 cursor.write_all(&[4, 5, 6]).unwrap();
495 assert_eq!(cursor.position(), 3);
496 }
497 assert_eq!(vec, [4, 5, 6]);
498 }
499
500 #[test]
501 fn cursor_buf_read_impl_hold() {
502 use alloc::vec;
503
504 use crate::{BufRead, Cursor};
505
506 let mut cursor = Cursor::new(vec![1, 2, 3, 4, 5]);
508
509 let buf = cursor.fill_buf().unwrap();
511 assert_eq!(buf, &[1, 2, 3, 4, 5]);
512
513 let mut cursor = Cursor::new(vec![10, 20, 30, 40, 50]);
515 let mut read_buf = [0u8; 3];
516 let n = cursor.read(&mut read_buf).unwrap();
517 assert_eq!(n, 3);
518 assert_eq!(&read_buf, &[10, 20, 30]);
519 assert_eq!(cursor.position(), 3);
520 }
521
522 #[test]
523 fn cursor_write_box_array_and_fixed_size_hold() {
524 use alloc::boxed::Box;
525
526 use crate::{Cursor, Write};
527
528 let boxed: Box<[u8]> = Box::new([0u8; 16]);
530 let mut cursor = Cursor::new(boxed);
531 cursor.write_all(&[1, 2, 3]).unwrap();
532 assert_eq!(cursor.position(), 3);
533
534 let mut cursor = Cursor::new([0u8; 8]);
536 cursor.write_all(&[4, 5, 6, 7]).unwrap();
537 assert_eq!(cursor.position(), 4);
538
539 let mut cursor = Cursor::new([0u8; 4]);
541 cursor.flush().unwrap();
542 }
543}