uninit/read/
impls.rs

1use super::*;
2
3#[cfg(feature = "specialization")]
4#[doc(cfg(feature = "specialization"))]
5default unsafe impl<R: Read> ReadIntoUninit for R {
6    #[inline]
7    default fn read_into_uninit<'buf>(
8        self: &'_ mut Self,
9        buf: Out<'buf, [u8]>,
10    ) -> io::Result<&'buf mut [u8]> {
11        let buf = buf.fill_with_iter(::core::iter::repeat(0));
12        self.read(buf).map(move |n| &mut buf[..n])
13    }
14
15    #[inline]
16    default fn read_into_uninit_exact<'buf>(
17        self: &'_ mut Self,
18        buf: Out<'buf, [u8]>,
19    ) -> io::Result<&'buf mut [u8]> {
20        let buf = buf.fill_with_iter(::core::iter::repeat(0));
21        self.read_exact(buf).map(|()| buf)
22    }
23}
24
25// # Safety:
26//
27//   - basic delegation
28//
29//   - `read_into_uninit_exact` is not overriden
30unsafe impl<R: ReadIntoUninit + ?Sized> ReadIntoUninit for &'_ mut R {
31    #[inline]
32    fn read_into_uninit<'buf>(
33        self: &'_ mut Self,
34        buf: Out<'buf, [u8]>,
35    ) -> io::Result<&'buf mut [u8]> {
36        (**self).read_into_uninit(buf)
37    }
38}
39
40// # Safety
41//
42//   - `read_into_uninit` does return a prefix slice on success;
43//
44//   - `read_into_uninit_exact` is not overriden
45unsafe impl ReadIntoUninit for &'_ [u8] {
46    #[inline]
47    fn read_into_uninit<'buf>(
48        self: &'_ mut Self,
49        buf: Out<'buf, [u8]>,
50    ) -> io::Result<&'buf mut [u8]> {
51        let count = ::std::cmp::min(buf.len(), self.len());
52        let (to_copy, remaining) = self.split_at(count);
53        *self = remaining;
54
55        // Taken from stdlib:
56        // "First check if the amount of bytes we want to read is small:
57        // `copy_from_slice` will generally expand to a call to `memcpy`, and
58        // for a single byte the overhead is significant."
59        if count == 1 {
60            Ok(slice::from_mut(buf.get_out(0).unwrap().write(to_copy[0])))
61        } else {
62            Ok(buf.get_out(..count).unwrap().copy_from_slice(to_copy))
63        }
64    }
65}
66
67macro_rules! impl_ReadIntoUninit_for_impl_BufRead {(
68    $(
69        for [$($generics:tt)*]
70            $T:ty
71        $(where {
72            $($wc:tt)*
73        })? ;
74    )*
75) => (
76    $(
77        // # Safety:
78        //
79        //   - delegates to `<&'_ [u8] as ReadIntoUninit>::read_into_uninit`
80        //
81        //   - `read_into_uninit_exact` is not overriden
82        unsafe
83        impl<$($generics)*> ReadIntoUninit
84            for $T
85        $(where
86            $($wc)*
87        )?
88        {
89            #[inline]
90            fn read_into_uninit<'buf> (
91                self: &'_ mut Self,
92                buf: Out<'buf, [u8]>,
93            ) -> io::Result<&'buf mut [u8]>
94            {
95                let buf = {
96                    let mut read_buf: &[u8] = io::BufRead::fill_buf(self)?;
97                    read_buf.read_into_uninit(buf)?
98                };
99                io::BufRead::consume(self, buf.len());
100                Ok(buf)
101            }
102
103        }
104    )*
105)}
106
107impl_ReadIntoUninit_for_impl_BufRead! {
108    for [R : io::Read]
109        io::BufReader<R>
110    ;
111    for [T : AsRef<[u8]>]
112        io::Cursor<T>
113    ;
114    for []
115        io::Empty
116    ;
117    for []
118        io::StdinLock<'_>
119    ;
120    for [T : io::BufRead]
121        io::Take<T>
122    ;
123}
124
125// # Safety:
126//
127//   - basic delegation
128//
129//   - `read_into_uninit_exact` is not overriden
130unsafe impl<R: ReadIntoUninit + ?Sized> ReadIntoUninit for Box<R> {
131    #[inline]
132    fn read_into_uninit<'buf>(
133        self: &'_ mut Self,
134        buf: Out<'buf, [u8]>,
135    ) -> io::Result<&'buf mut [u8]> {
136        (**self).read_into_uninit(buf)
137    }
138}