Skip to main content

genio/
std_impls.rs

1//! This module contains glue `for std::io` and other `std` types.
2
3use Read;
4use Write;
5use ExtendFromReader;
6use ExtendFromReaderSlow;
7use error::ExtendError;
8use ReadOverwrite;
9use void::Void;
10use std::vec::Vec;
11use std::io::{Sink, Empty};
12use std::io;
13use bufio::BufWrite;
14
15impl Write for Vec<u8> {
16    type WriteError = Void;
17    type FlushError = Void;
18
19    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::WriteError> {
20        self.extend_from_slice(buf);
21        Ok(buf.len())
22    }
23
24    fn flush(&mut self) -> Result<(), Self::FlushError> {
25        Ok(())
26    }
27
28    fn size_hint(&mut self, bytes: usize) {
29        self.reserve(bytes)
30    }
31
32    fn uses_size_hint(&self) -> bool {
33        true
34    }
35}
36
37unsafe impl BufWrite for Vec<u8> {
38    fn request_buffer(&mut self) -> Result<*mut [u8], Self::WriteError> {
39        use ::std::slice;
40
41        // Ensure there is a space for data
42        self.reserve(1);
43        unsafe {
44            Ok(&mut slice::from_raw_parts_mut(self.as_mut_ptr(), self.capacity())[self.len()..])
45        }
46    }
47
48    unsafe fn submit_buffer(&mut self, size: usize) {
49        let new_len = self.len() + size;
50        self.set_len(new_len)
51    }
52}
53
54impl ExtendFromReaderSlow for Vec<u8> {
55    // We could return OOM, but there is no `try_alloc`, so we have to panic.
56    // That means `Vec` can never fail.
57    type ExtendError = Void;
58
59    fn extend_from_reader_slow<R: Read + ?Sized>(&mut self, reader: &mut R) -> Result<usize, ExtendError<R::ReadError, Self::ExtendError>> {
60        let begin = self.len();
61        self.resize(begin + 1024, 0);
62        match reader.read(&mut self[begin..]) {
63            Ok(bytes) => {
64                // Check that returned value is correct.
65                // This could be omitted, since `ReadOverwrite` is `unsafe` but this is
66                // quite cheap check and avoids serious problems.
67                assert!(bytes <= self.capacity() - begin);
68                self.resize(begin + bytes, 0);
69                Ok(bytes)
70            },
71            Err(e) => {
72                // We have to reset len to previous value if error happens.
73                self.resize(begin, 0);
74                Err(ExtendError::ReadErr(e))
75            },
76        }
77    }
78}
79
80// Efficient implementation
81impl ExtendFromReader for Vec<u8> {
82    fn extend_from_reader<R: Read + ReadOverwrite + ?Sized>(&mut self, reader: &mut R) -> Result<usize, ExtendError<R::ReadError, Self::ExtendError>> {
83        // Prepare space
84        self.reserve(1024);
85
86        // This code is "unsafe because we use `.set_len()` to improve performance.
87        // It also relies on `ReadOverwrite`.
88        unsafe {
89            // `std::Vec` doesn't guarantee that capacity will be greater after call to `reserve()`
90            // so we don't rely on it.
91            // "Vec does not guarantee any particular growth strategy when reallocating when full,
92            // nor when reserve is called." - documentation
93            if self.capacity() > self.len() {
94                let begin = self.len();
95                // This is correct in the sense it won't cause UB but the `Vec` will contain
96                // uninitialized bytes. Those bytes will be overwritten by reader thanks to
97                // `ReadOverwrite`
98                let capacity = self.capacity();
99                self.set_len(capacity);
100                match reader.read(&mut self[begin..]) {
101                    Ok(bytes) => {
102                        // Check that returned value is correct.
103                        // This could be omitted, since `ReadOverwrite` is `unsafe` but this is
104                        // quite cheap check and avoids serious problems.
105                        assert!(bytes <= capacity - begin);
106                        self.set_len(begin + bytes);
107                        Ok(bytes)
108                    },
109                    Err(e) => {
110                        // We have to reset len to previous value if error happens.
111                        self.set_len(begin);
112                        Err(ExtendError::ReadErr(e))
113                    },
114                }
115            } else {
116                // Fallback for cases where `reserve` reserves nothing.
117                self.extend_from_reader_slow(reader)
118            }
119        }
120    }
121}
122
123// Same as our Sink.
124impl Write for Sink {
125    type WriteError = Void;
126    type FlushError = Void;
127
128    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::WriteError> {
129        Ok(buf.len())
130    }
131
132    fn flush(&mut self) -> Result<(), Self::FlushError> {
133        Ok(())
134    }
135
136    fn size_hint(&mut self, _bytes: usize) {
137    }
138}
139
140// Same as our Empty.
141impl Read for Empty {
142    type ReadError = Void;
143
144    fn read(&mut self, _buf: &mut [u8]) -> Result<usize, Self::ReadError> {
145        Ok(0)
146    }
147}
148
149/// Wrapper providing `std::io::Read` trait for `genio::Read` types.
150pub struct StdRead<R> (R);
151
152impl<R: Read> StdRead<R> {
153    /// Wraps `genio` reader into `std` reader.
154    pub fn new(reader: R) -> Self {
155        StdRead(reader)
156    }
157
158    /// Unwraps inner reader.
159    pub fn into_inner(self) -> R {
160        self.0
161    }
162}
163
164impl<E: Into<io::Error>, R: Read<ReadError=E>> io::Read for StdRead<R> {
165    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
166        self.0.read(buf).map_err(Into::into)
167    }
168}
169
170/// Wrapper providing `std::io::Write` trait for `genio::Write` types.
171pub struct StdWrite<W> (W);
172
173impl<W: Write> StdWrite<W> {
174    /// Wraps `genio` writer into `std` writer.
175    pub fn new(writer: W) -> Self {
176        StdWrite(writer)
177    }
178
179    /// Unwraps inner writer.
180    pub fn into_inner(self) -> W {
181        self.0
182    }
183}
184
185impl<WE: Into<io::Error>, FE: Into<io::Error>, W: Write<WriteError=WE, FlushError=FE>> io::Write for StdWrite<W> {
186    fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
187        self.0.write(buf).map_err(Into::into)
188    }
189
190    fn flush(&mut self) -> Result<(), io::Error> {
191        self.0.flush().map_err(Into::into)
192    }
193}
194
195/// Wrapper providing `std::io::Read + std::io::Write` traits for `genio::Read + genio::Write` types.
196pub struct StdIo<T> (T);
197
198impl<RE: Into<io::Error>, WE: Into<io::Error>, FE: Into<io::Error>, T: Read<ReadError=RE> + Write<WriteError=WE, FlushError=FE>> StdIo<T> {
199    /// Wraps `genio` reader+writer into `std` reader+writer.
200    pub fn new(io: T) -> Self {
201        StdIo(io)
202    }
203
204    /// Unwraps inner io.
205    pub fn into_inner(self) -> T {
206        self.0
207    }
208}
209
210impl<E: Into<io::Error>, T: Read<ReadError=E>> io::Read for StdIo<T> {
211    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
212        self.0.read(buf).map_err(Into::into)
213    }
214}
215
216impl<WE: Into<io::Error>, FE: Into<io::Error>, T: Write<WriteError=WE, FlushError=FE>> io::Write for StdIo<T> {
217    fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
218        self.0.write(buf).map_err(Into::into)
219    }
220
221    fn flush(&mut self) -> Result<(), io::Error> {
222        self.0.flush().map_err(Into::into)
223    }
224}
225
226/// Wrapper providing `genio::Read` trait for `std::io::Read` types.
227pub struct GenioRead<R> (R);
228
229impl<R: io::Read> GenioRead<R> {
230    /// Wraps `std` readerinto `genio` reader.
231    pub fn new(reader: R) -> Self {
232        GenioRead(reader)
233    }
234
235    /// Unwraps `std` reader `genio` reader.
236    pub fn into_inner(self) -> R {
237        self.0
238    }
239}
240
241impl<R: io::Read> Read for GenioRead<R> {
242    type ReadError = io::Error;
243
244    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
245        self.0.read(buf)
246    }
247}
248
249/// Wrapper providing `genio::Write` trait for `std::io::Write` types.
250pub struct GenioWrite<W> (W);
251
252impl<W: io::Write> GenioWrite<W> {
253    /// Wraps `std` writer into `genio` writer.
254    pub fn new(writer: W) -> Self {
255        GenioWrite(writer)
256    }
257
258    /// Unwraps `std` writer into `genio` writer.
259    pub fn into_inner(self) -> W {
260        self.0
261    }
262}
263
264impl<W: io::Write> Write for GenioWrite<W> {
265    type WriteError = io::Error;
266    type FlushError = io::Error;
267
268    fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
269        self.0.write(buf)
270    }
271
272    fn flush(&mut self) -> Result<(), io::Error> {
273        self.0.flush()
274    }
275
276    fn size_hint(&mut self, _bytes: usize) {
277    }
278}
279
280/// Wrapper providing `genio::Read + genio::Write` traits for `std::io::Read + std::io::Write` types.
281pub struct GenioIo<T> (T);
282
283impl<T: io::Read + io::Write> GenioIo<T> {
284    /// Wraps `std` reader+writer into `genio` reader+writer.
285    pub fn new(io: T) -> Self {
286        GenioIo(io)
287    }
288
289    /// Unwraps `std` reader+writer into `genio` reader+writer.
290    pub fn into_inner(self) -> T {
291        self.0
292    }
293}
294
295impl<T: io::Read> Read for GenioIo<T> {
296    type ReadError = io::Error;
297
298    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
299        self.0.read(buf)
300    }
301}
302
303impl<T: io::Write> Write for GenioIo<T> {
304    type WriteError = io::Error;
305    type FlushError = io::Error;
306
307    fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
308        self.0.write(buf)
309    }
310
311    fn flush(&mut self) -> Result<(), io::Error> {
312        self.0.flush()
313    }
314
315    fn size_hint(&mut self, _bytes: usize) {
316    }
317}