1use std::{collections::{HashMap, hash_map}, io::{Read, Seek, SeekFrom, Write}, ops::Index, slice::Iter};
8
9use crate::{PsbError, PsbErrorKind, PsbRefs};
10
11use byteorder::{ReadBytesExt, WriteBytesExt};
12use itertools::Itertools;
13
14use super::{PSB_TYPE_INTEGER_ARRAY_N, PsbValue, number::PsbNumber};
15
16#[cfg(feature = "serde")]
17use serde::{Serialize, Deserialize};
18
19#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
21#[cfg_attr(feature = "serde", serde(transparent))]
22pub struct PsbUintArray {
23
24 vec: Vec<u64>
25
26}
27
28impl PsbUintArray {
29
30 pub fn new() -> Self {
31 Self {
32 vec: Vec::new()
33 }
34 }
35
36 pub fn len(&self) -> usize {
37 self.vec.len()
38 }
39
40 pub fn iter(&self) -> Iter<'_, u64> {
41 self.vec.iter()
42 }
43
44 pub fn vec(&self) -> &Vec<u64> {
45 &self.vec
46 }
47
48 pub fn vec_mut(&mut self) -> &mut Vec<u64> {
49 &mut self.vec
50 }
51
52 pub fn unwrap(self) -> Vec<u64> {
53 self.vec
54 }
55
56 pub fn get_item_n(&self) -> u8 {
58 PsbNumber::get_uint_n(*self.vec.iter().max().unwrap_or(&0))
59 }
60
61 pub fn get_n(&self) -> u8 {
62 PsbNumber::get_uint_n(self.vec.len() as u64)
63 }
64
65 pub fn from_bytes(n: u8, stream: &mut impl Read) -> Result<(u64, PsbUintArray), PsbError> {
66 let (count_read, item_count) = PsbNumber::read_uint(n, stream)?;
67
68 let item_byte_size = stream.read_u8()? - PSB_TYPE_INTEGER_ARRAY_N;
69
70 let mut list = Vec::<u64>::new();
71
72 let mut item_total_read = 0_u64;
73 for _ in 0..item_count {
74 let (item_read, item) = PsbNumber::read_uint(item_byte_size, stream)?;
75 list.push(item as u64);
76
77 item_total_read += item_read;
78 }
79
80 Ok((count_read + item_total_read + 1, PsbUintArray::from(list)))
81 }
82
83 pub fn write_bytes(&self, stream: &mut impl Write) -> Result<u64, PsbError> {
84 let len = self.vec.len() as u64;
85
86 let count_written = PsbNumber::write_uint(self.get_n(), len, stream)? as u64;
87
88 let n = self.get_item_n();
89
90 stream.write_u8(n + PSB_TYPE_INTEGER_ARRAY_N)?;
91
92 for num in self.vec.iter() {
93 PsbNumber::write_uint(n, *num, stream)?;
94 }
95
96 Ok(1 + count_written + n as u64 * len as u64)
97 }
98
99}
100
101impl From<Vec<u64>> for PsbUintArray {
102
103 fn from(vec: Vec<u64>) -> Self {
104 Self {
105 vec
106 }
107 }
108
109}
110
111impl Index<usize> for PsbUintArray {
112
113 type Output = u64;
114
115 fn index(&self, index: usize) -> &Self::Output {
116 &self.vec[index]
117 }
118}
119
120#[derive(Debug, PartialEq)]
121#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
122#[cfg_attr(feature = "serde", serde(transparent))]
123pub struct PsbList {
124
125 values: Vec<PsbValue>
126
127}
128
129impl PsbList {
130
131 pub fn new() -> Self {
132 Self {
133 values: Vec::new()
134 }
135 }
136
137 pub fn values(&self) -> &Vec<PsbValue> {
138 &self.values
139 }
140
141 pub fn len(&self) -> usize {
142 self.values.len()
143 }
144
145 pub fn iter(&self) -> Iter<'_, PsbValue> {
146 self.values.iter()
147 }
148
149 pub fn unwrap(self) -> Vec<PsbValue> {
150 self.values
151 }
152
153 pub fn from_bytes<T: Read + Seek>(stream: &mut T, table: &PsbRefs) -> Result<(u64, PsbList), PsbError> {
154 let (offsets_read, ref_offsets) = match PsbValue::from_bytes(stream)? {
155
156 (read, PsbValue::IntArray(array)) => Ok((read, array)),
157
158 _ => Err(PsbError::new(PsbErrorKind::InvalidOffsetTable, None))
159
160 }?;
161
162 if ref_offsets.len() < 1 {
163 return Ok((offsets_read, Self::new()));
164 }
165
166 let max_offset = ref_offsets.iter().max().unwrap();
167
168 let mut values = Vec::<PsbValue>::with_capacity(ref_offsets.len());
169
170 let start = stream.seek(SeekFrom::Current(0)).unwrap();
171 let mut total_read = 0_u64;
172
173 for offset in ref_offsets.iter() {
174 stream.seek(SeekFrom::Start(start + *offset as u64))?;
175 let (read, val) = PsbValue::from_bytes_refs(stream, table)?;
176
177 values.push(val);
178
179 if max_offset == offset {
180 total_read = read + *offset as u64;
181 }
182 }
183
184 stream.seek(SeekFrom::Start(start + total_read))?;
185
186 Ok((offsets_read + total_read, Self::from(values)))
187 }
188
189 pub fn write_bytes(&self, stream: &mut impl Write, table: &PsbRefs) -> Result<u64, PsbError> {
190 let mut value_offset_cache = HashMap::<u64, &PsbValue>::new();
191
192 let mut offsets = Vec::<u64>::new();
193 let mut data_buffer = Vec::<u8>::new();
194
195 let mut total_data_written = 0_u64;
196 for value in &self.values {
197 let mut cached = false;
198 for (offset, cache_value) in &value_offset_cache {
199 if value == *cache_value {
200 offsets.push(*offset);
201 cached = true;
202 break;
203 }
204 }
205
206 if !cached {
207 value_offset_cache.insert(total_data_written, &value);
208 offsets.push(total_data_written);
209
210 total_data_written += value.write_bytes_refs(&mut data_buffer, table)?;
211 }
212 }
213
214 let offset_written = PsbValue::IntArray(PsbUintArray::from(offsets)).write_bytes(stream)?;
215 stream.write_all(&data_buffer)?;
216
217 Ok(offset_written + total_data_written)
218 }
219
220 pub fn collect_strings(&self, vec: &mut Vec<String>) {
221 for child in self.values.iter() {
222 match child {
223
224 PsbValue::Object(child_obj) => {
225 child_obj.collect_strings(vec);
226 }
227
228 PsbValue::List(child_list) => {
229 child_list.collect_strings(vec);
230 }
231
232 PsbValue::String(string) => {
233 if !vec.contains(string.string()) {
234 vec.push(string.string().clone());
235 }
236 }
237
238 _ => {}
239 }
240
241 }
242 }
243
244 pub fn collect_names(&self, vec: &mut Vec<String>) {
245 for child in self.values.iter() {
246 match child {
247
248 PsbValue::Object(child_obj) => {
249 child_obj.collect_names(vec);
250 }
251
252 PsbValue::List(child_list) => {
253 child_list.collect_names(vec);
254 }
255
256 _ => {}
257 }
258
259 }
260 }
261
262}
263
264impl From<Vec<PsbValue>> for PsbList {
265
266 fn from(values: Vec<PsbValue>) -> Self {
267 Self {
268 values
269 }
270 }
271
272}
273
274#[derive(Debug, PartialEq)]
275#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
276#[cfg_attr(feature = "serde", serde(transparent))]
277pub struct PsbObject {
278
279 map: HashMap<String, PsbValue>
281
282}
283
284impl PsbObject {
285
286 pub fn new() -> Self {
287 Self {
288 map: HashMap::new()
289 }
290 }
291
292 pub fn len(&self) -> usize {
293 self.map.len()
294 }
295
296 pub fn get_value(&self, key: String) -> Option<&PsbValue> {
297 self.map.get(&key)
298 }
299
300 pub fn map(&self) -> &HashMap<String, PsbValue> {
301 &self.map
302 }
303
304 pub fn iter(&self) -> hash_map::Iter<'_, String, PsbValue>{
305 self.map.iter()
306 }
307
308 pub fn unwrap(self) -> HashMap<String, PsbValue> {
309 self.map
310 }
311
312 pub fn from_bytes<T: Read + Seek>(stream: &mut T, table: &PsbRefs) -> Result<(u64, PsbObject), PsbError> {
313 let (names_read, name_refs) = match PsbValue::from_bytes(stream)? {
314
315 (read, PsbValue::IntArray(array)) => Ok((read, array)),
316
317 _ => Err(PsbError::new(PsbErrorKind::InvalidOffsetTable, None))
318
319 }?;
320
321 let (offsets_read, ref_offsets) = match PsbValue::from_bytes(stream)? {
322
323 (read, PsbValue::IntArray(array)) => Ok((read, array)),
324
325 _ => Err(PsbError::new(PsbErrorKind::InvalidOffsetTable, None))
326
327 }?;
328
329 if name_refs.len() < 1 {
330 return Ok((names_read + offsets_read, Self::new()));
331 }
332
333 let max_offset = ref_offsets.iter().max().unwrap();
334
335 let mut map = HashMap::<String, PsbValue>::new();
336
337 let start = stream.seek(SeekFrom::Current(0)).unwrap();
338 let mut total_read = 0_u64;
339
340 for (name_ref, offset) in name_refs.iter().zip(ref_offsets.iter()) {
341 stream.seek(SeekFrom::Start(start + *offset as u64))?;
342 let (read, val) = PsbValue::from_bytes_refs(stream, table)?;
343
344 let key = table.names().get(*name_ref as usize);
345
346 if key.is_none() {
347 return Err(PsbError::new(PsbErrorKind::InvalidOffsetTable, None));
348 }
349
350 map.insert(key.unwrap().clone(), val);
351
352 if *max_offset == *offset {
353 total_read = read + *offset as u64;
354 }
355 }
356
357 stream.seek(SeekFrom::Start(start + total_read))?;
358
359 Ok((names_read + offsets_read + total_read, Self::from(map)))
360 }
361
362 pub fn write_bytes(&self, stream: &mut impl Write, ref_table: &PsbRefs) -> Result<u64, PsbError> {
363 let mut value_offset_cache = HashMap::<u64, &PsbValue>::new();
364
365 let mut ref_cache = HashMap::<&String, u64>::new();
366
367 let mut name_refs = Vec::<u64>::new();
368 let mut offsets = Vec::<u64>::new();
369 let mut data_buffer = Vec::<u8>::new();
370
371 let mut total_data_written = 0_u64;
372
373 for name in self.map.keys().into_iter().sorted() {
374 let value = self.map.get(name).unwrap();
375
376 let name_ref = if ref_cache.contains_key(name) {
377 *ref_cache.get(name).unwrap()
378 } else {
379 match ref_table.find_name_index(name) {
380 Some(index) => {
381 ref_cache.insert(name, index);
382
383 Ok(index)
384 },
385
386 None => Err(PsbError::new(PsbErrorKind::InvalidOffsetTable, None))
387 }?
388 };
389
390 name_refs.push(name_ref);
391
392 let mut cached = false;
393 for (offset, cache_value) in value_offset_cache.iter() {
394 if value == *cache_value {
395 offsets.push(*offset);
396 cached = true;
397 break;
398 }
399 }
400
401 if !cached {
402 value_offset_cache.insert(total_data_written, &value);
403 offsets.push(total_data_written);
404
405 total_data_written += value.write_bytes_refs(&mut data_buffer, ref_table)?;
406 }
407 }
408
409 let names_written = PsbValue::IntArray(PsbUintArray::from(name_refs)).write_bytes(stream)?;
410 let offset_written = PsbValue::IntArray(PsbUintArray::from(offsets)).write_bytes(stream)?;
411
412 stream.write_all(&data_buffer)?;
413
414 Ok(names_written + offset_written + total_data_written as u64)
415 }
416
417 pub fn collect_names(&self, vec: &mut Vec<String>) {
418 for (name, child) in self.map.iter() {
419 match child {
420
421 PsbValue::Object(child_obj) => {
422 child_obj.collect_names(vec);
423 }
424
425 PsbValue::List(child_list) => {
426 child_list.collect_names(vec);
427 }
428
429 _ => {}
430 }
431
432 if !vec.contains(&name) {
433 vec.push(name.clone());
434 }
435 }
436 }
437
438 pub fn collect_strings(&self, vec: &mut Vec<String>) {
439 for (_, child) in self.map.iter() {
440 match child {
441
442 PsbValue::Object(child_obj) => {
443 child_obj.collect_strings(vec);
444 }
445
446 PsbValue::List(child_list) => {
447 child_list.collect_strings(vec);
448 }
449
450 PsbValue::String(string) => {
451 if !vec.contains(string.string()) {
452 vec.push(string.string().clone());
453 }
454 }
455
456 _ => {}
457 }
458
459 }
460 }
461
462}
463
464impl From<HashMap<String, PsbValue>> for PsbObject {
465
466 fn from(map: HashMap<String, PsbValue>) -> Self {
467 Self {
468 map
469 }
470 }
471
472}