std/io/
cursor.rs

1#[cfg(test)]
2mod tests;
3
4use crate::alloc::Allocator;
5use crate::cmp;
6use crate::io::prelude::*;
7use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut, SeekFrom};
8
9/// A `Cursor` wraps an in-memory buffer and provides it with a
10/// [`Seek`] implementation.
11///
12/// `Cursor`s are used with in-memory buffers, anything implementing
13/// <code>[AsRef]<\[u8]></code>, to allow them to implement [`Read`] and/or [`Write`],
14/// allowing these buffers to be used anywhere you might use a reader or writer
15/// that does actual I/O.
16///
17/// The standard library implements some I/O traits on various types which
18/// are commonly used as a buffer, like <code>Cursor<[Vec]\<u8>></code> and
19/// <code>Cursor<[&\[u8\]][bytes]></code>.
20///
21/// # Examples
22///
23/// We may want to write bytes to a [`File`] in our production
24/// code, but use an in-memory buffer in our tests. We can do this with
25/// `Cursor`:
26///
27/// [bytes]: crate::slice "slice"
28/// [`File`]: crate::fs::File
29///
30/// ```no_run
31/// use std::io::prelude::*;
32/// use std::io::{self, SeekFrom};
33/// use std::fs::File;
34///
35/// // a library function we've written
36/// fn write_ten_bytes_at_end<W: Write + Seek>(mut writer: W) -> io::Result<()> {
37///     writer.seek(SeekFrom::End(-10))?;
38///
39///     for i in 0..10 {
40///         writer.write(&[i])?;
41///     }
42///
43///     // all went well
44///     Ok(())
45/// }
46///
47/// # fn foo() -> io::Result<()> {
48/// // Here's some code that uses this library function.
49/// //
50/// // We might want to use a BufReader here for efficiency, but let's
51/// // keep this example focused.
52/// let mut file = File::create("foo.txt")?;
53/// // First, we need to allocate 10 bytes to be able to write into.
54/// file.set_len(10)?;
55///
56/// write_ten_bytes_at_end(&mut file)?;
57/// # Ok(())
58/// # }
59///
60/// // now let's write a test
61/// #[test]
62/// fn test_writes_bytes() {
63///     // setting up a real File is much slower than an in-memory buffer,
64///     // let's use a cursor instead
65///     use std::io::Cursor;
66///     let mut buff = Cursor::new(vec![0; 15]);
67///
68///     write_ten_bytes_at_end(&mut buff).unwrap();
69///
70///     assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
71/// }
72/// ```
73#[stable(feature = "rust1", since = "1.0.0")]
74#[derive(Debug, Default, Eq, PartialEq)]
75pub struct Cursor<T> {
76    inner: T,
77    pos: u64,
78}
79
80impl<T> Cursor<T> {
81    /// Creates a new cursor wrapping the provided underlying in-memory buffer.
82    ///
83    /// Cursor initial position is `0` even if underlying buffer (e.g., [`Vec`])
84    /// is not empty. So writing to cursor starts with overwriting [`Vec`]
85    /// content, not with appending to it.
86    ///
87    /// # Examples
88    ///
89    /// ```
90    /// use std::io::Cursor;
91    ///
92    /// let buff = Cursor::new(Vec::new());
93    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
94    /// # force_inference(&buff);
95    /// ```
96    #[stable(feature = "rust1", since = "1.0.0")]
97    #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
98    pub const fn new(inner: T) -> Cursor<T> {
99        Cursor { pos: 0, inner }
100    }
101
102    /// Consumes this cursor, returning the underlying value.
103    ///
104    /// # Examples
105    ///
106    /// ```
107    /// use std::io::Cursor;
108    ///
109    /// let buff = Cursor::new(Vec::new());
110    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
111    /// # force_inference(&buff);
112    ///
113    /// let vec = buff.into_inner();
114    /// ```
115    #[stable(feature = "rust1", since = "1.0.0")]
116    pub fn into_inner(self) -> T {
117        self.inner
118    }
119
120    /// Gets a reference to the underlying value in this cursor.
121    ///
122    /// # Examples
123    ///
124    /// ```
125    /// use std::io::Cursor;
126    ///
127    /// let buff = Cursor::new(Vec::new());
128    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
129    /// # force_inference(&buff);
130    ///
131    /// let reference = buff.get_ref();
132    /// ```
133    #[stable(feature = "rust1", since = "1.0.0")]
134    #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
135    pub const fn get_ref(&self) -> &T {
136        &self.inner
137    }
138
139    /// Gets a mutable reference to the underlying value in this cursor.
140    ///
141    /// Care should be taken to avoid modifying the internal I/O state of the
142    /// underlying value as it may corrupt this cursor's position.
143    ///
144    /// # Examples
145    ///
146    /// ```
147    /// use std::io::Cursor;
148    ///
149    /// let mut buff = Cursor::new(Vec::new());
150    /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
151    /// # force_inference(&buff);
152    ///
153    /// let reference = buff.get_mut();
154    /// ```
155    #[stable(feature = "rust1", since = "1.0.0")]
156    #[rustc_const_stable(feature = "const_mut_cursor", since = "1.86.0")]
157    pub const fn get_mut(&mut self) -> &mut T {
158        &mut self.inner
159    }
160
161    /// Returns the current position of this cursor.
162    ///
163    /// # Examples
164    ///
165    /// ```
166    /// use std::io::Cursor;
167    /// use std::io::prelude::*;
168    /// use std::io::SeekFrom;
169    ///
170    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
171    ///
172    /// assert_eq!(buff.position(), 0);
173    ///
174    /// buff.seek(SeekFrom::Current(2)).unwrap();
175    /// assert_eq!(buff.position(), 2);
176    ///
177    /// buff.seek(SeekFrom::Current(-1)).unwrap();
178    /// assert_eq!(buff.position(), 1);
179    /// ```
180    #[stable(feature = "rust1", since = "1.0.0")]
181    #[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
182    pub const fn position(&self) -> u64 {
183        self.pos
184    }
185
186    /// Sets the position of this cursor.
187    ///
188    /// # Examples
189    ///
190    /// ```
191    /// use std::io::Cursor;
192    ///
193    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
194    ///
195    /// assert_eq!(buff.position(), 0);
196    ///
197    /// buff.set_position(2);
198    /// assert_eq!(buff.position(), 2);
199    ///
200    /// buff.set_position(4);
201    /// assert_eq!(buff.position(), 4);
202    /// ```
203    #[stable(feature = "rust1", since = "1.0.0")]
204    #[rustc_const_stable(feature = "const_mut_cursor", since = "1.86.0")]
205    pub const fn set_position(&mut self, pos: u64) {
206        self.pos = pos;
207    }
208}
209
210impl<T> Cursor<T>
211where
212    T: AsRef<[u8]>,
213{
214    /// Splits the underlying slice at the cursor position and returns them.
215    ///
216    /// # Examples
217    ///
218    /// ```
219    /// #![feature(cursor_split)]
220    /// use std::io::Cursor;
221    ///
222    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
223    ///
224    /// assert_eq!(buff.split(), ([].as_slice(), [1, 2, 3, 4, 5].as_slice()));
225    ///
226    /// buff.set_position(2);
227    /// assert_eq!(buff.split(), ([1, 2].as_slice(), [3, 4, 5].as_slice()));
228    ///
229    /// buff.set_position(6);
230    /// assert_eq!(buff.split(), ([1, 2, 3, 4, 5].as_slice(), [].as_slice()));
231    /// ```
232    #[unstable(feature = "cursor_split", issue = "86369")]
233    pub fn split(&self) -> (&[u8], &[u8]) {
234        let slice = self.inner.as_ref();
235        let pos = self.pos.min(slice.len() as u64);
236        slice.split_at(pos as usize)
237    }
238}
239
240impl<T> Cursor<T>
241where
242    T: AsMut<[u8]>,
243{
244    /// Splits the underlying slice at the cursor position and returns them
245    /// mutably.
246    ///
247    /// # Examples
248    ///
249    /// ```
250    /// #![feature(cursor_split)]
251    /// use std::io::Cursor;
252    ///
253    /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
254    ///
255    /// assert_eq!(buff.split_mut(), ([].as_mut_slice(), [1, 2, 3, 4, 5].as_mut_slice()));
256    ///
257    /// buff.set_position(2);
258    /// assert_eq!(buff.split_mut(), ([1, 2].as_mut_slice(), [3, 4, 5].as_mut_slice()));
259    ///
260    /// buff.set_position(6);
261    /// assert_eq!(buff.split_mut(), ([1, 2, 3, 4, 5].as_mut_slice(), [].as_mut_slice()));
262    /// ```
263    #[unstable(feature = "cursor_split", issue = "86369")]
264    pub fn split_mut(&mut self) -> (&mut [u8], &mut [u8]) {
265        let slice = self.inner.as_mut();
266        let pos = self.pos.min(slice.len() as u64);
267        slice.split_at_mut(pos as usize)
268    }
269}
270
271#[stable(feature = "rust1", since = "1.0.0")]
272impl<T> Clone for Cursor<T>
273where
274    T: Clone,
275{
276    #[inline]
277    fn clone(&self) -> Self {
278        Cursor { inner: self.inner.clone(), pos: self.pos }
279    }
280
281    #[inline]
282    fn clone_from(&mut self, other: &Self) {
283        self.inner.clone_from(&other.inner);
284        self.pos = other.pos;
285    }
286}
287
288#[stable(feature = "rust1", since = "1.0.0")]
289impl<T> io::Seek for Cursor<T>
290where
291    T: AsRef<[u8]>,
292{
293    fn seek(&mut self, style: SeekFrom) -> io::Result<u64> {
294        let (base_pos, offset) = match style {
295            SeekFrom::Start(n) => {
296                self.pos = n;
297                return Ok(n);
298            }
299            SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n),
300            SeekFrom::Current(n) => (self.pos, n),
301        };
302        match base_pos.checked_add_signed(offset) {
303            Some(n) => {
304                self.pos = n;
305                Ok(self.pos)
306            }
307            None => Err(io::const_error!(
308                ErrorKind::InvalidInput,
309                "invalid seek to a negative or overflowing position",
310            )),
311        }
312    }
313
314    fn stream_len(&mut self) -> io::Result<u64> {
315        Ok(self.inner.as_ref().len() as u64)
316    }
317
318    fn stream_position(&mut self) -> io::Result<u64> {
319        Ok(self.pos)
320    }
321}
322
323#[stable(feature = "rust1", since = "1.0.0")]
324impl<T> Read for Cursor<T>
325where
326    T: AsRef<[u8]>,
327{
328    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
329        let n = Read::read(&mut Cursor::split(self).1, buf)?;
330        self.pos += n as u64;
331        Ok(n)
332    }
333
334    fn read_buf(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
335        let prev_written = cursor.written();
336
337        Read::read_buf(&mut Cursor::split(self).1, cursor.reborrow())?;
338
339        self.pos += (cursor.written() - prev_written) as u64;
340
341        Ok(())
342    }
343
344    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
345        let mut nread = 0;
346        for buf in bufs {
347            let n = self.read(buf)?;
348            nread += n;
349            if n < buf.len() {
350                break;
351            }
352        }
353        Ok(nread)
354    }
355
356    fn is_read_vectored(&self) -> bool {
357        true
358    }
359
360    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
361        let result = Read::read_exact(&mut Cursor::split(self).1, buf);
362
363        match result {
364            Ok(_) => self.pos += buf.len() as u64,
365            // The only possible error condition is EOF, so place the cursor at "EOF"
366            Err(_) => self.pos = self.inner.as_ref().len() as u64,
367        }
368
369        result
370    }
371
372    fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
373        let prev_written = cursor.written();
374
375        let result = Read::read_buf_exact(&mut Cursor::split(self).1, cursor.reborrow());
376        self.pos += (cursor.written() - prev_written) as u64;
377
378        result
379    }
380
381    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
382        let content = Cursor::split(self).1;
383        let len = content.len();
384        buf.try_reserve(len)?;
385        buf.extend_from_slice(content);
386        self.pos += len as u64;
387
388        Ok(len)
389    }
390
391    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
392        let content =
393            crate::str::from_utf8(Cursor::split(self).1).map_err(|_| io::Error::INVALID_UTF8)?;
394        let len = content.len();
395        buf.try_reserve(len)?;
396        buf.push_str(content);
397        self.pos += len as u64;
398
399        Ok(len)
400    }
401}
402
403#[stable(feature = "rust1", since = "1.0.0")]
404impl<T> BufRead for Cursor<T>
405where
406    T: AsRef<[u8]>,
407{
408    fn fill_buf(&mut self) -> io::Result<&[u8]> {
409        Ok(Cursor::split(self).1)
410    }
411    fn consume(&mut self, amt: usize) {
412        self.pos += amt as u64;
413    }
414}
415
416// Non-resizing write implementation
417#[inline]
418fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<usize> {
419    let pos = cmp::min(*pos_mut, slice.len() as u64);
420    let amt = (&mut slice[(pos as usize)..]).write(buf)?;
421    *pos_mut += amt as u64;
422    Ok(amt)
423}
424
425#[inline]
426fn slice_write_vectored(
427    pos_mut: &mut u64,
428    slice: &mut [u8],
429    bufs: &[IoSlice<'_>],
430) -> io::Result<usize> {
431    let mut nwritten = 0;
432    for buf in bufs {
433        let n = slice_write(pos_mut, slice, buf)?;
434        nwritten += n;
435        if n < buf.len() {
436            break;
437        }
438    }
439    Ok(nwritten)
440}
441
442#[inline]
443fn slice_write_all(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<()> {
444    let n = slice_write(pos_mut, slice, buf)?;
445    if n < buf.len() { Err(io::Error::WRITE_ALL_EOF) } else { Ok(()) }
446}
447
448#[inline]
449fn slice_write_all_vectored(
450    pos_mut: &mut u64,
451    slice: &mut [u8],
452    bufs: &[IoSlice<'_>],
453) -> io::Result<()> {
454    for buf in bufs {
455        let n = slice_write(pos_mut, slice, buf)?;
456        if n < buf.len() {
457            return Err(io::Error::WRITE_ALL_EOF);
458        }
459    }
460    Ok(())
461}
462
463/// Reserves the required space, and pads the vec with 0s if necessary.
464fn reserve_and_pad<A: Allocator>(
465    pos_mut: &mut u64,
466    vec: &mut Vec<u8, A>,
467    buf_len: usize,
468) -> io::Result<usize> {
469    let pos: usize = (*pos_mut).try_into().map_err(|_| {
470        io::const_error!(
471            ErrorKind::InvalidInput,
472            "cursor position exceeds maximum possible vector length",
473        )
474    })?;
475
476    // For safety reasons, we don't want these numbers to overflow
477    // otherwise our allocation won't be enough
478    let desired_cap = pos.saturating_add(buf_len);
479    if desired_cap > vec.capacity() {
480        // We want our vec's total capacity
481        // to have room for (pos+buf_len) bytes. Reserve allocates
482        // based on additional elements from the length, so we need to
483        // reserve the difference
484        vec.reserve(desired_cap - vec.len());
485    }
486    // Pad if pos is above the current len.
487    if pos > vec.len() {
488        let diff = pos - vec.len();
489        // Unfortunately, `resize()` would suffice but the optimiser does not
490        // realise the `reserve` it does can be eliminated. So we do it manually
491        // to eliminate that extra branch
492        let spare = vec.spare_capacity_mut();
493        debug_assert!(spare.len() >= diff);
494        // Safety: we have allocated enough capacity for this.
495        // And we are only writing, not reading
496        unsafe {
497            spare.get_unchecked_mut(..diff).fill(core::mem::MaybeUninit::new(0));
498            vec.set_len(pos);
499        }
500    }
501
502    Ok(pos)
503}
504
505/// Writes the slice to the vec without allocating.
506///
507/// # Safety
508///
509/// `vec` must have `buf.len()` spare capacity.
510unsafe fn vec_write_all_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize
511where
512    A: Allocator,
513{
514    debug_assert!(vec.capacity() >= pos + buf.len());
515    unsafe { vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()) };
516    pos + buf.len()
517}
518
519/// Resizing `write_all` implementation for [`Cursor`].
520///
521/// Cursor is allowed to have a pre-allocated and initialised
522/// vector body, but with a position of 0. This means the [`Write`]
523/// will overwrite the contents of the vec.
524///
525/// This also allows for the vec body to be empty, but with a position of N.
526/// This means that [`Write`] will pad the vec with 0 initially,
527/// before writing anything from that point
528fn vec_write_all<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
529where
530    A: Allocator,
531{
532    let buf_len = buf.len();
533    let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
534
535    // Write the buf then progress the vec forward if necessary
536    // Safety: we have ensured that the capacity is available
537    // and that all bytes get written up to pos
538    unsafe {
539        pos = vec_write_all_unchecked(pos, vec, buf);
540        if pos > vec.len() {
541            vec.set_len(pos);
542        }
543    };
544
545    // Bump us forward
546    *pos_mut += buf_len as u64;
547    Ok(buf_len)
548}
549
550/// Resizing `write_all_vectored` implementation for [`Cursor`].
551///
552/// Cursor is allowed to have a pre-allocated and initialised
553/// vector body, but with a position of 0. This means the [`Write`]
554/// will overwrite the contents of the vec.
555///
556/// This also allows for the vec body to be empty, but with a position of N.
557/// This means that [`Write`] will pad the vec with 0 initially,
558/// before writing anything from that point
559fn vec_write_all_vectored<A>(
560    pos_mut: &mut u64,
561    vec: &mut Vec<u8, A>,
562    bufs: &[IoSlice<'_>],
563) -> io::Result<usize>
564where
565    A: Allocator,
566{
567    // For safety reasons, we don't want this sum to overflow ever.
568    // If this saturates, the reserve should panic to avoid any unsound writing.
569    let buf_len = bufs.iter().fold(0usize, |a, b| a.saturating_add(b.len()));
570    let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
571
572    // Write the buf then progress the vec forward if necessary
573    // Safety: we have ensured that the capacity is available
574    // and that all bytes get written up to the last pos
575    unsafe {
576        for buf in bufs {
577            pos = vec_write_all_unchecked(pos, vec, buf);
578        }
579        if pos > vec.len() {
580            vec.set_len(pos);
581        }
582    }
583
584    // Bump us forward
585    *pos_mut += buf_len as u64;
586    Ok(buf_len)
587}
588
589#[stable(feature = "rust1", since = "1.0.0")]
590impl Write for Cursor<&mut [u8]> {
591    #[inline]
592    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
593        slice_write(&mut self.pos, self.inner, buf)
594    }
595
596    #[inline]
597    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
598        slice_write_vectored(&mut self.pos, self.inner, bufs)
599    }
600
601    #[inline]
602    fn is_write_vectored(&self) -> bool {
603        true
604    }
605
606    #[inline]
607    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
608        slice_write_all(&mut self.pos, self.inner, buf)
609    }
610
611    #[inline]
612    fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
613        slice_write_all_vectored(&mut self.pos, self.inner, bufs)
614    }
615
616    #[inline]
617    fn flush(&mut self) -> io::Result<()> {
618        Ok(())
619    }
620}
621
622#[stable(feature = "cursor_mut_vec", since = "1.25.0")]
623impl<A> Write for Cursor<&mut Vec<u8, A>>
624where
625    A: Allocator,
626{
627    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
628        vec_write_all(&mut self.pos, self.inner, buf)
629    }
630
631    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
632        vec_write_all_vectored(&mut self.pos, self.inner, bufs)
633    }
634
635    #[inline]
636    fn is_write_vectored(&self) -> bool {
637        true
638    }
639
640    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
641        vec_write_all(&mut self.pos, self.inner, buf)?;
642        Ok(())
643    }
644
645    fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
646        vec_write_all_vectored(&mut self.pos, self.inner, bufs)?;
647        Ok(())
648    }
649
650    #[inline]
651    fn flush(&mut self) -> io::Result<()> {
652        Ok(())
653    }
654}
655
656#[stable(feature = "rust1", since = "1.0.0")]
657impl<A> Write for Cursor<Vec<u8, A>>
658where
659    A: Allocator,
660{
661    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
662        vec_write_all(&mut self.pos, &mut self.inner, buf)
663    }
664
665    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
666        vec_write_all_vectored(&mut self.pos, &mut self.inner, bufs)
667    }
668
669    #[inline]
670    fn is_write_vectored(&self) -> bool {
671        true
672    }
673
674    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
675        vec_write_all(&mut self.pos, &mut self.inner, buf)?;
676        Ok(())
677    }
678
679    fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
680        vec_write_all_vectored(&mut self.pos, &mut self.inner, bufs)?;
681        Ok(())
682    }
683
684    #[inline]
685    fn flush(&mut self) -> io::Result<()> {
686        Ok(())
687    }
688}
689
690#[stable(feature = "cursor_box_slice", since = "1.5.0")]
691impl<A> Write for Cursor<Box<[u8], A>>
692where
693    A: Allocator,
694{
695    #[inline]
696    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
697        slice_write(&mut self.pos, &mut self.inner, buf)
698    }
699
700    #[inline]
701    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
702        slice_write_vectored(&mut self.pos, &mut self.inner, bufs)
703    }
704
705    #[inline]
706    fn is_write_vectored(&self) -> bool {
707        true
708    }
709
710    #[inline]
711    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
712        slice_write_all(&mut self.pos, &mut self.inner, buf)
713    }
714
715    #[inline]
716    fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
717        slice_write_all_vectored(&mut self.pos, &mut self.inner, bufs)
718    }
719
720    #[inline]
721    fn flush(&mut self) -> io::Result<()> {
722        Ok(())
723    }
724}
725
726#[stable(feature = "cursor_array", since = "1.61.0")]
727impl<const N: usize> Write for Cursor<[u8; N]> {
728    #[inline]
729    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
730        slice_write(&mut self.pos, &mut self.inner, buf)
731    }
732
733    #[inline]
734    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
735        slice_write_vectored(&mut self.pos, &mut self.inner, bufs)
736    }
737
738    #[inline]
739    fn is_write_vectored(&self) -> bool {
740        true
741    }
742
743    #[inline]
744    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
745        slice_write_all(&mut self.pos, &mut self.inner, buf)
746    }
747
748    #[inline]
749    fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
750        slice_write_all_vectored(&mut self.pos, &mut self.inner, bufs)
751    }
752
753    #[inline]
754    fn flush(&mut self) -> io::Result<()> {
755        Ok(())
756    }
757}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy