1mod num;
2use std::io::Read;
3
4use log::warn;
5
6use crate::{ProtocolError, Result};
7
8pub trait Deserialize: Sized {
9 fn deserialize<R>(reader: &mut R, length: u32) -> Result<Self>
10 where
11 R: Read;
12
13 fn deserialize_in_place<R>(reader: &mut R, length: u32, place: &mut Self) -> Result<()>
14 where
15 R: Read,
16 {
17 *place = Deserialize::deserialize(reader, length)?;
18
19 Ok(())
20 }
21}
22
23impl Deserialize for String {
24 fn deserialize<R>(reader: &mut R, length: u32) -> Result<Self>
25 where
26 R: Read,
27 {
28 let mut bts = vec![0; length as usize];
29 reader.read_exact(&mut bts)?;
30
31 Ok(String::from_utf8(bts).unwrap())
32 }
33}
34
35impl<T> Deserialize for Option<T>
36where
37 T: Deserialize,
38{
39 fn deserialize<R>(reader: &mut R, length: u32) -> Result<Self>
40 where
41 R: Read,
42 {
43 Ok(Some(Deserialize::deserialize(reader, length)?))
44 }
45}
46
47impl<T> Deserialize for Vec<T>
48where
49 T: Deserialize,
50{
51 fn deserialize<R>(reader: &mut R, length: u32) -> Result<Self>
63 where
64 R: Read,
65 {
66 let vec: Vec<T> = vec![Deserialize::deserialize(reader, length)?];
67
68 Ok(vec)
69 }
70
71 fn deserialize_in_place<R>(reader: &mut R, length: u32, place: &mut Self) -> Result<()>
73 where
74 R: Read,
75 {
76 place.push(Deserialize::deserialize(reader, length)?);
77
78 Ok(())
79 }
80}
81
82#[derive(PartialEq, Debug)]
83pub enum Header {
84 StructEnd,
85 Field {
86 id: u16,
87 len: u32,
89 },
90}
91
92pub fn read_header<R>(reader: &mut R) -> Result<Header>
98where
99 R: Read,
100{
101 let mut buf = [0; 4];
102 reader.read_exact(&mut buf)?;
103
104 let mut len = u32::from_le_bytes(buf);
105 if len == 0xFFFFFFFF {
106 return Ok(Header::StructEnd);
107 } else if len > 2 {
108 len -= 2;
109 }
110
111 let mut buf = [0; 2];
112 reader.read_exact(&mut buf)?;
113 let id = u16::from_le_bytes(buf);
114
115 Ok(Header::Field { id, len })
116}
117
118pub fn read_unknown_field<R>(reader: &mut R, header: Header) -> Result<()>
119where
120 R: Read,
121{
122 if let Header::Field { id, len } = header {
123 warn!("reading unknown field {} with len={}", id, len);
124
125 if len == 0 {
126 while let Header::Field { id, len } = read_header(reader)? {
128 read_unknown_field(reader, Header::Field { id, len })?
129 }
130 } else {
131 let mut buf = vec![0; len as usize];
132 reader.read_exact(&mut buf)?;
133 }
134 } else {
135 return Err(ProtocolError::Deserialization(
136 "calling read_unknown_field is not supported nor useful".to_string(),
137 ));
138 }
139
140 Ok(())
141}
142
143#[cfg(test)]
144mod tests {
145 use crate::de::{read_header, Header};
146
147 #[test]
148 fn test_read_header() {
149 let bts: Vec<u8> = vec![10, 0, 0, 0, 5, 0];
150
151 let result = read_header(&mut &bts[..]).unwrap();
152
153 if let Header::Field { id, len } = result {
154 assert_eq!(id, 5);
155 assert_eq!(len, 8);
157 } else {
158 panic!("Header should be of type Attribute")
159 }
160 }
161}