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