1use std::{
9 fmt::Debug,
10 io::{Cursor, Read, Result, Write},
11};
12
13use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
14use chrono::Duration;
15
16use crate::{constants, status_codes::StatusCode};
17
18pub type EncodingResult<T> = std::result::Result<T, StatusCode>;
19
20#[derive(Clone, Copy, Debug)]
21pub struct DecodingOptions {
22 pub client_offset: Duration,
25 pub max_chunk_count: usize,
27 pub max_string_length: usize,
29 pub max_byte_string_length: usize,
31 pub max_array_length: usize,
33}
34
35impl Default for DecodingOptions {
36 fn default() -> Self {
37 DecodingOptions {
38 client_offset: Duration::zero(),
39 max_chunk_count: 0,
40 max_string_length: constants::MAX_STRING_LENGTH,
41 max_byte_string_length: constants::MAX_BYTE_STRING_LENGTH,
42 max_array_length: constants::MAX_ARRAY_LENGTH,
43 }
44 }
45}
46
47impl DecodingOptions {
48 pub fn minimal() -> Self {
51 DecodingOptions {
52 client_offset: Duration::zero(),
53 max_chunk_count: 0,
54 max_string_length: 0,
55 max_byte_string_length: 0,
56 max_array_length: 0,
57 }
58 }
59}
60
61pub trait BinaryEncoder<T> {
65 fn byte_len(&self) -> usize;
68 fn encode<S: Write>(&self, stream: &mut S) -> EncodingResult<usize>;
70 fn decode<S: Read>(stream: &mut S, decoding_options: &DecodingOptions) -> EncodingResult<T>;
74
75 fn encode_to_vec(&self) -> Vec<u8> {
78 let mut buffer = Cursor::new(Vec::with_capacity(self.byte_len()));
79 let _ = self.encode(&mut buffer);
80 buffer.into_inner()
81 }
82}
83
84pub fn process_encode_io_result(result: Result<usize>) -> EncodingResult<usize> {
86 result.map_err(|err| {
87 trace!("Encoding error - {:?}", err);
88 StatusCode::BadEncodingError
89 })
90}
91
92pub fn process_decode_io_result<T>(result: Result<T>) -> EncodingResult<T>
94where
95 T: Debug,
96{
97 result.map_err(|err| {
98 trace!("Decoding error - {:?}", err);
99 StatusCode::BadDecodingError
100 })
101}
102
103pub fn byte_len_array<T: BinaryEncoder<T>>(values: &Option<Vec<T>>) -> usize {
105 let mut size = 4;
106 if let Some(ref values) = values {
107 size += values.iter().map(|v| v.byte_len()).sum::<usize>();
108 }
109 size
110}
111
112pub fn write_array<S: Write, T: BinaryEncoder<T>>(
114 stream: &mut S,
115 values: &Option<Vec<T>>,
116) -> EncodingResult<usize> {
117 let mut size = 0;
118 if let Some(ref values) = values {
119 size += write_i32(stream, values.len() as i32)?;
120 for value in values.iter() {
121 size += value.encode(stream)?;
122 }
123 } else {
124 size += write_i32(stream, -1)?;
125 }
126 Ok(size)
127}
128
129pub fn read_array<S: Read, T: BinaryEncoder<T>>(
131 stream: &mut S,
132 decoding_options: &DecodingOptions,
133) -> EncodingResult<Option<Vec<T>>> {
134 let len = read_i32(stream)?;
135 if len == -1 {
136 Ok(None)
137 } else if len < -1 {
138 error!("Array length is negative value and invalid");
139 Err(StatusCode::BadDecodingError)
140 } else if len as usize > decoding_options.max_array_length {
141 error!(
142 "Array length {} exceeds decoding limit {}",
143 len, decoding_options.max_array_length
144 );
145 Err(StatusCode::BadDecodingError)
146 } else {
147 let mut values: Vec<T> = Vec::with_capacity(len as usize);
148 for _ in 0..len {
149 values.push(T::decode(stream, decoding_options)?);
150 }
151 Ok(Some(values))
152 }
153}
154
155pub fn write_bytes(stream: &mut dyn Write, value: u8, count: usize) -> EncodingResult<usize> {
157 for _ in 0..count {
158 let _ = stream
159 .write_u8(value)
160 .map_err(|_| StatusCode::BadEncodingError)?;
161 }
162 Ok(count)
163}
164
165pub fn write_u8<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
167where
168 T: Into<u8>,
169{
170 let buf: [u8; 1] = [value.into()];
171 process_encode_io_result(stream.write(&buf))
172}
173
174pub fn write_i16<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
176where
177 T: Into<i16>,
178{
179 let mut buf = [0u8; 2];
180 LittleEndian::write_i16(&mut buf, value.into());
181 process_encode_io_result(stream.write(&buf))
182}
183
184pub fn write_u16<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
186where
187 T: Into<u16>,
188{
189 let mut buf = [0u8; 2];
190 LittleEndian::write_u16(&mut buf, value.into());
191 process_encode_io_result(stream.write(&buf))
192}
193
194pub fn write_i32<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
196where
197 T: Into<i32>,
198{
199 let mut buf = [0u8; 4];
200 LittleEndian::write_i32(&mut buf, value.into());
201 process_encode_io_result(stream.write(&buf))
202}
203
204pub fn write_u32<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
206where
207 T: Into<u32>,
208{
209 let mut buf = [0u8; 4];
210 LittleEndian::write_u32(&mut buf, value.into());
211 process_encode_io_result(stream.write(&buf))
212}
213
214pub fn write_i64<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
216where
217 T: Into<i64>,
218{
219 let mut buf = [0u8; 8];
220 LittleEndian::write_i64(&mut buf, value.into());
221 process_encode_io_result(stream.write(&buf))
222}
223
224pub fn write_u64<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
226where
227 T: Into<u64>,
228{
229 let mut buf = [0u8; 8];
230 LittleEndian::write_u64(&mut buf, value.into());
231 process_encode_io_result(stream.write(&buf))
232}
233
234pub fn write_f32<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
236where
237 T: Into<f32>,
238{
239 let mut buf = [0u8; 4];
240 LittleEndian::write_f32(&mut buf, value.into());
241 process_encode_io_result(stream.write(&buf))
242}
243
244pub fn write_f64<T>(stream: &mut dyn Write, value: T) -> EncodingResult<usize>
246where
247 T: Into<f64>,
248{
249 let mut buf = [0u8; 8];
250 LittleEndian::write_f64(&mut buf, value.into());
251 process_encode_io_result(stream.write(&buf))
252}
253
254pub fn read_bytes(stream: &mut dyn Read, buf: &mut [u8]) -> EncodingResult<usize> {
256 let result = stream.read_exact(buf);
257 process_decode_io_result(result)?;
258 Ok(buf.len())
259}
260
261pub fn read_u8(stream: &mut dyn Read) -> EncodingResult<u8> {
263 let mut buf = [0u8];
264 let result = stream.read_exact(&mut buf);
265 process_decode_io_result(result)?;
266 Ok(buf[0])
267}
268
269pub fn read_i16(stream: &mut dyn Read) -> EncodingResult<i16> {
271 let mut buf = [0u8; 2];
272 let result = stream.read_exact(&mut buf);
273 process_decode_io_result(result)?;
274 Ok(LittleEndian::read_i16(&buf))
275}
276
277pub fn read_u16(stream: &mut dyn Read) -> EncodingResult<u16> {
279 let mut buf = [0u8; 2];
280 let result = stream.read_exact(&mut buf);
281 process_decode_io_result(result)?;
282 Ok(LittleEndian::read_u16(&buf))
283}
284
285pub fn read_i32(stream: &mut dyn Read) -> EncodingResult<i32> {
287 let mut buf = [0u8; 4];
288 let result = stream.read_exact(&mut buf);
289 process_decode_io_result(result)?;
290 Ok(LittleEndian::read_i32(&buf))
291}
292
293pub fn read_u32(stream: &mut dyn Read) -> EncodingResult<u32> {
295 let mut buf = [0u8; 4];
296 let result = stream.read_exact(&mut buf);
297 process_decode_io_result(result)?;
298 Ok(LittleEndian::read_u32(&buf))
299}
300
301pub fn read_i64(stream: &mut dyn Read) -> EncodingResult<i64> {
303 let mut buf = [0u8; 8];
304 let result = stream.read_exact(&mut buf);
305 process_decode_io_result(result)?;
306 Ok(LittleEndian::read_i64(&buf))
307}
308
309pub fn read_u64(stream: &mut dyn Read) -> EncodingResult<u64> {
311 let mut buf = [0u8; 8];
312 let result = stream.read_exact(&mut buf);
313 process_decode_io_result(result)?;
314 Ok(LittleEndian::read_u64(&buf))
315}
316
317pub fn read_f32(stream: &mut dyn Read) -> EncodingResult<f32> {
319 let mut buf = [0u8; 4];
320 let result = stream.read_exact(&mut buf);
321 process_decode_io_result(result)?;
322 Ok(LittleEndian::read_f32(&buf))
323}
324
325pub fn read_f64(stream: &mut dyn Read) -> EncodingResult<f64> {
327 let mut buf = [0u8; 8];
328 let result = stream.read_exact(&mut buf);
329 process_decode_io_result(result)?;
330 Ok(LittleEndian::read_f64(&buf))
331}