1pub mod collection;
8pub mod number;
9pub mod reference;
10pub mod binary_tree;
11pub mod string;
12
13use std::io::{Read, Seek, Write};
14
15use collection::{PsbUintArray, PsbList, PsbObject};
16use number::PsbNumber;
17use reference::PsbExtraRef;
18
19use crate::{PsbError, PsbErrorKind, PsbRefs};
20use byteorder::{ReadBytesExt, WriteBytesExt};
21
22use self::{reference::PsbResourceRef, string::PsbString};
23
24#[cfg(feature = "serde")]
25use serde::{Serialize, Deserialize};
26
27pub const PSB_TYPE_NONE: u8 = 0x00;
28
29pub const PSB_TYPE_NULL: u8 = 0x01;
30
31pub const PSB_TYPE_FALSE: u8 = 0x02;
32pub const PSB_TYPE_TRUE: u8 = 0x03;
33
34pub const PSB_TYPE_INTEGER_N: u8 = 0x04;
36pub const PSB_TYPE_FLOAT0: u8 = 0x1d;
37pub const PSB_TYPE_FLOAT: u8 = 0x1e;
38pub const PSB_TYPE_DOUBLE: u8 = 0x1f;
39
40pub const PSB_TYPE_INTEGER_ARRAY_N: u8 = 0x0C;
42
43pub const PSB_TYPE_STRING_N: u8 = 0x14;
45
46pub const PSB_TYPE_RESOURCE_N: u8 = 0x18;
48
49pub const PSB_TYPE_LIST: u8 = 0x20;
50pub const PSB_TYPE_OBJECT: u8 = 0x21;
51
52pub const PSB_TYPE_EXTRA_N: u8 = 0x21;
54
55pub const PSB_COMPILER_INTEGER: u8 = 0x80;
56pub const PSB_COMPILER_STRING: u8 = 0x81;
57pub const PSB_COMPILER_RESOURCE: u8 = 0x82;
58pub const PSB_COMPILER_DECIMAL: u8 = 0x83;
59pub const PSB_COMPILER_ARRAY: u8 = 0x84;
60pub const PSB_COMPILER_BOOL: u8 = 0x85;
61pub const PSB_COMPILER_BINARY_TREE: u8 = 0x86;
62
63#[derive(Debug, PartialEq)]
64#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
65#[cfg_attr(feature = "serde", serde(untagged))]
66pub enum PsbValue {
67
68 None, Null,
69 Bool(bool),
70 Number(PsbNumber),
71 IntArray(PsbUintArray),
72
73 String(PsbString),
74
75 List(PsbList),
76 Object(PsbObject),
77
78 Resource(PsbResourceRef),
79 ExtraResource(PsbExtraRef),
80
81 CompilerNumber,
82 CompilerString,
83 CompilerResource,
84 CompilerDecimal,
85 CompilerArray,
86 CompilerBool,
87 CompilerBinaryTree
88
89}
90
91impl PsbValue {
92
93 fn from_bytes_type<T: Read + Seek>(value_type: u8, stream: &mut T) -> Result<(u64, PsbValue), PsbError> {
94 match value_type {
95 PSB_TYPE_NONE => Ok((1, PsbValue::None)),
96 PSB_TYPE_NULL => Ok((1, PsbValue::Null)),
97
98 PSB_TYPE_FALSE => Ok((1, PsbValue::Bool(false))),
99 PSB_TYPE_TRUE => Ok((1, PsbValue::Bool(true))),
100
101 PSB_TYPE_DOUBLE => {
102 let (read, val) = PsbNumber::from_bytes(value_type, stream)?;
103 Ok((read + 1, PsbValue::Number(val)))
104 },
105
106 PSB_TYPE_FLOAT0 => {
107 let (read, val) = PsbNumber::from_bytes(value_type, stream)?;
108 Ok((read + 1, PsbValue::Number(val)))
109 },
110
111 PSB_TYPE_FLOAT => {
112 let (read, val) = PsbNumber::from_bytes(value_type, stream)?;
113 Ok((read + 1, PsbValue::Number(val)))
114 },
115
116 _ if value_type >= PSB_TYPE_INTEGER_N && value_type <= PSB_TYPE_INTEGER_N + 8 => {
117 let (read, number) = PsbNumber::from_bytes(value_type, stream)?;
118 Ok((read + 1, PsbValue::Number(number)))
119 },
120
121 _ if value_type > PSB_TYPE_INTEGER_ARRAY_N && value_type <= PSB_TYPE_INTEGER_ARRAY_N + 8 => {
122 let (read, array) = PsbUintArray::from_bytes(value_type - PSB_TYPE_INTEGER_ARRAY_N, stream)?;
123 Ok((read + 1, PsbValue::IntArray(array)))
124 },
125
126 _ if value_type > PSB_TYPE_RESOURCE_N && value_type <= PSB_TYPE_RESOURCE_N + 4 => {
127 let (read, map) = PsbResourceRef::from_bytes(value_type - PSB_TYPE_RESOURCE_N, stream)?;
128
129 Ok((read + 1, PsbValue::Resource(map)))
130 },
131
132 _ if value_type > PSB_TYPE_EXTRA_N && value_type <= PSB_TYPE_EXTRA_N + 4 => {
133 let (read, map) = PsbExtraRef::from_bytes(value_type - PSB_TYPE_EXTRA_N, stream)?;
134
135 Ok((read + 1, PsbValue::ExtraResource(map)))
136 },
137
138 PSB_COMPILER_INTEGER => Ok((1, PsbValue::CompilerNumber)),
139 PSB_COMPILER_STRING => Ok((1, PsbValue::CompilerString)),
140 PSB_COMPILER_RESOURCE => Ok((1, PsbValue::CompilerResource)),
141 PSB_COMPILER_ARRAY => Ok((1, PsbValue::CompilerArray)),
142 PSB_COMPILER_BOOL => Ok((1, PsbValue::CompilerBool)),
143 PSB_COMPILER_BINARY_TREE => Ok((1, PsbValue::CompilerBinaryTree)),
144
145 _ => {
146 Err(PsbError::new(PsbErrorKind::InvalidPSBValue, None))
147 }
148 }
149 }
150
151 pub fn from_bytes<T: Read + Seek>(stream: &mut T) -> Result<(u64, PsbValue), PsbError> {
152 Self::from_bytes_type(stream.read_u8()?, stream)
153 }
154
155 pub fn from_bytes_refs<T: Read + Seek>(stream: &mut T, table: &PsbRefs) -> Result<(u64, PsbValue), PsbError> {
156 let value_type = stream.read_u8()?;
157
158 match value_type {
159
160 PSB_TYPE_LIST => {
161 let (read, list) = PsbList::from_bytes(stream, table)?;
162
163 Ok((read + 1, PsbValue::List(list)))
164 },
165
166 PSB_TYPE_OBJECT => {
167 let (read, map) = PsbObject::from_bytes(stream, table)?;
168
169 Ok((read + 1, PsbValue::Object(map)))
170 },
171
172 _ if value_type > PSB_TYPE_STRING_N && value_type <= PSB_TYPE_STRING_N + 4 => {
173 let (read, string) = PsbString::from_bytes(value_type - PSB_TYPE_STRING_N, stream, table)?;
174
175 Ok((read + 1, PsbValue::String(string)))
176 },
177
178 _ => {
179 Self::from_bytes_type(value_type, stream)
180 }
181
182 }
183 }
184
185 pub fn write_bytes(&self, stream: &mut impl Write) -> Result<u64, PsbError> {
186 match self {
187 PsbValue::None => {
188 stream.write_u8(PSB_TYPE_NONE)?;
189 Ok(1)
190 },
191 PsbValue::Null => {
192 stream.write_u8(PSB_TYPE_NULL)?;
193 Ok(1)
194 },
195 PsbValue::Bool(value) => {
196 if *value {
197 stream.write_u8(PSB_TYPE_TRUE)?;
198 } else {
199 stream.write_u8(PSB_TYPE_FALSE)?;
200 }
201
202 Ok(1)
203 },
204 PsbValue::Number(number) => {
205 match number {
206 PsbNumber::Integer(integer) => {
207 let n = if *integer == 0 {
208 0
209 } else {
210 PsbNumber::get_n(*integer)
211 };
212
213 stream.write_u8(PSB_TYPE_INTEGER_N + n)?;
214 },
215
216 PsbNumber::Double(_) => {
217 stream.write_u8(PSB_TYPE_DOUBLE)?;
218 },
219
220 PsbNumber::Float(float) => {
221 if *float == 0_f32 {
222 stream.write_u8(PSB_TYPE_FLOAT0)?;
223 } else {
224 stream.write_u8(PSB_TYPE_FLOAT)?;
225 }
226 }
227 }
228
229 Ok(1 + number.write_bytes(stream)?)
230 },
231
232 PsbValue::IntArray(array) => {
233 stream.write_u8(PSB_TYPE_INTEGER_ARRAY_N + array.get_n())?;
234
235 Ok(1 + array.write_bytes(stream)?)
236 },
237
238 PsbValue::Resource(res) => {
239 stream.write_u8(PSB_TYPE_RESOURCE_N + res.get_n())?;
240
241 Ok(1 + res.write_bytes(stream)?)
242 },
243 PsbValue::ExtraResource(res) => {
244 stream.write_u8(PSB_TYPE_EXTRA_N + res.get_n())?;
245
246 Ok(1 + res.write_bytes(stream)?)
247 },
248
249 PsbValue::CompilerNumber => {
250 stream.write_u8(PSB_COMPILER_INTEGER)?;
251 Ok(1)
252 },
253 PsbValue::CompilerString => {
254 stream.write_u8(PSB_COMPILER_STRING)?;
255 Ok(1)
256 },
257 PsbValue::CompilerResource => {
258 stream.write_u8(PSB_COMPILER_RESOURCE)?;
259 Ok(1)
260 },
261 PsbValue::CompilerDecimal => {
262 stream.write_u8(PSB_COMPILER_DECIMAL)?;
263 Ok(1)
264 },
265 PsbValue::CompilerArray => {
266 stream.write_u8(PSB_COMPILER_ARRAY)?;
267 Ok(1)
268 },
269 PsbValue::CompilerBool => {
270 stream.write_u8(PSB_COMPILER_BOOL)?;
271 Ok(1)
272 },
273 PsbValue::CompilerBinaryTree => {
274 stream.write_u8(PSB_COMPILER_BINARY_TREE)?;
275 Ok(1)
276 },
277
278 _ => {
279 Err(PsbError::new(PsbErrorKind::InvalidPSBValue, None))
280 }
281 }
282 }
283
284 pub fn write_bytes_refs(&self, stream: &mut impl Write, table: &PsbRefs) -> Result<u64, PsbError> {
285 match &self {
286
287 PsbValue::String(string) => {
288 let n = PsbNumber::get_uint_n(match table.find_string_index(string.string()) {
289
290 Some(ref_index) => {
291 Ok(ref_index)
292 },
293
294 None => Err(PsbError::new(PsbErrorKind::InvalidOffsetTable, None))
295 }?);
296
297 stream.write_u8(PSB_TYPE_STRING_N + n)?;
298
299 Ok(1 + string.write_bytes(stream, table)?)
300 },
301
302 PsbValue::List(list) => {
303 stream.write_u8(PSB_TYPE_LIST)?;
304
305 Ok(1 + list.write_bytes(stream, table)?)
306 },
307
308 PsbValue::Object(object) => {
309 stream.write_u8(PSB_TYPE_OBJECT)?;
310
311 Ok(1 + object.write_bytes(stream, table)?)
312 },
313
314 _ => self.write_bytes(stream)
315
316 }
317 }
318
319}