1use std::cmp::min;
15use std::io::SeekFrom;
16use std::sync::{Arc, RwLock};
17
18use super::data_stream::{DataStream, DataStreamReference};
19use super::errors::ErrorTrace;
20
21pub struct FakeDataStream {
23 data: Vec<u8>,
25
26 data_size: usize,
28
29 current_offset: u64,
31
32 pub size: u64,
34}
35
36impl FakeDataStream {
37 pub fn new(data: &[u8], size: u64) -> Self {
39 Self {
40 data: data.to_vec(),
41 data_size: data.len(),
42 current_offset: 0,
43 size: size,
44 }
45 }
46}
47
48impl DataStream for FakeDataStream {
49 fn get_size(&mut self) -> Result<u64, ErrorTrace> {
51 Ok(self.size)
52 }
53
54 fn read(&mut self, buf: &mut [u8]) -> Result<usize, ErrorTrace> {
56 if self.current_offset >= self.size {
57 return Ok(0);
58 }
59 let remaining_size: u64 = self.size - self.current_offset;
60 let mut read_size: usize = buf.len();
61
62 if (read_size as u64) > remaining_size {
63 read_size = remaining_size as usize;
64 }
65 let mut buf_offset: usize = 0;
66
67 while buf_offset < read_size {
68 let read_remainder_size: usize = read_size - buf_offset;
69
70 let read_count: usize = if self.current_offset < self.data_size as u64 {
71 let data_offset: usize = self.current_offset as usize;
72
73 let data_remainder_size: usize =
74 min(read_remainder_size, self.data_size - data_offset);
75
76 let data_end_offset: usize = data_offset + data_remainder_size;
77 let buf_end_offset: usize = buf_offset + data_remainder_size;
78
79 buf[buf_offset..buf_end_offset]
80 .copy_from_slice(&self.data[data_offset..data_end_offset]);
81
82 data_remainder_size
83 } else {
84 let buf_end_offset: usize = buf_offset + read_remainder_size;
85
86 buf[buf_offset..buf_end_offset].fill(0);
87
88 read_remainder_size
89 };
90 buf_offset += read_count;
91 }
92 self.current_offset += buf_offset as u64;
93
94 Ok(buf_offset)
95 }
96
97 fn seek(&mut self, pos: SeekFrom) -> Result<u64, ErrorTrace> {
99 self.current_offset = match pos {
100 SeekFrom::Current(relative_offset) => {
101 let mut current_offset: i64 = self.current_offset as i64;
102 current_offset += relative_offset;
103 current_offset as u64
104 }
105 SeekFrom::End(relative_offset) => {
106 let mut end_offset: i64 = self.size as i64;
107 end_offset += relative_offset;
108 end_offset as u64
109 }
110 SeekFrom::Start(offset) => offset,
111 };
112 Ok(self.current_offset)
113 }
114}
115
116pub fn open_fake_data_stream(data: Vec<u8>) -> DataStreamReference {
118 let data_size: u64 = data.len() as u64;
119 let fake_data_stream: FakeDataStream = FakeDataStream::new(&data, data_size);
120 Arc::new(RwLock::new(fake_data_stream))
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 fn get_test_data() -> Vec<u8> {
128 return vec![
129 0x41, 0x20, 0x63, 0x65, 0x72, 0x61, 0x6d, 0x69, 0x63, 0x20, 0x69, 0x73, 0x20, 0x61,
130 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x72, 0x69,
131 0x6f, 0x75, 0x73, 0x20, 0x68, 0x61, 0x72, 0x64, 0x2c, 0x20, 0x62, 0x72, 0x69, 0x74,
132 0x74, 0x6c, 0x65, 0x2c, 0x20, 0x68, 0x65, 0x61, 0x74, 0x2d, 0x72, 0x65, 0x73, 0x69,
133 0x73, 0x74, 0x61, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x72,
134 0x72, 0x6f, 0x73, 0x69, 0x6f, 0x6e, 0x2d, 0x72, 0x65, 0x73, 0x69, 0x73, 0x74, 0x61,
135 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x20, 0x6d,
136 0x61, 0x64, 0x65, 0x20, 0x62, 0x79, 0x20, 0x73, 0x68, 0x61, 0x70, 0x69, 0x6e, 0x67,
137 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x66, 0x69, 0x72, 0x69,
138 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69,
139 0x63, 0x2c, 0x20, 0x6e, 0x6f, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x6c, 0x69, 0x63,
140 0x20, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x20, 0x73, 0x75, 0x63,
141 0x68, 0x20, 0x61, 0x73, 0x20, 0x63, 0x6c, 0x61, 0x79, 0x2c, 0x20, 0x61, 0x74, 0x20,
142 0x61, 0x20, 0x68, 0x69, 0x67, 0x68, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61,
143 0x74, 0x75, 0x72, 0x65, 0x2e, 0x0a,
144 ];
145 }
146
147 fn get_test_data_stream() -> FakeDataStream {
148 let test_data: Vec<u8> = get_test_data();
149 FakeDataStream::new(&test_data, 32768)
150 }
151
152 #[test]
153 fn test_seek_from_start() -> Result<(), ErrorTrace> {
154 let mut data_stream: FakeDataStream = get_test_data_stream();
155
156 let offset: u64 = data_stream.seek(SeekFrom::Start(1024))?;
157 assert_eq!(offset, 1024);
158
159 Ok(())
160 }
161
162 #[test]
163 fn test_seek_from_end() -> Result<(), ErrorTrace> {
164 let mut data_stream: FakeDataStream = get_test_data_stream();
165
166 let offset: u64 = data_stream.seek(SeekFrom::End(-512))?;
167 assert_eq!(offset, data_stream.size - 512);
168
169 Ok(())
170 }
171
172 #[test]
173 fn test_seek_from_current() -> Result<(), ErrorTrace> {
174 let mut data_stream: FakeDataStream = get_test_data_stream();
175
176 let offset = data_stream.seek(SeekFrom::Start(1024))?;
177 assert_eq!(offset, 1024);
178
179 let offset: u64 = data_stream.seek(SeekFrom::Current(-512))?;
180 assert_eq!(offset, 512);
181
182 Ok(())
183 }
184
185 #[test]
186 fn test_seek_beyond_size() -> Result<(), ErrorTrace> {
187 let mut data_stream: FakeDataStream = get_test_data_stream();
188
189 let offset: u64 = data_stream.seek(SeekFrom::End(512))?;
190 assert_eq!(offset, data_stream.size + 512);
191
192 Ok(())
193 }
194
195 #[test]
196 fn test_seek_and_read() -> Result<(), ErrorTrace> {
197 let mut data_stream: FakeDataStream = get_test_data_stream();
198 data_stream.seek(SeekFrom::Start(128))?;
199
200 let mut data: Vec<u8> = vec![0; 64];
201 let read_size: usize = data_stream.read(&mut data)?;
202 assert_eq!(read_size, 64);
203
204 let expected_data: String = [
205 "A ceramic is any of the various hard, brittle, heat-resistant, and ",
206 "corrosion-resistant materials made by shaping and then firing an inorganic, ",
207 "nonmetallic material, such as clay, at a high temperature.\n",
208 ]
209 .join("");
210
211 assert_eq!(data, expected_data.as_bytes()[128..192]);
212
213 Ok(())
214 }
215
216 #[test]
217 fn test_seek_and_read_beyond_size() -> Result<(), ErrorTrace> {
218 let mut data_stream: FakeDataStream = get_test_data_stream();
219 data_stream.seek(SeekFrom::End(512))?;
220
221 let mut data: Vec<u8> = vec![0; 512];
222 let read_size: usize = data_stream.read(&mut data)?;
223 assert_eq!(read_size, 0);
224
225 Ok(())
226 }
227
228 }