onenote_parser/fsshttpb/data/
stream_object.rs1use crate::errors::{ErrorKind, Result};
2use crate::fsshttpb::data::compact_u64::CompactU64;
3use crate::fsshttpb::data::object_types::ObjectType;
4use crate::Reader;
5use num_traits::{FromPrimitive, ToPrimitive};
6
7#[derive(Debug)]
13pub struct ObjectHeader {
14 pub compound: bool,
15 pub object_type: ObjectType,
16 pub length: u64,
17}
18
19impl ObjectHeader {
20 pub(crate) fn try_parse(reader: Reader, object_type: ObjectType) -> Result<()> {
21 Self::try_parse_start(reader, object_type, Self::parse)
22 }
23
24 pub(crate) fn parse(reader: Reader) -> Result<ObjectHeader> {
26 let header_type = reader.bytes().first().ok_or(ErrorKind::UnexpectedEof)?;
27
28 match header_type & 0b11 {
29 0x0 => Self::parse_16(reader),
30 0x2 => Self::parse_32(reader),
31 _ => Err(ErrorKind::MalformedFssHttpBData(
32 format!("unexpected object header type: {:x}", header_type).into(),
33 )
34 .into()),
35 }
36 }
37
38 pub(crate) fn try_parse_16(reader: Reader, object_type: ObjectType) -> Result<()> {
39 Self::try_parse_start(reader, object_type, Self::parse_16)
40 }
41
42 pub(crate) fn parse_16(reader: Reader) -> Result<ObjectHeader> {
48 let data = reader.get_u16()?;
49
50 let header_type = data & 0b11;
51 if header_type != 0x0 {
52 return Err(ErrorKind::MalformedFssHttpBData(
53 format!(
54 "unexpected object header type for 16 bit header: 0x{:x}",
55 header_type
56 )
57 .into(),
58 )
59 .into());
60 }
61
62 let compound = data & 0x4 == 0x4;
63 let object_type_value = (data >> 3) & 0x3f;
64 let object_type = if let Some(object_type) = ObjectType::from_u16(object_type_value) {
65 object_type
66 } else {
67 return Err(ErrorKind::MalformedFssHttpBData(
68 format!("invalid object type: 0x{:x}", object_type_value).into(),
69 )
70 .into());
71 };
72 let length = (data >> 9) as u64;
73
74 Ok(ObjectHeader {
75 compound,
76 object_type,
77 length,
78 })
79 }
80
81 pub(crate) fn try_parse_32(reader: Reader, object_type: ObjectType) -> Result<()> {
82 Self::try_parse_start(reader, object_type, Self::parse_32)
83 }
84
85 fn parse_32(reader: Reader) -> Result<ObjectHeader> {
91 let data = reader.get_u32()?;
92
93 let header_type = data & 0b11;
94 if header_type != 0x2 {
95 return Err(ErrorKind::MalformedFssHttpBData(
96 format!(
97 "unexpected object header type for 32 bit header: 0x{:x}",
98 header_type
99 )
100 .into(),
101 )
102 .into());
103 }
104
105 let compound = data & 0x4 == 0x4;
106 let object_type_value = (data >> 3) & 0x3fff;
107 let object_type = if let Some(object_type) = ObjectType::from_u32(object_type_value) {
108 object_type
109 } else {
110 return Err(ErrorKind::MalformedFssHttpBData(
111 format!("invalid object type: 0x{:x}", object_type_value).into(),
112 )
113 .into());
114 };
115 let mut length = (data >> 17) as u64;
116
117 if length == 0x7fff {
118 length = CompactU64::parse(reader)?.value();
119 }
120
121 Ok(ObjectHeader {
122 compound,
123 object_type,
124 length,
125 })
126 }
127
128 pub(crate) fn try_parse_end_16(reader: Reader, object_type: ObjectType) -> Result<()> {
129 Self::try_parse_end(reader, object_type, Self::parse_end_16)
130 }
131
132 fn parse_end_16(reader: Reader) -> Result<ObjectType> {
138 let data = reader.get_u16()?;
139 let header_type = data & 0b11;
140 if header_type != 0x3 {
141 return Err(ErrorKind::MalformedFssHttpBData(
142 format!(
143 "unexpected object header type for 16 bit end header: {:x}",
144 header_type
145 )
146 .into(),
147 )
148 .into());
149 }
150
151 let object_type_value = data >> 2;
152
153 if let Some(object_type) = ObjectType::from_u16(object_type_value) {
154 Ok(object_type)
155 } else {
156 Err(ErrorKind::MalformedFssHttpBData(
157 format!("invalid object type: 0x{:x}", object_type_value).into(),
158 )
159 .into())
160 }
161 }
162
163 pub(crate) fn try_parse_end_8(reader: Reader, object_type: ObjectType) -> Result<()> {
164 Self::try_parse_end(reader, object_type, Self::parse_end_8)
165 }
166
167 fn parse_end_8(reader: Reader) -> Result<ObjectType> {
173 let data = reader.get_u8()?;
174 let header_type = data & 0b11;
175 if header_type != 0x1 {
176 return Err(ErrorKind::MalformedFssHttpBData(
177 format!(
178 "unexpected object header type for 8 bit end header: {:x}",
179 header_type
180 )
181 .into(),
182 )
183 .into());
184 }
185
186 let object_type_value = data >> 2;
187
188 if let Some(object_type) = ObjectType::from_u8(object_type_value) {
189 Ok(object_type)
190 } else {
191 Err(ErrorKind::MalformedFssHttpBData(
192 format!("invalid object type: 0x{:x}", object_type_value).into(),
193 )
194 .into())
195 }
196 }
197
198 pub(crate) fn has_end_8(reader: Reader, object_type: ObjectType) -> Result<bool> {
199 let data = reader.bytes().first().ok_or(ErrorKind::UnexpectedEof)?;
200
201 Ok(data & 0b11 == 0x1 && data >> 2 == object_type.to_u8().unwrap())
202 }
203
204 fn try_parse_start(
205 reader: Reader,
206 object_type: ObjectType,
207 parse: fn(Reader) -> Result<ObjectHeader>,
208 ) -> Result<()> {
209 match parse(reader) {
210 Ok(header) if header.object_type == object_type => Ok(()),
211 Ok(header) => Err(ErrorKind::MalformedFssHttpBData(
212 format!("unexpected object type: {:x}", header.object_type).into(),
213 )
214 .into()),
215 Err(e) => Err(e),
216 }
217 }
218
219 fn try_parse_end(
220 reader: Reader,
221 object_type: ObjectType,
222 parse: fn(Reader) -> Result<ObjectType>,
223 ) -> Result<()> {
224 match parse(reader) {
225 Ok(header) if header == object_type => Ok(()),
226 Ok(header) => Err(ErrorKind::MalformedFssHttpBData(
227 format!("unexpected object type: {:x}", header).into(),
228 )
229 .into()),
230 Err(e) => Err(e),
231 }
232 }
233}