1use std::io;
2use std::fmt;
3use std::cmp;
4
5use super::*;
6
7#[derive(Debug)]
14pub struct Dup<T: BufferedReader<C>, C: fmt::Debug + Sync + Send> {
15 cursor: usize,
17
18 cookie: C,
20
21 reader: T,
22}
23
24assert_send_and_sync!(Dup<T, C>
25 where T: BufferedReader<C>,
26 C: fmt::Debug);
27
28impl<T: BufferedReader<C>, C: fmt::Debug + Sync + Send> fmt::Display for Dup<T, C> {
29 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
30 f.debug_struct("Dup")
31 .field("cursor", &self.cursor)
32 .finish()
33 }
34}
35
36impl<T: BufferedReader<()>> Dup<T, ()> {
37 pub fn new(reader: T) -> Self {
41 Self::with_cookie(reader, ())
42 }
43}
44
45impl<T: BufferedReader<C>, C: fmt::Debug + Sync + Send> Dup<T, C> {
46 pub fn with_cookie(reader: T, cookie: C) -> Self {
51 Dup {
52 reader,
53 cursor: 0,
54 cookie,
55 }
56 }
57
58 pub fn total_out(&self) -> usize {
60 self.cursor
61 }
62
63 pub fn rewind(&mut self) {
65 self.cursor = 0;
66 }
67}
68
69impl<T: BufferedReader<C>, C: fmt::Debug + Sync + Send> io::Read for Dup<T, C> {
70 fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
71 let data = self.reader.data(self.cursor + buf.len())?;
72 assert!(data.len() >= self.cursor);
73 let data = &data[self.cursor..];
74
75 let amount = cmp::min(buf.len(), data.len());
76 buf[..amount].copy_from_slice(&data[..amount]);
77
78 self.cursor += amount;
79
80 Ok(amount)
81 }
82}
83
84impl<T: BufferedReader<C>, C: fmt::Debug + Send + Sync> BufferedReader<C> for Dup<T, C> {
85 fn buffer(&self) -> &[u8] {
86 let data = self.reader.buffer();
87 assert!(data.len() >= self.cursor);
88 &data[self.cursor..]
89 }
90
91 fn data(&mut self, amount: usize) -> Result<&[u8], io::Error> {
92 let data = self.reader.data(self.cursor + amount)?;
93 assert!(data.len() >= self.cursor);
94 Ok(&data[self.cursor..])
95 }
96
97 fn consume(&mut self, amount: usize) -> &[u8] {
98 let data = self.reader.buffer();
99 assert!(data.len() >= self.cursor + amount);
100 let data = &data[self.cursor..];
101 self.cursor += amount;
102 data
103 }
104
105 fn data_consume(&mut self, amount: usize) -> Result<&[u8], io::Error> {
106 let data = self.reader.data(self.cursor + amount)?;
107 assert!(data.len() >= self.cursor);
108 let data = &data[self.cursor..];
109 self.cursor += cmp::min(data.len(), amount);
110 Ok(data)
111 }
112
113 fn data_consume_hard(&mut self, amount: usize) -> Result<&[u8], io::Error> {
114 let data = self.reader.data_hard(self.cursor + amount)?;
115 assert!(data.len() >= self.cursor + amount);
116 let data = &data[self.cursor..];
117 self.cursor += amount;
118 Ok(data)
119 }
120
121 fn get_mut(&mut self) -> Option<&mut dyn BufferedReader<C>> {
122 Some(&mut self.reader)
123 }
124
125 fn get_ref(&self) -> Option<&dyn BufferedReader<C>> {
126 Some(&self.reader)
127 }
128
129 fn into_inner<'b>(self: Box<Self>) -> Option<Box<dyn BufferedReader<C> + 'b>>
130 where Self: 'b {
131 Some(self.reader.into_boxed())
132 }
133
134 fn cookie_set(&mut self, cookie: C) -> C {
135 use std::mem;
136
137 mem::replace(&mut self.cookie, cookie)
138 }
139
140 fn cookie_ref(&self) -> &C {
141 &self.cookie
142 }
143
144 fn cookie_mut(&mut self) -> &mut C {
145 &mut self.cookie
146 }
147}
148
149#[cfg(test)]
150mod test {
151 use super::*;
152
153 #[test]
154 fn buffered_reader_memory_test () {
155 let data = crate::BUFFERED_READER_TEST_DATA;
156 let reader = Memory::new(data);
157 let mut reader = Dup::new(reader);
158
159 buffered_reader_test_data_check(&mut reader);
160
161 let consumed = reader.total_out();
162 assert_eq!(consumed, data.len());
163
164 let mut reader = Box::new(reader).into_inner().unwrap();
167
168 assert_eq!(consumed, reader.data(consumed + 1).unwrap().len());
171
172 buffered_reader_test_data_check(&mut reader);
173 }
174
175 #[test]
177 fn buffer_test() {
178 let size = default_buf_size();
181 let mut input = Vec::with_capacity(size);
182 let mut v = 0u8;
183 for _ in 0..size {
184 input.push(v);
185 if v == std::u8::MAX {
186 v = 0;
187 } else {
188 v += 1;
189 }
190 }
191
192 let reader = Memory::new(&input[..]);
193 let mut reader = Dup::new(reader);
194
195 for i in 0..input.len() {
196 let data = reader.data(default_buf_size() + 1).unwrap().to_vec();
197 assert!(!data.is_empty());
198 assert_eq!(data, reader.buffer());
199 assert_eq!(data, &input[i..i+data.len()]);
202
203 reader.consume(1);
205 }
206 }
207}