rpfm_lib/files/asset_variation_db/
v1.rs1use crate::binary::{ReadBytes, WriteBytes};
12use crate::files::{DecodeableExtraData, Decodeable, EncodeableExtraData, Encodeable};
13use crate::utils::check_size_mismatch;
14
15use super::*;
16
17const RECORD_VERSION: u16 = 1;
19
20impl Decodeable for AssetVariationDb {
25
26 fn decode<R: ReadBytes>(data: &mut R, _extra_data: &Option<DecodeableExtraData>) -> Result<Self> {
27 let signature_bytes = data.read_slice(8, false)?;
28 if signature_bytes.as_slice() != SIGNATURE {
29 return Err(RLibError::DecodingFastBinUnsupportedSignature(signature_bytes));
30 }
31
32 let mut db = Self {
33 serialise_version: data.read_u16()?,
34 ..Default::default()
35 };
36
37 if db.serialise_version != 1 {
38 return Err(RLibError::DecodingFastBinUnsupportedVersion(String::from("AssetVariationDb"), db.serialise_version));
39 }
40
41 let category_count = data.read_u32()?;
42 db.categories = Vec::with_capacity(category_count as usize);
43 for _ in 0..category_count {
44 read_record_version(data, "VariationCategory")?;
45
46 let name = data.read_sized_string_u8()?;
47 let value_count = data.read_u32()?;
48 let values = (0..value_count).map(|_| data.read_sized_string_u8()).collect::<Result<_>>()?;
49 db.categories.push(VariationCategory { name, values });
50 }
51
52 let entry_count = data.read_u32()?;
53 db.entries = Vec::with_capacity(entry_count as usize);
54 for _ in 0..entry_count {
55 let key = data.read_sized_string_u8()?;
56 read_record_version(data, "VariationEntry")?;
57
58 let variation_count = data.read_u32()?;
59 let mut variations = Vec::with_capacity(variation_count as usize);
60 for _ in 0..variation_count {
61 read_record_version(data, "Variation")?;
62 variations.push(Variation {
63 filename: data.read_sized_string_u8()?,
64 flags: data.read_u32()?,
65 });
66 }
67
68 db.entries.push(VariationEntry { key, variations });
69 }
70
71 check_size_mismatch(data.stream_position()? as usize, data.len()? as usize)?;
72
73 Ok(db)
74 }
75}
76
77impl Encodeable for AssetVariationDb {
78
79 fn encode<W: WriteBytes>(&mut self, buffer: &mut W, _extra_data: &Option<EncodeableExtraData>) -> Result<()> {
80 if self.serialise_version != 1 {
81 return Err(RLibError::EncodingFastBinUnsupportedVersion(String::from("AssetVariationDb"), self.serialise_version));
82 }
83
84 buffer.write_all(SIGNATURE)?;
85 buffer.write_u16(self.serialise_version)?;
86
87 buffer.write_u32(self.categories.len() as u32)?;
88 for category in &self.categories {
89 buffer.write_u16(RECORD_VERSION)?;
90 buffer.write_sized_string_u8(&category.name)?;
91 buffer.write_u32(category.values.len() as u32)?;
92 for value in &category.values {
93 buffer.write_sized_string_u8(value)?;
94 }
95 }
96
97 buffer.write_u32(self.entries.len() as u32)?;
98 for entry in &self.entries {
99 buffer.write_sized_string_u8(&entry.key)?;
100 buffer.write_u16(RECORD_VERSION)?;
101 buffer.write_u32(entry.variations.len() as u32)?;
102 for variation in &entry.variations {
103 buffer.write_u16(RECORD_VERSION)?;
104 buffer.write_sized_string_u8(&variation.filename)?;
105 buffer.write_u32(variation.flags)?;
106 }
107 }
108
109 Ok(())
110 }
111}
112
113fn read_record_version<R: ReadBytes>(data: &mut R, record: &str) -> Result<()> {
115 let version = data.read_u16()?;
116 if version != RECORD_VERSION {
117 return Err(RLibError::DecodingFastBinUnsupportedVersion(record.to_owned(), version));
118 }
119
120 Ok(())
121}