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#[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 #[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 #[stable(feature = "rust1", since = "1.0.0")]
116 pub fn into_inner(self) -> T {
117 self.inner
118 }
119
120 #[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 #[stable(feature = "rust1", since = "1.0.0")]
156 #[rustc_const_stable(feature = "const_mut_cursor", since = "CURRENT_RUSTC_VERSION")]
157 pub const fn get_mut(&mut self) -> &mut T {
158 &mut self.inner
159 }
160
161 #[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 #[stable(feature = "rust1", since = "1.0.0")]
204 #[rustc_const_stable(feature = "const_mut_cursor", since = "CURRENT_RUSTC_VERSION")]
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 #[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 #[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 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#[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
442fn reserve_and_pad<A: Allocator>(
444 pos_mut: &mut u64,
445 vec: &mut Vec<u8, A>,
446 buf_len: usize,
447) -> io::Result<usize> {
448 let pos: usize = (*pos_mut).try_into().map_err(|_| {
449 io::const_error!(
450 ErrorKind::InvalidInput,
451 "cursor position exceeds maximum possible vector length",
452 )
453 })?;
454
455 let desired_cap = pos.saturating_add(buf_len);
458 if desired_cap > vec.capacity() {
459 vec.reserve(desired_cap - vec.len());
464 }
465 if pos > vec.len() {
467 let diff = pos - vec.len();
468 let spare = vec.spare_capacity_mut();
472 debug_assert!(spare.len() >= diff);
473 unsafe {
476 spare.get_unchecked_mut(..diff).fill(core::mem::MaybeUninit::new(0));
477 vec.set_len(pos);
478 }
479 }
480
481 Ok(pos)
482}
483
484unsafe fn vec_write_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize
487where
488 A: Allocator,
489{
490 debug_assert!(vec.capacity() >= pos + buf.len());
491 unsafe { vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()) };
492 pos + buf.len()
493}
494
495fn vec_write<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
505where
506 A: Allocator,
507{
508 let buf_len = buf.len();
509 let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
510
511 unsafe {
515 pos = vec_write_unchecked(pos, vec, buf);
516 if pos > vec.len() {
517 vec.set_len(pos);
518 }
519 };
520
521 *pos_mut += buf_len as u64;
523 Ok(buf_len)
524}
525
526fn vec_write_vectored<A>(
536 pos_mut: &mut u64,
537 vec: &mut Vec<u8, A>,
538 bufs: &[IoSlice<'_>],
539) -> io::Result<usize>
540where
541 A: Allocator,
542{
543 let buf_len = bufs.iter().fold(0usize, |a, b| a.saturating_add(b.len()));
546 let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
547
548 unsafe {
552 for buf in bufs {
553 pos = vec_write_unchecked(pos, vec, buf);
554 }
555 if pos > vec.len() {
556 vec.set_len(pos);
557 }
558 }
559
560 *pos_mut += buf_len as u64;
562 Ok(buf_len)
563}
564
565#[stable(feature = "rust1", since = "1.0.0")]
566impl Write for Cursor<&mut [u8]> {
567 #[inline]
568 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
569 slice_write(&mut self.pos, self.inner, buf)
570 }
571
572 #[inline]
573 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
574 slice_write_vectored(&mut self.pos, self.inner, bufs)
575 }
576
577 #[inline]
578 fn is_write_vectored(&self) -> bool {
579 true
580 }
581
582 #[inline]
583 fn flush(&mut self) -> io::Result<()> {
584 Ok(())
585 }
586}
587
588#[stable(feature = "cursor_mut_vec", since = "1.25.0")]
589impl<A> Write for Cursor<&mut Vec<u8, A>>
590where
591 A: Allocator,
592{
593 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
594 vec_write(&mut self.pos, self.inner, buf)
595 }
596
597 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
598 vec_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 flush(&mut self) -> io::Result<()> {
608 Ok(())
609 }
610}
611
612#[stable(feature = "rust1", since = "1.0.0")]
613impl<A> Write for Cursor<Vec<u8, A>>
614where
615 A: Allocator,
616{
617 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
618 vec_write(&mut self.pos, &mut self.inner, buf)
619 }
620
621 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
622 vec_write_vectored(&mut self.pos, &mut self.inner, bufs)
623 }
624
625 #[inline]
626 fn is_write_vectored(&self) -> bool {
627 true
628 }
629
630 #[inline]
631 fn flush(&mut self) -> io::Result<()> {
632 Ok(())
633 }
634}
635
636#[stable(feature = "cursor_box_slice", since = "1.5.0")]
637impl<A> Write for Cursor<Box<[u8], A>>
638where
639 A: Allocator,
640{
641 #[inline]
642 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
643 slice_write(&mut self.pos, &mut self.inner, buf)
644 }
645
646 #[inline]
647 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
648 slice_write_vectored(&mut self.pos, &mut self.inner, bufs)
649 }
650
651 #[inline]
652 fn is_write_vectored(&self) -> bool {
653 true
654 }
655
656 #[inline]
657 fn flush(&mut self) -> io::Result<()> {
658 Ok(())
659 }
660}
661
662#[stable(feature = "cursor_array", since = "1.61.0")]
663impl<const N: usize> Write for Cursor<[u8; N]> {
664 #[inline]
665 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
666 slice_write(&mut self.pos, &mut self.inner, buf)
667 }
668
669 #[inline]
670 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
671 slice_write_vectored(&mut self.pos, &mut self.inner, bufs)
672 }
673
674 #[inline]
675 fn is_write_vectored(&self) -> bool {
676 true
677 }
678
679 #[inline]
680 fn flush(&mut self) -> io::Result<()> {
681 Ok(())
682 }
683}