msg_tool\scripts\qlie\archive\pack/
delphi.rs1use crate::ext::io::*;
2use crate::types::*;
3use crate::utils::encoding::*;
4use crate::utils::struct_pack::*;
5use anyhow::Result;
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::io::{Read, Seek};
9
10#[derive(Serialize, Deserialize, Debug, Clone)]
11#[serde(tag = "type", content = "value")]
12pub enum DelphiValue {
13 Uint8(u8),
14 Uint16(u16),
15 LongDouble([u8; 10]),
16 Unk6,
17 String(String),
18 Unk8,
19 Bool(bool),
20 ByteString(Vec<u8>),
21 StringArray(Vec<String>),
22 UnicodeString(String),
23}
24
25impl DelphiValue {
26 pub fn as_bytes<'a>(&'a self) -> Option<&'a [u8]> {
27 match self {
28 DelphiValue::ByteString(b) => Some(b),
29 _ => None,
30 }
31 }
32}
33
34impl StructUnpack for DelphiValue {
35 fn unpack<R: Read + Seek>(
36 reader: &mut R,
37 big: bool,
38 encoding: Encoding,
39 info: &Option<Box<dyn std::any::Any>>,
40 ) -> Result<Self> {
41 let type_id = u8::unpack(reader, big, encoding, info)?;
42 match type_id {
43 2 => Ok(DelphiValue::Uint8(u8::unpack(reader, big, encoding, info)?)),
44 3 => Ok(DelphiValue::Uint16(u16::unpack(
45 reader, big, encoding, info,
46 )?)),
47 5 => Ok(DelphiValue::LongDouble({
48 let mut buf = [0u8; 10];
49 reader.read_exact(&mut buf)?;
50 buf
51 })),
52 6 | 7 => Ok(DelphiValue::String({
53 let slen = u8::unpack(reader, big, encoding, info)? as usize;
54 let buf = reader.read_exact_vec(slen)?;
55 decode_to_string(encoding, &buf, true)?
56 })),
57 8 => Ok(DelphiValue::Bool(false)),
58 9 => Ok(DelphiValue::Bool(true)),
59 10 => Ok(DelphiValue::ByteString({
60 let slen = u32::unpack(reader, big, encoding, info)? as usize;
61 reader.read_exact_vec(slen)?
62 })),
63 11 => Ok(DelphiValue::StringArray({
64 let mut arr = Vec::new();
65 let mut len;
66 while {
67 len = u8::unpack(reader, big, encoding, info)?;
68 len > 0
69 } {
70 let buf = reader.read_exact_vec(len as usize)?;
71 arr.push(decode_to_string(encoding, &buf, true)?);
72 }
73 arr
74 })),
75 18 => Ok(DelphiValue::UnicodeString({
76 let slen = u32::unpack(reader, big, encoding, info)? as usize;
77 let buf = reader.read_exact_vec(slen * 2)?;
78 decode_to_string(
79 if big {
80 Encoding::Utf16BE
81 } else {
82 Encoding::Utf16LE
83 },
84 &buf,
85 true,
86 )?
87 })),
88 _ => Err(anyhow::anyhow!("Unknown Delphi value type: {}", type_id)),
89 }
90 }
91}
92
93#[derive(Serialize, Deserialize, Debug, Clone)]
94
95pub struct DelphiObject {
96 pub type_name: String,
97 pub name: String,
98 pub properties: HashMap<String, DelphiValue>,
99 pub contents: Vec<DelphiObject>,
100}
101
102impl StructUnpack for DelphiObject {
103 fn unpack<R: Read + Seek>(
104 reader: &mut R,
105 big: bool,
106 encoding: Encoding,
107 info: &Option<Box<dyn std::any::Any>>,
108 ) -> Result<Self> {
109 let type_len = u8::unpack(reader, big, encoding, info)? as usize;
110 let type_name = {
111 let buf = reader.read_exact_vec(type_len)?;
112 decode_to_string(encoding, &buf, true)?
113 };
114 let name_len = u8::unpack(reader, big, encoding, info)? as usize;
115 let name = {
116 let buf = reader.read_exact_vec(name_len)?;
117 decode_to_string(encoding, &buf, true)?
118 };
119 let mut properties = HashMap::new();
120 let mut keylen;
121 while {
122 keylen = u8::unpack(reader, big, encoding, info)?;
123 keylen > 0
124 } {
125 let key_buf = reader.read_exact_vec(keylen as usize)?;
126 let key = decode_to_string(encoding, &key_buf, true)?;
127 let value = DelphiValue::unpack(reader, big, encoding, info)?;
128 properties.insert(key, value);
129 }
130 let mut contents = Vec::new();
131 while reader.peek_u8()? != 0 {
132 contents.push(DelphiObject::unpack(reader, big, encoding, info)?);
133 }
134 reader.read_u8()?; return Ok(Self {
136 type_name,
137 name,
138 properties,
139 contents,
140 });
141 }
142}
143
144pub fn deser_delphi<R: Read + Seek>(reader: &mut R) -> Result<DelphiObject> {
145 let sig = reader.read_u32()?;
146 if sig != 0x30465054 {
147 return Err(anyhow::anyhow!(
148 "Invalid Delphi object signature: {:08X}",
149 sig
150 ));
151 }
152 Ok(DelphiObject::unpack(reader, false, Encoding::Cp932, &None)?)
153}