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}