ark_std/io/
mod.rs

1//! no-std io replacement
2use crate::{cmp, convert::TryInto, mem, vec::Vec};
3
4mod error;
5pub use error::*;
6
7pub mod prelude {
8    pub use super::{Read, Result, Write};
9}
10
11/// The `Read` trait allows for reading bytes from a source.
12///
13/// Implementors of the `Read` trait are called 'readers'.
14///
15/// Readers are defined by one required method, [`read()`]. Each call to [`read()`]
16/// will attempt to pull bytes from this source into a provided buffer. A
17/// number of other methods are implemented in terms of [`read()`], giving
18/// implementors a number of ways to read bytes while only needing to implement
19/// a single method.
20///
21/// Readers are intended to be composable with one another. Many implementors
22/// throughout [`ark_std::io`] take and provide types which implement the `Read`
23/// trait.
24///
25/// Please note that each call to [`read()`] may involve a system call, and
26/// therefore, using something that implements [`BufRead`], such as
27/// [`BufReader`], will be more efficient.
28///
29///
30/// Read from [`&str`] because [`&[u8]`][slice] implements `Read`:
31///
32/// ```no_run
33/// # use ark_std::io;
34/// use ark_std::io::prelude::*;
35///
36/// fn main() -> Result<()> {
37///     let mut b = "This string will be read".as_bytes();
38///     let mut buffer = [0; 10];
39///
40///     // read up to 10 bytes
41///     b.read(&mut buffer)?;
42///
43///     Ok(())
44/// }
45/// ```
46///
47/// [`read()`]: trait.Read.html#tymethod.read
48/// [`ark_std::io`]: ../../std/io/index.html
49/// [`BufRead`]: trait.BufRead.html
50/// [`BufReader`]: struct.BufReader.html
51/// [`&str`]: ../../std/primitive.str.html
52/// [slice]: ../../std/primitive.slice.html
53pub trait Read {
54    /// Pull some bytes from this source into the specified buffer, returning
55    /// how many bytes were read.
56    ///
57    /// This function does not provide any guarantees about whether it blocks
58    /// waiting for data, but if an object needs to block for a read but cannot
59    /// it will typically signal this via an [`Err`] return value.
60    ///
61    /// If the return value of this method is [`Ok(n)`], then it must be
62    /// guaranteed that `0 <= n <= buf.len()`. A nonzero `n` value indicates
63    /// that the buffer `buf` has been filled in with `n` bytes of data from this
64    /// source. If `n` is `0`, then it can indicate that the the buffer
65    /// specified was 0 bytes in length.
66    ///
67    /// No guarantees are provided about the contents of `buf` when this
68    /// function is called, implementations cannot rely on any property of the
69    /// contents of `buf` being true. It is recommended that implementations
70    /// only write data to `buf` instead of reading its contents.
71    ///
72    /// # Errors
73    ///
74    /// If this function encounters any form of I/O or other error, an error
75    /// variant will be returned. If an error is returned then it must be
76    /// guaranteed that no bytes were read.
77    ///
78    /// An error of the [`ErrorKind::Interrupted`] kind is non-fatal and the read
79    /// operation should be retried if there is nothing else to do.
80    ///
81    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
82
83    /// Read the exact number of bytes required to fill `buf`.
84    ///
85    /// This function reads as many bytes as necessary to completely fill the
86    /// specified buffer `buf`.
87    ///
88    /// No guarantees are provided about the contents of `buf` when this
89    /// function is called, implementations cannot rely on any property of the
90    /// contents of `buf` being true. It is recommended that implementations
91    /// only write data to `buf` instead of reading its contents.
92    ///
93    /// # Errors
94    ///
95    /// If this function encounters an error of the kind
96    /// [`ErrorKind::Interrupted`] then the error is ignored and the operation
97    /// will continue.
98    ///
99    /// If any other read error is encountered then this function immediately
100    /// returns. The contents of `buf` are unspecified in this case.
101    ///
102    /// If this function returns an error, it is unspecified how many bytes it
103    /// has read, but it will never read more than would be necessary to
104    /// completely fill the buffer.
105    fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
106        while !buf.is_empty() {
107            match self.read(buf) {
108                Ok(0) => break,
109                Ok(n) => {
110                    let tmp = buf;
111                    buf = &mut tmp[n..];
112                },
113                Err(ref e) if e.kind() == ErrorKind::Interrupted => {},
114                Err(e) => return Err(e),
115            }
116        }
117        if !buf.is_empty() {
118            Err(Error::new(
119                ErrorKind::UnexpectedEof,
120                "failed to fill whole buffer",
121            ))
122        } else {
123            Ok(())
124        }
125    }
126
127    /// Creates a "by reference" adaptor for this instance of `Read`.
128    ///
129    /// The returned adaptor also implements `Read` and will simply borrow this
130    /// current reader.
131    fn by_ref(&mut self) -> &mut Self
132    where
133        Self: Sized,
134    {
135        self
136    }
137}
138
139pub trait Write {
140    /// Write a buffer into this writer, returning how many bytes were written.
141    ///
142    /// This function will attempt to write the entire contents of `buf`, but
143    /// the entire write may not succeed, or the write may also generate an
144    /// error. A call to `write` represents *at most one* attempt to write to
145    /// any wrapped object.
146    ///
147    /// Calls to `write` are not guaranteed to block waiting for data to be
148    /// written, and a write which would otherwise block can be indicated through
149    /// an [`Err`] variant.
150    ///
151    /// If the return value is [`Ok(n)`] then it must be guaranteed that
152    /// `0 <= n <= buf.len()`. A return value of `0` typically means that the
153    /// underlying object is no longer able to accept bytes and will likely not
154    /// be able to in the future as well, or that the buffer provided is empty.
155    ///
156    /// # Errors
157    ///
158    /// Each call to `write` may generate an I/O error indicating that the
159    /// operation could not be completed. If an error is returned then no bytes
160    /// in the buffer were written to this writer.
161    ///
162    /// It is **not** considered an error if the entire buffer could not be
163    /// written to this writer.
164    ///
165    /// An error of the [`ErrorKind::Interrupted`] kind is non-fatal and the
166    /// write operation should be retried if there is nothing else to do.
167    ///
168    /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
169    /// [`Ok(n)`]:  ../../std/result/enum.Result.html#variant.Ok
170    /// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted
171    fn write(&mut self, buf: &[u8]) -> Result<usize>;
172
173    /// Flush this output stream, ensuring that all intermediately buffered
174    /// contents reach their destination.
175    ///
176    /// # Errors
177    ///
178    /// It is considered an error if not all bytes could be written due to
179    /// I/O errors or EOF being reached.
180    ///
181    fn flush(&mut self) -> Result<()>;
182
183    /// Attempts to write an entire buffer into this writer.
184    ///
185    /// This method will continuously call [`write`] until there is no more data
186    /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is
187    /// returned. This method will not return until the entire buffer has been
188    /// successfully written or such an error occurs. The first error that is
189    /// not of [`ErrorKind::Interrupted`] kind generated from this method will be
190    /// returned.
191    ///
192    /// # Errors
193    ///
194    /// This function will return the first error of
195    /// non-[`ErrorKind::Interrupted`] kind that [`write`] returns.
196    ///
197    /// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted
198    /// [`write`]: #tymethod.write
199    fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
200        while !buf.is_empty() {
201            match self.write(buf) {
202                Ok(0) => {
203                    return Err(Error::new(
204                        ErrorKind::WriteZero,
205                        "failed to write whole buffer",
206                    ))
207                },
208                Ok(n) => buf = &buf[n..],
209                Err(ref e) if e.kind() == ErrorKind::Interrupted => {},
210                Err(e) => return Err(e),
211            }
212        }
213        Ok(())
214    }
215
216    /// Creates a "by reference" adaptor for this instance of `Write`.
217    ///
218    /// The returned adaptor also implements `Write` and will simply borrow this
219    /// current writer.
220    fn by_ref(&mut self) -> &mut Self
221    where
222        Self: Sized,
223    {
224        self
225    }
226}
227
228impl<R: Read + ?Sized> Read for &mut R {
229    #[inline]
230    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
231        (**self).read(buf)
232    }
233
234    #[inline]
235    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
236        (**self).read_exact(buf)
237    }
238}
239
240impl Read for &[u8] {
241    #[inline]
242    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
243        let amt = cmp::min(buf.len(), self.len());
244        let (a, b) = self.split_at(amt);
245
246        // First check if the amount of bytes we want to read is small:
247        // `copy_from_slice` will generally expand to a call to `memcpy`, and
248        // for a single byte the overhead is significant.
249        if amt == 1 {
250            buf[0] = a[0];
251        } else {
252            buf[..amt].copy_from_slice(a);
253        }
254
255        *self = b;
256        Ok(amt)
257    }
258
259    #[inline]
260    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
261        if buf.len() > self.len() {
262            return Err(Error::new(
263                ErrorKind::UnexpectedEof,
264                "failed to fill whole buffer",
265            ));
266        }
267        let (a, b) = self.split_at(buf.len());
268
269        // First check if the amount of bytes we want to read is small:
270        // `copy_from_slice` will generally expand to a call to `memcpy`, and
271        // for a single byte the overhead is significant.
272        if buf.len() == 1 {
273            buf[0] = a[0];
274        } else {
275            buf.copy_from_slice(a);
276        }
277
278        *self = b;
279        Ok(())
280    }
281}
282
283impl<W: Write + ?Sized> Write for &mut W {
284    #[inline]
285    fn write(&mut self, buf: &[u8]) -> Result<usize> {
286        (**self).write(buf)
287    }
288
289    #[inline]
290    fn flush(&mut self) -> Result<()> {
291        (**self).flush()
292    }
293
294    #[inline]
295    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
296        (**self).write_all(buf)
297    }
298}
299
300impl Write for &mut [u8] {
301    fn write(&mut self, data: &[u8]) -> Result<usize> {
302        let amt = cmp::min(data.len(), self.len());
303        let (a, b) = mem::replace(self, &mut []).split_at_mut(amt);
304        a.copy_from_slice(&data[..amt]);
305        *self = b;
306        Ok(amt)
307    }
308
309    #[inline]
310    fn write_all(&mut self, data: &[u8]) -> Result<()> {
311        if self.write(data)? == data.len() {
312            Ok(())
313        } else {
314            Err(Error::new(
315                ErrorKind::WriteZero,
316                "failed to write whole buffer",
317            ))
318        }
319    }
320
321    #[inline]
322    fn flush(&mut self) -> Result<()> {
323        Ok(())
324    }
325}
326
327impl Write for Vec<u8> {
328    #[inline]
329    fn write(&mut self, buf: &[u8]) -> Result<usize> {
330        self.extend_from_slice(buf);
331        Ok(buf.len())
332    }
333
334    #[inline]
335    fn write_all(&mut self, buf: &[u8]) -> Result<()> {
336        self.extend_from_slice(buf);
337        Ok(())
338    }
339
340    #[inline]
341    fn flush(&mut self) -> Result<()> {
342        Ok(())
343    }
344}
345
346/////////////////////////////////////////////////////////////////////////////////
347/////////////////////////////////////////////////////////////////////////////////
348/////////////////////////////////////////////////////////////////////////////////
349
350/// This data structure is used as a workaround for current design of `ToBytes`
351/// which does not allow multiple writes to `&mut [u8]`.
352pub struct Cursor<T> {
353    inner: T,
354    pos: u64,
355}
356
357impl<T> Cursor<T> {
358    /// Creates a new cursor wrapping the provided underlying in-memory buffer.
359    ///
360    /// Cursor initial position is `0` even if underlying buffer (e.g., `Vec`)
361    /// is not empty. So writing to cursor starts with overwriting `Vec`
362    /// content, not with appending to it.
363    ///
364    /// # Examples
365    ///
366    /// ```
367    /// use ark_std::io::Cursor;
368    ///
369    /// let buff = Cursor::new(Vec::new());
370    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
371    /// # force_inference(&buff);
372    /// ```
373    pub fn new(inner: T) -> Self {
374        Cursor { inner, pos: 0 }
375    }
376
377    /// Consumes this cursor, returning the underlying value.
378    ///
379    /// # Examples
380    ///
381    /// ```
382    /// use ark_std::io::Cursor;
383    ///
384    /// let buff = Cursor::new(Vec::new());
385    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
386    /// # force_inference(&buff);
387    ///
388    /// let vec = buff.into_inner();
389    /// ```
390    pub fn into_inner(self) -> T {
391        self.inner
392    }
393
394    /// Gets a reference to the underlying value in this cursor.
395    ///
396    /// # Examples
397    ///
398    /// ```
399    /// use ark_std::io::Cursor;
400    ///
401    /// let buff = Cursor::new(Vec::new());
402    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
403    /// # force_inference(&buff);
404    ///
405    /// let reference = buff.get_ref();
406    /// ```
407    pub fn get_ref(&self) -> &T {
408        &self.inner
409    }
410
411    /// Gets a mutable reference to the underlying value in this cursor.
412    ///
413    /// Care should be taken to avoid modifying the internal I/O state of the
414    /// underlying value as it may corrupt this cursor's position.
415    ///
416    /// # Examples
417    ///
418    /// ```
419    /// use ark_std::io::Cursor;
420    ///
421    /// let mut buff = Cursor::new(Vec::new());
422    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
423    /// # force_inference(&buff);
424    ///
425    /// let reference = buff.get_mut();
426    /// ```
427    pub fn get_mut(&mut self) -> &mut T {
428        &mut self.inner
429    }
430
431    /// Returns the current position of this cursor.
432    pub fn position(&self) -> u64 {
433        self.pos
434    }
435
436    /// Sets the position of this cursor.
437    ///
438    /// # Examples
439    ///
440    /// ```
441    /// use ark_std::io::Cursor;
442    ///
443    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
444    ///
445    /// assert_eq!(buff.position(), 0);
446    ///
447    /// buff.set_position(2);
448    /// assert_eq!(buff.position(), 2);
449    ///
450    /// buff.set_position(4);
451    /// assert_eq!(buff.position(), 4);
452    /// ```
453    pub fn set_position(&mut self, pos: u64) {
454        self.pos = pos;
455    }
456}
457
458impl<T> Read for Cursor<T>
459where
460    T: AsRef<[u8]>,
461{
462    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
463        let n = Read::read(&mut self.get_buf()?, buf)?;
464        self.pos += n as u64;
465        Ok(n)
466    }
467
468    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
469        let n = buf.len();
470        Read::read_exact(&mut self.get_buf()?, buf)?;
471        self.pos += n as u64;
472        Ok(())
473    }
474}
475
476impl<T> Cursor<T>
477where
478    T: AsRef<[u8]>,
479{
480    fn get_buf(&mut self) -> Result<&[u8]> {
481        let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64);
482        Ok(&self.inner.as_ref()[(amt as usize)..])
483    }
484}
485
486impl Write for Cursor<&mut [u8]> {
487    #[inline]
488    fn write(&mut self, buf: &[u8]) -> Result<usize> {
489        slice_write(&mut self.pos, self.inner, buf)
490    }
491
492    #[inline]
493    fn flush(&mut self) -> Result<()> {
494        Ok(())
495    }
496}
497
498impl Write for Cursor<Vec<u8>> {
499    fn write(&mut self, buf: &[u8]) -> Result<usize> {
500        vec_write(&mut self.pos, &mut self.inner, buf)
501    }
502
503    #[inline]
504    fn flush(&mut self) -> Result<()> {
505        Ok(())
506    }
507}
508
509// Non-resizing write implementation
510#[inline]
511fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> Result<usize> {
512    let pos = cmp::min(*pos_mut, slice.len() as u64);
513    let amt = (&mut slice[(pos as usize)..]).write(buf)?;
514    *pos_mut += amt as u64;
515    Ok(amt)
516}
517
518fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> Result<usize> {
519    let pos: usize = (*pos_mut).try_into().map_err(|_| {
520        Error::new(
521            ErrorKind::InvalidInput,
522            "cursor position exceeds maximum possible vector length",
523        )
524    })?;
525    // Make sure the internal buffer is as least as big as where we
526    // currently are
527    let len = vec.len();
528    if len < pos {
529        // use `resize` so that the zero filling is as efficient as possible
530        vec.resize(pos, 0);
531    }
532    // Figure out what bytes will be used to overwrite what's currently
533    // there (left), and what will be appended on the end (right)
534    {
535        let space = vec.len() - pos;
536        let (left, right) = buf.split_at(cmp::min(space, buf.len()));
537        vec[pos..pos + left.len()].copy_from_slice(left);
538        vec.extend_from_slice(right);
539    }
540
541    // Bump us forward
542    *pos_mut = (pos + buf.len()) as u64;
543    Ok(buf.len())
544}