1use fidl_constants::{ALLOC_ABSENT_U64, ALLOC_PRESENT_U64};
11
12#[derive(Default)]
14pub struct Structure {
15 fields: Vec<Field>,
16}
17
18impl Structure {
19 fn alignment(&self) -> usize {
20 let mut alignment = 1;
21 for field in &self.fields {
22 if field.alignment() > alignment {
23 alignment = field.alignment();
24 }
25 }
26 alignment
27 }
28
29 pub fn field(mut self, field: Field) -> Self {
31 self.fields.push(field);
32 self
33 }
34
35 pub fn encode_persistent(&self) -> Vec<u8> {
39 let mut buf = Vec::new();
40
41 buf.push(0); buf.push(1); buf.extend(2u16.to_le_bytes()); buf.extend([0; 4]); self.encode(&mut buf);
49
50 buf
51 }
52
53 pub fn encode(&self, buf: &mut Vec<u8>) {
55 self.encode_inline(buf);
56 buf.pad_to(8);
59 }
60
61 pub fn encode_inline(&self, buf: &mut Vec<u8>) {
62 self.encode_fields(buf);
63 }
64
65 pub fn encode_fields(&self, buf: &mut Vec<u8>) {
66 if self.fields.is_empty() {
68 BasicField::UInt8(0).encode_inline(buf);
74 } else {
75 for field in &self.fields {
77 field.encode_inline(buf);
78 }
79
80 for field in &self.fields {
81 field.encode_out_of_line(buf);
82 }
83 buf.pad_to(self.alignment());
84 }
85 }
86}
87
88#[derive(Default)]
90pub struct Box {
91 inner: Option<Structure>,
92}
93
94impl Box {
95 pub fn set_present(self) -> Self {
96 Box {
97 inner: match self.inner {
98 Some(s) => Some(s),
99 None => Some(Structure::default()),
100 },
101 }
102 }
103 pub fn field(mut self, field: Field) -> Self {
105 self.inner = match self.inner {
106 Some(s) => Some(s.field(field)),
107 None => Some(Structure::default().field(field)),
108 };
109 self
110 }
111
112 fn alignment(&self) -> usize {
113 8
114 }
115
116 fn encode_inline(&self, buf: &mut Vec<u8>) {
117 match &self.inner {
121 None => buf.extend(ALLOC_ABSENT_U64.to_le_bytes()),
122 Some(_) => buf.extend(ALLOC_PRESENT_U64.to_le_bytes()),
123 }
124 }
125
126 fn encode_out_of_line(&self, buf: &mut Vec<u8>) {
127 match &self.inner {
128 None => (),
129 Some(s) => s.encode_fields(buf),
130 }
131 }
132}
133
134pub enum Field {
136 Basic(BasicField),
137 Vector(VectorField),
138 Struct(Structure),
139 Box(Box),
140}
141
142impl Field {
143 fn alignment(&self) -> usize {
144 match self {
145 Self::Basic(b) => b.alignment(),
146 Self::Vector(l) => l.alignment(),
147 Self::Struct(s) => s.alignment(),
148 Self::Box(s) => s.alignment(),
149 }
150 }
151
152 fn encode_inline(&self, buf: &mut Vec<u8>) {
153 buf.pad_to(self.alignment());
154 match self {
155 Self::Basic(b) => b.encode_inline(buf),
156 Self::Vector(l) => l.encode_inline(buf),
157 Self::Struct(s) => s.encode_inline(buf),
158 Self::Box(s) => s.encode_inline(buf),
159 }
160 }
161
162 fn encode_out_of_line(&self, buf: &mut Vec<u8>) {
163 match self {
164 Self::Basic(_) => (),
165 Self::Vector(l) => {
166 buf.pad_to(8);
168 l.encode_out_of_line(buf);
169 }
170 Self::Struct(_) => (),
171 Self::Box(s) => {
172 buf.pad_to(8);
174 s.encode_out_of_line(buf)
175 }
176 }
177 }
178}
179
180pub enum BasicField {
181 Bool(bool),
182 UInt8(u8),
183 UInt16(u16),
184 UInt32(u32),
185 UInt64(u64),
186 Int8(i8),
187 Int16(i16),
188 Int32(i32),
189 Int64(i64),
190}
191
192impl BasicField {
193 fn encode_inline(&self, buf: &mut Vec<u8>) {
194 match self {
195 Self::Bool(b) => buf.push(if *b { 1u8 } else { 0u8 }),
196 Self::UInt8(n) => buf.push(*n),
197 Self::UInt16(n) => buf.extend(n.to_le_bytes()),
198 Self::UInt32(n) => buf.extend(n.to_le_bytes()),
199 Self::UInt64(n) => buf.extend(n.to_le_bytes()),
200 Self::Int8(n) => buf.extend(n.to_le_bytes()),
201 Self::Int16(n) => buf.extend(n.to_le_bytes()),
202 Self::Int32(n) => buf.extend(n.to_le_bytes()),
203 Self::Int64(n) => buf.extend(n.to_le_bytes()),
204 }
205 }
206
207 fn alignment(&self) -> usize {
208 match self {
209 Self::Bool(_) | Self::UInt8(_) | Self::Int8(_) => 1,
210 Self::UInt16(_) | Self::Int16(_) => 2,
211 Self::UInt32(_) | Self::Int32(_) => 4,
212 _ => 8,
213 }
214 }
215}
216
217pub enum VectorField {
218 Null,
220 BoolVector(Vec<bool>),
221 UInt8Vector(Vec<u8>),
222 UInt16Vector(Vec<u16>),
223 UInt32Vector(Vec<u32>),
224 UInt64Vector(Vec<u64>),
225 Int8Vector(Vec<i8>),
226 Int16Vector(Vec<i16>),
227 Int32Vector(Vec<i32>),
228 Int64Vector(Vec<i64>),
229 UInt8VectorVector(Vec<Vec<u8>>),
231}
232
233impl VectorField {
234 fn alignment(&self) -> usize {
235 8
236 }
237
238 fn encode_inline(&self, buf: &mut Vec<u8>) {
239 let size = match self {
243 Self::Null => 0,
244 Self::BoolVector(v) => v.len(),
245 Self::UInt8Vector(v) => v.len(),
246 Self::UInt16Vector(v) => v.len(),
247 Self::UInt32Vector(v) => v.len(),
248 Self::UInt64Vector(v) => v.len(),
249 Self::Int8Vector(v) => v.len(),
250 Self::Int16Vector(v) => v.len(),
251 Self::Int32Vector(v) => v.len(),
252 Self::Int64Vector(v) => v.len(),
253 Self::UInt8VectorVector(v) => v.len(),
254 } as u64;
255 buf.extend(size.to_le_bytes());
256
257 match self {
261 Self::Null => buf.extend(ALLOC_ABSENT_U64.to_le_bytes()),
262 _ => buf.extend(ALLOC_PRESENT_U64.to_le_bytes()),
263 }
264 }
265
266 fn encode_out_of_line(&self, buf: &mut Vec<u8>) {
267 match self {
268 Self::Null => (),
269 Self::BoolVector(v) => {
270 for b in v {
271 BasicField::Bool(*b).encode_inline(buf);
272 }
273 }
274 Self::UInt8Vector(v) => buf.extend(v),
275 Self::UInt16Vector(v) => {
276 for n in v {
277 BasicField::UInt16(*n).encode_inline(buf);
278 }
279 }
280 Self::UInt32Vector(v) => {
281 for n in v {
282 BasicField::UInt32(*n).encode_inline(buf);
283 }
284 }
285 Self::UInt64Vector(v) => {
286 for n in v {
287 BasicField::UInt64(*n).encode_inline(buf);
288 }
289 }
290 Self::Int8Vector(v) => {
291 for n in v {
292 BasicField::Int8(*n).encode_inline(buf);
293 }
294 }
295 Self::Int16Vector(v) => {
296 for n in v {
297 BasicField::Int16(*n).encode_inline(buf);
298 }
299 }
300 Self::Int32Vector(v) => {
301 for n in v {
302 BasicField::Int32(*n).encode_inline(buf);
303 }
304 }
305 Self::Int64Vector(v) => {
306 for n in v {
307 BasicField::Int64(*n).encode_inline(buf);
308 }
309 }
310 Self::UInt8VectorVector(outer) => {
311 let as_fields = outer
312 .iter()
313 .map(|v| Field::Vector(VectorField::UInt8Vector(v.clone())))
314 .collect::<Vec<_>>();
315
316 for field in &as_fields {
317 field.encode_inline(buf);
318 }
319 for field in &as_fields {
320 field.encode_out_of_line(buf);
321 }
322 }
323 }
324 }
325}
326
327trait Padding {
328 fn pad_to(&mut self, align: usize);
329}
330
331impl Padding for Vec<u8> {
332 fn pad_to(&mut self, align: usize) {
333 let start_len = self.len();
334 let num_bytes = (align - (start_len % align)) % align;
335 self.resize(start_len + num_bytes, 0);
336 }
337}