1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
use super::*; #[derive(Clone, Debug, Default)] pub struct Cursor<T: AsRef<[u8]>> { inner: T, pos: u64 } impl<T: AsRef<[u8]>> Cursor<T> { pub fn get_mut(&mut self) -> &mut T { &mut self.inner } pub fn get_ref(&self) -> &T { &self.inner } pub fn into_inner(self) -> T { self.inner } pub fn new(inner: T) -> Self { Self { inner, pos: 0 } } pub fn position(&self) -> u64 { self.pos } pub fn set_position(&mut self, pos: u64) { self.pos = pos; } } impl<T: AsRef<[u8]>> Read for Cursor<T> { fn read(&mut self, buf: &mut [u8]) -> Result<usize> { let slice = self.inner.as_ref(); if self.pos > slice.len() as u64 { return Ok(0) } let amt = u64::min(slice.len() as u64 - self.pos, buf.len() as u64); buf[..amt as usize].copy_from_slice(&slice[self.pos as usize..(self.pos + amt) as usize]); self.pos += amt; Ok(amt as usize) } } impl<T: AsRef<[u8]>> Seek for Cursor<T> { fn seek(&mut self, pos: SeekFrom) -> Result<u64> { match pos { SeekFrom::Current(x) => { if (self.pos as i64) + x < 0 { Err(Error::new(ErrorKind::InvalidInput, "invalid seek to a negative or overflowing position")) } else { self.pos = ((self.pos as i64) + x) as u64; Ok(self.pos) } } SeekFrom::Start(x) => { self.pos = x; Ok(self.pos) } SeekFrom::End(x) => { let end = self.inner.as_ref().len() as i64; if (self.pos as i64) + end + x < 0 { Err(Error::new(ErrorKind::InvalidInput, "invalid seek to a negative or overflowing position")) } else { Ok(self.pos) } } } } } #[cfg(test)] #[cfg(std)] mod test { use super::*; #[test] fn cursor_test() { let data = &[1, 2, 3, 4, 5]; let mut test = Cursor::new(data); let mut test2 = std::io::Cursor::new(data); assert_eq!(test.get_ref(), test2.get_ref()); assert_eq!(test.get_mut(), test2.get_mut()); assert_eq!(test.position(), test2.position()); assert_eq!(test.position(), test2.position()); test.set_position(5); test2.set_position(5); assert_eq!(test.position(), test2.position()); test.set_position(5000); test2.set_position(5000); assert_eq!(test.position(), test2.position()); assert_eq!( test.seek(SeekFrom::Start(0)).unwrap(), test2.seek(std::io::SeekFrom::Start(0)).unwrap(), ); let mut buf = [0u8; 4]; let mut buf2 = [0u8; 4]; assert_eq!( test.read(&mut buf).unwrap(), test2.read(&mut buf2).unwrap() ); assert_eq!(buf, buf2); assert_eq!( test.read(&mut buf).unwrap(), test2.read(&mut buf2).unwrap() ); assert_eq!(buf, buf2); } }