]> git.lizzy.rs Git - rust.git/blob - library/std/src/io/cursor.rs
word wrpa
[rust.git] / library / std / src / io / cursor.rs
1 #[cfg(test)]
2 mod tests;
3
4 use crate::io::prelude::*;
5
6 use crate::cmp;
7 use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, ReadBuf, SeekFrom};
8
9 use core::convert::TryInto;
10
11 /// A `Cursor` wraps an in-memory buffer and provides it with a
12 /// [`Seek`] implementation.
13 ///
14 /// `Cursor`s are used with in-memory buffers, anything implementing
15 /// <code>[AsRef]<\[u8]></code>, to allow them to implement [`Read`] and/or [`Write`],
16 /// allowing these buffers to be used anywhere you might use a reader or writer
17 /// that does actual I/O.
18 ///
19 /// The standard library implements some I/O traits on various types which
20 /// are commonly used as a buffer, like <code>Cursor<[Vec]\<u8>></code> and
21 /// <code>Cursor<[&\[u8\]][bytes]></code>.
22 ///
23 /// # Examples
24 ///
25 /// We may want to write bytes to a [`File`] in our production
26 /// code, but use an in-memory buffer in our tests. We can do this with
27 /// `Cursor`:
28 ///
29 /// [bytes]: crate::slice "slice"
30 /// [`File`]: crate::fs::File
31 ///
32 /// ```no_run
33 /// use std::io::prelude::*;
34 /// use std::io::{self, SeekFrom};
35 /// use std::fs::File;
36 ///
37 /// // a library function we've written
38 /// fn write_ten_bytes_at_end<W: Write + Seek>(writer: &mut W) -> io::Result<()> {
39 ///     writer.seek(SeekFrom::End(-10))?;
40 ///
41 ///     for i in 0..10 {
42 ///         writer.write(&[i])?;
43 ///     }
44 ///
45 ///     // all went well
46 ///     Ok(())
47 /// }
48 ///
49 /// # fn foo() -> io::Result<()> {
50 /// // Here's some code that uses this library function.
51 /// //
52 /// // We might want to use a BufReader here for efficiency, but let's
53 /// // keep this example focused.
54 /// let mut file = File::create("foo.txt")?;
55 ///
56 /// write_ten_bytes_at_end(&mut file)?;
57 /// # Ok(())
58 /// # }
59 ///
60 /// // now let's write a test
61 /// #[test]
62 /// fn test_writes_bytes() {
63 ///     // setting up a real File is much slower than an in-memory buffer,
64 ///     // let's use a cursor instead
65 ///     use std::io::Cursor;
66 ///     let mut buff = Cursor::new(vec![0; 15]);
67 ///
68 ///     write_ten_bytes_at_end(&mut buff).unwrap();
69 ///
70 ///     assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
71 /// }
72 /// ```
73 #[stable(feature = "rust1", since = "1.0.0")]
74 #[derive(Debug, Default, Eq, PartialEq)]
75 pub struct Cursor<T> {
76     inner: T,
77     pos: u64,
78 }
79
80 impl<T> Cursor<T> {
81     /// Creates a new cursor wrapping the provided underlying in-memory buffer.
82     ///
83     /// Cursor initial position is `0` even if underlying buffer (e.g., [`Vec`])
84     /// is not empty. So writing to cursor starts with overwriting [`Vec`]
85     /// content, not with appending to it.
86     ///
87     /// # Examples
88     ///
89     /// ```
90     /// use std::io::Cursor;
91     ///
92     /// let buff = Cursor::new(Vec::new());
93     /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
94     /// # force_inference(&buff);
95     /// ```
96     #[stable(feature = "rust1", since = "1.0.0")]
97     #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
98     pub const fn new(inner: T) -> Cursor<T> {
99         Cursor { pos: 0, inner }
100     }
101
102     /// Consumes this cursor, returning the underlying value.
103     ///
104     /// # Examples
105     ///
106     /// ```
107     /// use std::io::Cursor;
108     ///
109     /// let buff = Cursor::new(Vec::new());
110     /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
111     /// # force_inference(&buff);
112     ///
113     /// let vec = buff.into_inner();
114     /// ```
115     #[stable(feature = "rust1", since = "1.0.0")]
116     pub fn into_inner(self) -> T {
117         self.inner
118     }
119
120     /// Gets a reference to the underlying value in this cursor.
121     ///
122     /// # Examples
123     ///
124     /// ```
125     /// use std::io::Cursor;
126     ///
127     /// let buff = Cursor::new(Vec::new());
128     /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
129     /// # force_inference(&buff);
130     ///
131     /// let reference = buff.get_ref();
132     /// ```
133     #[stable(feature = "rust1", since = "1.0.0")]
134     #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
135     pub const fn get_ref(&self) -> &T {
136         &self.inner
137     }
138
139     /// Gets a mutable reference to the underlying value in this cursor.
140     ///
141     /// Care should be taken to avoid modifying the internal I/O state of the
142     /// underlying value as it may corrupt this cursor's position.
143     ///
144     /// # Examples
145     ///
146     /// ```
147     /// use std::io::Cursor;
148     ///
149     /// let mut buff = Cursor::new(Vec::new());
150     /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
151     /// # force_inference(&buff);
152     ///
153     /// let reference = buff.get_mut();
154     /// ```
155     #[stable(feature = "rust1", since = "1.0.0")]
156     pub fn get_mut(&mut self) -> &mut T {
157         &mut self.inner
158     }
159
160     /// Returns the current position of this cursor.
161     ///
162     /// # Examples
163     ///
164     /// ```
165     /// use std::io::Cursor;
166     /// use std::io::prelude::*;
167     /// use std::io::SeekFrom;
168     ///
169     /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
170     ///
171     /// assert_eq!(buff.position(), 0);
172     ///
173     /// buff.seek(SeekFrom::Current(2)).unwrap();
174     /// assert_eq!(buff.position(), 2);
175     ///
176     /// buff.seek(SeekFrom::Current(-1)).unwrap();
177     /// assert_eq!(buff.position(), 1);
178     /// ```
179     #[stable(feature = "rust1", since = "1.0.0")]
180     #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
181     pub const fn position(&self) -> u64 {
182         self.pos
183     }
184
185     /// Sets the position of this cursor.
186     ///
187     /// # Examples
188     ///
189     /// ```
190     /// use std::io::Cursor;
191     ///
192     /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
193     ///
194     /// assert_eq!(buff.position(), 0);
195     ///
196     /// buff.set_position(2);
197     /// assert_eq!(buff.position(), 2);
198     ///
199     /// buff.set_position(4);
200     /// assert_eq!(buff.position(), 4);
201     /// ```
202     #[stable(feature = "rust1", since = "1.0.0")]
203     pub fn set_position(&mut self, pos: u64) {
204         self.pos = pos;
205     }
206 }
207
208 impl<T> Cursor<T>
209 where
210     T: AsRef<[u8]>,
211 {
212     /// Returns the remaining slice.
213     ///
214     /// # Examples
215     ///
216     /// ```
217     /// #![feature(cursor_remaining)]
218     /// use std::io::Cursor;
219     ///
220     /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
221     ///
222     /// assert_eq!(buff.remaining_slice(), &[1, 2, 3, 4, 5]);
223     ///
224     /// buff.set_position(2);
225     /// assert_eq!(buff.remaining_slice(), &[3, 4, 5]);
226     ///
227     /// buff.set_position(4);
228     /// assert_eq!(buff.remaining_slice(), &[5]);
229     ///
230     /// buff.set_position(6);
231     /// assert_eq!(buff.remaining_slice(), &[]);
232     /// ```
233     #[unstable(feature = "cursor_remaining", issue = "86369")]
234     pub fn remaining_slice(&self) -> &[u8] {
235         let len = self.pos.min(self.inner.as_ref().len() as u64);
236         &self.inner.as_ref()[(len as usize)..]
237     }
238
239     /// Returns `true` if the remaining slice is empty.
240     ///
241     /// # Examples
242     ///
243     /// ```
244     /// #![feature(cursor_remaining)]
245     /// use std::io::Cursor;
246     ///
247     /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
248     ///
249     /// buff.set_position(2);
250     /// assert!(!buff.is_empty());
251     ///
252     /// buff.set_position(5);
253     /// assert!(buff.is_empty());
254     ///
255     /// buff.set_position(10);
256     /// assert!(buff.is_empty());
257     /// ```
258     #[unstable(feature = "cursor_remaining", issue = "86369")]
259     pub fn is_empty(&self) -> bool {
260         self.pos >= self.inner.as_ref().len() as u64
261     }
262 }
263
264 #[stable(feature = "rust1", since = "1.0.0")]
265 impl<T> Clone for Cursor<T>
266 where
267     T: Clone,
268 {
269     #[inline]
270     fn clone(&self) -> Self {
271         Cursor { inner: self.inner.clone(), pos: self.pos }
272     }
273
274     #[inline]
275     fn clone_from(&mut self, other: &Self) {
276         self.inner.clone_from(&other.inner);
277         self.pos = other.pos;
278     }
279 }
280
281 #[stable(feature = "rust1", since = "1.0.0")]
282 impl<T> io::Seek for Cursor<T>
283 where
284     T: AsRef<[u8]>,
285 {
286     fn seek(&mut self, style: SeekFrom) -> io::Result<u64> {
287         let (base_pos, offset) = match style {
288             SeekFrom::Start(n) => {
289                 self.pos = n;
290                 return Ok(n);
291             }
292             SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n),
293             SeekFrom::Current(n) => (self.pos, n),
294         };
295         match base_pos.checked_add_signed(offset) {
296             Some(n) => {
297                 self.pos = n;
298                 Ok(self.pos)
299             }
300             None => Err(io::const_io_error!(
301                 ErrorKind::InvalidInput,
302                 "invalid seek to a negative or overflowing position",
303             )),
304         }
305     }
306
307     fn stream_len(&mut self) -> io::Result<u64> {
308         Ok(self.inner.as_ref().len() as u64)
309     }
310
311     fn stream_position(&mut self) -> io::Result<u64> {
312         Ok(self.pos)
313     }
314 }
315
316 #[stable(feature = "rust1", since = "1.0.0")]
317 impl<T> Read for Cursor<T>
318 where
319     T: AsRef<[u8]>,
320 {
321     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
322         let n = Read::read(&mut self.remaining_slice(), buf)?;
323         self.pos += n as u64;
324         Ok(n)
325     }
326
327     fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
328         let prev_filled = buf.filled_len();
329
330         Read::read_buf(&mut self.fill_buf()?, buf)?;
331
332         self.pos += (buf.filled_len() - prev_filled) as u64;
333
334         Ok(())
335     }
336
337     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
338         let mut nread = 0;
339         for buf in bufs {
340             let n = self.read(buf)?;
341             nread += n;
342             if n < buf.len() {
343                 break;
344             }
345         }
346         Ok(nread)
347     }
348
349     fn is_read_vectored(&self) -> bool {
350         true
351     }
352
353     fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
354         let n = buf.len();
355         Read::read_exact(&mut self.remaining_slice(), buf)?;
356         self.pos += n as u64;
357         Ok(())
358     }
359 }
360
361 #[stable(feature = "rust1", since = "1.0.0")]
362 impl<T> BufRead for Cursor<T>
363 where
364     T: AsRef<[u8]>,
365 {
366     fn fill_buf(&mut self) -> io::Result<&[u8]> {
367         Ok(self.remaining_slice())
368     }
369     fn consume(&mut self, amt: usize) {
370         self.pos += amt as u64;
371     }
372 }
373
374 // Non-resizing write implementation
375 #[inline]
376 fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<usize> {
377     let pos = cmp::min(*pos_mut, slice.len() as u64);
378     let amt = (&mut slice[(pos as usize)..]).write(buf)?;
379     *pos_mut += amt as u64;
380     Ok(amt)
381 }
382
383 #[inline]
384 fn slice_write_vectored(
385     pos_mut: &mut u64,
386     slice: &mut [u8],
387     bufs: &[IoSlice<'_>],
388 ) -> io::Result<usize> {
389     let mut nwritten = 0;
390     for buf in bufs {
391         let n = slice_write(pos_mut, slice, buf)?;
392         nwritten += n;
393         if n < buf.len() {
394             break;
395         }
396     }
397     Ok(nwritten)
398 }
399
400 // Resizing write implementation
401 fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> {
402     let pos: usize = (*pos_mut).try_into().map_err(|_| {
403         io::const_io_error!(
404             ErrorKind::InvalidInput,
405             "cursor position exceeds maximum possible vector length",
406         )
407     })?;
408     // Make sure the internal buffer is as least as big as where we
409     // currently are
410     let len = vec.len();
411     if len < pos {
412         // use `resize` so that the zero filling is as efficient as possible
413         vec.resize(pos, 0);
414     }
415     // Figure out what bytes will be used to overwrite what's currently
416     // there (left), and what will be appended on the end (right)
417     {
418         let space = vec.len() - pos;
419         let (left, right) = buf.split_at(cmp::min(space, buf.len()));
420         vec[pos..pos + left.len()].copy_from_slice(left);
421         vec.extend_from_slice(right);
422     }
423
424     // Bump us forward
425     *pos_mut = (pos + buf.len()) as u64;
426     Ok(buf.len())
427 }
428
429 fn vec_write_vectored(
430     pos_mut: &mut u64,
431     vec: &mut Vec<u8>,
432     bufs: &[IoSlice<'_>],
433 ) -> io::Result<usize> {
434     let mut nwritten = 0;
435     for buf in bufs {
436         nwritten += vec_write(pos_mut, vec, buf)?;
437     }
438     Ok(nwritten)
439 }
440
441 #[stable(feature = "rust1", since = "1.0.0")]
442 impl Write for Cursor<&mut [u8]> {
443     #[inline]
444     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
445         slice_write(&mut self.pos, self.inner, buf)
446     }
447
448     #[inline]
449     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
450         slice_write_vectored(&mut self.pos, self.inner, bufs)
451     }
452
453     #[inline]
454     fn is_write_vectored(&self) -> bool {
455         true
456     }
457
458     #[inline]
459     fn flush(&mut self) -> io::Result<()> {
460         Ok(())
461     }
462 }
463
464 #[stable(feature = "cursor_mut_vec", since = "1.25.0")]
465 impl Write for Cursor<&mut Vec<u8>> {
466     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
467         vec_write(&mut self.pos, self.inner, buf)
468     }
469
470     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
471         vec_write_vectored(&mut self.pos, self.inner, bufs)
472     }
473
474     #[inline]
475     fn is_write_vectored(&self) -> bool {
476         true
477     }
478
479     #[inline]
480     fn flush(&mut self) -> io::Result<()> {
481         Ok(())
482     }
483 }
484
485 #[stable(feature = "rust1", since = "1.0.0")]
486 impl Write for Cursor<Vec<u8>> {
487     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
488         vec_write(&mut self.pos, &mut self.inner, buf)
489     }
490
491     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
492         vec_write_vectored(&mut self.pos, &mut self.inner, bufs)
493     }
494
495     #[inline]
496     fn is_write_vectored(&self) -> bool {
497         true
498     }
499
500     #[inline]
501     fn flush(&mut self) -> io::Result<()> {
502         Ok(())
503     }
504 }
505
506 #[stable(feature = "cursor_box_slice", since = "1.5.0")]
507 impl Write for Cursor<Box<[u8]>> {
508     #[inline]
509     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
510         slice_write(&mut self.pos, &mut self.inner, buf)
511     }
512
513     #[inline]
514     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
515         slice_write_vectored(&mut self.pos, &mut self.inner, bufs)
516     }
517
518     #[inline]
519     fn is_write_vectored(&self) -> bool {
520         true
521     }
522
523     #[inline]
524     fn flush(&mut self) -> io::Result<()> {
525         Ok(())
526     }
527 }