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}