cursor.rs 11.9 KB
Newer Older
1 2 3
#[cfg(test)]
mod tests;

T
Taiki Endo 已提交
4 5 6
use crate::io::prelude::*;

use crate::cmp;
M
Mark Rousskov 已提交
7
use crate::io::{self, Error, ErrorKind, Initializer, IoSlice, IoSliceMut, SeekFrom};
A
Alex Crichton 已提交
8

9
use core::convert::TryInto;
A
Alex Crichton 已提交
10

11
/// A `Cursor` wraps an in-memory buffer and provides it with a
G
Guillaume Gomez 已提交
12
/// [`Seek`] implementation.
A
Alex Crichton 已提交
13
///
14
/// `Cursor`s are used with in-memory buffers, anything implementing
15
/// [`AsRef`]`<[u8]>`, to allow them to implement [`Read`] and/or [`Write`],
16 17
/// allowing these buffers to be used anywhere you might use a reader or writer
/// that does actual I/O.
18 19
///
/// The standard library implements some I/O traits on various types which
G
Guillaume Gomez 已提交
20
/// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
O
Oliver Middleton 已提交
21
/// `Cursor<`[`&[u8]`][bytes]`>`.
22 23 24
///
/// # Examples
///
G
Guillaume Gomez 已提交
25
/// We may want to write bytes to a [`File`] in our production
26 27 28
/// code, but use an in-memory buffer in our tests. We can do this with
/// `Cursor`:
///
29 30
/// [bytes]: crate::slice
/// [`File`]: crate::fs::File
31 32 33 34 35 36 37 38
///
/// ```no_run
/// use std::io::prelude::*;
/// use std::io::{self, SeekFrom};
/// use std::fs::File;
///
/// // a library function we've written
/// 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 46 47 48 49 50 51 52 53
///     }
///
///     // all went well
///     Ok(())
/// }
///
/// # fn foo() -> io::Result<()> {
/// // Here's some code that uses this library function.
/// //
/// // We might want to use a BufReader here for efficiency, but let's
/// // keep this example focused.
54
/// let mut file = File::create("foo.txt")?;
55
///
56
/// write_ten_bytes_at_end(&mut file)?;
57 58 59 60 61 62
/// # Ok(())
/// # }
///
/// // now let's write a test
/// #[test]
/// fn test_writes_bytes() {
A
adrian5 已提交
63
///     // setting up a real File is much slower than an in-memory buffer,
64 65 66 67
///     // let's use a cursor instead
///     use std::io::Cursor;
///     let mut buff = Cursor::new(vec![0; 15]);
///
W
Wesley Wiser 已提交
68
///     write_ten_bytes_at_end(&mut buff).unwrap();
69 70 71 72
///
///     assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
/// }
/// ```
73
#[stable(feature = "rust1", since = "1.0.0")]
L
Luro02 已提交
74
#[derive(Clone, Debug, Default, Eq, PartialEq)]
A
Alex Crichton 已提交
75 76 77 78 79 80
pub struct Cursor<T> {
    inner: T,
    pos: u64,
}

impl<T> Cursor<T> {
81
    /// Creates a new cursor wrapping the provided underlying in-memory buffer.
82
    ///
83 84
    /// Cursor initial position is `0` even if underlying buffer (e.g., [`Vec`])
    /// is not empty. So writing to cursor starts with overwriting [`Vec`]
85
    /// content, not with appending to it.
86
    ///
87 88 89 90 91 92 93 94 95
    /// # Examples
    ///
    /// ```
    /// use std::io::Cursor;
    ///
    /// let buff = Cursor::new(Vec::new());
    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
    /// # force_inference(&buff);
    /// ```
96
    #[stable(feature = "rust1", since = "1.0.0")]
B
Benoît du Garreau 已提交
97
    #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
98
    pub const fn new(inner: T) -> Cursor<T> {
99
        Cursor { pos: 0, inner }
A
Alex Crichton 已提交
100 101
    }

102
    /// Consumes this cursor, returning the underlying value.
103 104 105 106 107 108 109 110 111 112 113 114
    ///
    /// # Examples
    ///
    /// ```
    /// use std::io::Cursor;
    ///
    /// let buff = Cursor::new(Vec::new());
    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
    /// # force_inference(&buff);
    ///
    /// let vec = buff.into_inner();
    /// ```
115
    #[stable(feature = "rust1", since = "1.0.0")]
M
Mark Rousskov 已提交
116 117 118
    pub fn into_inner(self) -> T {
        self.inner
    }
A
Alex Crichton 已提交
119

120
    /// Gets a reference to the underlying value in this cursor.
121 122 123 124 125 126 127 128 129 130 131 132
    ///
    /// # Examples
    ///
    /// ```
    /// use std::io::Cursor;
    ///
    /// let buff = Cursor::new(Vec::new());
    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
    /// # force_inference(&buff);
    ///
    /// let reference = buff.get_ref();
    /// ```
133
    #[stable(feature = "rust1", since = "1.0.0")]
B
Benoît du Garreau 已提交
134
    #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
135
    pub const fn get_ref(&self) -> &T {
M
Mark Rousskov 已提交
136 137
        &self.inner
    }
A
Alex Crichton 已提交
138

139
    /// Gets a mutable reference to the underlying value in this cursor.
A
Alex Crichton 已提交
140 141 142
    ///
    /// Care should be taken to avoid modifying the internal I/O state of the
    /// underlying value as it may corrupt this cursor's position.
143 144 145 146 147 148 149 150 151 152 153 154
    ///
    /// # Examples
    ///
    /// ```
    /// use std::io::Cursor;
    ///
    /// let mut buff = Cursor::new(Vec::new());
    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
    /// # force_inference(&buff);
    ///
    /// let reference = buff.get_mut();
    /// ```
155
    #[stable(feature = "rust1", since = "1.0.0")]
M
Mark Rousskov 已提交
156 157 158
    pub fn get_mut(&mut self) -> &mut T {
        &mut self.inner
    }
A
Alex Crichton 已提交
159

160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
    /// Returns the current position of this cursor.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::io::Cursor;
    /// use std::io::prelude::*;
    /// use std::io::SeekFrom;
    ///
    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
    ///
    /// assert_eq!(buff.position(), 0);
    ///
    /// buff.seek(SeekFrom::Current(2)).unwrap();
    /// assert_eq!(buff.position(), 2);
    ///
    /// buff.seek(SeekFrom::Current(-1)).unwrap();
    /// assert_eq!(buff.position(), 1);
    /// ```
179
    #[stable(feature = "rust1", since = "1.0.0")]
B
Benoît du Garreau 已提交
180
    #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
181
    pub const fn position(&self) -> u64 {
M
Mark Rousskov 已提交
182 183
        self.pos
    }
A
Alex Crichton 已提交
184

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
    /// Sets the position of this cursor.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::io::Cursor;
    ///
    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
    ///
    /// assert_eq!(buff.position(), 0);
    ///
    /// buff.set_position(2);
    /// assert_eq!(buff.position(), 2);
    ///
    /// buff.set_position(4);
    /// assert_eq!(buff.position(), 4);
    /// ```
202
    #[stable(feature = "rust1", since = "1.0.0")]
M
Mark Rousskov 已提交
203 204 205
    pub fn set_position(&mut self, pos: u64) {
        self.pos = pos;
    }
A
Alex Crichton 已提交
206 207
}

208
#[stable(feature = "rust1", since = "1.0.0")]
M
Mark Rousskov 已提交
209 210 211 212
impl<T> io::Seek for Cursor<T>
where
    T: AsRef<[u8]>,
{
213
    fn seek(&mut self, style: SeekFrom) -> io::Result<u64> {
214
        let (base_pos, offset) = match style {
M
Mark Rousskov 已提交
215 216 217 218
            SeekFrom::Start(n) => {
                self.pos = n;
                return Ok(n);
            }
219 220
            SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n),
            SeekFrom::Current(n) => (self.pos, n),
221
        };
222 223
        let new_pos = if offset >= 0 {
            base_pos.checked_add(offset as u64)
224
        } else {
225 226 227
            base_pos.checked_sub((offset.wrapping_neg()) as u64)
        };
        match new_pos {
M
Mark Rousskov 已提交
228 229 230 231
            Some(n) => {
                self.pos = n;
                Ok(self.pos)
            }
232
            None => Err(Error::new_const(
M
Mark Rousskov 已提交
233
                ErrorKind::InvalidInput,
234
                &"invalid seek to a negative or overflowing position",
M
Mark Rousskov 已提交
235
            )),
A
Alex Crichton 已提交
236 237
        }
    }
238 239 240 241 242 243 244 245

    fn stream_len(&mut self) -> io::Result<u64> {
        Ok(self.inner.as_ref().len() as u64)
    }

    fn stream_position(&mut self) -> io::Result<u64> {
        Ok(self.pos)
    }
A
Alex Crichton 已提交
246 247
}

248
#[stable(feature = "rust1", since = "1.0.0")]
M
Mark Rousskov 已提交
249 250 251 252
impl<T> Read for Cursor<T>
where
    T: AsRef<[u8]>,
{
253
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
J
Jorge Aparicio 已提交
254
        let n = Read::read(&mut self.fill_buf()?, buf)?;
255 256
        self.pos += n as u64;
        Ok(n)
A
Alex Crichton 已提交
257
    }
S
Steven Fackler 已提交
258

S
Steven Fackler 已提交
259
    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
260 261 262 263 264 265 266 267 268 269 270
        let mut nread = 0;
        for buf in bufs {
            let n = self.read(buf)?;
            nread += n;
            if n < buf.len() {
                break;
            }
        }
        Ok(nread)
    }

S
Steven Fackler 已提交
271
    fn is_read_vectored(&self) -> bool {
272 273 274
        true
    }

275 276 277 278 279 280 281
    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        let n = buf.len();
        Read::read_exact(&mut self.fill_buf()?, buf)?;
        self.pos += n as u64;
        Ok(())
    }

S
Steven Fackler 已提交
282 283 284 285
    #[inline]
    unsafe fn initializer(&self) -> Initializer {
        Initializer::nop()
    }
A
Alex Crichton 已提交
286 287
}

288
#[stable(feature = "rust1", since = "1.0.0")]
M
Mark Rousskov 已提交
289 290 291 292
impl<T> BufRead for Cursor<T>
where
    T: AsRef<[u8]>,
{
293 294 295
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64);
        Ok(&self.inner.as_ref()[(amt as usize)..])
A
Alex Crichton 已提交
296
    }
M
Mark Rousskov 已提交
297 298 299
    fn consume(&mut self, amt: usize) {
        self.pos += amt as u64;
    }
A
Alex Crichton 已提交
300 301
}

302
// Non-resizing write implementation
P
Peter Todd 已提交
303
#[inline]
304 305 306 307 308 309 310
fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<usize> {
    let pos = cmp::min(*pos_mut, slice.len() as u64);
    let amt = (&mut slice[(pos as usize)..]).write(buf)?;
    *pos_mut += amt as u64;
    Ok(amt)
}

P
Peter Todd 已提交
311
#[inline]
312 313 314
fn slice_write_vectored(
    pos_mut: &mut u64,
    slice: &mut [u8],
S
Steven Fackler 已提交
315
    bufs: &[IoSlice<'_>],
M
Mark Rousskov 已提交
316
) -> io::Result<usize> {
317 318 319 320 321 322 323 324 325 326 327
    let mut nwritten = 0;
    for buf in bufs {
        let n = slice_write(pos_mut, slice, buf)?;
        nwritten += n;
        if n < buf.len() {
            break;
        }
    }
    Ok(nwritten)
}

328 329
// Resizing write implementation
fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> {
330
    let pos: usize = (*pos_mut).try_into().map_err(|_| {
331
        Error::new_const(
M
Mark Rousskov 已提交
332
            ErrorKind::InvalidInput,
333
            &"cursor position exceeds maximum possible vector length",
M
Mark Rousskov 已提交
334
        )
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
    })?;
    // Make sure the internal buffer is as least as big as where we
    // currently are
    let len = vec.len();
    if len < pos {
        // use `resize` so that the zero filling is as efficient as possible
        vec.resize(pos, 0);
    }
    // Figure out what bytes will be used to overwrite what's currently
    // there (left), and what will be appended on the end (right)
    {
        let space = vec.len() - pos;
        let (left, right) = buf.split_at(cmp::min(space, buf.len()));
        vec[pos..pos + left.len()].copy_from_slice(left);
        vec.extend_from_slice(right);
    }

    // Bump us forward
    *pos_mut = (pos + buf.len()) as u64;
    Ok(buf.len())
}

357 358 359
fn vec_write_vectored(
    pos_mut: &mut u64,
    vec: &mut Vec<u8>,
S
Steven Fackler 已提交
360
    bufs: &[IoSlice<'_>],
M
Mark Rousskov 已提交
361
) -> io::Result<usize> {
362 363
    let mut nwritten = 0;
    for buf in bufs {
364
        nwritten += vec_write(pos_mut, vec, buf)?;
365 366 367 368
    }
    Ok(nwritten)
}

369
#[stable(feature = "rust1", since = "1.0.0")]
370
impl Write for Cursor<&mut [u8]> {
J
Jamey Sharp 已提交
371
    #[inline]
372 373 374
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        slice_write(&mut self.pos, self.inner, buf)
    }
375 376

    #[inline]
S
Steven Fackler 已提交
377
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
378 379 380
        slice_write_vectored(&mut self.pos, self.inner, bufs)
    }

381
    #[inline]
S
Steven Fackler 已提交
382
    fn is_write_vectored(&self) -> bool {
383 384 385
        true
    }

P
Peter Todd 已提交
386
    #[inline]
M
Mark Rousskov 已提交
387 388 389
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
390 391
}

392
#[stable(feature = "cursor_mut_vec", since = "1.25.0")]
393
impl Write for Cursor<&mut Vec<u8>> {
394 395
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        vec_write(&mut self.pos, self.inner, buf)
A
Alex Crichton 已提交
396
    }
397

S
Steven Fackler 已提交
398
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
399 400 401
        vec_write_vectored(&mut self.pos, self.inner, bufs)
    }

402
    #[inline]
S
Steven Fackler 已提交
403
    fn is_write_vectored(&self) -> bool {
404 405 406
        true
    }

P
Peter Todd 已提交
407
    #[inline]
M
Mark Rousskov 已提交
408 409 410
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
A
Alex Crichton 已提交
411 412
}

413
#[stable(feature = "rust1", since = "1.0.0")]
A
Alex Crichton 已提交
414 415
impl Write for Cursor<Vec<u8>> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
416
        vec_write(&mut self.pos, &mut self.inner, buf)
A
Alex Crichton 已提交
417
    }
418

S
Steven Fackler 已提交
419
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
420 421 422
        vec_write_vectored(&mut self.pos, &mut self.inner, bufs)
    }

423
    #[inline]
S
Steven Fackler 已提交
424
    fn is_write_vectored(&self) -> bool {
425 426 427
        true
    }

P
Peter Todd 已提交
428
    #[inline]
M
Mark Rousskov 已提交
429 430 431
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
A
Alex Crichton 已提交
432 433
}

434 435
#[stable(feature = "cursor_box_slice", since = "1.5.0")]
impl Write for Cursor<Box<[u8]>> {
J
Jamey Sharp 已提交
436
    #[inline]
437
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
438
        slice_write(&mut self.pos, &mut self.inner, buf)
439
    }
440 441

    #[inline]
S
Steven Fackler 已提交
442
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
443 444 445
        slice_write_vectored(&mut self.pos, &mut self.inner, bufs)
    }

446
    #[inline]
S
Steven Fackler 已提交
447
    fn is_write_vectored(&self) -> bool {
448 449 450
        true
    }

P
Peter Todd 已提交
451
    #[inline]
M
Mark Rousskov 已提交
452 453 454
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
455
}