Skip to main content

alloc/io/
cursor.rs

1use crate::alloc::Allocator;
2use crate::boxed::Box;
3use crate::io::{
4    self, BorrowedCursor, BufRead, Cursor, ErrorKind, IoSlice, IoSliceMut, Read,
5    WriteThroughCursor, slice_write, slice_write_all, slice_write_all_vectored,
6    slice_write_vectored,
7};
8use crate::string::String;
9use crate::vec::Vec;
10
11#[stable(feature = "rust1", since = "1.0.0")]
12impl<T> Read for Cursor<T>
13where
14    T: AsRef<[u8]>,
15{
16    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
17        let n = Read::read(&mut Cursor::split(self).1, buf)?;
18        self.set_position(self.position() + n as u64);
19        Ok(n)
20    }
21
22    fn read_buf(&mut self, mut cursor: BorrowedCursor<'_, u8>) -> io::Result<()> {
23        let prev_written = cursor.written();
24
25        Read::read_buf(&mut Cursor::split(self).1, cursor.reborrow())?;
26
27        self.set_position(self.position() + (cursor.written() - prev_written) as u64);
28
29        Ok(())
30    }
31
32    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
33        let mut nread = 0;
34        for buf in bufs {
35            let n = self.read(buf)?;
36            nread += n;
37            if n < buf.len() {
38                break;
39            }
40        }
41        Ok(nread)
42    }
43
44    fn is_read_vectored(&self) -> bool {
45        true
46    }
47
48    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
49        let result = Read::read_exact(&mut Cursor::split(self).1, buf);
50
51        match result {
52            Ok(_) => self.set_position(self.position() + buf.len() as u64),
53            // The only possible error condition is EOF, so place the cursor at "EOF"
54            Err(_) => self.set_position(self.get_ref().as_ref().len() as u64),
55        }
56
57        result
58    }
59
60    fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_, u8>) -> io::Result<()> {
61        let prev_written = cursor.written();
62
63        let result = Read::read_buf_exact(&mut Cursor::split(self).1, cursor.reborrow());
64        self.set_position(self.position() + (cursor.written() - prev_written) as u64);
65
66        result
67    }
68
69    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
70        let content = Cursor::split(self).1;
71        let len = content.len();
72        buf.try_reserve(len)?;
73        cfg_select! {
74            no_global_oom_handling => {
75                buf.try_extend_from_slice_of_bytes(content)?;
76            }
77            _ => {
78                buf.extend_from_slice(content);
79            }
80        }
81        self.set_position(self.position() + len as u64);
82
83        Ok(len)
84    }
85
86    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
87        let content =
88            crate::str::from_utf8(Cursor::split(self).1).map_err(|_| io::Error::INVALID_UTF8)?;
89        let len = content.len();
90        buf.try_reserve(len)?;
91
92        cfg_select! {
93            no_global_oom_handling => {
94                buf.try_push_str(content)?;
95            }
96            _ => {
97                buf.push_str(content);
98            }
99        }
100
101        self.set_position(self.position() + len as u64);
102
103        Ok(len)
104    }
105}
106
107#[stable(feature = "rust1", since = "1.0.0")]
108impl<T> BufRead for Cursor<T>
109where
110    T: AsRef<[u8]>,
111{
112    fn fill_buf(&mut self) -> io::Result<&[u8]> {
113        Ok(Cursor::split(self).1)
114    }
115    fn consume(&mut self, amt: usize) {
116        self.set_position(self.position() + amt as u64);
117    }
118}
119
120/// Reserves the required space, and pads the vec with 0s if necessary.
121fn reserve_and_pad<A: Allocator>(
122    pos_mut: &mut u64,
123    vec: &mut Vec<u8, A>,
124    buf_len: usize,
125) -> io::Result<usize> {
126    let pos: usize = (*pos_mut).try_into().map_err(|_| {
127        io::const_error!(
128            ErrorKind::InvalidInput,
129            "cursor position exceeds maximum possible vector length",
130        )
131    })?;
132
133    // For safety reasons, we don't want these numbers to overflow
134    // otherwise our allocation won't be enough
135    let desired_cap = pos.saturating_add(buf_len);
136    if desired_cap > vec.capacity() {
137        // We want our vec's total capacity
138        // to have room for (pos+buf_len) bytes. Reserve allocates
139        // based on additional elements from the length, so we need to
140        // reserve the difference
141        cfg_select! {
142            no_global_oom_handling => {
143                vec.try_reserve(desired_cap - vec.len())?;
144            }
145            _ => {
146                vec.reserve(desired_cap - vec.len());
147            }
148        }
149    }
150    // Pad if pos is above the current len.
151    if pos > vec.len() {
152        let diff = pos - vec.len();
153        // Unfortunately, `resize()` would suffice but the optimiser does not
154        // realise the `reserve` it does can be eliminated. So we do it manually
155        // to eliminate that extra branch
156        let spare = vec.spare_capacity_mut();
157        debug_assert!(spare.len() >= diff);
158        // Safety: we have allocated enough capacity for this.
159        // And we are only writing, not reading
160        unsafe {
161            spare.get_unchecked_mut(..diff).fill(core::mem::MaybeUninit::new(0));
162            vec.set_len(pos);
163        }
164    }
165
166    Ok(pos)
167}
168
169/// Writes the slice to the vec without allocating.
170///
171/// # Safety
172///
173/// `vec` must have `buf.len()` spare capacity.
174unsafe fn vec_write_all_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize
175where
176    A: Allocator,
177{
178    debug_assert!(vec.capacity() >= pos + buf.len());
179    unsafe { vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()) };
180    pos + buf.len()
181}
182
183/// Resizing `write_all` implementation for [`Cursor`].
184///
185/// Cursor is allowed to have a pre-allocated and initialised
186/// vector body, but with a position of 0. This means the [`Write`]
187/// will overwrite the contents of the vec.
188///
189/// This also allows for the vec body to be empty, but with a position of N.
190/// This means that [`Write`] will pad the vec with 0 initially,
191/// before writing anything from that point
192///
193/// [`Write`]: crate::io::Write
194fn vec_write_all<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
195where
196    A: Allocator,
197{
198    let buf_len = buf.len();
199    let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
200
201    // Write the buf then progress the vec forward if necessary
202    // Safety: we have ensured that the capacity is available
203    // and that all bytes get written up to pos
204    unsafe {
205        pos = vec_write_all_unchecked(pos, vec, buf);
206        if pos > vec.len() {
207            vec.set_len(pos);
208        }
209    };
210
211    // Bump us forward
212    *pos_mut += buf_len as u64;
213    Ok(buf_len)
214}
215
216/// Resizing `write_all_vectored` implementation for [`Cursor`].
217///
218/// Cursor is allowed to have a pre-allocated and initialised
219/// vector body, but with a position of 0. This means the [`Write`]
220/// will overwrite the contents of the vec.
221///
222/// This also allows for the vec body to be empty, but with a position of N.
223/// This means that [`Write`] will pad the vec with 0 initially,
224/// before writing anything from that point
225///
226/// [`Write`]: crate::io::Write
227fn vec_write_all_vectored<A>(
228    pos_mut: &mut u64,
229    vec: &mut Vec<u8, A>,
230    bufs: &[IoSlice<'_>],
231) -> io::Result<usize>
232where
233    A: Allocator,
234{
235    // For safety reasons, we don't want this sum to overflow ever.
236    // If this saturates, the reserve should panic to avoid any unsound writing.
237    let buf_len = bufs.iter().fold(0usize, |a, b| a.saturating_add(b.len()));
238    let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
239
240    // Write the buf then progress the vec forward if necessary
241    // Safety: we have ensured that the capacity is available
242    // and that all bytes get written up to the last pos
243    unsafe {
244        for buf in bufs {
245            pos = vec_write_all_unchecked(pos, vec, buf);
246        }
247        if pos > vec.len() {
248            vec.set_len(pos);
249        }
250    }
251
252    // Bump us forward
253    *pos_mut += buf_len as u64;
254    Ok(buf_len)
255}
256
257#[stable(feature = "cursor_mut_vec", since = "1.25.0")]
258impl<A> WriteThroughCursor for &mut Vec<u8, A>
259where
260    A: Allocator,
261{
262    fn write(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<usize> {
263        let (pos, inner) = this.into_parts_mut();
264        vec_write_all(pos, inner, buf)
265    }
266
267    fn write_vectored(this: &mut Cursor<Self>, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
268        let (pos, inner) = this.into_parts_mut();
269        vec_write_all_vectored(pos, inner, bufs)
270    }
271
272    #[inline]
273    fn is_write_vectored(_this: &Cursor<Self>) -> bool {
274        true
275    }
276
277    fn write_all(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<()> {
278        let (pos, inner) = this.into_parts_mut();
279        vec_write_all(pos, inner, buf)?;
280        Ok(())
281    }
282
283    fn write_all_vectored(this: &mut Cursor<Self>, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
284        let (pos, inner) = this.into_parts_mut();
285        vec_write_all_vectored(pos, inner, bufs)?;
286        Ok(())
287    }
288
289    #[inline]
290    fn flush(_this: &mut Cursor<Self>) -> io::Result<()> {
291        Ok(())
292    }
293}
294
295#[stable(feature = "rust1", since = "1.0.0")]
296impl<A> WriteThroughCursor for Vec<u8, A>
297where
298    A: Allocator,
299{
300    fn write(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<usize> {
301        let (pos, inner) = this.into_parts_mut();
302        vec_write_all(pos, inner, buf)
303    }
304
305    fn write_vectored(this: &mut Cursor<Self>, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
306        let (pos, inner) = this.into_parts_mut();
307        vec_write_all_vectored(pos, inner, bufs)
308    }
309
310    #[inline]
311    fn is_write_vectored(_this: &Cursor<Self>) -> bool {
312        true
313    }
314
315    fn write_all(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<()> {
316        let (pos, inner) = this.into_parts_mut();
317        vec_write_all(pos, inner, buf)?;
318        Ok(())
319    }
320
321    fn write_all_vectored(this: &mut Cursor<Self>, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
322        let (pos, inner) = this.into_parts_mut();
323        vec_write_all_vectored(pos, inner, bufs)?;
324        Ok(())
325    }
326
327    #[inline]
328    fn flush(_this: &mut Cursor<Self>) -> io::Result<()> {
329        Ok(())
330    }
331}
332
333#[stable(feature = "cursor_box_slice", since = "1.5.0")]
334impl<A> WriteThroughCursor for Box<[u8], A>
335where
336    A: Allocator,
337{
338    #[inline]
339    fn write(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<usize> {
340        let (pos, inner) = this.into_parts_mut();
341        slice_write(pos, inner, buf)
342    }
343
344    #[inline]
345    fn write_vectored(this: &mut Cursor<Self>, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
346        let (pos, inner) = this.into_parts_mut();
347        slice_write_vectored(pos, inner, bufs)
348    }
349
350    #[inline]
351    fn is_write_vectored(_this: &Cursor<Self>) -> bool {
352        true
353    }
354
355    #[inline]
356    fn write_all(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<()> {
357        let (pos, inner) = this.into_parts_mut();
358        slice_write_all(pos, inner, buf)
359    }
360
361    #[inline]
362    fn write_all_vectored(this: &mut Cursor<Self>, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
363        let (pos, inner) = this.into_parts_mut();
364        slice_write_all_vectored(pos, inner, bufs)
365    }
366
367    #[inline]
368    fn flush(_this: &mut Cursor<Self>) -> io::Result<()> {
369        Ok(())
370    }
371}