1use crate::io::read::Read;
4use crate::io::{Error, Seek, Write};
5use crate::io::{Result, SeekFrom};
6
7pub struct Cursor<T> {
8 inner: T,
9 pos: u64,
10}
11
12impl<T> Cursor<T> {
13 pub const fn new(inner: T) -> Self {
14 Self { inner, pos: 0 }
15 }
16
17 pub fn into_inner(self) -> T {
18 self.inner
19 }
20
21 pub const fn get_ref(&self) -> &T {
22 &self.inner
23 }
24
25 pub fn get_mut(&mut self) -> &mut T {
26 &mut self.inner
27 }
28
29 pub fn position(&self) -> u64 {
30 self.pos
31 }
32
33 pub fn set_position(&mut self, pos: u64) {
34 self.pos = pos;
35 }
36}
37
38impl<T> Cursor<T>
39where
40 T: AsRef<[u8]>,
41{
42 pub fn remaining_slice(&self) -> &[u8] {
43 let len = self.pos.min(self.inner.as_ref().len() as u64);
44 &self.inner.as_ref()[(len as usize)..]
45 }
46
47 pub fn is_empty(&self) -> bool {
48 self.pos >= self.inner.as_ref().len() as u64
49 }
50}
51
52impl<T> Clone for Cursor<T>
53where
54 T: Clone,
55{
56 fn clone(&self) -> Self {
57 Self {
58 inner: self.inner.clone(),
59 pos: self.pos,
60 }
61 }
62
63 fn clone_from(&mut self, source: &Self) {
64 self.inner.clone_from(&source.inner);
65 self.pos = source.pos;
66 }
67}
68
69impl<T> Seek for Cursor<T>
70where
71 T: AsRef<[u8]>,
72{
73 fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
74 let new_pos = match pos {
75 SeekFrom::Start(n) => n,
76 SeekFrom::End(n) => {
77 let p = (self.inner.as_ref().len() as i64) - n;
78 if p < 0 {
79 return Err(Error::InvalidOffset);
80 }
81 p as u64
82 }
83 SeekFrom::Current(n) => self.pos as u64 + n as u64,
84 };
85 if new_pos >= self.inner.as_ref().len() as u64 {
86 Err(Error::InvalidOffset)
87 } else {
88 self.pos = new_pos;
89 Ok(self.pos)
90 }
91 }
92}
93
94impl<T> Read<u8> for Cursor<T>
95where
96 T: AsRef<[u8]>,
97{
98 fn read(&mut self, buf: &mut dyn AsMut<[u8]>) -> Result<usize> {
99 let data = self.inner.as_ref();
100 let buffer = buf.as_mut();
101 let len = (data.len() as u64 - self.pos).min(buffer.len() as u64) as usize;
102 let target_buffer = &mut buffer[..len];
103 target_buffer.copy_from_slice(&data[(self.pos as usize)..(self.pos as usize + len)]);
104 self.pos += len as u64;
105 Ok(len)
106 }
107}
108
109impl<T> Write<u8> for Cursor<T>
110where
111 T: AsMut<[u8]>,
112{
113 fn write(&mut self, buf: &dyn AsRef<[u8]>) -> Result<usize> {
114 let data = self.inner.as_mut();
115 let buffer = buf.as_ref();
116 let len = (data.len() as u64 - self.pos).min(buffer.len() as u64) as usize;
117 let target_buffer = &mut data[(self.pos as usize)..(self.pos as usize + len)];
118 target_buffer.copy_from_slice(&buffer[..len]);
119 self.pos += len as u64;
120 Ok(len)
121 }
122
123 fn flush(&mut self) -> Result<()> {
124 Ok(())
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131 use alloc::vec;
132
133 #[test]
134 fn test_read() {
135 let data = &[0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9];
136 let mut buf = [0u8; 4];
137 let mut c = Cursor::new(data);
138
139 let read1 = c.read(&mut buf);
140 assert_eq!(Ok(4), read1);
141 assert_eq!(&[0, 1, 2, 3], &buf);
142
143 let read2 = c.read(&mut buf);
144 assert_eq!(Ok(4), read2);
145 assert_eq!(&[4, 5, 6, 7], &buf);
146
147 let read3 = c.read(&mut buf);
148 assert_eq!(Ok(2), read3);
149 assert_eq!(&[8, 9, 6, 7], &buf);
150 }
151
152 #[test]
153 fn test_read_vec() {
154 let data = vec![0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9];
155 let mut buf = [0u8; 4];
156 let mut c = Cursor::new(data);
157
158 let read1 = c.read(&mut buf);
159 assert_eq!(Ok(4), read1);
160 assert_eq!(&[0, 1, 2, 3], &buf);
161
162 let read2 = c.read(&mut buf);
163 assert_eq!(Ok(4), read2);
164 assert_eq!(&[4, 5, 6, 7], &buf);
165
166 let read3 = c.read(&mut buf);
167 assert_eq!(Ok(2), read3);
168 assert_eq!(&[8, 9, 6, 7], &buf);
169 }
170}