io_unity/serialized_file/
version10.rs1use super::version13::path_id_parser;
2use super::version17::{FileIdentifier, TypeTree, TypeTreeNode};
3use super::{BuildTarget, SerializedFileCommonHeader};
4use super::{Serialized, SerializedFileFormatVersion};
5use crate::type_tree::{reader::TypeTreeObjectBinReadClassArgs, TypeField};
6use crate::until::Endian;
7use binrw::io::Cursor;
8use binrw::{binrw, NullString};
9use std::borrow::Cow;
10use std::sync::Arc;
11
12#[binrw]
13#[brw(big)]
14#[derive(Debug, PartialEq)]
15pub struct SerializedFile {
16 header: SerializedFileCommonHeader,
17 endianess: Endian,
18 reserved: [u8; 3],
19 #[br(is_little = endianess == Endian::Little)]
20 content: SerializedFileContent,
21}
22
23impl Serialized for SerializedFile {
24 fn get_serialized_file_version(&self) -> &SerializedFileFormatVersion {
25 &self.header.version
26 }
27
28 fn get_data_offset(&self) -> u64 {
29 self.header.data_offset as u64
30 }
31
32 fn get_endianess(&self) -> &Endian {
33 &self.endianess
34 }
35
36 fn get_objects_metadata(&self) -> Vec<super::Object> {
37 self.content
38 .objects
39 .iter()
40 .map(|obj| super::Object {
41 path_id: obj.path_id,
42 byte_start: obj.byte_start as u64,
43 byte_size: obj.byte_size,
44 class: obj.class_id as i32,
45 type_id: obj.type_id as usize,
46 })
47 .collect()
48 }
49
50 fn get_unity_version(&self) -> String {
51 self.content.unity_version.to_string()
52 }
53
54 fn get_target_platform(&self) -> &BuildTarget {
55 &self.content.target_platform
56 }
57
58 fn get_enable_type_tree(&self) -> bool {
59 true
60 }
61
62 fn get_type_object_args_by_type_id(
63 &self,
64 type_id: usize,
65 ) -> Option<TypeTreeObjectBinReadClassArgs> {
66 let stypetree = self
67 .content
68 .types
69 .iter()
70 .find(|tp| tp.class_id == type_id as i32)?;
71 let type_tree = &stypetree.type_tree;
72 let mut type_fields = Vec::new();
73 let mut string_reader = Cursor::new(&type_tree.string_buffer);
74
75 for tp in &type_tree.type_tree_node_blobs {
76 type_fields.push(Arc::new(Box::new(TypeTreeNode {
77 name: tp.get_name_str(&mut string_reader),
78 type_name: tp.get_type_str(&mut string_reader),
79 node: tp.clone(),
80 }) as Box<dyn TypeField + Send + Sync>))
81 }
82
83 Some(TypeTreeObjectBinReadClassArgs::new(
84 stypetree.class_id,
85 type_fields,
86 ))
87 }
88 fn get_externals(&self) -> Cow<Vec<FileIdentifier>> {
89 return Cow::Borrowed(&self.content.externals);
90 }
91}
92
93#[binrw]
94#[derive(Debug, PartialEq)]
95struct SerializedFileContent {
96 unity_version: NullString,
97 target_platform: BuildTarget,
98 type_count: u32,
99 #[br(count = type_count)]
100 types: Vec<SerializedType>,
101 big_id_enabled: i32,
102 object_count: i32,
103 #[br(args { count: object_count as usize, inner: ObjectBinReadArgs::builder().big_id_enabled(big_id_enabled != 0).finalize() })]
104 objects: Vec<Object>,
105 externals_count: i32,
106 #[br(count = externals_count)]
107 externals: Vec<FileIdentifier>,
108 user_information: NullString,
109}
110
111#[binrw]
112#[derive(Debug, PartialEq)]
113pub struct SerializedType {
114 pub class_id: i32,
115 pub type_tree: TypeTree,
116}
117
118#[binrw]
119#[br(import { big_id_enabled: bool})]
120#[derive(Debug, PartialEq)]
121pub struct Object {
122 #[br(parse_with = path_id_parser, args (big_id_enabled))]
123 pub path_id: i64,
124 pub byte_start: u32,
125 pub byte_size: u32,
126 pub type_id: i32,
127 pub class_id: u16,
128 pub is_destroyed: u16,
129}