1use {
2 crate::io::{BorrowKind, ReadResult, Reader, read_size_limit, slice::SliceScopedUnchecked},
3 core::{mem::MaybeUninit, ptr::copy_nonoverlapping},
4 std::io::{self, BufReader, Cursor, Read},
5};
6
7pub struct ReadAdapter<R: ?Sized>(R);
26
27impl<R: Read> ReadAdapter<R> {
28 pub fn new(inner: R) -> Self {
29 Self(inner)
30 }
31}
32
33#[inline]
34fn copy_into_slice<R: Read + ?Sized>(reader: &mut R, dst: &mut [u8]) -> ReadResult<()> {
35 #[cold]
36 fn maybe_eof_to_read_size_limit(err: io::Error, len: usize) -> ReadResult<()> {
37 if err.kind() == io::ErrorKind::UnexpectedEof {
38 Err(read_size_limit(len))
39 } else {
40 Err(err.into())
41 }
42 }
43 if let Err(e) = reader.read_exact(dst) {
44 return maybe_eof_to_read_size_limit(e, dst.len());
45 };
46 Ok(())
47}
48
49unsafe impl<R: Read + ?Sized> Reader<'_> for ReadAdapter<R> {
50 #[inline(always)]
51 fn copy_into_slice(&mut self, dst: &mut [u8]) -> ReadResult<()> {
52 copy_into_slice(&mut self.0, dst)
53 }
54}
55
56unsafe impl<R: Read + ?Sized> Reader<'_> for BufReader<R> {
57 #[inline(always)]
58 fn copy_into_slice(&mut self, dst: &mut [u8]) -> ReadResult<()> {
59 copy_into_slice(self, dst)
60 }
61}
62
63#[inline]
64fn cursor_advance(cursor: &mut Cursor<impl AsRef<[u8]>>, n: usize) -> ReadResult<&[u8]> {
65 let Ok(pos) = usize::try_from(cursor.position()) else {
66 return Err(read_size_limit(usize::MAX));
67 };
68
69 let inner = cursor.get_ref().as_ref();
70 let next_pos = pos.saturating_add(n);
71 if next_pos > inner.len() {
72 return Err(read_size_limit(n));
73 }
74
75 cursor.set_position(next_pos as u64);
76 let inner = cursor.get_ref().as_ref();
77 Ok(&inner[pos..next_pos])
78}
79
80unsafe impl<'a, T> Reader<'a> for Cursor<T>
81where
82 T: AsRef<[u8]>,
83{
84 const BORROW_KINDS: u8 = BorrowKind::CallSite.mask();
85
86 #[inline]
87 fn copy_into_slice(&mut self, dst: &mut [u8]) -> ReadResult<()> {
88 let src = cursor_advance(self, dst.len())?;
89 unsafe { copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), dst.len()) };
94 Ok(())
95 }
96
97 #[inline]
98 fn copy_into_uninit_slice(&mut self, dst: &mut [MaybeUninit<u8>]) -> ReadResult<()> {
99 let src = cursor_advance(self, dst.len())?;
100 unsafe { copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr().cast::<u8>(), dst.len()) };
105 Ok(())
106 }
107
108 #[inline(always)]
109 fn take_array<const N: usize>(&mut self) -> ReadResult<[u8; N]> {
110 let src = cursor_advance(self, N)?;
111 Ok(unsafe { *(src.as_ptr().cast::<[u8; N]>()) })
116 }
117
118 #[inline]
119 fn take_scoped(&mut self, len: usize) -> ReadResult<&[u8]> {
120 cursor_advance(self, len)
121 }
122
123 #[inline]
124 unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> ReadResult<impl Reader<'a>> {
125 let buf = cursor_advance(self, n_bytes)?;
126 Ok(unsafe { SliceScopedUnchecked::new(buf) })
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 struct InspectingReader {
141 data: Vec<u8>,
142 pos: usize,
143 observed: Vec<u8>,
144 }
145
146 impl InspectingReader {
147 fn new(data: Vec<u8>) -> Self {
148 Self {
149 data,
150 pos: 0,
151 observed: Vec::new(),
152 }
153 }
154 }
155
156 impl Read for InspectingReader {
157 fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
158 self.observed.extend_from_slice(dst);
159
160 let remaining = &self.data[self.pos..];
161 let len = dst.len().min(remaining.len());
162 dst[..len].copy_from_slice(&remaining[..len]);
163 self.pos = self.pos.checked_add(len).unwrap();
164 Ok(len)
165 }
166 }
167
168 #[test]
169 fn read_adapter_initializes_destination_before_reading() {
170 let expected = 0x0123_4567_89ab_cdef_u64;
171 let data = crate::serialize(&expected).unwrap();
172 let mut reader = InspectingReader::new(data.clone());
173
174 let actual: u64 = crate::deserialize_from(ReadAdapter::new(&mut reader)).unwrap();
175
176 assert_eq!(actual, expected);
177 assert_eq!(reader.observed, vec![0; data.len()]);
178 }
179
180 #[test]
181 fn buf_reader_initializes_destination_before_reading() {
182 let expected = 0x0123_4567_89ab_cdef_u64;
183 let data = crate::serialize(&expected).unwrap();
184 let mut reader = InspectingReader::new(data.clone());
185
186 let actual: u64 =
187 crate::deserialize_from(BufReader::with_capacity(1, &mut reader)).unwrap();
188
189 assert_eq!(actual, expected);
190 assert_eq!(reader.observed, vec![0; data.len()]);
191 }
192}