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        ::core::hint::must_use(::core::io::Error::from_static_message(const {
                &::core::io::SimpleMessage {
                        kind: ErrorKind::InvalidInput,
                        message: "cursor position exceeds maximum possible vector length",
                    }
            }))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        if true {
    if !(spare.len() >= diff) {
        ::core::panicking::panic("assertion failed: spare.len() >= diff")
    };
};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    if true {
    if !(vec.capacity() >= pos + buf.len()) {
        ::core::panicking::panic("assertion failed: vec.capacity() >= pos + buf.len()")
    };
};debug_assert!(vec.capacity() >= pos + buf.len());
179    // SAFETY: Upheld by caller.
180    unsafe { vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()) };
181    pos + buf.len()
182}
183
184/// Resizing `write_all` implementation for [`Cursor`].
185///
186/// Cursor is allowed to have a pre-allocated and initialised
187/// vector body, but with a position of 0. This means the [`Write`]
188/// will overwrite the contents of the vec.
189///
190/// This also allows for the vec body to be empty, but with a position of N.
191/// This means that [`Write`] will pad the vec with 0 initially,
192/// before writing anything from that point
193///
194/// [`Write`]: crate::io::Write
195fn vec_write_all<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
196where
197    A: Allocator,
198{
199    let buf_len = buf.len();
200    let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
201
202    // Write the buf then progress the vec forward if necessary
203    // SAFETY: we have ensured that the capacity is available
204    // and that all bytes get written up to pos
205    unsafe {
206        pos = vec_write_all_unchecked(pos, vec, buf);
207        if pos > vec.len() {
208            vec.set_len(pos);
209        }
210    };
211
212    // Bump us forward
213    *pos_mut += buf_len as u64;
214    Ok(buf_len)
215}
216
217/// Resizing `write_all_vectored` implementation for [`Cursor`].
218///
219/// Cursor is allowed to have a pre-allocated and initialised
220/// vector body, but with a position of 0. This means the [`Write`]
221/// will overwrite the contents of the vec.
222///
223/// This also allows for the vec body to be empty, but with a position of N.
224/// This means that [`Write`] will pad the vec with 0 initially,
225/// before writing anything from that point
226///
227/// [`Write`]: crate::io::Write
228fn vec_write_all_vectored<A>(
229    pos_mut: &mut u64,
230    vec: &mut Vec<u8, A>,
231    bufs: &[IoSlice<'_>],
232) -> io::Result<usize>
233where
234    A: Allocator,
235{
236    // For safety reasons, we don't want this sum to overflow ever.
237    // If this saturates, the reserve should panic to avoid any unsound writing.
238    let buf_len = bufs.iter().fold(0usize, |a, b| a.saturating_add(b.len()));
239    let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
240
241    // Write the buf then progress the vec forward if necessary.
242    // SAFETY: We have ensured that the capacity is available
243    // and that all bytes get written up to the last pos
244    unsafe {
245        for buf in bufs {
246            pos = vec_write_all_unchecked(pos, vec, buf);
247        }
248        if pos > vec.len() {
249            vec.set_len(pos);
250        }
251    }
252
253    // Bump us forward
254    *pos_mut += buf_len as u64;
255    Ok(buf_len)
256}
257
258#[stable(feature = "cursor_mut_vec", since = "1.25.0")]
259impl<A> WriteThroughCursor for &mut Vec<u8, A>
260where
261    A: Allocator,
262{
263    fn write(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<usize> {
264        let (pos, inner) = this.into_parts_mut();
265        vec_write_all(pos, inner, buf)
266    }
267
268    fn write_vectored(this: &mut Cursor<Self>, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
269        let (pos, inner) = this.into_parts_mut();
270        vec_write_all_vectored(pos, inner, bufs)
271    }
272
273    #[inline]
274    fn is_write_vectored(_this: &Cursor<Self>) -> bool {
275        true
276    }
277
278    fn write_all(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<()> {
279        let (pos, inner) = this.into_parts_mut();
280        vec_write_all(pos, inner, buf)?;
281        Ok(())
282    }
283
284    fn write_all_vectored(this: &mut Cursor<Self>, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
285        let (pos, inner) = this.into_parts_mut();
286        vec_write_all_vectored(pos, inner, bufs)?;
287        Ok(())
288    }
289
290    #[inline]
291    fn flush(_this: &mut Cursor<Self>) -> io::Result<()> {
292        Ok(())
293    }
294}
295
296#[stable(feature = "rust1", since = "1.0.0")]
297impl<A> WriteThroughCursor for Vec<u8, A>
298where
299    A: Allocator,
300{
301    fn write(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<usize> {
302        let (pos, inner) = this.into_parts_mut();
303        vec_write_all(pos, inner, buf)
304    }
305
306    fn write_vectored(this: &mut Cursor<Self>, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
307        let (pos, inner) = this.into_parts_mut();
308        vec_write_all_vectored(pos, inner, bufs)
309    }
310
311    #[inline]
312    fn is_write_vectored(_this: &Cursor<Self>) -> bool {
313        true
314    }
315
316    fn write_all(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<()> {
317        let (pos, inner) = this.into_parts_mut();
318        vec_write_all(pos, inner, buf)?;
319        Ok(())
320    }
321
322    fn write_all_vectored(this: &mut Cursor<Self>, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
323        let (pos, inner) = this.into_parts_mut();
324        vec_write_all_vectored(pos, inner, bufs)?;
325        Ok(())
326    }
327
328    #[inline]
329    fn flush(_this: &mut Cursor<Self>) -> io::Result<()> {
330        Ok(())
331    }
332}
333
334#[stable(feature = "cursor_box_slice", since = "1.5.0")]
335impl<A> WriteThroughCursor for Box<[u8], A>
336where
337    A: Allocator,
338{
339    #[inline]
340    fn write(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<usize> {
341        let (pos, inner) = this.into_parts_mut();
342        slice_write(pos, inner, buf)
343    }
344
345    #[inline]
346    fn write_vectored(this: &mut Cursor<Self>, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
347        let (pos, inner) = this.into_parts_mut();
348        slice_write_vectored(pos, inner, bufs)
349    }
350
351    #[inline]
352    fn is_write_vectored(_this: &Cursor<Self>) -> bool {
353        true
354    }
355
356    #[inline]
357    fn write_all(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<()> {
358        let (pos, inner) = this.into_parts_mut();
359        slice_write_all(pos, inner, buf)
360    }
361
362    #[inline]
363    fn write_all_vectored(this: &mut Cursor<Self>, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
364        let (pos, inner) = this.into_parts_mut();
365        slice_write_all_vectored(pos, inner, bufs)
366    }
367
368    #[inline]
369    fn flush(_this: &mut Cursor<Self>) -> io::Result<()> {
370        Ok(())
371    }
372}