1use {super::*, core::marker::PhantomData};
2
3pub(super) mod trusted_slice {
5 use super::*;
6
7 #[inline]
8 pub(super) fn fill_buf(bytes: &[u8], n_bytes: usize) -> &[u8] {
9 unsafe { bytes.get_unchecked(..n_bytes.min(bytes.len())) }
10 }
11
12 #[inline]
13 pub(super) fn fill_exact(bytes: &[u8], n_bytes: usize) -> &[u8] {
14 unsafe { bytes.get_unchecked(..n_bytes) }
15 }
16
17 #[inline]
18 pub(super) unsafe fn consume_unchecked(bytes: &mut &[u8], amt: usize) {
19 *bytes = unsafe { bytes.get_unchecked(amt..) };
20 }
21
22 #[inline]
23 pub(super) fn consume(bytes: &mut &[u8], amt: usize) {
24 unsafe { consume_unchecked(bytes, amt) };
25 }
26
27 #[inline]
29 pub(super) fn get_slice_mut<'a>(
30 buffer: &mut &'a mut [MaybeUninit<u8>],
31 len: usize,
32 ) -> &'a mut [MaybeUninit<u8>] {
33 let (dst, rest) = unsafe { mem::take(buffer).split_at_mut_unchecked(len) };
34 *buffer = rest;
35 dst
36 }
37}
38
39pub struct TrustedSliceReaderZeroCopy<'a> {
48 cursor: &'a [u8],
49}
50
51impl<'a> TrustedSliceReaderZeroCopy<'a> {
52 pub(super) const fn new(bytes: &'a [u8]) -> Self {
53 Self { cursor: bytes }
54 }
55}
56
57impl<'a> Reader<'a> for TrustedSliceReaderZeroCopy<'a> {
58 type Trusted<'b>
59 = Self
60 where
61 Self: 'b;
62
63 #[inline]
64 fn fill_buf(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
65 Ok(trusted_slice::fill_buf(self.cursor, n_bytes))
66 }
67
68 #[inline]
69 fn fill_exact(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
70 Ok(trusted_slice::fill_exact(self.cursor, n_bytes))
71 }
72
73 #[inline]
74 fn borrow_exact(&mut self, len: usize) -> ReadResult<&'a [u8]> {
75 let (src, rest) = unsafe { self.cursor.split_at_unchecked(len) };
76 self.cursor = rest;
77 Ok(src)
78 }
79
80 #[inline]
81 unsafe fn consume_unchecked(&mut self, amt: usize) {
82 trusted_slice::consume_unchecked(&mut self.cursor, amt);
83 }
84
85 #[inline]
86 fn consume(&mut self, amt: usize) -> ReadResult<()> {
87 trusted_slice::consume(&mut self.cursor, amt);
88 Ok(())
89 }
90
91 #[inline]
92 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> ReadResult<Self::Trusted<'_>> {
93 Ok(TrustedSliceReaderZeroCopy::new(self.borrow_exact(n_bytes)?))
94 }
95}
96
97pub struct TrustedSliceReaderZeroCopyMut<'a> {
104 cursor: &'a mut [u8],
105}
106
107impl<'a> TrustedSliceReaderZeroCopyMut<'a> {
108 pub(super) const fn new(bytes: &'a mut [u8]) -> Self {
109 Self { cursor: bytes }
110 }
111}
112
113impl<'a> Reader<'a> for TrustedSliceReaderZeroCopyMut<'a> {
114 type Trusted<'b>
115 = Self
116 where
117 Self: 'b;
118
119 #[inline]
120 fn fill_buf(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
121 Ok(trusted_slice::fill_buf(self.cursor, n_bytes))
122 }
123
124 #[inline]
125 fn fill_exact(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
126 Ok(trusted_slice::fill_exact(self.cursor, n_bytes))
127 }
128
129 #[inline]
130 fn borrow_exact_mut(&mut self, len: usize) -> ReadResult<&'a mut [u8]> {
131 let (src, rest) = unsafe { mem::take(&mut self.cursor).split_at_mut_unchecked(len) };
132 self.cursor = rest;
133 Ok(src)
134 }
135
136 #[inline]
137 unsafe fn consume_unchecked(&mut self, amt: usize) {
138 self.cursor = unsafe { mem::take(&mut self.cursor).get_unchecked_mut(amt..) };
139 }
140
141 #[inline]
142 fn consume(&mut self, amt: usize) -> ReadResult<()> {
143 unsafe { Self::consume_unchecked(self, amt) };
144 Ok(())
145 }
146
147 #[inline]
148 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> ReadResult<Self::Trusted<'_>> {
149 Ok(TrustedSliceReaderZeroCopyMut::new(
150 self.borrow_exact_mut(n_bytes)?,
151 ))
152 }
153}
154
155pub struct TrustedSliceReader<'a, 'b> {
166 cursor: &'b [u8],
167 _marker: PhantomData<&'a ()>,
168}
169
170impl<'a, 'b> TrustedSliceReader<'a, 'b> {
171 pub(super) const fn new(bytes: &'b [u8]) -> Self {
172 Self {
173 cursor: bytes,
174 _marker: PhantomData,
175 }
176 }
177}
178
179impl<'a, 'b> Reader<'a> for TrustedSliceReader<'a, 'b> {
180 type Trusted<'c>
181 = Self
182 where
183 Self: 'c;
184
185 #[inline]
186 fn fill_buf(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
187 Ok(trusted_slice::fill_buf(self.cursor, n_bytes))
188 }
189
190 #[inline]
191 fn fill_exact(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
192 Ok(trusted_slice::fill_exact(self.cursor, n_bytes))
193 }
194
195 #[inline]
196 unsafe fn consume_unchecked(&mut self, amt: usize) {
197 trusted_slice::consume_unchecked(&mut self.cursor, amt);
198 }
199
200 #[inline]
201 fn consume(&mut self, amt: usize) -> ReadResult<()> {
202 trusted_slice::consume(&mut self.cursor, amt);
203 Ok(())
204 }
205
206 #[inline]
207 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> ReadResult<Self::Trusted<'_>> {
208 let (src, rest) = unsafe { self.cursor.split_at_unchecked(n_bytes) };
209 self.cursor = rest;
210 Ok(TrustedSliceReader::new(src))
211 }
212}
213
214impl<'a> Reader<'a> for &'a [u8] {
215 type Trusted<'b>
216 = TrustedSliceReaderZeroCopy<'a>
217 where
218 Self: 'b;
219
220 #[inline]
221 fn fill_buf(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
222 Ok(unsafe { self.get_unchecked(..n_bytes.min(self.len())) })
224 }
225
226 #[inline]
227 fn fill_exact(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
228 let Some(src) = self.get(..n_bytes) else {
229 return Err(read_size_limit(n_bytes));
230 };
231 Ok(src)
232 }
233
234 #[inline]
235 fn borrow_exact(&mut self, len: usize) -> ReadResult<&'a [u8]> {
236 let Some((src, rest)) = self.split_at_checked(len) else {
237 return Err(read_size_limit(len));
238 };
239 *self = rest;
240 Ok(src)
241 }
242
243 #[inline]
244 unsafe fn consume_unchecked(&mut self, amt: usize) {
245 *self = unsafe { self.get_unchecked(amt..) };
246 }
247
248 #[inline]
249 fn consume(&mut self, amt: usize) -> ReadResult<()> {
250 if self.len() < amt {
251 return Err(read_size_limit(amt));
252 }
253 unsafe { self.consume_unchecked(amt) };
255 Ok(())
256 }
257
258 #[inline]
259 unsafe fn as_trusted_for(&mut self, n: usize) -> ReadResult<Self::Trusted<'_>> {
260 Ok(TrustedSliceReaderZeroCopy::new(self.borrow_exact(n)?))
261 }
262}
263
264impl<'a> Reader<'a> for &'a mut [u8] {
265 type Trusted<'b>
266 = TrustedSliceReaderZeroCopyMut<'a>
267 where
268 Self: 'b;
269
270 #[inline]
271 fn fill_buf(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
272 Ok(unsafe { self.get_unchecked(..n_bytes.min(self.len())) })
274 }
275
276 #[inline]
277 fn fill_exact(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
278 let Some(src) = self.get(..n_bytes) else {
279 return Err(read_size_limit(n_bytes));
280 };
281 Ok(src)
282 }
283
284 #[inline]
285 fn borrow_exact_mut(&mut self, len: usize) -> ReadResult<&'a mut [u8]> {
286 let Some((src, rest)) = mem::take(self).split_at_mut_checked(len) else {
287 return Err(read_size_limit(len));
288 };
289 *self = rest;
290 Ok(src)
291 }
292
293 #[inline]
294 unsafe fn consume_unchecked(&mut self, amt: usize) {
295 *self = unsafe { mem::take(self).get_unchecked_mut(amt..) };
296 }
297
298 #[inline]
299 fn consume(&mut self, amt: usize) -> ReadResult<()> {
300 if self.len() < amt {
301 return Err(read_size_limit(amt));
302 }
303 unsafe { self.consume_unchecked(amt) };
305 Ok(())
306 }
307
308 #[inline]
309 unsafe fn as_trusted_for(&mut self, n: usize) -> ReadResult<Self::Trusted<'_>> {
310 Ok(TrustedSliceReaderZeroCopyMut::new(
311 self.borrow_exact_mut(n)?,
312 ))
313 }
314}
315
316pub struct TrustedSliceWriter<'a> {
325 buffer: &'a mut [MaybeUninit<u8>],
326}
327
328#[cfg(test)]
329impl core::ops::Deref for TrustedSliceWriter<'_> {
330 type Target = [MaybeUninit<u8>];
331
332 fn deref(&self) -> &Self::Target {
333 self.buffer
334 }
335}
336
337impl<'a> TrustedSliceWriter<'a> {
338 #[inline(always)]
339 pub(super) const fn new(buffer: &'a mut [MaybeUninit<u8>]) -> Self {
340 Self { buffer }
341 }
342}
343
344impl<'a> Writer for TrustedSliceWriter<'a> {
345 type Trusted<'b>
346 = TrustedSliceWriter<'b>
347 where
348 Self: 'b;
349
350 #[inline]
351 fn write(&mut self, src: &[u8]) -> WriteResult<()> {
352 let dst = trusted_slice::get_slice_mut(&mut self.buffer, src.len());
353 unsafe { ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr().cast(), src.len()) };
354 Ok(())
355 }
356
357 #[inline]
358 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
359 Ok(TrustedSliceWriter::new(trusted_slice::get_slice_mut(
360 &mut self.buffer,
361 n_bytes,
362 )))
363 }
364}
365
366#[inline]
369fn advance_slice_mut_checked<'a, T>(
370 input: &mut &'a mut [T],
371 len: usize,
372) -> WriteResult<&'a mut [T]> {
373 let Some((dst, rest)) = mem::take(input).split_at_mut_checked(len) else {
374 return Err(write_size_limit(len));
375 };
376 *input = rest;
377 Ok(dst)
378}
379
380#[inline]
383fn get_slice_mut_checked<T>(input: &mut [T], len: usize) -> WriteResult<&'_ mut [T]> {
384 let Some((dst, _)) = input.split_at_mut_checked(len) else {
385 return Err(write_size_limit(len));
386 };
387 Ok(dst)
388}
389
390impl Writer for &mut [MaybeUninit<u8>] {
391 type Trusted<'b>
392 = TrustedSliceWriter<'b>
393 where
394 Self: 'b;
395
396 #[inline]
397 fn write(&mut self, src: &[u8]) -> WriteResult<()> {
398 let dst = advance_slice_mut_checked(self, src.len())?;
399 unsafe { ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr().cast(), src.len()) };
400 Ok(())
401 }
402
403 #[inline]
404 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
405 Ok(TrustedSliceWriter::new(advance_slice_mut_checked(
406 self, n_bytes,
407 )?))
408 }
409}
410
411impl Writer for [MaybeUninit<u8>] {
412 type Trusted<'b>
413 = TrustedSliceWriter<'b>
414 where
415 Self: 'b;
416
417 #[inline]
418 fn write(&mut self, src: &[u8]) -> WriteResult<()> {
419 let dst = get_slice_mut_checked(self, src.len())?;
420 unsafe { ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr().cast(), src.len()) };
421 Ok(())
422 }
423
424 #[inline]
425 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
426 Ok(TrustedSliceWriter::new(get_slice_mut_checked(
427 self, n_bytes,
428 )?))
429 }
430}
431
432impl Writer for &mut [u8] {
433 type Trusted<'b>
434 = TrustedSliceWriter<'b>
435 where
436 Self: 'b;
437
438 #[inline]
439 fn write(&mut self, src: &[u8]) -> WriteResult<()> {
440 let dst = advance_slice_mut_checked(self, src.len())?;
441 unsafe { ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), src.len()) };
444 Ok(())
445 }
446
447 #[inline]
448 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
449 let buf = advance_slice_mut_checked(self, n_bytes)?;
450 let buf = unsafe { transmute::<&mut [u8], &mut [MaybeUninit<u8>]>(buf) };
453 Ok(TrustedSliceWriter::new(buf))
454 }
455}
456
457impl Writer for [u8] {
458 type Trusted<'b>
459 = TrustedSliceWriter<'b>
460 where
461 Self: 'b;
462
463 #[inline]
464 fn write(&mut self, src: &[u8]) -> WriteResult<()> {
465 let dst = get_slice_mut_checked(self, src.len())?;
466 unsafe { ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), src.len()) };
469 Ok(())
470 }
471
472 #[inline]
473 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
474 let buf = get_slice_mut_checked(self, n_bytes)?;
475 let buf = unsafe { transmute::<&mut [u8], &mut [MaybeUninit<u8>]>(buf) };
478 Ok(TrustedSliceWriter::new(buf))
479 }
480}
481
482#[cfg(all(test, feature = "alloc"))]
483mod tests {
484 #![allow(clippy::arithmetic_side_effects)]
485 use {super::*, crate::proptest_config::proptest_cfg, alloc::vec::Vec, proptest::prelude::*};
486
487 #[test]
488 fn test_reader_peek() {
489 let mut reader = b"hello" as &[u8];
490 assert!(matches!(reader.peek(), Ok(&b'h')));
491 }
492
493 #[test]
494 fn test_reader_peek_empty() {
495 let mut reader = b"" as &[u8];
496 assert!(matches!(reader.peek(), Err(ReadError::ReadSizeLimit(1))));
497 }
498
499 macro_rules! with_readers {
501 ($bytes:expr, |$reader:ident| $body:block) => {{
502 {
503 let mut $reader = $bytes.as_slice();
504 $body
505 }
506 {
507 let mut $reader = TrustedSliceReaderZeroCopy::new($bytes);
508 $body
509 }
510 {
511 let mut $reader = Cursor::new($bytes);
512 $body
513 }
514 }};
515 }
516
517 macro_rules! with_untrusted_readers {
519 ($bytes:expr, |$reader:ident| $body:block) => {{
520 {
521 let mut $reader = $bytes.as_slice();
522 $body
523 }
524 }};
525 }
526
527 macro_rules! with_writers {
529 ($buffer:expr, |$writer:ident| $body:block) => {{
530 {
531 let $writer = &mut $buffer.spare_capacity_mut();
532 $body
533 $buffer.clear();
534 }
535 {
536 let mut $writer = TrustedSliceWriter::new($buffer.spare_capacity_mut());
537 $body
538 $buffer.clear();
539 }
540 {
541 let _capacity = $buffer.capacity();
542 $buffer.resize(_capacity, 0);
543 let $writer = &mut $buffer.as_mut_slice();
544 $body
545 $buffer.clear();
546 }
547 }};
548 }
549
550 macro_rules! with_known_len_writers {
552 ($buffer:expr, |$writer:ident| $body_write:block, $body_check:expr) => {{
553 let capacity = $buffer.capacity();
554 {
555 $buffer.resize(capacity, 0);
556 $buffer.fill(0);
557 let $writer = $buffer.as_mut_slice();
558 $body_write
559 $body_check;
560 $buffer.clear();
561 }
562 {
563 $buffer.fill(0);
564 $buffer.clear();
565 let $writer = $buffer.spare_capacity_mut();
566 $body_write
567 unsafe { $buffer.set_len(capacity) }
568 $body_check;
569 }
570 }};
571 }
572
573 proptest! {
574 #![proptest_config(proptest_cfg())]
575
576 #[test]
577 fn test_reader_copy_into_slice(bytes in any::<Vec<u8>>()) {
578 with_readers!(&bytes, |reader| {
579 let mut vec = Vec::with_capacity(bytes.len());
580 let half = bytes.len() / 2;
581 let dst = vec.spare_capacity_mut();
582 reader.copy_into_slice(&mut dst[..half]).unwrap();
583 unsafe { reader.as_trusted_for(bytes.len() - half) }
584 .unwrap()
585 .copy_into_slice(&mut dst[half..])
586 .unwrap();
587 unsafe { vec.set_len(bytes.len()) };
588 prop_assert_eq!(&vec, &bytes);
589 });
590 }
591
592 #[test]
593 fn test_reader_fill_exact(bytes in any::<Vec<u8>>()) {
594 with_readers!(&bytes, |reader| {
595 let read = reader.fill_exact(bytes.len()).unwrap();
596 prop_assert_eq!(&read, &bytes);
597 });
598 }
599
600 #[test]
601 fn slice_reader_fill_exact_input_too_large(bytes in any::<Vec<u8>>()) {
602 with_untrusted_readers!(&bytes, |reader| {
603 prop_assert!(matches!(reader.fill_exact(bytes.len() + 1), Err(ReadError::ReadSizeLimit(x)) if x == bytes.len() + 1));
604 });
605 }
606
607 #[test]
608 fn test_reader_copy_into_slice_input_too_large(bytes in any::<Vec<u8>>()) {
609 with_untrusted_readers!(&bytes, |reader| {
610 let mut vec = Vec::with_capacity(bytes.len() + 1);
611 let dst = vec.spare_capacity_mut();
612 prop_assert!(matches!(reader.copy_into_slice(dst), Err(ReadError::ReadSizeLimit(x)) if x == bytes.len() + 1));
613 });
614 }
615
616 #[test]
617 fn test_reader_consume(bytes in any::<Vec<u8>>()) {
618 with_readers!(&bytes, |reader| {
619 reader.consume(bytes.len()).unwrap();
620 prop_assert!(matches!(reader.fill_buf(1), Ok(&[])));
621 });
622 }
623
624 #[test]
625 fn test_reader_consume_input_too_large(bytes in any::<Vec<u8>>()) {
626 let mut reader = bytes.as_slice();
627 prop_assert!(matches!(reader.consume(bytes.len() + 1), Err(ReadError::ReadSizeLimit(x)) if x == bytes.len() + 1));
628 }
629
630 #[test]
631 fn test_reader_copy_into_t(ints in proptest::collection::vec(any::<u64>(), 0..=100)) {
632 let bytes = ints.iter().flat_map(|int| int.to_le_bytes()).collect::<Vec<u8>>();
633 with_readers!(&bytes, |reader| {
634 for int in &ints {
635 let mut val = MaybeUninit::<u64>::uninit();
636 unsafe { reader.copy_into_t(&mut val).unwrap() };
637 unsafe { prop_assert_eq!(val.assume_init(), *int) };
638 }
639 });
640 }
641
642 #[test]
643 fn test_reader_copy_into_slice_t(ints in proptest::collection::vec(any::<u64>(), 0..=100)) {
644 let bytes = ints.iter().flat_map(|int| int.to_le_bytes()).collect::<Vec<u8>>();
645 with_readers!(&bytes, |reader| {
646 let mut vals: Vec<u64> = Vec::with_capacity(ints.len());
647 let dst = vals.spare_capacity_mut();
648 unsafe { reader.copy_into_slice_t(dst).unwrap() };
649 unsafe { vals.set_len(ints.len()) };
650 prop_assert_eq!(&vals, &ints);
651 });
652 }
653
654 #[test]
655 fn test_writer_write(bytes in any::<Vec<u8>>()) {
656 let capacity = bytes.len();
657 let mut buffer = Vec::with_capacity(capacity);
658 with_writers!(&mut buffer, |writer| {
659 writer.write(&bytes).unwrap();
660 let written = capacity - writer.len();
661 unsafe { buffer.set_len(written) };
662 prop_assert_eq!(&buffer, &bytes);
663 });
664
665 with_known_len_writers!(&mut buffer, |writer| {
666 writer.write(&bytes).unwrap();
667 }, prop_assert_eq!(&buffer, &bytes));
668 }
669
670 #[test]
671 fn test_writer_write_input_too_large(bytes in proptest::collection::vec(any::<u8>(), 1..=100)) {
672 let mut buffer = Vec::with_capacity(bytes.len() - 1);
673 let writer = &mut buffer.spare_capacity_mut();
674 prop_assert!(matches!(writer.write(&bytes), Err(WriteError::WriteSizeLimit(x)) if x == bytes.len()));
675
676 let writer = buffer.spare_capacity_mut();
677 prop_assert!(matches!(writer.write(&bytes), Err(WriteError::WriteSizeLimit(x)) if x == bytes.len()));
678 }
679
680 #[test]
681 fn test_writer_write_t(int in any::<u64>()) {
682 let capacity = 8;
683 let mut buffer = Vec::with_capacity(capacity);
684 with_writers!(&mut buffer, |writer| {
685 unsafe { writer.write_t(&int).unwrap() };
686 let written = capacity - writer.len();
687 unsafe { buffer.set_len(written) };
688 prop_assert_eq!(&buffer, &int.to_le_bytes());
689 });
690
691 with_known_len_writers!(&mut buffer, |writer| {
692 unsafe { writer.write_t(&int).unwrap() };
693 }, prop_assert_eq!(&buffer, &int.to_le_bytes()));
694 }
695
696 #[test]
697 fn test_writer_write_slice_t(ints in proptest::collection::vec(any::<u64>(), 0..=100)) {
698 let bytes = ints.iter().flat_map(|int| int.to_le_bytes()).collect::<Vec<u8>>();
699 let capacity = bytes.len();
700 let mut buffer = Vec::with_capacity(capacity);
701 with_writers!(&mut buffer, |writer| {
702 unsafe { writer.write_slice_t(&ints).unwrap() };
703 let written = capacity - writer.len();
704 unsafe { buffer.set_len(written) };
705 prop_assert_eq!(&buffer, &bytes);
706 });
707
708 with_known_len_writers!(&mut buffer, |writer| {
709 unsafe { writer.write_slice_t(&ints).unwrap() };
710 }, prop_assert_eq!(&buffer, &bytes));
711 }
712 }
713}