hawktracer_parser/
data_provider.rs1pub struct DataProvider {
2 reader: Box<dyn std::io::Read>,
3 buffer: [u8; 512],
4 data_pointer: usize,
5 data_available: usize,
6}
7
8#[derive(Debug)]
9pub enum DataError {
10 EndOfStream,
11 Utf8Error,
12 IOError(std::io::Error),
13}
14
15impl PartialEq for DataError {
16 fn eq(&self, other: &DataError) -> bool {
17 match (self, other) {
18 (DataError::IOError(_e1), DataError::IOError(_e2)) => true, (DataError::EndOfStream, DataError::EndOfStream) => true,
20 (DataError::Utf8Error, DataError::Utf8Error) => true,
21 _ => false,
22 }
23 }
24}
25
26impl DataProvider {
27 pub fn new(reader: Box<dyn std::io::Read>) -> DataProvider {
28 DataProvider {
29 reader,
30 buffer: [0; 512],
31 data_pointer: 0,
32 data_available: 0,
33 }
34 }
35
36 fn get_next_byte(&mut self) -> Result<u8, DataError> {
37 if self.data_pointer == self.data_available {
38 match self.load_data() {
39 Err(err) => return Err(DataError::IOError(err)),
40 Ok(_) => {
41 if self.data_available == 0 {
42 return Err(DataError::EndOfStream);
43 }
44 }
45 }
46 }
47
48 let data = Ok(self.buffer[self.data_pointer]);
49 self.data_pointer += 1;
50 data
51 }
52
53 pub fn read_bytes(&mut self, buffer: &mut [u8]) -> Result<(), DataError> {
54 for b in buffer {
56 *b = match self.get_next_byte() {
57 Ok(value) => value,
58 Err(err) => return Err(err),
59 }
60 }
61
62 Ok(())
63 }
64
65 pub fn read_string(&mut self) -> Result<String, DataError> {
66 let mut data = std::vec::Vec::new();
67 loop {
68 match self.get_next_byte() {
69 Ok(0) => break,
70 Ok(b) => data.push(b),
71 Err(err) => return Err(err),
72 };
73 }
74
75 match String::from_utf8(data) {
76 Ok(res) => Ok(res),
77 Err(_err) => Err(DataError::Utf8Error),
78 }
79 }
80
81 fn load_data(&mut self) -> std::io::Result<usize> {
82 self.data_pointer = 0;
83 match self.reader.read(&mut self.buffer) {
84 Ok(size) => {
85 self.data_available = size;
86 Ok(size)
87 }
88 Err(err) => Err(err),
89 }
90 }
91}
92
93#[cfg(test)]
94pub mod tests {
95 use super::*;
96 use hawktracer_parser_test_utilities::FakeDataReader;
97
98 fn buffers_equal(b1: &[u8], b2: &[u8]) -> usize {
99 return b1.iter().zip(b2).map(|(a, b)| assert_eq!(a, b)).count();
100 }
101
102 #[test]
103 fn should_not_set_eos_if_still_have_data() {
104 let mut provider = DataProvider::new(Box::new(FakeDataReader::new(vec![1, 2], false)));
105 let mut buf = [0u8; 2];
106 assert!(provider.read_bytes(&mut buf).is_ok());
107
108 buffers_equal(&buf, &[1, 2]);
109 }
110
111 #[test]
112 fn should_set_eos_if_try_to_read_too_much_data() {
113 let mut provider =
114 DataProvider::new(Box::new(FakeDataReader::new(vec![1, 2, 3, 4], false)));
115 let mut buf = [0u8; 5];
116 assert!(provider.read_bytes(&mut buf).is_err());
117
118 buffers_equal(&buf[0..4], &[1, 2, 3, 4]);
119 }
120
121 #[test]
122 fn should_fail_if_data_reader_fails() {
123 let mut provider = DataProvider::new(Box::new(FakeDataReader::new(vec![1, 2], true)));
124 let mut buf = [0u8; 2];
125
126 assert!(provider.read_bytes(&mut buf).is_err());
127 }
128
129 #[test]
130 fn read_string_should_not_fail_if_valid_string() {
131 let mut provider = DataProvider::new(Box::new(FakeDataReader::new(vec![65, 66, 0], false)));
132
133 let message = provider.read_string();
134 assert!(message.is_ok());
135 assert_eq!("AB", message.unwrap());
136 }
137
138 #[test]
139 fn read_string_should_fail_if_no_zero_at_the_end() {
140 let mut provider =
141 DataProvider::new(Box::new(FakeDataReader::new(vec![65, 66, 67, 68], false)));
142
143 let message = provider.read_string();
144 assert!(message.is_err());
145 }
146
147 #[test]
148 fn read_string_should_fail_if_non_utf8_string() {
149 let mut provider =
150 DataProvider::new(Box::new(FakeDataReader::new(vec![65, 220, 0, 5], false)));
151
152 let message = provider.read_string();
153 assert!(message.is_err());
154 }
155}