1use crate::error::{Error, Result};
18use crate::records::*;
19use std::collections::HashMap;
20use std::io::Read;
21
22pub struct Decoder<R: Read> {
24 reader: R,
25 metadata_registry: HashMap<i32, ClassInfoWithTypes>,
26 pub library_registry: HashMap<i32, String>,
28 pub offset: usize,
30}
31
32#[derive(Clone)]
34pub struct ClassInfoWithTypes {
35 pub class_info: ClassInfo,
36 pub member_type_info: Option<MemberTypeInfo>,
37 pub library_id: Option<i32>,
38}
39
40impl<R: Read> Decoder<R> {
41 pub fn new(reader: R) -> Self {
43 Self {
44 reader,
45 metadata_registry: HashMap::new(),
46 library_registry: HashMap::new(),
47 offset: 0,
48 }
49 }
50
51 pub fn decode_next(&mut self) -> Result<Option<Record>> {
57 let mut header = [0u8; 1];
58 if self.reader.read_exact(&mut header).is_err() {
59 return Ok(None);
60 }
61 self.offset += 1;
62
63 let record_type = RecordType::try_from(header[0])?;
64 match record_type {
65 RecordType::SerializedStreamHeader => {
66 let rec = self.read_serialization_header()?;
67 Ok(Some(Record::SerializationHeader(rec)))
68 }
69 RecordType::BinaryLibrary => {
70 let lib = self.read_binary_library()?;
71 self.library_registry
72 .insert(lib.library_id, lib.library_name.clone());
73 Ok(Some(Record::BinaryLibrary(lib)))
74 }
75 RecordType::ClassWithMembersAndTypes => {
76 let rec = self.read_class_with_members_and_types()?;
77 Ok(Some(Record::ClassWithMembersAndTypes(rec)))
78 }
79 RecordType::SystemClassWithMembersAndTypes => {
80 let rec = self.read_system_class_with_members_and_types()?;
81 Ok(Some(Record::SystemClassWithMembersAndTypes(rec)))
82 }
83 RecordType::SystemClassWithMembers => {
84 let rec = self.read_system_class_with_members()?;
85 Ok(Some(Record::SystemClassWithMembers(rec)))
86 }
87 RecordType::ClassWithMembers => {
88 let rec = self.read_class_with_members()?;
89 Ok(Some(Record::ClassWithMembers(rec)))
90 }
91 RecordType::ClassWithId => {
92 let rec = self.read_class_with_id()?;
93 Ok(Some(Record::ClassWithId(rec)))
94 }
95 RecordType::BinaryObjectString => {
96 let object_id = self.read_i32()?;
97 let value = self.read_length_prefixed_string()?;
98 Ok(Some(Record::BinaryObjectString { object_id, value }))
99 }
100 RecordType::BinaryArray => {
101 let rec = self.read_binary_array_full()?;
102 Ok(Some(Record::BinaryArray(rec)))
103 }
104 RecordType::MemberPrimitiveTyped => {
105 let pt = PrimitiveType::try_from(self.read_u8()?)?;
106 let value = self.read_primitive_value(pt)?;
107 Ok(Some(Record::MemberPrimitiveTyped {
108 primitive_type_enum: pt,
109 value,
110 }))
111 }
112 RecordType::MemberReference => Ok(Some(Record::MemberReference {
113 id_ref: self.read_i32()?,
114 })),
115 RecordType::ObjectNull => Ok(Some(Record::ObjectNull)),
116 RecordType::ObjectNullMultiple256 => {
117 Ok(Some(Record::ObjectNullMultiple256(ObjectNullMultiple256 {
118 null_count: self.read_u8()?,
119 })))
120 }
121 RecordType::ObjectNullMultiple => {
122 Ok(Some(Record::ObjectNullMultiple(ObjectNullMultiple {
123 null_count: self.read_i32()?,
124 })))
125 }
126 RecordType::ArraySinglePrimitive => {
127 let object_id = self.read_i32()?;
128 let length = self.read_i32()?;
129 let pt = PrimitiveType::try_from(self.read_u8()?)?;
130 let mut values = Vec::with_capacity(length as usize);
131 for _ in 0..length {
132 values.push(self.read_primitive_value(pt)?);
133 }
134 Ok(Some(Record::ArraySinglePrimitive(ArraySinglePrimitive {
135 object_id,
136 length,
137 primitive_type_enum: pt,
138 element_values: values,
139 })))
140 }
141 RecordType::ArraySingleObject => {
142 let object_id = self.read_i32()?;
143 let length = self.read_i32()?;
144 let values =
145 self.read_all_elements(length, BinaryType::Object, &AdditionalTypeInfo::None)?;
146 Ok(Some(Record::ArraySingleObject(ArraySingleObject {
147 object_id,
148 length,
149 element_values: values,
150 })))
151 }
152 RecordType::ArraySingleString => {
153 let object_id = self.read_i32()?;
154 let length = self.read_i32()?;
155 let values =
156 self.read_all_elements(length, BinaryType::String, &AdditionalTypeInfo::None)?;
157 Ok(Some(Record::ArraySingleString(ArraySingleString {
158 object_id,
159 length,
160 element_values: values,
161 })))
162 }
163 RecordType::MessageEnd => Ok(Some(Record::MessageEnd)),
164 _ => Err(Error::Custom(format!(
165 "Unimplemented record type 0x{:02x}",
166 header[0]
167 ))),
168 }
169 }
170
171 fn read_i32(&mut self) -> Result<i32> {
172 let mut buf = [0u8; 4];
173 self.reader.read_exact(&mut buf)?;
174 self.offset += 4;
175 Ok(i32::from_le_bytes(buf))
176 }
177
178 fn read_u8(&mut self) -> Result<u8> {
179 let mut buf = [0u8; 1];
180 self.reader.read_exact(&mut buf)?;
181 self.offset += 1;
182 Ok(buf[0])
183 }
184
185 fn read_serialization_header(&mut self) -> Result<SerializationHeader> {
186 Ok(SerializationHeader {
187 root_id: self.read_i32()?,
188 header_id: self.read_i32()?,
189 major_version: self.read_i32()?,
190 minor_version: self.read_i32()?,
191 })
192 }
193
194 fn read_binary_library(&mut self) -> Result<BinaryLibrary> {
195 Ok(BinaryLibrary {
196 library_id: self.read_i32()?,
197 library_name: self.read_length_prefixed_string()?,
198 })
199 }
200
201 fn read_length_prefixed_string(&mut self) -> Result<String> {
202 let length = self.read_variable_length_int()?;
203 if length < 0 {
204 return Err(Error::InvalidStringLength(length));
205 }
206 if length == 0 {
207 return Ok(String::new());
208 }
209 let mut buf = vec![0u8; length as usize];
210 self.reader.read_exact(&mut buf)?;
211 self.offset += length as usize;
212 Ok(String::from_utf8(buf)?)
213 }
214
215 fn read_variable_length_int(&mut self) -> Result<i32> {
216 let mut value: i32 = 0;
217 let mut shift = 0;
218 loop {
219 let b = self.read_u8()?;
220 value |= ((b & 0x7F) as i32) << shift;
221 if (b & 0x80) == 0 {
222 break;
223 }
224 shift += 7;
225 if shift >= 35 {
226 return Err(Error::Custom("Variable length int too long".into()));
227 }
228 }
229 Ok(value)
230 }
231
232 fn read_class_info(&mut self) -> Result<ClassInfo> {
233 let object_id = self.read_i32()?;
234 let name = self.read_length_prefixed_string()?;
235 let member_count = self.read_i32()?;
236 let mut member_names = Vec::with_capacity(member_count as usize);
237 for _ in 0..member_count {
238 member_names.push(self.read_length_prefixed_string()?);
239 }
240 Ok(ClassInfo {
241 object_id,
242 name,
243 member_count,
244 member_names,
245 })
246 }
247
248 fn read_member_type_info(&mut self, count: i32) -> Result<MemberTypeInfo> {
249 let mut binary_type_enums = Vec::with_capacity(count as usize);
250 for _ in 0..count {
251 binary_type_enums.push(BinaryType::try_from(self.read_u8()?)?);
252 }
253
254 let mut additional_infos = Vec::with_capacity(count as usize);
255 for i in 0..count {
256 let bt = binary_type_enums[i as usize];
257 let info = match bt {
258 BinaryType::Primitive => {
259 AdditionalTypeInfo::Primitive(PrimitiveType::try_from(self.read_u8()?)?)
260 }
261 BinaryType::SystemClass => {
262 AdditionalTypeInfo::SystemClass(self.read_length_prefixed_string()?)
263 }
264 BinaryType::Class => AdditionalTypeInfo::Class(ClassTypeInfo {
265 type_name: self.read_length_prefixed_string()?,
266 library_id: self.read_i32()?,
267 }),
268 _ => AdditionalTypeInfo::None,
269 };
270 additional_infos.push(info);
271 }
272
273 Ok(MemberTypeInfo {
274 binary_type_enums,
275 additional_infos,
276 })
277 }
278
279 fn read_class_with_members_and_types(&mut self) -> Result<ClassWithMembersAndTypes> {
280 let class_info = self.read_class_info()?;
281 let member_type_info = self.read_member_type_info(class_info.member_count)?;
282 let library_id = self.read_i32()?;
283
284 self.metadata_registry.insert(
285 class_info.object_id,
286 ClassInfoWithTypes {
287 class_info: class_info.clone(),
288 member_type_info: Some(member_type_info.clone()),
289 library_id: Some(library_id),
290 },
291 );
292
293 let member_values =
294 self.read_all_member_values(&class_info, &Some(member_type_info.clone()))?;
295 Ok(ClassWithMembersAndTypes {
296 class_info,
297 member_type_info,
298 library_id,
299 member_values,
300 })
301 }
302
303 fn read_system_class_with_members_and_types(
304 &mut self,
305 ) -> Result<SystemClassWithMembersAndTypes> {
306 let class_info = self.read_class_info()?;
307 let member_type_info = self.read_member_type_info(class_info.member_count)?;
308
309 self.metadata_registry.insert(
310 class_info.object_id,
311 ClassInfoWithTypes {
312 class_info: class_info.clone(),
313 member_type_info: Some(member_type_info.clone()),
314 library_id: None,
315 },
316 );
317
318 let member_values =
319 self.read_all_member_values(&class_info, &Some(member_type_info.clone()))?;
320 Ok(SystemClassWithMembersAndTypes {
321 class_info,
322 member_type_info,
323 member_values,
324 })
325 }
326
327 fn read_system_class_with_members(&mut self) -> Result<SystemClassWithMembers> {
328 let class_info = self.read_class_info()?;
329
330 self.metadata_registry.insert(
331 class_info.object_id,
332 ClassInfoWithTypes {
333 class_info: class_info.clone(),
334 member_type_info: None,
335 library_id: None,
336 },
337 );
338
339 let member_values = self.read_all_member_values(&class_info, &None)?;
340 Ok(SystemClassWithMembers {
341 class_info,
342 member_values,
343 })
344 }
345
346 fn read_class_with_members(&mut self) -> Result<ClassWithMembers> {
347 let class_info = self.read_class_info()?;
348 let library_id = self.read_i32()?;
349
350 self.metadata_registry.insert(
351 class_info.object_id,
352 ClassInfoWithTypes {
353 class_info: class_info.clone(),
354 member_type_info: None,
355 library_id: Some(library_id),
356 },
357 );
358
359 let member_values = self.read_all_member_values(&class_info, &None)?;
360 Ok(ClassWithMembers {
361 class_info,
362 library_id,
363 member_values,
364 })
365 }
366
367 fn read_class_with_id(&mut self) -> Result<ClassWithId> {
368 let object_id = self.read_i32()?;
369 let metadata_id = self.read_i32()?;
370
371 let meta = self
372 .metadata_registry
373 .get(&metadata_id)
374 .ok_or_else(|| Error::Custom(format!("Metadata ID {} not found", metadata_id)))?
375 .clone();
376
377 let member_values =
378 self.read_all_member_values(&meta.class_info, &meta.member_type_info)?;
379
380 Ok(ClassWithId {
381 object_id,
382 metadata_id,
383 member_values,
384 })
385 }
386
387 fn read_binary_array_full(&mut self) -> Result<BinaryArray> {
388 let object_id = self.read_i32()?;
389 let binary_array_type_enum = self.read_u8()?;
390 let rank = self.read_i32()?;
391 let mut lengths = Vec::with_capacity(rank as usize);
392 for _ in 0..rank {
393 lengths.push(self.read_i32()?);
394 }
395
396 let mut lower_bounds = None;
397 if binary_array_type_enum == 3 || binary_array_type_enum == 4 || binary_array_type_enum == 5
398 {
399 let mut bounds = Vec::with_capacity(rank as usize);
400 for _ in 0..rank {
401 bounds.push(self.read_i32()?);
402 }
403 lower_bounds = Some(bounds);
404 }
405
406 let type_enum = BinaryType::try_from(self.read_u8()?)?;
407 let additional_type_info = match type_enum {
408 BinaryType::Primitive => {
409 AdditionalTypeInfo::Primitive(PrimitiveType::try_from(self.read_u8()?)?)
410 }
411 BinaryType::SystemClass => {
412 AdditionalTypeInfo::SystemClass(self.read_length_prefixed_string()?)
413 }
414 BinaryType::Class => AdditionalTypeInfo::Class(ClassTypeInfo {
415 type_name: self.read_length_prefixed_string()?,
416 library_id: self.read_i32()?,
417 }),
418 _ => AdditionalTypeInfo::None,
419 };
420
421 let total_elements: i32 = lengths.iter().product();
422 let element_values =
423 self.read_all_elements(total_elements, type_enum, &additional_type_info)?;
424
425 Ok(BinaryArray {
426 object_id,
427 binary_array_type_enum,
428 rank,
429 lengths,
430 lower_bounds,
431 type_enum,
432 additional_type_info,
433 element_values,
434 })
435 }
436
437 fn read_primitive_value(&mut self, pt: PrimitiveType) -> Result<PrimitiveValue> {
438 match pt {
439 PrimitiveType::Boolean => Ok(PrimitiveValue::Boolean(self.read_u8()? != 0)),
440 PrimitiveType::Byte => Ok(PrimitiveValue::Byte(self.read_u8()?)),
441 PrimitiveType::Char => {
442 let b = self.read_u8()?;
443 Ok(PrimitiveValue::Char(b as char))
444 }
445 PrimitiveType::Int16 => {
446 let mut buf = [0u8; 2];
447 self.reader.read_exact(&mut buf)?;
448 self.offset += 2;
449 Ok(PrimitiveValue::Int16(i16::from_le_bytes(buf)))
450 }
451 PrimitiveType::Int32 => Ok(PrimitiveValue::Int32(self.read_i32()?)),
452 PrimitiveType::Int64 => {
453 let mut buf = [0u8; 8];
454 self.reader.read_exact(&mut buf)?;
455 self.offset += 8;
456 Ok(PrimitiveValue::Int64(i64::from_le_bytes(buf)))
457 }
458 PrimitiveType::TimeSpan => {
459 let mut buf = [0u8; 8];
460 self.reader.read_exact(&mut buf)?;
461 self.offset += 8;
462 Ok(PrimitiveValue::TimeSpan(i64::from_le_bytes(buf)))
463 }
464 PrimitiveType::DateTime => {
465 let mut buf = [0u8; 8];
466 self.reader.read_exact(&mut buf)?;
467 self.offset += 8;
468 Ok(PrimitiveValue::DateTime(u64::from_le_bytes(buf)))
469 }
470 PrimitiveType::SByte => Ok(PrimitiveValue::SByte(self.read_u8()? as i8)),
471 PrimitiveType::Single => {
472 let mut buf = [0u8; 4];
473 self.reader.read_exact(&mut buf)?;
474 self.offset += 4;
475 Ok(PrimitiveValue::Single(f32::from_le_bytes(buf)))
476 }
477 PrimitiveType::Double => {
478 let mut buf = [0u8; 8];
479 self.reader.read_exact(&mut buf)?;
480 self.offset += 8;
481 Ok(PrimitiveValue::Double(f64::from_le_bytes(buf)))
482 }
483 PrimitiveType::Decimal => {
484 let mut buf = [0u8; 16];
485 self.reader.read_exact(&mut buf)?;
486 self.offset += 16;
487 Ok(PrimitiveValue::Decimal(hex::encode(buf)))
489 }
490 PrimitiveType::UInt16 => {
491 let mut buf = [0u8; 2];
492 self.reader.read_exact(&mut buf)?;
493 self.offset += 2;
494 Ok(PrimitiveValue::UInt16(u16::from_le_bytes(buf)))
495 }
496 PrimitiveType::UInt32 => {
497 let mut buf = [0u8; 4];
498 self.reader.read_exact(&mut buf)?;
499 self.offset += 4;
500 Ok(PrimitiveValue::UInt32(u32::from_le_bytes(buf)))
501 }
502 PrimitiveType::UInt64 => {
503 let mut buf = [0u8; 8];
504 self.reader.read_exact(&mut buf)?;
505 self.offset += 8;
506 Ok(PrimitiveValue::UInt64(u64::from_le_bytes(buf)))
507 }
508 PrimitiveType::String => {
509 Ok(PrimitiveValue::String(self.read_length_prefixed_string()?))
510 }
511 PrimitiveType::Null => Ok(PrimitiveValue::Null),
512 }
513 }
514
515 fn read_object_value(
516 &mut self,
517 bt: BinaryType,
518 add_info: &AdditionalTypeInfo,
519 ) -> Result<ObjectValue> {
520 match bt {
521 BinaryType::Primitive => {
522 if let AdditionalTypeInfo::Primitive(pt) = add_info {
523 Ok(ObjectValue::Primitive(self.read_primitive_value(*pt)?))
524 } else {
525 Err(Error::Custom("Expected primitive type info".into()))
526 }
527 }
528 _ => {
529 if let Some(record) = self.decode_next()? {
530 Ok(ObjectValue::Record(Box::new(record)))
531 } else {
532 Err(Error::Custom("Expected record for object value".into()))
533 }
534 }
535 }
536 }
537
538 fn read_all_member_values(
539 &mut self,
540 class_info: &ClassInfo,
541 member_type_info: &Option<MemberTypeInfo>,
542 ) -> Result<Vec<ObjectValue>> {
543 let mut values = Vec::with_capacity(class_info.member_count as usize);
544 for i in 0..class_info.member_count {
545 if let Some(mti) = member_type_info {
546 let bt = mti.binary_type_enums[i as usize];
547 let add_info = &mti.additional_infos[i as usize];
548 values.push(self.read_object_value(bt, add_info)?);
549 } else if let Some(record) = self.decode_next()? {
550 values.push(ObjectValue::Record(Box::new(record)));
551 } else {
552 return Err(Error::Custom("Expected record for member value".into()));
553 }
554 }
555 Ok(values)
556 }
557
558 fn read_all_elements(
559 &mut self,
560 count: i32,
561 bt: BinaryType,
562 add_info: &AdditionalTypeInfo,
563 ) -> Result<Vec<ObjectValue>> {
564 let mut values = Vec::with_capacity(count as usize);
565 let mut i = 0;
566 while i < count {
567 let val = self.read_object_value(bt, add_info)?;
568 match &val {
569 ObjectValue::Record(r) => match r.as_ref() {
570 Record::ObjectNullMultiple(n) => {
571 for _ in 0..n.null_count {
572 values.push(ObjectValue::Primitive(PrimitiveValue::Null));
573 i += 1;
574 }
575 continue;
576 }
577 Record::ObjectNullMultiple256(n) => {
578 for _ in 0..n.null_count {
579 values.push(ObjectValue::Primitive(PrimitiveValue::Null));
580 i += 1;
581 }
582 continue;
583 }
584 Record::ObjectNull => {
585 values.push(ObjectValue::Primitive(PrimitiveValue::Null));
586 }
587 _ => {
588 values.push(val);
589 }
590 },
591 _ => {
592 values.push(val);
593 }
594 }
595 i += 1;
596 }
597 Ok(values)
598 }
599}