1use crate::constants;
2
3#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5#[derive(Debug, Clone)]
6pub struct SerializationStream {
7 pub version: u16,
8 pub contents: Vec<ContentElement>,
9}
10
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13#[derive(Debug, Clone)]
14pub enum ContentElement {
15 Object(StreamObject),
16 BlockData(BlockData),
17}
18
19#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
21#[derive(Debug, Clone)]
22pub enum StreamObject {
23 NewObject(NewObject),
24 NewClass(NewClass),
25 NewArray(NewArray),
26 NewString(StreamString),
27 NewEnum(NewEnum),
28 NewClassDesc(ClassDesc),
29 PrevObject { handle: u32 },
30 NullReference,
31 Exception,
32 Reset,
33}
34
35#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
37#[derive(Debug, Clone)]
38pub struct NewObject {
39 pub class_desc: ClassDescRef,
40 pub handle: u32,
41 pub class_data: Vec<ClassData>,
42}
43
44#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
46#[derive(Debug, Clone)]
47pub struct NewClass {
48 pub class_desc: ClassDescRef,
49 pub handle: u32,
50}
51
52#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
54#[derive(Debug, Clone)]
55pub struct NewArray {
56 pub class_desc: ClassDescRef,
57 pub handle: u32,
58 pub size: u32,
59 pub values: ArrayValues,
60}
61
62#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
64#[derive(Debug, Clone)]
65pub enum ArrayValues {
66 Byte(Vec<i8>),
67 Char(Vec<u16>),
68 Double(Vec<f64>),
69 Float(Vec<f32>),
70 Int(Vec<i32>),
71 Long(Vec<i64>),
72 Short(Vec<i16>),
73 Boolean(Vec<u8>),
74 Object(Vec<Option<StreamObject>>),
75}
76
77#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
79#[derive(Debug, Clone)]
80pub struct StreamString {
81 pub value: String,
82 pub handle: u32,
83 pub is_long: bool,
84}
85
86#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
88#[derive(Debug, Clone)]
89pub struct NewEnum {
90 pub class_desc: ClassDescRef,
91 pub handle: u32,
92 pub constant_name: StreamString,
93}
94
95#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
97#[derive(Debug, Clone)]
98pub enum ClassDescRef {
99 Inline(Box<ClassDesc>),
101 Null,
103 Reference { handle: u32 },
105}
106
107#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
109#[derive(Debug, Clone)]
110pub enum ClassDesc {
111 Normal(Box<NormalClassDesc>),
112 Proxy(ProxyClassDesc),
113}
114
115#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
117#[derive(Debug, Clone)]
118pub struct NormalClassDesc {
119 pub class_name: String,
120 pub serial_version_uid: i64,
121 pub handle: u32,
122 pub flags: u8,
123 pub fields: Vec<FieldDesc>,
124 pub class_annotation: Vec<AnnotationElement>,
125 pub super_class_desc: Box<ClassDescRef>,
126}
127
128#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
130#[derive(Debug, Clone)]
131pub struct ProxyClassDesc {
132 pub handle: u32,
133 pub interface_names: Vec<String>,
134 pub class_annotation: Vec<AnnotationElement>,
135 pub super_class_desc: Box<ClassDescRef>,
136}
137
138#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
140#[derive(Debug, Clone)]
141pub enum FieldDesc {
142 Primitive(PrimitiveFieldDesc),
143 Object(ObjectFieldDesc),
144}
145
146#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
148#[derive(Debug, Clone)]
149pub struct PrimitiveFieldDesc {
150 pub type_code: u8,
151 pub field_name: String,
152}
153
154#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
156#[derive(Debug, Clone)]
157pub struct ObjectFieldDesc {
158 pub type_code: u8,
159 pub field_name: String,
160 pub class_name: String,
161}
162
163#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
165#[derive(Debug, Clone)]
166pub enum AnnotationElement {
167 Object(StreamObject),
168 BlockData(BlockData),
169}
170
171#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
173#[derive(Debug, Clone)]
174pub enum BlockData {
175 Short { data: Vec<u8> },
176 Long { data: Vec<u8> },
177}
178
179#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
181#[derive(Debug, Clone)]
182pub enum ClassData {
183 NoWriteMethod(FieldValueSet),
185 WriteMethodWithFields(FieldValueSet, ObjectAnnotation),
188 WriteMethod(ObjectAnnotation),
191 ExternalContents(Vec<u8>),
193 ExternalBlockData(ObjectAnnotation),
195}
196
197#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
199#[derive(Debug, Clone)]
200pub struct FieldValueSet {
201 pub values: Vec<FieldValue>,
202}
203
204#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
206#[derive(Debug, Clone)]
207pub enum FieldValue {
208 Byte(i8),
209 Char(u16),
210 Double(f64),
211 Float(f32),
212 Int(i32),
213 Long(i64),
214 Short(i16),
215 Boolean(bool),
216 Object(Option<Box<StreamObject>>),
217}
218
219#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
221#[derive(Debug, Clone)]
222pub struct ObjectAnnotation {
223 pub contents: Vec<AnnotationElement>,
224}
225
226impl NormalClassDesc {
227 pub fn has_write_method(&self) -> bool {
228 self.flags & constants::SC_WRITE_METHOD != 0
229 }
230
231 pub fn is_serializable(&self) -> bool {
232 self.flags & constants::SC_SERIALIZABLE != 0
233 }
234
235 pub fn is_externalizable(&self) -> bool {
236 self.flags & constants::SC_EXTERNALIZABLE != 0
237 }
238
239 pub fn has_block_data(&self) -> bool {
240 self.flags & constants::SC_BLOCK_DATA != 0
241 }
242
243 pub fn is_enum(&self) -> bool {
244 self.flags & constants::SC_ENUM != 0
245 }
246}
247
248impl BlockData {
249 pub fn data(&self) -> &[u8] {
251 match self {
252 BlockData::Short { data } => data,
253 BlockData::Long { data } => data,
254 }
255 }
256}
257
258impl ClassDescRef {
259 pub fn class_name(&self) -> Option<&str> {
262 match self {
263 ClassDescRef::Inline(cd) => cd.class_name(),
264 ClassDescRef::Null => None,
265 ClassDescRef::Reference { .. } => None,
266 }
267 }
268}
269
270impl ClassDesc {
271 pub fn class_name(&self) -> Option<&str> {
273 match self {
274 ClassDesc::Normal(desc) => Some(&desc.class_name),
275 ClassDesc::Proxy(_) => None,
276 }
277 }
278}
279
280impl NewObject {
281 pub fn class_name(&self) -> Option<&str> {
283 self.class_desc.class_name()
284 }
285}
286
287impl NewArray {
288 pub fn class_name(&self) -> Option<&str> {
290 self.class_desc.class_name()
291 }
292}
293
294impl StreamObject {
295 pub fn handle(&self) -> Option<u32> {
297 match self {
298 StreamObject::NewObject(o) => Some(o.handle),
299 StreamObject::NewClass(c) => Some(c.handle),
300 StreamObject::NewArray(a) => Some(a.handle),
301 StreamObject::NewString(s) => Some(s.handle),
302 StreamObject::NewEnum(e) => Some(e.handle),
303 StreamObject::NewClassDesc(ClassDesc::Normal(d)) => Some(d.handle),
304 StreamObject::NewClassDesc(ClassDesc::Proxy(d)) => Some(d.handle),
305 StreamObject::PrevObject { handle } => Some(*handle),
306 StreamObject::NullReference | StreamObject::Exception | StreamObject::Reset => None,
307 }
308 }
309}
310
311impl SerializationStream {
312 pub fn objects(&self) -> impl Iterator<Item = &StreamObject> {
314 self.contents.iter().filter_map(|c| match c {
315 ContentElement::Object(obj) => Some(obj),
316 ContentElement::BlockData(_) => None,
317 })
318 }
319}