uasset/
serialization.rs

1#![allow(dead_code)]
2
3use crate::{
4    archive::{SerializedFlags, SerializedObjectVersion},
5    ObjectVersion, ObjectVersionUE5, Result,
6};
7use binread::BinReaderExt;
8use std::io::{Read, Seek, SeekFrom};
9
10mod implementations;
11pub use implementations::*;
12
13pub trait ReadInfo
14where
15    Self: Sized,
16{
17    fn get_count(&self) -> u64;
18
19    fn from_current_position<R>(reader: &mut R) -> Result<Self>
20    where
21        R: Seek + Read + BinReaderExt;
22}
23
24pub trait StreamInfo
25where
26    Self: Sized,
27{
28    type ReadInfoType: ReadInfo;
29
30    fn get_offset(&self) -> u64;
31
32    fn from_current_position<R>(reader: &mut R) -> Result<Self>
33    where
34        R: Seek + Read + BinReaderExt;
35
36    fn from_indirect_reference<R>(reader: &mut R) -> Result<Self>
37    where
38        R: Read + BinReaderExt;
39
40    fn to_read_info(&self) -> Self::ReadInfoType;
41}
42
43pub trait Deferrable {
44    type StreamInfoType: StreamInfo;
45}
46
47pub trait Parseable: Deferrable
48where
49    Self: Sized,
50{
51    type ParsedType: Sized;
52
53    fn parse_with_info_seekless<R>(
54        reader: &mut R,
55        read_info: &<Self::StreamInfoType as StreamInfo>::ReadInfoType,
56    ) -> Result<Self::ParsedType>
57    where
58        R: Seek
59            + Read
60            + SerializedObjectVersion<ObjectVersion>
61            + SerializedObjectVersion<ObjectVersionUE5>
62            + SerializedFlags;
63
64    fn parse_with_info<R>(
65        reader: &mut R,
66        stream_info: &Self::StreamInfoType,
67    ) -> Result<Self::ParsedType>
68    where
69        R: Seek
70            + Read
71            + SerializedObjectVersion<ObjectVersion>
72            + SerializedObjectVersion<ObjectVersionUE5>
73            + SerializedFlags,
74    {
75        reader.seek(SeekFrom::Start(stream_info.get_offset()))?;
76        Self::parse_with_info_seekless(reader, &stream_info.to_read_info())
77    }
78
79    fn parse_inline<R>(reader: &mut R) -> Result<Self::ParsedType>
80    where
81        R: Seek
82            + Read
83            + SerializedObjectVersion<ObjectVersion>
84            + SerializedObjectVersion<ObjectVersionUE5>
85            + SerializedFlags,
86    {
87        let read_info =
88            <Self::StreamInfoType as StreamInfo>::ReadInfoType::from_current_position(reader)?;
89        Self::parse_with_info_seekless(reader, &read_info)
90    }
91
92    fn parse_indirect<R>(reader: &mut R) -> Result<Self::ParsedType>
93    where
94        R: Seek
95            + Read
96            + SerializedObjectVersion<ObjectVersion>
97            + SerializedObjectVersion<ObjectVersionUE5>
98            + SerializedFlags,
99    {
100        let stream_info = Self::StreamInfoType::from_indirect_reference(reader)?;
101        let current_position = reader.stream_position()?;
102        let obj = Self::parse_with_info(reader, &stream_info)?;
103        reader.seek(SeekFrom::Start(current_position))?;
104        Ok(obj)
105    }
106}
107
108pub trait Skippable: Deferrable {
109    fn seek_past_with_info<R>(reader: &mut R, stream_info: &Self::StreamInfoType) -> Result<()>
110    where
111        R: Seek + Read;
112
113    fn seek_past<R>(reader: &mut R) -> Result<()>
114    where
115        R: Seek + Read,
116    {
117        let stream_info = Self::StreamInfoType::from_current_position(reader)?;
118        Self::seek_past_with_info(reader, &stream_info)?;
119        Ok(())
120    }
121}
122
123#[derive(Debug)]
124pub struct SingleItemReadInfo {}
125
126impl ReadInfo for SingleItemReadInfo {
127    fn get_count(&self) -> u64 {
128        1
129    }
130
131    fn from_current_position<R>(_reader: &mut R) -> Result<Self> {
132        Ok(Self {})
133    }
134}
135
136#[derive(Debug)]
137pub struct SingleItemStreamInfo {
138    pub offset: u64,
139}
140
141impl StreamInfo for SingleItemStreamInfo {
142    type ReadInfoType = SingleItemReadInfo;
143
144    fn get_offset(&self) -> u64 {
145        self.offset
146    }
147
148    fn from_current_position<R>(reader: &mut R) -> Result<Self>
149    where
150        R: Read + Seek,
151    {
152        Ok(Self {
153            offset: reader.stream_position()?,
154        })
155    }
156
157    fn from_indirect_reference<R>(reader: &mut R) -> Result<Self>
158    where
159        R: Read + BinReaderExt,
160    {
161        let offset: i32 = reader.read_le()?;
162        Ok(Self {
163            offset: offset as u64,
164        })
165    }
166
167    fn to_read_info(&self) -> Self::ReadInfoType {
168        Self::ReadInfoType {}
169    }
170}
171
172impl SingleItemStreamInfo {
173    pub fn from_stream<R>(reader: &mut R) -> Result<Self>
174    where
175        R: Seek,
176    {
177        Ok(SingleItemStreamInfo {
178            offset: reader.stream_position()?,
179        })
180    }
181}
182
183#[derive(Debug)]
184pub struct ArrayReadInfo {
185    pub count: u64,
186}
187
188impl ReadInfo for ArrayReadInfo {
189    fn get_count(&self) -> u64 {
190        self.count
191    }
192
193    fn from_current_position<R>(reader: &mut R) -> Result<Self>
194    where
195        R: Seek + Read + BinReaderExt,
196    {
197        let count: i32 = reader.read_le()?;
198        Ok(Self {
199            count: count as u64,
200        })
201    }
202}
203
204#[derive(Debug, Clone)]
205pub struct ArrayStreamInfo {
206    pub offset: u64,
207    pub count: u64,
208}
209
210impl StreamInfo for ArrayStreamInfo {
211    type ReadInfoType = ArrayReadInfo;
212
213    fn get_offset(&self) -> u64 {
214        self.offset
215    }
216
217    fn from_current_position<R>(reader: &mut R) -> Result<Self>
218    where
219        R: Seek + Read + BinReaderExt,
220    {
221        let count: i32 = reader.read_le()?;
222        Ok(Self {
223            offset: reader.stream_position()?,
224            count: count as u64,
225        })
226    }
227
228    fn from_indirect_reference<R>(reader: &mut R) -> Result<Self>
229    where
230        R: Read + BinReaderExt,
231    {
232        let count: i32 = reader.read_le()?;
233        let offset: i32 = reader.read_le()?;
234        Ok(Self {
235            offset: offset as u64,
236            count: count as u64,
237        })
238    }
239
240    fn to_read_info(&self) -> Self::ReadInfoType {
241        Self::ReadInfoType { count: self.count }
242    }
243}