1use super::*;
2#[cfg(feature = "alloc")]
3use {alloc::vec::Vec, core::slice::from_raw_parts_mut};
4
5pub struct Cursor<T> {
63 inner: T,
64 pos: usize,
65}
66
67impl<T> Cursor<T> {
68 pub const fn new(inner: T) -> Self {
69 Self { inner, pos: 0 }
70 }
71
72 pub const fn new_at(inner: T, pos: usize) -> Self {
74 Self { inner, pos }
75 }
76
77 pub const fn set_position(&mut self, pos: usize) {
79 self.pos = pos;
80 }
81
82 pub fn into_inner(self) -> T {
84 self.inner
85 }
86
87 pub const fn position(&self) -> usize {
89 self.pos
90 }
91}
92
93impl<T> Cursor<T>
94where
95 T: AsRef<[u8]>,
96{
97 #[inline]
99 fn cur_slice(&self) -> &[u8] {
100 let slice = self.inner.as_ref();
101 &slice[self.pos.min(slice.len())..]
102 }
103
104 #[inline]
106 fn cur_len(&self) -> usize {
107 self.inner.as_ref().len().saturating_sub(self.pos)
108 }
109
110 #[inline]
112 fn consume_slice_checked(&mut self, mid: usize) -> ReadResult<&[u8]> {
113 let slice = self.inner.as_ref();
114 let cur = &slice[self.pos.min(slice.len())..];
115 let Some(left) = cur.get(..mid) else {
116 return Err(read_size_limit(mid));
117 };
118 self.pos = unsafe { self.pos.unchecked_add(mid) };
120 Ok(left)
121 }
122}
123
124impl<'a, T> Reader<'a> for Cursor<T>
125where
126 T: AsRef<[u8]>,
127{
128 type Trusted<'b>
129 = TrustedSliceReader<'a, 'b>
130 where
131 Self: 'b;
132
133 #[inline]
134 fn fill_buf(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
135 let src = self.cur_slice();
136 Ok(&src[..n_bytes.min(src.len())])
137 }
138
139 #[inline]
140 fn fill_exact(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
141 let Some(src) = self.cur_slice().get(..n_bytes) else {
142 return Err(read_size_limit(n_bytes));
143 };
144 Ok(src)
145 }
146
147 #[inline]
148 unsafe fn consume_unchecked(&mut self, amt: usize) {
149 self.pos = unsafe { self.pos.unchecked_add(amt) };
150 }
151
152 fn consume(&mut self, amt: usize) -> ReadResult<()> {
153 if self.cur_len() < amt {
154 return Err(read_size_limit(amt));
155 }
156 unsafe { self.consume_unchecked(amt) };
158 Ok(())
159 }
160
161 #[inline]
162 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> ReadResult<Self::Trusted<'_>> {
163 Ok(TrustedSliceReader::new(
164 self.consume_slice_checked(n_bytes)?,
165 ))
166 }
167}
168
169mod uninit_slice {
171 use super::*;
172
173 #[inline]
175 pub(super) fn cur_slice_mut(
176 inner: &mut [MaybeUninit<u8>],
177 pos: usize,
178 ) -> &mut [MaybeUninit<u8>] {
179 let len = inner.len();
180 &mut inner[pos.min(len)..]
181 }
182
183 #[inline]
186 pub(super) fn get_slice_mut_checked(
187 inner: &mut [MaybeUninit<u8>],
188 pos: usize,
189 len: usize,
190 ) -> WriteResult<&mut [MaybeUninit<u8>]> {
191 let Some(dst) = cur_slice_mut(inner, pos).get_mut(..len) else {
192 return Err(write_size_limit(len));
193 };
194 Ok(dst)
195 }
196
197 pub(super) fn write(
199 inner: &mut [MaybeUninit<u8>],
200 pos: &mut usize,
201 src: &[u8],
202 ) -> WriteResult<()> {
203 let len = src.len();
204 let dst = get_slice_mut_checked(inner, *pos, len)?;
205 unsafe { ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr().cast(), len) };
207 *pos = unsafe { pos.unchecked_add(len) };
209 Ok(())
210 }
211
212 #[inline]
213 pub(super) fn as_trusted_for<'a>(
214 inner: &'a mut [MaybeUninit<u8>],
215 pos: &mut usize,
216 n_bytes: usize,
217 ) -> WriteResult<TrustedSliceWriter<'a>> {
218 let dst = get_slice_mut_checked(inner, *pos, n_bytes)?;
219 *pos = unsafe { pos.unchecked_add(n_bytes) };
221 Ok(TrustedSliceWriter::new(dst))
222 }
223}
224
225impl Writer for Cursor<&mut [MaybeUninit<u8>]> {
226 type Trusted<'b>
227 = TrustedSliceWriter<'b>
228 where
229 Self: 'b;
230
231 #[inline]
232 fn write(&mut self, src: &[u8]) -> WriteResult<()> {
233 uninit_slice::write(self.inner, &mut self.pos, src)
234 }
235
236 #[inline]
237 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
238 uninit_slice::as_trusted_for(self.inner, &mut self.pos, n_bytes)
239 }
240}
241
242impl<const N: usize> Cursor<&mut MaybeUninit<[u8; N]>> {
243 #[inline(always)]
244 pub(super) const fn transpose(inner: &mut MaybeUninit<[u8; N]>) -> &mut [MaybeUninit<u8>; N] {
246 unsafe { transmute::<&mut MaybeUninit<[u8; N]>, &mut [MaybeUninit<u8>; N]>(inner) }
248 }
249}
250
251impl<const N: usize> Writer for Cursor<&mut MaybeUninit<[u8; N]>> {
252 type Trusted<'b>
253 = TrustedSliceWriter<'b>
254 where
255 Self: 'b;
256
257 #[inline]
258 fn write(&mut self, src: &[u8]) -> WriteResult<()> {
259 uninit_slice::write(Self::transpose(self.inner), &mut self.pos, src)
260 }
261
262 #[inline]
263 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
264 uninit_slice::as_trusted_for(Self::transpose(self.inner), &mut self.pos, n_bytes)
265 }
266}
267
268#[cfg(feature = "alloc")]
270mod vec {
271 use super::*;
272
273 #[inline]
284 pub(super) fn maybe_grow(inner: &mut Vec<u8>, pos: usize, needed: usize) -> WriteResult<()> {
285 let Some(required) = pos.checked_add(needed) else {
286 return Err(write_size_limit(needed));
287 };
288 if required > inner.capacity() {
289 grow(inner, required);
290 }
291 #[cold]
292 fn grow(inner: &mut Vec<u8>, required: usize) {
293 let additional = unsafe { required.unchecked_sub(inner.len()) };
296 inner.reserve(additional);
297 }
298 Ok(())
299 }
300
301 pub(super) unsafe fn add_len(inner: &mut Vec<u8>, pos: &mut usize, len: usize) {
306 let next_pos = unsafe { pos.unchecked_add(len) };
308
309 if next_pos > inner.len() {
312 unsafe {
313 inner.set_len(next_pos);
314 }
315 }
316 *pos = next_pos;
317 }
318
319 pub(super) fn write(inner: &mut Vec<u8>, pos: &mut usize, src: &[u8]) -> WriteResult<()> {
321 maybe_grow(inner, *pos, src.len())?;
322 unsafe { ptr::copy_nonoverlapping(src.as_ptr(), inner.as_mut_ptr().add(*pos), src.len()) };
324 unsafe { add_len(inner, pos, src.len()) };
326 Ok(())
327 }
328
329 #[inline]
332 pub(super) fn as_trusted_for<'a>(
333 inner: &'a mut Vec<u8>,
334 pos: &'a mut usize,
335 n_bytes: usize,
336 ) -> WriteResult<TrustedVecWriter<'a>> {
337 maybe_grow(inner, *pos, n_bytes)?;
338 let buf = unsafe {
339 from_raw_parts_mut(
340 inner.as_mut_ptr().cast::<MaybeUninit<u8>>(),
341 inner.capacity(),
342 )
343 };
344 Ok(TrustedVecWriter::new(buf, pos))
345 }
346
347 #[inline]
348 pub(super) fn finish(inner: &mut Vec<u8>, pos: &mut usize) {
349 if *pos > inner.len() {
350 unsafe {
351 inner.set_len(*pos);
352 }
353 }
354 }
355}
356
357#[cfg(feature = "alloc")]
374pub struct TrustedVecWriter<'a> {
375 inner: &'a mut [MaybeUninit<u8>],
376 pos: &'a mut usize,
377}
378
379#[cfg(feature = "alloc")]
380impl<'a> TrustedVecWriter<'a> {
381 pub fn new(inner: &'a mut [MaybeUninit<u8>], pos: &'a mut usize) -> Self {
382 Self { inner, pos }
383 }
384}
385
386#[cfg(feature = "alloc")]
387impl<'a> Writer for TrustedVecWriter<'a> {
388 type Trusted<'b>
389 = TrustedVecWriter<'b>
390 where
391 Self: 'b;
392
393 fn write(&mut self, src: &[u8]) -> WriteResult<()> {
394 unsafe {
396 ptr::copy_nonoverlapping(
397 src.as_ptr().cast(),
398 self.inner.as_mut_ptr().add(*self.pos),
399 src.len(),
400 )
401 };
402
403 *self.pos = unsafe { self.pos.unchecked_add(src.len()) };
404 Ok(())
405 }
406
407 #[inline]
408 unsafe fn as_trusted_for(&mut self, _n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
409 Ok(TrustedVecWriter::new(self.inner, self.pos))
410 }
411}
412
413#[cfg(feature = "alloc")]
442impl Writer for Cursor<&mut Vec<u8>> {
443 type Trusted<'b>
444 = TrustedVecWriter<'b>
445 where
446 Self: 'b;
447
448 #[inline]
449 fn write(&mut self, src: &[u8]) -> WriteResult<()> {
450 vec::write(self.inner, &mut self.pos, src)
451 }
452
453 #[inline]
454 fn finish(&mut self) -> WriteResult<()> {
455 vec::finish(self.inner, &mut self.pos);
456 Ok(())
457 }
458
459 #[inline]
460 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
461 vec::as_trusted_for(self.inner, &mut self.pos, n_bytes)
462 }
463}
464
465#[cfg(feature = "alloc")]
491impl Writer for Cursor<Vec<u8>> {
492 type Trusted<'b>
493 = TrustedVecWriter<'b>
494 where
495 Self: 'b;
496
497 #[inline]
498 fn write(&mut self, src: &[u8]) -> WriteResult<()> {
499 vec::write(&mut self.inner, &mut self.pos, src)
500 }
501
502 #[inline]
503 fn finish(&mut self) -> WriteResult<()> {
504 vec::finish(&mut self.inner, &mut self.pos);
505 Ok(())
506 }
507
508 #[inline]
509 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
510 vec::as_trusted_for(&mut self.inner, &mut self.pos, n_bytes)
511 }
512}
513
514#[cfg(all(test, feature = "alloc"))]
515mod tests {
516 #![allow(clippy::arithmetic_side_effects)]
517 use {super::*, crate::proptest_config::proptest_cfg, alloc::vec, proptest::prelude::*};
518
519 proptest! {
520 #![proptest_config(proptest_cfg())]
521
522 #[test]
523 fn cursor_read_no_panic_no_ub_check(bytes in any::<Vec<u8>>(), pos in any::<usize>()) {
524 let mut cursor = Cursor::new_at(&bytes, pos);
525 let buf = cursor.fill_buf(bytes.len()).unwrap();
526 if pos > bytes.len() {
527 prop_assert_eq!(buf, &[]);
530 } else {
531 prop_assert_eq!(buf, &bytes[pos..]);
532 }
533
534 let res = cursor.fill_exact(bytes.len());
535 if pos > bytes.len() && !bytes.is_empty() {
536 prop_assert!(matches!(res, Err(ReadError::ReadSizeLimit(x)) if x == bytes.len()));
537 } else {
538 prop_assert_eq!(res.unwrap(), &bytes[pos.min(bytes.len())..]);
539 }
540 }
541
542 #[test]
543 fn cursor_zero_len_ops_ok(bytes in any::<Vec<u8>>(), pos in any::<usize>()) {
544 let mut cursor = Cursor::new_at(&bytes, pos);
545 let start = cursor.position();
546
547 let fe = cursor.fill_exact(0).unwrap();
549 prop_assert_eq!(fe.len(), 0);
550 prop_assert_eq!(cursor.position(), start);
551
552 prop_assert!(cursor.consume(0).is_ok());
554 prop_assert_eq!(cursor.position(), start);
555
556 let start2 = cursor.position();
558 let mut trusted = unsafe { <Cursor<_> as Reader>::as_trusted_for(&mut cursor, 0) }.unwrap();
559 prop_assert_eq!(trusted.fill_buf(1).unwrap(), &[]);
561 prop_assert_eq!(trusted.fill_exact(0).unwrap().len(), 0);
562 prop_assert_eq!(cursor.position(), start2);
563 }
564
565 #[test]
566 fn cursor_as_trusted_for_remaining_advances_to_len(bytes in any::<Vec<u8>>(), pos in any::<usize>()) {
567 let len = bytes.len();
569 let pos = if len == 0 { 0 } else { pos % (len + 1) };
570 let mut cursor = Cursor::new_at(&bytes, pos);
571 let remaining = len.saturating_sub(pos);
572
573 let _trusted = unsafe { <Cursor<_> as Reader>::as_trusted_for(&mut cursor, remaining) }.unwrap();
574 prop_assert_eq!(cursor.position(), len);
576 }
577
578 #[test]
579 fn cursor_extremal_pos_max_zero_len_ok(bytes in any::<Vec<u8>>()) {
580 let mut cursor = Cursor::new_at(&bytes, usize::MAX);
581 prop_assert_eq!(cursor.fill_buf(1).unwrap(), &[]);
583 prop_assert!(matches!(cursor.peek(), Err(ReadError::ReadSizeLimit(1))));
584
585 let start = cursor.position();
587 prop_assert!(cursor.fill_exact(0).is_ok());
588 prop_assert!(cursor.consume(0).is_ok());
589 let _trusted = unsafe { <Cursor<_> as Reader>::as_trusted_for(&mut cursor, 0) }.unwrap();
590 prop_assert_eq!(cursor.position(), start);
591 }
592
593 #[test]
594 fn uninit_slice_write_no_panic_no_ub_check(bytes in any::<Vec<u8>>(), pos in any::<usize>()) {
595 let mut output: Vec<u8> = Vec::with_capacity(bytes.len());
596 let mut cursor = Cursor::new_at(output.spare_capacity_mut(), pos);
597 let res = cursor.write(&bytes);
598 if pos > bytes.len() && !bytes.is_empty() {
599 prop_assert!(matches!(res, Err(WriteError::WriteSizeLimit(x)) if x == bytes.len()));
600 } else if pos == 0 {
601 prop_assert_eq!(output, bytes);
602 }
603 }
604
605 #[test]
606 fn vec_write_no_panic_no_ub_check(bytes in any::<Vec<u8>>(), pos in any::<u16>()) {
607 let pos = pos as usize;
608 let mut output: Vec<u8> = Vec::new();
609 let mut cursor = Cursor::new_at(&mut output, pos);
610 cursor.write(&bytes).unwrap();
612 prop_assert_eq!(&output[pos..], &bytes);
613 }
614
615 #[test]
616 fn cursor_write_vec_new(bytes in any::<Vec<u8>>()) {
617 let mut cursor = Cursor::new(Vec::new());
618 cursor.write(&bytes).unwrap();
619 prop_assert_eq!(&cursor.inner, &bytes);
620
621 let mut vec = Vec::with_capacity(bytes.len());
622 let mut cursor = Cursor::new(vec.spare_capacity_mut());
623 cursor.write(&bytes).unwrap();
624 unsafe { vec.set_len(bytes.len()) };
625 prop_assert_eq!(&vec, &bytes);
626 }
627
628 #[test]
629 fn cursor_write_existing_vec(bytes in any::<Vec<u8>>()) {
630 let mut cursor = Cursor::new(vec![0; bytes.len()]);
631 cursor.write(&bytes).unwrap();
632 prop_assert_eq!(&cursor.inner, &bytes);
633 }
634
635 #[test]
636 fn cursor_write_existing_grow_vec(bytes in any::<Vec<u8>>()) {
637 let mut cursor = Cursor::new(vec![0; bytes.len() / 2]);
638 cursor.write(&bytes).unwrap();
639 prop_assert_eq!(&cursor.inner, &bytes);
640 }
641
642 #[test]
643 fn cursor_write_partial_vec(bytes in any::<Vec<u8>>()) {
644 let mut cursor = Cursor::new(vec![1; bytes.len()]);
645 let half = bytes.len() - bytes.len() / 2;
646 cursor.write(&bytes[..half]).unwrap();
647 prop_assert_eq!(&cursor.inner[..half], &bytes[..half]);
648 prop_assert_eq!(&cursor.inner[half..], &vec![1; bytes.len() - half]);
650 cursor.write(&bytes[half..]).unwrap();
651 prop_assert_eq!(&cursor.inner, &bytes);
652 }
653
654 #[test]
655 fn cursor_write_trusted_vec(bytes in any::<Vec<u8>>()) {
656 let mut cursor = Cursor::new(vec![1; bytes.len()]);
657 let half = bytes.len() - bytes.len() / 2;
658 cursor.write(&bytes[..half]).unwrap();
659 unsafe { <Cursor<_> as Writer>::as_trusted_for(&mut cursor, bytes.len() - half) }
660 .unwrap()
661 .write(&bytes[half..])
662 .unwrap();
663 cursor.finish().unwrap();
664 prop_assert_eq!(&cursor.inner, &bytes);
665 }
666
667 #[test]
668 fn cursor_write_trusted_grow_vec(bytes in any::<Vec<u8>>()) {
669 let mut cursor = Cursor::new(vec![1; bytes.len() / 2]);
670 let half = bytes.len() - bytes.len() / 2;
671 cursor.write(&bytes[..half]).unwrap();
672 unsafe { <Cursor<_> as Writer>::as_trusted_for(&mut cursor, bytes.len() - half) }
673 .unwrap()
674 .write(&bytes[half..])
675 .unwrap();
676 cursor.finish().unwrap();
677 prop_assert_eq!(&cursor.inner, &bytes);
678 }
679
680 #[test]
681 fn cursor_write_trusted_oversized_vec(bytes in any::<Vec<u8>>()) {
682 let mut cursor = Cursor::new(vec![1; bytes.len() * 2]);
683 let half = bytes.len() - bytes.len() / 2;
684 cursor.write(&bytes[..half]).unwrap();
685 unsafe { <Cursor<_> as Writer>::as_trusted_for(&mut cursor, bytes.len() - half) }
686 .unwrap()
687 .write(&bytes[half..])
688 .unwrap();
689 cursor.finish().unwrap();
690 prop_assert_eq!(&cursor.inner[..bytes.len()], &bytes);
691 prop_assert_eq!(&cursor.inner[bytes.len()..], &vec![1; bytes.len()]);
693 }
694 }
695}