Skip to main content

std/io/
cursor.rs

1#[cfg(test)]
2mod tests;
3
4#[stable(feature = "rust1", since = "1.0.0")]
5pub use core::io::Cursor;
6
7use crate::alloc::Allocator;
8use crate::cmp;
9use crate::io::prelude::*;
10use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut, SeekFrom};
11
12#[stable(feature = "rust1", since = "1.0.0")]
13impl<T> io::Seek for Cursor<T>
14where
15    T: AsRef<[u8]>,
16{
17    fn seek(&mut self, style: SeekFrom) -> io::Result<u64> {
18        let (base_pos, offset) = match style {
19            SeekFrom::Start(n) => {
20                self.set_position(n);
21                return Ok(n);
22            }
23            SeekFrom::End(n) => (self.get_ref().as_ref().len() as u64, n),
24            SeekFrom::Current(n) => (self.position(), n),
25        };
26        match base_pos.checked_add_signed(offset) {
27            Some(n) => {
28                self.set_position(n);
29                Ok(n)
30            }
31            None => Err(io::const_error!(
32                ErrorKind::InvalidInput,
33                "invalid seek to a negative or overflowing position",
34            )),
35        }
36    }
37
38    fn stream_len(&mut self) -> io::Result<u64> {
39        Ok(self.get_ref().as_ref().len() as u64)
40    }
41
42    fn stream_position(&mut self) -> io::Result<u64> {
43        Ok(self.position())
44    }
45}
46
47#[stable(feature = "rust1", since = "1.0.0")]
48impl<T> Read for Cursor<T>
49where
50    T: AsRef<[u8]>,
51{
52    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
53        let n = Read::read(&mut Cursor::split(self).1, buf)?;
54        self.set_position(self.position() + n as u64);
55        Ok(n)
56    }
57
58    fn read_buf(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
59        let prev_written = cursor.written();
60
61        Read::read_buf(&mut Cursor::split(self).1, cursor.reborrow())?;
62
63        self.set_position(self.position() + (cursor.written() - prev_written) as u64);
64
65        Ok(())
66    }
67
68    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
69        let mut nread = 0;
70        for buf in bufs {
71            let n = self.read(buf)?;
72            nread += n;
73            if n < buf.len() {
74                break;
75            }
76        }
77        Ok(nread)
78    }
79
80    fn is_read_vectored(&self) -> bool {
81        true
82    }
83
84    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
85        let result = Read::read_exact(&mut Cursor::split(self).1, buf);
86
87        match result {
88            Ok(_) => self.set_position(self.position() + buf.len() as u64),
89            // The only possible error condition is EOF, so place the cursor at "EOF"
90            Err(_) => self.set_position(self.get_ref().as_ref().len() as u64),
91        }
92
93        result
94    }
95
96    fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
97        let prev_written = cursor.written();
98
99        let result = Read::read_buf_exact(&mut Cursor::split(self).1, cursor.reborrow());
100        self.set_position(self.position() + (cursor.written() - prev_written) as u64);
101
102        result
103    }
104
105    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
106        let content = Cursor::split(self).1;
107        let len = content.len();
108        buf.try_reserve(len)?;
109        buf.extend_from_slice(content);
110        self.set_position(self.position() + len as u64);
111
112        Ok(len)
113    }
114
115    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
116        let content =
117            crate::str::from_utf8(Cursor::split(self).1).map_err(|_| io::Error::INVALID_UTF8)?;
118        let len = content.len();
119        buf.try_reserve(len)?;
120        buf.push_str(content);
121        self.set_position(self.position() + len as u64);
122
123        Ok(len)
124    }
125}
126
127#[stable(feature = "rust1", since = "1.0.0")]
128impl<T> BufRead for Cursor<T>
129where
130    T: AsRef<[u8]>,
131{
132    fn fill_buf(&mut self) -> io::Result<&[u8]> {
133        Ok(Cursor::split(self).1)
134    }
135    fn consume(&mut self, amt: usize) {
136        self.set_position(self.position() + amt as u64);
137    }
138}
139
140// Non-resizing write implementation
141#[inline]
142fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<usize> {
143    let pos = cmp::min(*pos_mut, slice.len() as u64);
144    let amt = (&mut slice[(pos as usize)..]).write(buf)?;
145    *pos_mut += amt as u64;
146    Ok(amt)
147}
148
149#[inline]
150fn slice_write_vectored(
151    pos_mut: &mut u64,
152    slice: &mut [u8],
153    bufs: &[IoSlice<'_>],
154) -> io::Result<usize> {
155    let mut nwritten = 0;
156    for buf in bufs {
157        let n = slice_write(pos_mut, slice, buf)?;
158        nwritten += n;
159        if n < buf.len() {
160            break;
161        }
162    }
163    Ok(nwritten)
164}
165
166#[inline]
167fn slice_write_all(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<()> {
168    let n = slice_write(pos_mut, slice, buf)?;
169    if n < buf.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) }
170}
171
172#[inline]
173fn slice_write_all_vectored(
174    pos_mut: &mut u64,
175    slice: &mut [u8],
176    bufs: &[IoSlice<'_>],
177) -> io::Result<()> {
178    for buf in bufs {
179        let n = slice_write(pos_mut, slice, buf)?;
180        if n < buf.len() {
181            return Err(io::Error::WRITE_ALL_EOF);
182        }
183    }
184    Ok(())
185}
186
187/// Reserves the required space, and pads the vec with 0s if necessary.
188fn reserve_and_pad<A: Allocator>(
189    pos_mut: &mut u64,
190    vec: &mut Vec<u8, A>,
191    buf_len: usize,
192) -> io::Result<usize> {
193    let pos: usize = (*pos_mut).try_into().map_err(|_| {
194        io::const_error!(
195            ErrorKind::InvalidInput,
196            "cursor position exceeds maximum possible vector length",
197        )
198    })?;
199
200    // For safety reasons, we don't want these numbers to overflow
201    // otherwise our allocation won't be enough
202    let desired_cap = pos.saturating_add(buf_len);
203    if desired_cap > vec.capacity() {
204        // We want our vec's total capacity
205        // to have room for (pos+buf_len) bytes. Reserve allocates
206        // based on additional elements from the length, so we need to
207        // reserve the difference
208        vec.reserve(desired_cap - vec.len());
209    }
210    // Pad if pos is above the current len.
211    if pos > vec.len() {
212        let diff = pos - vec.len();
213        // Unfortunately, `resize()` would suffice but the optimiser does not
214        // realise the `reserve` it does can be eliminated. So we do it manually
215        // to eliminate that extra branch
216        let spare = vec.spare_capacity_mut();
217        debug_assert!(spare.len() >= diff);
218        // Safety: we have allocated enough capacity for this.
219        // And we are only writing, not reading
220        unsafe {
221            spare.get_unchecked_mut(..diff).fill(core::mem::MaybeUninit::new(0));
222            vec.set_len(pos);
223        }
224    }
225
226    Ok(pos)
227}
228
229/// Writes the slice to the vec without allocating.
230///
231/// # Safety
232///
233/// `vec` must have `buf.len()` spare capacity.
234unsafe fn vec_write_all_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize
235where
236    A: Allocator,
237{
238    debug_assert!(vec.capacity() >= pos + buf.len());
239    unsafe { vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()) };
240    pos + buf.len()
241}
242
243/// Resizing `write_all` implementation for [`Cursor`].
244///
245/// Cursor is allowed to have a pre-allocated and initialised
246/// vector body, but with a position of 0. This means the [`Write`]
247/// will overwrite the contents of the vec.
248///
249/// This also allows for the vec body to be empty, but with a position of N.
250/// This means that [`Write`] will pad the vec with 0 initially,
251/// before writing anything from that point
252fn vec_write_all<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
253where
254    A: Allocator,
255{
256    let buf_len = buf.len();
257    let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
258
259    // Write the buf then progress the vec forward if necessary
260    // Safety: we have ensured that the capacity is available
261    // and that all bytes get written up to pos
262    unsafe {
263        pos = vec_write_all_unchecked(pos, vec, buf);
264        if pos > vec.len() {
265            vec.set_len(pos);
266        }
267    };
268
269    // Bump us forward
270    *pos_mut += buf_len as u64;
271    Ok(buf_len)
272}
273
274/// Resizing `write_all_vectored` implementation for [`Cursor`].
275///
276/// Cursor is allowed to have a pre-allocated and initialised
277/// vector body, but with a position of 0. This means the [`Write`]
278/// will overwrite the contents of the vec.
279///
280/// This also allows for the vec body to be empty, but with a position of N.
281/// This means that [`Write`] will pad the vec with 0 initially,
282/// before writing anything from that point
283fn vec_write_all_vectored<A>(
284    pos_mut: &mut u64,
285    vec: &mut Vec<u8, A>,
286    bufs: &[IoSlice<'_>],
287) -> io::Result<usize>
288where
289    A: Allocator,
290{
291    // For safety reasons, we don't want this sum to overflow ever.
292    // If this saturates, the reserve should panic to avoid any unsound writing.
293    let buf_len = bufs.iter().fold(0usize, |a, b| a.saturating_add(b.len()));
294    let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
295
296    // Write the buf then progress the vec forward if necessary
297    // Safety: we have ensured that the capacity is available
298    // and that all bytes get written up to the last pos
299    unsafe {
300        for buf in bufs {
301            pos = vec_write_all_unchecked(pos, vec, buf);
302        }
303        if pos > vec.len() {
304            vec.set_len(pos);
305        }
306    }
307
308    // Bump us forward
309    *pos_mut += buf_len as u64;
310    Ok(buf_len)
311}
312
313#[stable(feature = "rust1", since = "1.0.0")]
314impl Write for Cursor<&mut [u8]> {
315    #[inline]
316    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
317        let (pos, inner) = self.into_parts_mut();
318        slice_write(pos, inner, buf)
319    }
320
321    #[inline]
322    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
323        let (pos, inner) = self.into_parts_mut();
324        slice_write_vectored(pos, inner, bufs)
325    }
326
327    #[inline]
328    fn is_write_vectored(&self) -> bool {
329        true
330    }
331
332    #[inline]
333    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
334        let (pos, inner) = self.into_parts_mut();
335        slice_write_all(pos, inner, buf)
336    }
337
338    #[inline]
339    fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
340        let (pos, inner) = self.into_parts_mut();
341        slice_write_all_vectored(pos, inner, bufs)
342    }
343
344    #[inline]
345    fn flush(&mut self) -> io::Result<()> {
346        Ok(())
347    }
348}
349
350#[stable(feature = "cursor_mut_vec", since = "1.25.0")]
351impl<A> Write for Cursor<&mut Vec<u8, A>>
352where
353    A: Allocator,
354{
355    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
356        let (pos, inner) = self.into_parts_mut();
357        vec_write_all(pos, inner, buf)
358    }
359
360    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
361        let (pos, inner) = self.into_parts_mut();
362        vec_write_all_vectored(pos, inner, bufs)
363    }
364
365    #[inline]
366    fn is_write_vectored(&self) -> bool {
367        true
368    }
369
370    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
371        let (pos, inner) = self.into_parts_mut();
372        vec_write_all(pos, inner, buf)?;
373        Ok(())
374    }
375
376    fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
377        let (pos, inner) = self.into_parts_mut();
378        vec_write_all_vectored(pos, inner, bufs)?;
379        Ok(())
380    }
381
382    #[inline]
383    fn flush(&mut self) -> io::Result<()> {
384        Ok(())
385    }
386}
387
388#[stable(feature = "rust1", since = "1.0.0")]
389impl<A> Write for Cursor<Vec<u8, A>>
390where
391    A: Allocator,
392{
393    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
394        let (pos, inner) = self.into_parts_mut();
395        vec_write_all(pos, inner, buf)
396    }
397
398    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
399        let (pos, inner) = self.into_parts_mut();
400        vec_write_all_vectored(pos, inner, bufs)
401    }
402
403    #[inline]
404    fn is_write_vectored(&self) -> bool {
405        true
406    }
407
408    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
409        let (pos, inner) = self.into_parts_mut();
410        vec_write_all(pos, inner, buf)?;
411        Ok(())
412    }
413
414    fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
415        let (pos, inner) = self.into_parts_mut();
416        vec_write_all_vectored(pos, inner, bufs)?;
417        Ok(())
418    }
419
420    #[inline]
421    fn flush(&mut self) -> io::Result<()> {
422        Ok(())
423    }
424}
425
426#[stable(feature = "cursor_box_slice", since = "1.5.0")]
427impl<A> Write for Cursor<Box<[u8], A>>
428where
429    A: Allocator,
430{
431    #[inline]
432    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
433        let (pos, inner) = self.into_parts_mut();
434        slice_write(pos, inner, buf)
435    }
436
437    #[inline]
438    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
439        let (pos, inner) = self.into_parts_mut();
440        slice_write_vectored(pos, inner, bufs)
441    }
442
443    #[inline]
444    fn is_write_vectored(&self) -> bool {
445        true
446    }
447
448    #[inline]
449    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
450        let (pos, inner) = self.into_parts_mut();
451        slice_write_all(pos, inner, buf)
452    }
453
454    #[inline]
455    fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
456        let (pos, inner) = self.into_parts_mut();
457        slice_write_all_vectored(pos, inner, bufs)
458    }
459
460    #[inline]
461    fn flush(&mut self) -> io::Result<()> {
462        Ok(())
463    }
464}
465
466#[stable(feature = "cursor_array", since = "1.61.0")]
467impl<const N: usize> Write for Cursor<[u8; N]> {
468    #[inline]
469    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
470        let (pos, inner) = self.into_parts_mut();
471        slice_write(pos, inner, buf)
472    }
473
474    #[inline]
475    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
476        let (pos, inner) = self.into_parts_mut();
477        slice_write_vectored(pos, inner, bufs)
478    }
479
480    #[inline]
481    fn is_write_vectored(&self) -> bool {
482        true
483    }
484
485    #[inline]
486    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
487        let (pos, inner) = self.into_parts_mut();
488        slice_write_all(pos, inner, buf)
489    }
490
491    #[inline]
492    fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
493        let (pos, inner) = self.into_parts_mut();
494        slice_write_all_vectored(pos, inner, bufs)
495    }
496
497    #[inline]
498    fn flush(&mut self) -> io::Result<()> {
499        Ok(())
500    }
501}