cursor.rs - source (original) (raw)
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}