flash_lso/amf0/writer/
array_writer.rs1use crate::amf0::writer::strict_array_writer::StrictArrayWriter;
2use crate::types::{ECMAArrayObjectValue, Element, ObjectId, Reference, Value};
3
4use super::{CacheKey, ObjWriter, ObjectWriter, TypedObjectWriter};
5
6pub struct ArrayWriter<'a, 'b> {
8 pub(crate) elements: Vec<Element>,
10
11 pub(crate) parent: &'a mut dyn ObjWriter<'b>,
13}
14
15impl<'a> ObjWriter<'a> for ArrayWriter<'a, '_> {
16 fn add_element(&mut self, name: &str, s: Value, inc_ref: bool) {
17 if inc_ref {
18 self.make_reference();
19 }
20
21 self.elements.push(Element::new(name.to_string(), s));
22 }
23
24 fn object<'c: 'a, 'd>(
25 &'d mut self,
26 cache_key: CacheKey,
27 ) -> (Option<ObjectWriter<'d, 'c>>, Reference)
28 where
29 'a: 'c,
30 'a: 'd,
31 {
32 if let Some(existing_ref) = self.cache_get(&cache_key) {
33 (None, existing_ref)
34 } else {
35 let r = self.make_reference();
36
37 self.cache_add(cache_key, r);
39
40 (
42 Some(ObjectWriter {
43 elements: Vec::new(),
44 parent: self,
45 }),
46 r,
47 )
48 }
49 }
50
51 fn array<'c: 'a, 'd>(
52 &'d mut self,
53 cache_key: CacheKey,
54 ) -> (Option<ArrayWriter<'d, 'c>>, Reference)
55 where
56 'a: 'c,
57 'a: 'd,
58 {
59 if let Some(existing_ref) = self.cache_get(&cache_key) {
60 (None, existing_ref)
61 } else {
62 let r = self.make_reference();
63
64 self.cache_add(cache_key, r);
66
67 (
69 Some(ArrayWriter {
70 elements: Vec::new(),
71 parent: self,
72 }),
73 r,
74 )
75 }
76 }
77
78 fn strict_array<'c: 'a, 'd>(
79 &'d mut self,
80 cache_key: CacheKey,
81 ) -> (Option<StrictArrayWriter<'d, 'c>>, Reference)
82 where
83 'a: 'c,
84 'a: 'd,
85 {
86 if let Some(existing_ref) = self.cache_get(&cache_key) {
87 (None, existing_ref)
88 } else {
89 let r = self.make_reference();
90
91 self.cache_add(cache_key, r);
93
94 (
96 Some(StrictArrayWriter {
97 values: Vec::new(),
98 parent: self,
99 }),
100 r,
101 )
102 }
103 }
104
105 fn typed_object<'c: 'a, 'd>(
106 &'d mut self,
107 class_name: &str,
108 cache_key: CacheKey,
109 ) -> (Option<TypedObjectWriter<'d, 'c>>, Reference)
110 where
111 'a: 'c,
112 'a: 'd,
113 {
114 if let Some(existing_ref) = self.cache_get(&cache_key) {
115 (None, existing_ref)
116 } else {
117 let r = self.make_reference();
118
119 self.cache_add(cache_key, r);
121
122 (
124 Some(TypedObjectWriter {
125 class_name: class_name.to_string(),
126 elements: Vec::new(),
127 parent: self,
128 }),
129 r,
130 )
131 }
132 }
133
134 fn make_reference(&mut self) -> Reference {
135 self.parent.make_reference()
136 }
137
138 fn cache_get(&mut self, cache_key: &CacheKey) -> Option<Reference> {
139 self.parent.cache_get(cache_key)
140 }
141
142 fn cache_add(&mut self, cache_key: CacheKey, reference: Reference) {
143 self.parent.cache_add(cache_key, reference);
144 }
145}
146
147impl ArrayWriter<'_, '_> {
148 pub fn commit<T: AsRef<str>>(self, name: T, length: u32) {
151 self.parent.add_element(
152 name.as_ref(),
153 Value::ECMAArray {
154 id: ObjectId::INVALID,
155 data: ECMAArrayObjectValue {
156 dense: Vec::new(),
157 elements: self.elements,
158 length,
159 },
160 },
161 false,
162 );
163 }
164}