mycelium_util/io/
cursor.rs

1use crate::io::prelude::*;
2use crate::io::{self, Error, ErrorKind, Initializer, SeekFrom};
3
4use core::cmp;
5
6#[cfg(feature = "alloc")]
7use core::convert::TryInto;
8
9#[cfg(feature = "alloc")]
10use alloc::{boxed::Box, vec::Vec};
11
12/// A `Cursor` wraps an in-memory buffer and provides it with a
13/// [`Seek`] implementation.
14///
15/// `Cursor`s are used with in-memory buffers, anything implementing
16/// `AsRef<[u8]>`, to allow them to implement [`Read`] and/or [`Write`],
17/// allowing these buffers to be used anywhere you might use a reader or writer
18/// that does actual I/O.
19///
20/// The standard library implements some I/O traits on various types which
21/// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
22/// `Cursor<`[`&[u8]`][bytes]`>`.
23///
24/// [`Seek`]: trait.Seek.html
25/// [`Read`]: trait.Read.html
26/// [`Write`]: trait.Write.html
27/// [`Vec`]: ../../alloc/vec/struct.Vec.html
28/// [bytes]: ../../core/primitive.slice.html
29#[derive(Clone, Debug, Default)]
30pub struct Cursor<T> {
31    inner: T,
32    pos: u64,
33}
34
35impl<T> Cursor<T> {
36    /// Creates a new cursor wrapping the provided underlying in-memory buffer.
37    ///
38    /// Cursor initial position is `0` even if underlying buffer (e.g., `Vec`)
39    /// is not empty. So writing to cursor starts with overwriting `Vec`
40    /// content, not with appending to it.
41    pub fn new(inner: T) -> Cursor<T> {
42        Cursor { pos: 0, inner }
43    }
44
45    /// Consumes this cursor, returning the underlying value.
46    pub fn into_inner(self) -> T {
47        self.inner
48    }
49
50    /// Gets a reference to the underlying value in this cursor.
51    pub fn get_ref(&self) -> &T {
52        &self.inner
53    }
54
55    /// Gets a mutable reference to the underlying value in this cursor.
56    ///
57    /// Care should be taken to avoid modifying the internal I/O state of the
58    /// underlying value as it may corrupt this cursor's position.
59    pub fn get_mut(&mut self) -> &mut T {
60        &mut self.inner
61    }
62
63    /// Returns the current position of this cursor.
64    pub fn position(&self) -> u64 {
65        self.pos
66    }
67
68    /// Sets the position of this cursor.
69    pub fn set_position(&mut self, pos: u64) {
70        self.pos = pos;
71    }
72}
73
74impl<T> io::Seek for Cursor<T>
75where
76    T: AsRef<[u8]>,
77{
78    fn seek(&mut self, style: SeekFrom) -> io::Result<u64> {
79        let (base_pos, offset) = match style {
80            SeekFrom::Start(n) => {
81                self.pos = n;
82                return Ok(n);
83            }
84            SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n),
85            SeekFrom::Current(n) => (self.pos, n),
86        };
87        let new_pos = if offset >= 0 {
88            base_pos.checked_add(offset as u64)
89        } else {
90            base_pos.checked_sub((offset.wrapping_neg()) as u64)
91        };
92        match new_pos {
93            Some(n) => {
94                self.pos = n;
95                Ok(self.pos)
96            }
97            None => Err(Error::new(
98                ErrorKind::InvalidInput,
99                "invalid seek to a negative or overflowing position",
100            )),
101        }
102    }
103
104    fn stream_len(&mut self) -> io::Result<u64> {
105        Ok(self.inner.as_ref().len() as u64)
106    }
107
108    fn stream_position(&mut self) -> io::Result<u64> {
109        Ok(self.pos)
110    }
111}
112
113impl<T> Read for Cursor<T>
114where
115    T: AsRef<[u8]>,
116{
117    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
118        let n = Read::read(&mut self.fill_buf()?, buf)?;
119        self.pos += n as u64;
120        Ok(n)
121    }
122
123    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
124        let n = buf.len();
125        Read::read_exact(&mut self.fill_buf()?, buf)?;
126        self.pos += n as u64;
127        Ok(())
128    }
129
130    #[inline]
131    unsafe fn initializer(&self) -> Initializer {
132        Initializer::nop()
133    }
134}
135
136impl<T> BufRead for Cursor<T>
137where
138    T: AsRef<[u8]>,
139{
140    fn fill_buf(&mut self) -> io::Result<&[u8]> {
141        let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64);
142        Ok(&self.inner.as_ref()[(amt as usize)..])
143    }
144    fn consume(&mut self, amt: usize) {
145        self.pos += amt as u64;
146    }
147}
148
149// Non-resizing write implementation
150#[inline]
151fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<usize> {
152    let pos = cmp::min(*pos_mut, slice.len() as u64);
153    let amt = (&mut slice[(pos as usize)..]).write(buf)?;
154    *pos_mut += amt as u64;
155    Ok(amt)
156}
157
158// Resizing write implementation
159#[cfg(feature = "alloc")]
160fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> {
161    let pos: usize = (*pos_mut).try_into().map_err(|_| {
162        Error::new(
163            ErrorKind::InvalidInput,
164            "cursor position exceeds maximum possible vector length",
165        )
166    })?;
167    // Make sure the internal buffer is as least as big as where we
168    // currently are
169    let len = vec.len();
170    if len < pos {
171        // use `resize` so that the zero filling is as efficient as possible
172        vec.resize(pos, 0);
173    }
174    // Figure out what bytes will be used to overwrite what's currently
175    // there (left), and what will be appended on the end (right)
176    {
177        let space = vec.len() - pos;
178        let (left, right) = buf.split_at(cmp::min(space, buf.len()));
179        vec[pos..pos + left.len()].copy_from_slice(left);
180        vec.extend_from_slice(right);
181    }
182
183    // Bump us forward
184    *pos_mut = (pos + buf.len()) as u64;
185    Ok(buf.len())
186}
187
188impl Write for Cursor<&mut [u8]> {
189    #[inline]
190    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
191        slice_write(&mut self.pos, self.inner, buf)
192    }
193
194    #[inline]
195    fn flush(&mut self) -> io::Result<()> {
196        Ok(())
197    }
198}
199
200#[cfg(feature = "alloc")]
201impl Write for Cursor<&mut Vec<u8>> {
202    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
203        vec_write(&mut self.pos, self.inner, buf)
204    }
205
206    #[inline]
207    fn flush(&mut self) -> io::Result<()> {
208        Ok(())
209    }
210}
211
212#[cfg(feature = "alloc")]
213impl Write for Cursor<Vec<u8>> {
214    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
215        vec_write(&mut self.pos, &mut self.inner, buf)
216    }
217
218    #[inline]
219    fn flush(&mut self) -> io::Result<()> {
220        Ok(())
221    }
222}
223
224#[cfg(feature = "alloc")]
225impl Write for Cursor<Box<[u8]>> {
226    #[inline]
227    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
228        slice_write(&mut self.pos, &mut self.inner, buf)
229    }
230
231    #[inline]
232    fn flush(&mut self) -> io::Result<()> {
233        Ok(())
234    }
235}
236
237#[cfg(all(test, not(loom)))]
238mod tests {
239    use crate::io::prelude::*;
240    use crate::io::{Cursor, SeekFrom};
241    #[cfg(feature = "alloc")]
242    use alloc::{vec, vec::Vec};
243
244    #[test]
245    #[cfg(feature = "alloc")]
246    fn test_vec_writer() {
247        let mut writer = Vec::new();
248        assert_eq!(writer.write(&[0]).unwrap(), 1);
249        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
250        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
251        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
252        assert_eq!(writer, b);
253    }
254
255    #[test]
256    #[cfg(feature = "alloc")]
257    fn test_mem_writer() {
258        let mut writer = Cursor::new(Vec::new());
259        assert_eq!(writer.write(&[0]).unwrap(), 1);
260        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
261        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
262        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
263        assert_eq!(&writer.get_ref()[..], b);
264    }
265
266    #[test]
267    #[cfg(feature = "alloc")]
268    fn test_mem_mut_writer() {
269        let mut vec = Vec::new();
270        let mut writer = Cursor::new(&mut vec);
271        assert_eq!(writer.write(&[0]).unwrap(), 1);
272        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
273        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
274        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
275        assert_eq!(&writer.get_ref()[..], b);
276    }
277
278    #[test]
279    #[cfg(feature = "alloc")]
280    fn test_box_slice_writer() {
281        let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice());
282        assert_eq!(writer.position(), 0);
283        assert_eq!(writer.write(&[0]).unwrap(), 1);
284        assert_eq!(writer.position(), 1);
285        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
286        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
287        assert_eq!(writer.position(), 8);
288        assert_eq!(writer.write(&[]).unwrap(), 0);
289        assert_eq!(writer.position(), 8);
290
291        assert_eq!(writer.write(&[8, 9]).unwrap(), 1);
292        assert_eq!(writer.write(&[10]).unwrap(), 0);
293        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
294        assert_eq!(&**writer.get_ref(), b);
295    }
296
297    #[test]
298    fn test_buf_writer() {
299        let mut buf = [0u8; 9];
300        {
301            let mut writer = Cursor::new(&mut buf[..]);
302            assert_eq!(writer.position(), 0);
303            assert_eq!(writer.write(&[0]).unwrap(), 1);
304            assert_eq!(writer.position(), 1);
305            assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
306            assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
307            assert_eq!(writer.position(), 8);
308            assert_eq!(writer.write(&[]).unwrap(), 0);
309            assert_eq!(writer.position(), 8);
310
311            assert_eq!(writer.write(&[8, 9]).unwrap(), 1);
312            assert_eq!(writer.write(&[10]).unwrap(), 0);
313        }
314        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
315        assert_eq!(buf, b);
316    }
317
318    #[test]
319    fn test_buf_writer_seek() {
320        let mut buf = [0u8; 8];
321        {
322            let mut writer = Cursor::new(&mut buf[..]);
323            assert_eq!(writer.position(), 0);
324            assert_eq!(writer.write(&[1]).unwrap(), 1);
325            assert_eq!(writer.position(), 1);
326
327            assert_eq!(writer.seek(SeekFrom::Start(2)).unwrap(), 2);
328            assert_eq!(writer.position(), 2);
329            assert_eq!(writer.write(&[2]).unwrap(), 1);
330            assert_eq!(writer.position(), 3);
331
332            assert_eq!(writer.seek(SeekFrom::Current(-2)).unwrap(), 1);
333            assert_eq!(writer.position(), 1);
334            assert_eq!(writer.write(&[3]).unwrap(), 1);
335            assert_eq!(writer.position(), 2);
336
337            assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7);
338            assert_eq!(writer.position(), 7);
339            assert_eq!(writer.write(&[4]).unwrap(), 1);
340            assert_eq!(writer.position(), 8);
341        }
342        let b: &[_] = &[1, 3, 2, 0, 0, 0, 0, 4];
343        assert_eq!(buf, b);
344    }
345
346    #[test]
347    fn test_buf_writer_error() {
348        let mut buf = [0u8; 2];
349        let mut writer = Cursor::new(&mut buf[..]);
350        assert_eq!(writer.write(&[0]).unwrap(), 1);
351        assert_eq!(writer.write(&[0, 0]).unwrap(), 1);
352        assert_eq!(writer.write(&[0, 0]).unwrap(), 0);
353    }
354
355    #[test]
356    #[cfg(feature = "alloc")]
357    fn test_mem_reader() {
358        let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]);
359        let mut buf = [];
360        assert_eq!(reader.read(&mut buf).unwrap(), 0);
361        assert_eq!(reader.position(), 0);
362        let mut buf = [0];
363        assert_eq!(reader.read(&mut buf).unwrap(), 1);
364        assert_eq!(reader.position(), 1);
365        let b: &[_] = &[0];
366        assert_eq!(buf, b);
367        let mut buf = [0; 4];
368        assert_eq!(reader.read(&mut buf).unwrap(), 4);
369        assert_eq!(reader.position(), 5);
370        let b: &[_] = &[1, 2, 3, 4];
371        assert_eq!(buf, b);
372        assert_eq!(reader.read(&mut buf).unwrap(), 3);
373        let b: &[_] = &[5, 6, 7];
374        assert_eq!(&buf[..3], b);
375        assert_eq!(reader.read(&mut buf).unwrap(), 0);
376    }
377
378    #[test]
379    #[cfg(feature = "alloc")]
380    fn test_boxed_slice_reader() {
381        let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice());
382        let mut buf = [];
383        assert_eq!(reader.read(&mut buf).unwrap(), 0);
384        assert_eq!(reader.position(), 0);
385        let mut buf = [0];
386        assert_eq!(reader.read(&mut buf).unwrap(), 1);
387        assert_eq!(reader.position(), 1);
388        let b: &[_] = &[0];
389        assert_eq!(buf, b);
390        let mut buf = [0; 4];
391        assert_eq!(reader.read(&mut buf).unwrap(), 4);
392        assert_eq!(reader.position(), 5);
393        let b: &[_] = &[1, 2, 3, 4];
394        assert_eq!(buf, b);
395        assert_eq!(reader.read(&mut buf).unwrap(), 3);
396        let b: &[_] = &[5, 6, 7];
397        assert_eq!(&buf[..3], b);
398        assert_eq!(reader.read(&mut buf).unwrap(), 0);
399    }
400
401    #[test]
402    #[cfg(feature = "alloc")]
403    fn read_to_end() {
404        let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]);
405        let mut v = Vec::new();
406        reader.read_to_end(&mut v).unwrap();
407        assert_eq!(v, [0, 1, 2, 3, 4, 5, 6, 7]);
408    }
409
410    #[test]
411    #[cfg(feature = "alloc")]
412    fn test_slice_reader() {
413        let in_buf = [0, 1, 2, 3, 4, 5, 6, 7];
414        let reader = &mut &in_buf[..];
415        let mut buf = [];
416        assert_eq!(reader.read(&mut buf).unwrap(), 0);
417        let mut buf = [0];
418        assert_eq!(reader.read(&mut buf).unwrap(), 1);
419        assert_eq!(reader.len(), 7);
420        let b: &[_] = &[0];
421        assert_eq!(&buf[..], b);
422        let mut buf = [0; 4];
423        assert_eq!(reader.read(&mut buf).unwrap(), 4);
424        assert_eq!(reader.len(), 3);
425        let b: &[_] = &[1, 2, 3, 4];
426        assert_eq!(&buf[..], b);
427        assert_eq!(reader.read(&mut buf).unwrap(), 3);
428        let b: &[_] = &[5, 6, 7];
429        assert_eq!(&buf[..3], b);
430        assert_eq!(reader.read(&mut buf).unwrap(), 0);
431    }
432
433    #[test]
434    #[cfg(feature = "alloc")]
435    fn test_read_exact() {
436        let in_buf = [0, 1, 2, 3, 4, 5, 6, 7];
437        let reader = &mut &in_buf[..];
438        let mut buf = [];
439        reader
440            .read_exact(&mut buf)
441            .expect("read_exact must succeed");
442        let mut buf = [8];
443        reader
444            .read_exact(&mut buf)
445            .expect("read_exact must succeed");
446        assert_eq!(buf[0], 0);
447        assert_eq!(reader.len(), 7);
448        let mut buf = [0, 0, 0, 0, 0, 0, 0];
449        reader
450            .read_exact(&mut buf)
451            .expect("read_exact must succeed");
452        assert_eq!(buf, [1, 2, 3, 4, 5, 6, 7]);
453        assert_eq!(reader.len(), 0);
454        let mut buf = [0];
455        reader
456            .read_exact(&mut buf)
457            .expect_err("read_exact on empty buffer must fail");
458    }
459
460    #[test]
461    #[cfg(feature = "alloc")]
462    fn test_buf_reader() {
463        let in_buf = [0, 1, 2, 3, 4, 5, 6, 7];
464        let mut reader = Cursor::new(&in_buf[..]);
465        let mut buf = [];
466        assert_eq!(reader.read(&mut buf).unwrap(), 0);
467        assert_eq!(reader.position(), 0);
468        let mut buf = [0];
469        assert_eq!(reader.read(&mut buf).unwrap(), 1);
470        assert_eq!(reader.position(), 1);
471        let b: &[_] = &[0];
472        assert_eq!(buf, b);
473        let mut buf = [0; 4];
474        assert_eq!(reader.read(&mut buf).unwrap(), 4);
475        assert_eq!(reader.position(), 5);
476        let b: &[_] = &[1, 2, 3, 4];
477        assert_eq!(buf, b);
478        assert_eq!(reader.read(&mut buf).unwrap(), 3);
479        let b: &[_] = &[5, 6, 7];
480        assert_eq!(&buf[..3], b);
481        assert_eq!(reader.read(&mut buf).unwrap(), 0);
482    }
483
484    #[test]
485    fn seek_past_end() {
486        let buf = [0xff];
487        let mut r = Cursor::new(&buf[..]);
488        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
489        assert_eq!(r.read(&mut [0]).unwrap(), 0);
490
491        let mut r = Cursor::new(vec![10]);
492        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
493        assert_eq!(r.read(&mut [0]).unwrap(), 0);
494
495        let mut buf = [0];
496        let mut r = Cursor::new(&mut buf[..]);
497        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
498        assert_eq!(r.write(&[3]).unwrap(), 0);
499
500        #[cfg(feature = "alloc")]
501        {
502            let mut r = Cursor::new(vec![10].into_boxed_slice());
503            assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
504            assert_eq!(r.write(&[3]).unwrap(), 0);
505        }
506    }
507
508    #[test]
509    fn seek_past_i64() {
510        let buf = [0xff];
511        let mut r = Cursor::new(&buf[..]);
512        assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6);
513        assert_eq!(
514            r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(),
515            0x7ffffffffffffff6
516        );
517        assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006);
518        assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006);
519        r.seek(SeekFrom::Current(0x7ffffffffffffffd))
520            .expect_err("`seek` with big offset must fail");
521        assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6);
522
523        let mut r = Cursor::new(vec![10]);
524        assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6);
525        assert_eq!(
526            r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(),
527            0x7ffffffffffffff6
528        );
529        assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006);
530        assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006);
531        r.seek(SeekFrom::Current(0x7ffffffffffffffd))
532            .expect_err("`seek` with big offset must fail");
533        assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6);
534
535        let mut buf = [0];
536        let mut r = Cursor::new(&mut buf[..]);
537        assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6);
538        assert_eq!(
539            r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(),
540            0x7ffffffffffffff6
541        );
542        assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006);
543        assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006);
544        r.seek(SeekFrom::Current(0x7ffffffffffffffd))
545            .expect_err("`seek` with big offset must fail");
546        assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6);
547
548        #[cfg(feature = "alloc")]
549        {
550            let mut r = Cursor::new(vec![10].into_boxed_slice());
551            assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6);
552            assert_eq!(
553                r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(),
554                0x7ffffffffffffff6
555            );
556            assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006);
557            assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006);
558            r.seek(SeekFrom::Current(0x7ffffffffffffffd))
559                .expect_err("`seek` with big offset must fail");
560            assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6);
561        }
562    }
563
564    #[test]
565    fn seek_before_0() {
566        let buf = [0xff];
567        let mut r = Cursor::new(&buf[..]);
568        r.seek(SeekFrom::End(-2))
569            .expect_err("`seek` before 0 must fail");
570
571        let mut r = Cursor::new(vec![10]);
572        r.seek(SeekFrom::End(-2))
573            .expect_err("`seek` before 0 must fail");
574
575        let mut buf = [0];
576        let mut r = Cursor::new(&mut buf[..]);
577        r.seek(SeekFrom::End(-2))
578            .expect_err("`seek` before 0 must fail");
579
580        #[cfg(feature = "alloc")]
581        {
582            let mut r = Cursor::new(vec![10].into_boxed_slice());
583            r.seek(SeekFrom::End(-2))
584                .expect_err("`seek` before 0 must fail");
585        }
586    }
587
588    #[test]
589    #[cfg(feature = "alloc")]
590    fn test_seekable_mem_writer() {
591        let mut writer = Cursor::new(Vec::<u8>::new());
592        assert_eq!(writer.position(), 0);
593        assert_eq!(writer.write(&[0]).unwrap(), 1);
594        assert_eq!(writer.position(), 1);
595        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
596        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
597        assert_eq!(writer.position(), 8);
598        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
599        assert_eq!(&writer.get_ref()[..], b);
600
601        assert_eq!(writer.seek(SeekFrom::Start(0)).unwrap(), 0);
602        assert_eq!(writer.position(), 0);
603        assert_eq!(writer.write(&[3, 4]).unwrap(), 2);
604        let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7];
605        assert_eq!(&writer.get_ref()[..], b);
606
607        assert_eq!(writer.seek(SeekFrom::Current(1)).unwrap(), 3);
608        assert_eq!(writer.write(&[0, 1]).unwrap(), 2);
609        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7];
610        assert_eq!(&writer.get_ref()[..], b);
611
612        assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7);
613        assert_eq!(writer.write(&[1, 2]).unwrap(), 2);
614        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2];
615        assert_eq!(&writer.get_ref()[..], b);
616
617        assert_eq!(writer.seek(SeekFrom::End(1)).unwrap(), 10);
618        assert_eq!(writer.write(&[1]).unwrap(), 1);
619        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1];
620        assert_eq!(&writer.get_ref()[..], b);
621    }
622
623    #[test]
624    #[cfg(feature = "alloc")]
625    fn vec_seek_past_end() {
626        let mut r = Cursor::new(Vec::new());
627        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
628        assert_eq!(r.write(&[3]).unwrap(), 1);
629    }
630
631    #[test]
632    #[cfg(feature = "alloc")]
633    fn vec_seek_before_0() {
634        let mut r = Cursor::new(Vec::new());
635        r.seek(SeekFrom::End(-2))
636            .expect_err("`seek` before 0 must fail");
637    }
638
639    #[test]
640    #[cfg(target_pointer_width = "32")]
641    #[cfg(feature = "alloc")]
642    fn vec_seek_and_write_past_usize_max() {
643        let mut c = Cursor::new(Vec::new());
644        c.set_position(<usize>::max_value() as u64 + 1);
645        assert!(c.write_all(&[1, 2, 3]).is_err());
646    }
647}