1use fidl::encoding::{TransactionHeader, ALLOC_PRESENT_U32, ALLOC_PRESENT_U64};
6use nom::bytes::complete::take;
7use nom::combinator::{map, value, verify};
8use nom::multi::count;
9use nom::sequence::{pair, preceded, terminated};
10use nom::{IResult, Parser};
11
12use crate::error::{Error, Result};
13use crate::library;
14use crate::util::*;
15use crate::value::Value;
16
17use std::str;
18
19type DResult<'a, R> = IResult<&'a [u8], R, Error>;
20
21enum Defer<'d> {
26 Complete(Value),
28
29 Action(
31 Box<
32 dyn for<'a> FnOnce(
33 &'a [u8],
34 &mut Vec<fidl::HandleInfo>,
35 RecursionCounter,
36 ) -> DResult<'a, Value>
37 + 'd,
38 >,
39 ),
40}
41
42impl<'d> Defer<'d> {
43 fn complete<'a>(
45 self,
46 data: &'a [u8],
47 handles: &mut Vec<fidl::HandleInfo>,
48 counter: RecursionCounter,
49 ) -> DResult<'a, Value> {
50 match self {
51 Defer::Complete(v) => Ok((data, v)),
52 Defer::Action(act) => act(data, handles, counter),
53 }
54 }
55}
56
57impl<'d> From<Value> for Defer<'d> {
58 fn from(v: Value) -> Defer<'d> {
59 Defer::Complete(v)
60 }
61}
62
63fn take_u8(data: &[u8]) -> DResult<'_, u8> {
64 map(take(1usize), |x: &[u8]| x[0]).parse(data)
65}
66
67fn value_u8(data: &[u8]) -> DResult<'_, Value> {
68 map(take_u8, Value::U8).parse(data)
69}
70
71fn value_bool(data: &[u8]) -> DResult<'_, Value> {
72 map(verify(take_u8, |&x| x == 0 || x == 1), |x| Value::Bool(x != 0)).parse(data)
73}
74
75fn take_u16(data: &[u8]) -> DResult<'_, u16> {
76 map(take(2usize), |x: &[u8]| u16::from_le_bytes(x.try_into().unwrap())).parse(data)
77}
78
79fn value_u16(data: &[u8]) -> DResult<'_, Value> {
80 map(take_u16, Value::U16).parse(data)
81}
82
83fn take_u32(data: &[u8]) -> DResult<'_, u32> {
84 map(take(4usize), |x: &[u8]| u32::from_le_bytes(x.try_into().unwrap())).parse(data)
85}
86
87fn value_u32(data: &[u8]) -> DResult<'_, Value> {
88 map(take_u32, Value::U32).parse(data)
89}
90
91fn take_u64(data: &[u8]) -> DResult<'_, u64> {
92 map(take(8usize), |x: &[u8]| u64::from_le_bytes(x.try_into().unwrap())).parse(data)
93}
94
95fn value_u64(data: &[u8]) -> DResult<'_, Value> {
96 map(take_u64, Value::U64).parse(data)
97}
98
99fn take_i8(data: &[u8]) -> DResult<'_, i8> {
100 map(take(1usize), |x: &[u8]| i8::from_le_bytes([x[0]])).parse(data)
101}
102
103fn value_i8(data: &[u8]) -> DResult<'_, Value> {
104 map(take_i8, Value::I8).parse(data)
105}
106
107fn take_i16(data: &[u8]) -> DResult<'_, i16> {
108 map(take(2usize), |x: &[u8]| i16::from_le_bytes(x.try_into().unwrap())).parse(data)
109}
110
111fn value_i16(data: &[u8]) -> DResult<'_, Value> {
112 map(take_i16, Value::I16).parse(data)
113}
114
115fn take_i32(data: &[u8]) -> DResult<'_, i32> {
116 map(take(4usize), |x: &[u8]| i32::from_le_bytes(x.try_into().unwrap())).parse(data)
117}
118
119fn value_i32(data: &[u8]) -> DResult<'_, Value> {
120 map(take_i32, Value::I32).parse(data)
121}
122
123fn take_i64(data: &[u8]) -> DResult<'_, i64> {
124 map(take(8usize), |x: &[u8]| i64::from_le_bytes(x.try_into().unwrap())).parse(data)
125}
126
127fn value_i64(data: &[u8]) -> DResult<'_, Value> {
128 map(take_i64, Value::I64).parse(data)
129}
130
131fn take_f32(data: &[u8]) -> DResult<'_, f32> {
132 map(take(4usize), |x: &[u8]| f32::from_le_bytes(x.try_into().unwrap())).parse(data)
133}
134
135fn value_f32(data: &[u8]) -> DResult<'_, Value> {
136 map(take_f32, Value::F32).parse(data)
137}
138
139fn take_f64(data: &[u8]) -> DResult<'_, f64> {
140 map(take(8usize), |x: &[u8]| f64::from_le_bytes(x.try_into().unwrap())).parse(data)
141}
142
143fn value_f64(data: &[u8]) -> DResult<'_, Value> {
144 map(take_f64, Value::F64).parse(data)
145}
146
147fn transaction_header(data: &[u8]) -> DResult<'_, TransactionHeader> {
148 fidl::encoding::decode_transaction_header(data)
149 .map(|(a, b)| (b, a))
150 .map_err(|e| Error::DecodeError(format!("Invalid FIDL transaction header ({e:?})")).into())
151}
152
153fn take_padding(amount: usize) -> impl Fn(&[u8]) -> DResult<'_, ()> {
154 move |bytes| value((), verify(take(amount), |x: &[u8]| x.iter().all(|&x| x == 0))).parse(bytes)
155}
156
157fn decode_struct<'s>(
158 ns: &'s library::Namespace,
159 st: &'s library::Struct,
160 nullable: bool,
161) -> impl Fn(&[u8]) -> DResult<'_, Defer<'s>> {
162 move |bytes: &[u8]| {
163 if !nullable {
164 return decode_struct_nonnull(ns, st).parse(bytes);
165 }
166
167 let (bytes, presence) = take_u64(bytes)?;
168
169 if presence == 0 {
170 Ok((bytes, Defer::Complete(Value::Null)))
171 } else if presence != ALLOC_PRESENT_U64 {
172 Err(Error::DecodeError("Bad presence indicator".to_owned()).into())
173 } else {
174 Ok((
175 bytes,
176 Defer::Action(Box::new(
177 move |bytes: &[u8],
178 handles: &mut Vec<fidl::HandleInfo>,
179 counter: RecursionCounter| {
180 let counter = counter.next()?;
181 let align = alignment_padding_for_size(st.size);
182 let (bytes, defer) =
183 terminated(decode_struct_nonnull(ns, st), take_padding(align))
184 .parse(bytes)?;
185 defer.complete(bytes, handles, counter)
186 },
187 )),
188 ))
189 }
190 }
191}
192
193fn decode_struct_nonnull<'s>(
194 ns: &'s library::Namespace,
195 st: &'s library::Struct,
196) -> impl Fn(&[u8]) -> DResult<'_, Defer<'s>> {
197 move |mut bytes: &[u8]| {
198 let mut offset = 0;
199 let mut fields = Vec::new();
200
201 for member in &st.members {
202 let (remaining, result) =
203 preceded(take_padding(member.offset - offset), decode_type(ns, &member.ty))
204 .parse(bytes)?;
205 fields.push((member.name.clone(), result));
206 bytes = remaining;
207 offset = member.offset + member.ty.inline_size(ns)?;
208 }
209
210 if offset < st.size {
211 let (remaining, _) = take_padding(st.size - offset).parse(bytes)?;
212 bytes = remaining;
213 }
214
215 Ok((
216 bytes,
217 Defer::Action(Box::new(
218 move |mut bytes: &[u8],
219 handles: &mut Vec<fidl::HandleInfo>,
220 counter: RecursionCounter| {
221 let mut complete_fields = Vec::new();
222
223 for (name, defer) in fields {
224 let (remaining, value) = defer.complete(bytes, handles, counter)?;
225 bytes = remaining;
226 complete_fields.push((name, value))
227 }
228
229 Ok((bytes, Value::Object(complete_fields)))
230 },
231 )),
232 ))
233 }
234}
235
236fn decode_type<'t>(
237 ns: &'t library::Namespace,
238 ty: &'t library::Type,
239) -> impl Fn(&[u8]) -> DResult<'_, Defer<'t>> {
240 use library::Type;
241 move |b: &[u8]| {
242 match ty {
243 Type::Bool => value_bool(b),
244 Type::U8 => value_u8(b),
245 Type::U16 => value_u16(b),
246 Type::U32 => value_u32(b),
247 Type::U64 => value_u64(b),
248 Type::I8 => value_i8(b),
249 Type::I16 => value_i16(b),
250 Type::I32 => value_i32(b),
251 Type::I64 => value_i64(b),
252 Type::F32 => value_f32(b),
253 Type::F64 => value_f64(b),
254 Type::Array(ty, size) => return decode_array(ns, ty, *size).parse(b),
255 Type::Vector { ty, nullable, element_count } => {
256 return decode_vector(ns, ty, *nullable, *element_count).parse(b)
257 }
258 Type::String { nullable, byte_count } => {
259 return decode_string(*nullable, *byte_count).parse(b)
260 }
261 Type::Identifier { name, nullable } => {
262 return decode_identifier(ns, name, *nullable).parse(b)
263 }
264 Type::Handle { object_type, nullable, rights } => {
265 return decode_handle(*object_type, *nullable, *rights).parse(b)
266 }
267 Type::Endpoint { protocol, rights, nullable, role } => match role {
268 library::EndpointRole::Client => {
269 return decode_client_end(protocol.clone(), *nullable, *rights).parse(b)
270 }
271 library::EndpointRole::Server => {
272 return decode_server_end(protocol.clone(), *nullable, *rights).parse(b)
273 }
274 },
275 Type::UnknownString(s) => {
276 Err(Error::LibraryError(format!("Unresolved Type: {}", s)).into())
277 }
278 Type::Unknown(library::TypeInfo { identifier: s, .. }) => {
279 return Err(Error::LibraryError(format!(
280 "Unresolved Type: {}",
281 s.as_ref().map_or("<unidentified>", String::as_str)
282 ))
283 .into())
284 }
285 Type::FrameworkError => map(take_u32, |_| Value::Null).parse(b),
286 }
287 .map(|(x, y)| (x, Defer::Complete(y)))
288 }
289}
290
291fn complete_deferred_list<'a>(
293 bytes: &'a [u8],
294 handles: &mut Vec<fidl::HandleInfo>,
295 defers: Vec<Defer<'_>>,
296 counter: RecursionCounter,
297) -> DResult<'a, Value> {
298 let mut bytes = bytes;
299 let mut values = Vec::new();
300
301 for defer in defers {
302 let (next_bytes, value) = defer.complete(bytes, handles, counter)?;
303 bytes = next_bytes;
304 values.push(value)
305 }
306
307 Ok((bytes, Value::List(values)))
308}
309
310fn decode_array<'t>(
311 ns: &'t library::Namespace,
312 ty: &'t library::Type,
313 size: usize,
314) -> impl Fn(&[u8]) -> DResult<'_, Defer<'t>> {
315 move |bytes: &[u8]| {
316 let (bytes, defers) = count(decode_type(ns, ty), size).parse(bytes)?;
317
318 Ok((
319 bytes,
320 Defer::Action(Box::new(
321 move |bytes: &[u8],
322 handles: &mut Vec<fidl::HandleInfo>,
323 counter: RecursionCounter| {
324 complete_deferred_list(bytes, handles, defers, counter)
325 },
326 )),
327 ))
328 }
329}
330
331fn decode_vector<'t>(
332 ns: &'t library::Namespace,
333 ty: &'t library::Type,
334 nullable: bool,
335 element_count: Option<usize>,
336) -> impl Fn(&[u8]) -> DResult<'_, Defer<'t>> {
337 move |bytes: &[u8]| {
338 let (bytes, (size, presence)) = pair(take_u64, take_u64).parse(bytes)?;
339 let size = size as usize;
340 let align = alignment_padding_for_size(size * ty.inline_size(ns)?);
341
342 if presence == 0 {
343 if nullable {
344 if size == 0 {
345 Ok((bytes, Defer::Complete(Value::Null)))
346 } else {
347 Err(Error::DecodeError("Absent vector had a size".to_owned()).into())
348 }
349 } else {
350 Err(Error::DecodeError("Missing non-nullable vector".to_owned()).into())
351 }
352 } else if presence != ALLOC_PRESENT_U64 {
353 Err(Error::DecodeError("Bad presence indicator".to_owned()).into())
354 } else if element_count.map(|x| x < size).unwrap_or(false) {
355 Err(Error::DecodeError("Vector too long".to_owned()).into())
356 } else {
357 Ok((
358 bytes,
359 Defer::Action(Box::new(
360 move |bytes: &[u8],
361 handles: &mut Vec<fidl::HandleInfo>,
362 counter: RecursionCounter| {
363 let counter = counter.next()?;
364 let (bytes, defers) =
365 terminated(count(decode_type(ns, ty), size), take_padding(align))
366 .parse(bytes)?;
367
368 complete_deferred_list(bytes, handles, defers, counter)
369 },
370 )),
371 ))
372 }
373 }
374}
375
376fn decode_string(
377 nullable: bool,
378 byte_count: Option<usize>,
379) -> impl Fn(&[u8]) -> DResult<'_, Defer<'static>> {
380 move |bytes: &[u8]| {
381 let (bytes, (size, presence)) = pair(take_u64, take_u64).parse(bytes)?;
382 let size = size as usize;
383 let align = alignment_padding_for_size(size);
384
385 if presence == 0 {
386 if nullable {
387 if size == 0 {
388 Ok((bytes, Defer::Complete(Value::Null)))
389 } else {
390 Err(Error::DecodeError("Absent string had a size".to_owned()).into())
391 }
392 } else {
393 Err(Error::DecodeError("Missing non-nullable string".to_owned()).into())
394 }
395 } else if presence != ALLOC_PRESENT_U64 {
396 Err(Error::DecodeError("Bad presence indicator".to_owned()).into())
397 } else if byte_count.map(|x| x < size).unwrap_or(false) {
398 Err(Error::DecodeError("String too long".to_owned()).into())
399 } else {
400 Ok((
401 bytes,
402 Defer::Action(Box::new(
403 move |bytes: &[u8],
404 _: &mut Vec<fidl::HandleInfo>,
405 counter: RecursionCounter| {
406 let _counter = counter.next()?;
407 let (bytes, data) =
408 terminated(take(size), take_padding(align)).parse(bytes)?;
409
410 match str::from_utf8(data) {
411 Ok(x) => Ok((bytes, Value::String(x.to_owned()))),
412 Err(x) => Err(Error::Utf8Error(x).into()),
413 }
414 },
415 )),
416 ))
417 }
418 }
419}
420
421fn decode_server_end(
422 interface: String,
423 nullable: bool,
424 rights: fidl::Rights,
425) -> impl Fn(&[u8]) -> DResult<'_, Defer<'static>> {
426 decode_handle_with(
427 interface,
428 nullable,
429 &|x, y| Value::ServerEnd(x.into(), y),
430 Some(fidl::ObjectType::CHANNEL),
431 rights,
432 )
433}
434
435fn decode_client_end(
436 interface: String,
437 nullable: bool,
438 rights: fidl::Rights,
439) -> impl Fn(&[u8]) -> DResult<'_, Defer<'static>> {
440 decode_handle_with(
441 interface,
442 nullable,
443 &|x, y| Value::ClientEnd(x.into(), y),
444 Some(fidl::ObjectType::CHANNEL),
445 rights,
446 )
447}
448
449fn decode_handle(
450 handle_type: fidl::ObjectType,
451 nullable: bool,
452 rights: fidl::Rights,
453) -> impl Fn(&[u8]) -> DResult<'_, Defer<'static>> {
454 decode_handle_with(handle_type, nullable, &Value::Handle, None, rights)
455}
456
457fn decode_handle_with<T: Clone + 'static>(
458 handle_type: T,
459 nullable: bool,
460 value_builder: &'static (impl Fn(fidl::Handle, T) -> Value + 'static),
461 constrain_type: Option<fidl::ObjectType>,
462 rights: fidl::Rights,
463) -> impl Fn(&[u8]) -> DResult<'_, Defer<'static>> {
464 move |bytes: &[u8]| {
465 let handle_type = handle_type.clone();
466 let (bytes, presence) = take_u32(bytes)?;
467
468 if presence == 0 {
469 if nullable {
470 Ok((bytes, Defer::Complete(Value::Null)))
471 } else {
472 Err(Error::DecodeError("Missing non-nullable handle".to_owned()).into())
473 }
474 } else if presence != ALLOC_PRESENT_U32 {
475 Err(Error::DecodeError("Bad presence indicator".to_owned()).into())
476 } else {
477 Ok((
478 bytes,
479 Defer::Action(Box::new(
480 move |bytes: &[u8],
481 handles: &mut Vec<fidl::HandleInfo>,
482 _: RecursionCounter| {
483 if !handles.is_empty() {
484 if constrain_type.map(|x| x == handles[0].object_type).unwrap_or(true) {
485 let handle = handles.remove(0);
486 if !handle.rights.contains(rights)
487 && handle.rights != fidl::Rights::SAME_RIGHTS
488 {
489 let missing = rights.clone().remove(handle.rights);
490 Err(Error::DecodeError(format!(
491 "Insufficient handle rights, need {missing:?}"
492 ))
493 .into())
494 } else {
495 Ok((bytes, value_builder(handle.handle, handle_type)))
496 }
497 } else {
498 Err(Error::DecodeError("Wrong handle type".to_owned()).into())
499 }
500 } else {
501 Err(Error::DecodeError("Too few handles".to_owned()).into())
502 }
503 },
504 )),
505 ))
506 }
507 }
508}
509
510fn decode_enum<'e>(
511 ns: &'e library::Namespace,
512 en: &'e library::Enum,
513) -> impl Fn(&[u8]) -> DResult<'_, Defer<'e>> {
514 move |bytes: &[u8]| {
515 let (bytes, defer) = decode_type(ns, &en.ty).parse(bytes)?;
516 Ok((
517 bytes,
518 Defer::Action(Box::new(
519 move |bytes: &[u8],
520 handles: &mut Vec<fidl::HandleInfo>,
521 counter: RecursionCounter| {
522 let (bytes, value) = defer.complete(bytes, handles, counter)?;
523
524 for member in &en.members {
525 if value == member.value || !en.strict {
526 return Ok((bytes, Value::Enum(en.name.to_owned(), Box::new(value))));
527 }
528 }
529
530 if en.strict {
531 Err(Error::DecodeError("Unknown Enum Variant.".to_owned()).into())
532 } else {
533 Ok((bytes, Value::Enum(en.name.to_owned(), Box::new(value))))
534 }
535 },
536 )),
537 ))
538 }
539}
540
541fn decode_bits<'b>(
542 ns: &'b library::Namespace,
543 bits: &'b library::Bits,
544) -> impl Fn(&[u8]) -> DResult<'_, Defer<'b>> {
545 move |bytes: &[u8]| {
546 let (bytes, defer) = decode_type(ns, &bits.ty).parse(bytes)?;
547 Ok((
548 bytes,
549 Defer::Action(Box::new(
550 move |bytes: &[u8],
551 handles: &mut Vec<fidl::HandleInfo>,
552 counter: RecursionCounter| {
553 let (bytes, value) = defer.complete(bytes, handles, counter)?;
554
555 let data = value.bits().ok_or_else(|| {
556 Error::LibraryError("Bits with non-integer type.".to_owned())
557 })?;
558
559 if bits.strict && data != data & bits.mask {
560 Err(Error::DecodeError("Invalid value for bits field.".to_owned()).into())
561 } else {
562 Ok((bytes, Value::Bits(bits.name.to_owned(), Box::new(value))))
563 }
564 },
565 )),
566 ))
567 }
568}
569
570enum Envelope {
572 Present { bytes: u32, handles: u16 },
573 Inline { bytes: [u8; 4], handles: u16 },
574 Empty,
575}
576
577impl Envelope {
578 fn skip(&self) -> Defer<'static> {
579 let (envelope_bytes, envelope_handles) = match self {
580 Envelope::Present { bytes, handles } => (*bytes, *handles),
581 Envelope::Inline { handles, .. } => (0, *handles),
582 Envelope::Empty => return Defer::Complete(Value::Null),
583 };
584
585 Defer::Action(Box::new(
586 move |bytes: &[u8], handles: &mut Vec<fidl::HandleInfo>, counter: RecursionCounter| {
587 let _counter = counter.next()?;
588 if (envelope_bytes & 7u32) != 0 {
589 return Err(Error::DecodeError("Invalid envelope size".to_owned()).into());
590 }
591 let envelope_bytes = envelope_bytes as usize;
592 let envelope_handles = envelope_handles as usize;
593
594 if envelope_handles > handles.len() {
595 Err(Error::DecodeError("Insufficient handles for envelope".to_owned()).into())
596 } else if envelope_bytes > bytes.len() {
597 Err(Error::DecodeError("Insufficient bytes for envelope".to_owned()).into())
598 } else {
599 *handles = handles.split_off(envelope_handles);
600 Ok((&bytes[envelope_bytes as usize..], Value::Null))
601 }
602 },
603 ))
604 }
605
606 fn decode_type<'s>(
607 &self,
608 ns: &'s library::Namespace,
609 ty: &'s library::Type,
610 ) -> Result<Defer<'s>> {
611 if let &Envelope::Empty = self {
612 Ok(self.skip())
613 } else if !ty.is_resolved(ns) {
614 Ok(self.skip())
615 } else if let Envelope::Inline { bytes, handles } = self {
616 let (padding, ret) = decode_type(ns, ty).parse(bytes)?;
617 take_padding(padding.len()).parse(padding)?;
618 let expect_handles = *handles as usize;
619 Ok(Defer::Action(Box::new(
620 move |bytes: &[u8],
621 handles: &mut Vec<fidl::HandleInfo>,
622 counter: RecursionCounter| {
623 let handle_count = handles.len();
624 let v = ret.complete(bytes, handles, counter)?;
625
626 let handles_used = handle_count - handles.len();
627 if handles_used != expect_handles {
628 Err(Error::DecodeError("Wrong number of handles in envelope".to_owned())
629 .into())
630 } else {
631 Ok(v)
632 }
633 },
634 )))
635 } else if ty.inline_size(ns)? <= 4 {
636 Err(Error::DecodeError("Envelope should be inline".to_owned()))
637 } else {
638 let Envelope::Present { bytes, handles } = self else { unreachable!() };
639 let expect_bytes = *bytes as usize;
640 let expect_handles = *handles as usize;
641 Ok(Defer::Action(Box::new(
642 move |bytes: &[u8],
643 handles: &mut Vec<fidl::HandleInfo>,
644 counter: RecursionCounter| {
645 let counter = counter.next()?;
646 let bytes_start = bytes.len();
647 let align = alignment_padding_for_size(ty.inline_size(ns)?);
648 let (bytes, defer) =
649 terminated(decode_type(ns, ty), take_padding(align)).parse(bytes)?;
650
651 let handle_count = handles.len();
652 let (bytes, value) = defer.complete(bytes, handles, counter)?;
653 let handles_used = handle_count - handles.len();
654 let bytes_used = bytes_start - bytes.len();
655 if handles_used != expect_handles {
656 Err(Error::DecodeError("Wrong number of handles in envelope".to_owned())
657 .into())
658 } else if bytes_used != expect_bytes {
659 Err(Error::DecodeError("Wrong number of bytes in envelope".to_owned())
660 .into())
661 } else {
662 Ok((bytes, value))
663 }
664 },
665 )))
666 }
667 }
668
669 fn take<'a>(empty_ok: bool) -> impl Fn(&'a [u8]) -> DResult<'a, Envelope> {
670 move |bytes: &[u8]| {
671 let (bytes, (envelope_bytes, envelope_handles, envelope_flags)) =
672 (take_u32, take_u16, take_u16).parse(bytes)?;
673
674 if envelope_bytes == 0 && envelope_handles == 0 && envelope_flags == 0 {
675 if !empty_ok {
676 Err(Error::DecodeError("Unexpected empty envelope.".to_owned()).into())
677 } else {
678 Ok((bytes, Envelope::Empty))
679 }
680 } else if envelope_flags == 0 {
681 Ok((bytes, Envelope::Present { bytes: envelope_bytes, handles: envelope_handles }))
682 } else if envelope_flags == 1 {
683 Ok((
684 bytes,
685 Envelope::Inline {
686 bytes: envelope_bytes.to_le_bytes(),
687 handles: envelope_handles,
688 },
689 ))
690 } else {
691 Err(Error::DecodeError("Unknown evelope flags.".to_owned()).into())
692 }
693 }
694 }
695}
696
697fn decode_union<'u>(
698 ns: &'u library::Namespace,
699 union: &'u library::TableOrUnion,
700 nullable: bool,
701) -> impl Fn(&[u8]) -> DResult<'_, Defer<'u>> {
702 move |bytes: &[u8]| {
703 let (bytes, (ordinal, envelope)) = (take_u64, Envelope::take(nullable)).parse(bytes)?;
704
705 match (ordinal, &envelope) {
706 (0, Envelope::Empty) => return Ok((bytes, envelope.skip())),
707 (0, _) => return Err(Error::DecodeError("Invalid Union block.".to_owned()).into()),
708 _ => (),
709 };
710
711 match union.members.get(&ordinal) {
712 None if union.strict => {
713 Err(Error::DecodeError("Invalid Union ordinal.".to_owned()).into())
714 }
715 None => Ok((bytes, envelope.skip())),
716 Some(member) => Ok((
717 bytes,
718 Defer::Action(Box::new(
719 move |bytes: &[u8],
720 handles: &mut Vec<fidl::HandleInfo>,
721 counter: RecursionCounter| {
722 let (bytes, inner) = envelope
723 .decode_type(ns, &member.ty)?
724 .complete(bytes, handles, counter)?;
725 Ok((
726 bytes,
727 Value::Union(
728 union.name.to_owned(),
729 member.name.to_owned(),
730 Box::new(inner),
731 ),
732 ))
733 },
734 )),
735 )),
736 }
737 }
738}
739
740fn decode_table<'t>(
741 ns: &'t library::Namespace,
742 table: &'t library::TableOrUnion,
743) -> impl Fn(&[u8]) -> DResult<'_, Defer<'t>> {
744 move |bytes: &[u8]| {
745 let (bytes, (size, data_ptr)) = pair(take_u64, take_u64).parse(bytes)?;
746
747 if data_ptr != ALLOC_PRESENT_U64 {
748 return Err(Error::DecodeError("Bad presence indicator.".to_owned()).into());
749 }
750
751 Ok((
752 bytes,
753 Defer::Action(Box::new(
754 move |bytes: &[u8],
755 handles: &mut Vec<fidl::HandleInfo>,
756 counter: RecursionCounter| {
757 let counter = counter.next()?;
758 let (mut bytes, envelopes) =
759 count(Envelope::take(true), size as usize).parse(bytes)?;
760
761 let mut result = Vec::new();
762 let mut expect_ord = 1u64;
763 for envelope in envelopes {
764 let member = table.members.get(&expect_ord);
765 expect_ord += 1;
766
767 let next_bytes = if let Some(member) = member {
768 let (next_bytes, val) = envelope
769 .decode_type(ns, &member.ty)?
770 .complete(bytes, handles, counter)?;
771 if !matches!(val, Value::Null) {
772 result.push((member.name.clone(), val));
773 }
774 next_bytes
775 } else {
776 envelope.skip().complete(bytes, handles, counter)?.0
777 };
778
779 bytes = next_bytes;
780 }
781
782 Ok((bytes, Value::Object(result)))
783 },
784 )),
785 ))
786 }
787}
788
789fn decode_identifier<'s>(
790 ns: &'s library::Namespace,
791 name: &'s str,
792 nullable: bool,
793) -> impl Fn(&[u8]) -> DResult<'_, Defer<'s>> {
794 move |bytes: &[u8]| match ns.lookup(name)? {
795 library::LookupResult::Bits(b) => decode_bits(ns, b).parse(bytes),
796 library::LookupResult::Enum(e) => decode_enum(ns, e).parse(bytes),
797 library::LookupResult::Struct(s) => decode_struct(ns, s, nullable).parse(bytes),
798 library::LookupResult::Union(u) => decode_union(ns, u, nullable).parse(bytes),
799 library::LookupResult::Table(t) => decode_table(ns, t).parse(bytes),
800 library::LookupResult::Protocol(_) => Err(Error::DecodeError(format!(
801 "Protocol names cannot be used as identifiers: {}",
802 name
803 ))
804 .into()),
805 }
806}
807
808fn decode_message<'a>(
810 ns: &library::Namespace,
811 direction: Direction,
812 bytes: &'a [u8],
813 mut handles: Vec<fidl::HandleInfo>,
814) -> Result<(TransactionHeader, Value)> {
815 let (bytes, header) = transaction_header(bytes)?;
816
817 let (_, method) = ns.lookup_method_ordinal(header.ordinal)?;
818
819 let (message, has) = match direction {
820 Direction::Request => (method.request.as_ref(), method.has_request),
821 Direction::Response => (method.response.as_ref(), method.has_response),
822 };
823
824 if let Some(message) = message {
825 let (bytes, defer) = decode_type(ns, message).parse(bytes)?;
826 let (bytes, value) = defer.complete(bytes, &mut handles, RecursionCounter::new())?;
827
828 if !bytes.is_empty() && (bytes.len() >= 8 || bytes.iter().any(|x| *x != 0)) {
829 Err(Error::DecodeError(format!("{} bytes left over.", bytes.len())))
830 } else if !handles.is_empty() {
831 Err(Error::DecodeError(format!("{} handles left over.", handles.len())))
832 } else {
833 Ok((header, value))
834 }
835 } else if !has {
836 Err(Error::DecodeError(format!(
837 "Header indicates method {}, which has no {}.",
838 method.name,
839 direction.to_string()
840 )))
841 } else {
842 Ok((header, Value::Null))
843 }
844}
845
846pub fn decode_request(
848 ns: &library::Namespace,
849 bytes: &[u8],
850 handles: Vec<fidl::HandleInfo>,
851) -> Result<(TransactionHeader, Value)> {
852 decode_message(ns, Direction::Request, bytes, handles)
853}
854
855pub fn decode_response(
857 ns: &library::Namespace,
858 bytes: &[u8],
859 handles: Vec<fidl::HandleInfo>,
860) -> Result<(TransactionHeader, Value)> {
861 decode_message(ns, Direction::Response, bytes, handles)
862}
863
864pub fn decode<'a>(
866 ns: &library::Namespace,
867 ty: &str,
868 bytes: &'a [u8],
869 mut handles: Vec<fidl::HandleInfo>,
870) -> Result<Value> {
871 if bytes.len() % 8 != 0 {
872 return Err(Error::DecodeError("Unaligned encoded object".to_owned()));
873 }
874 let (bytes, defer) = decode_identifier(ns, ty, false).parse(bytes)?;
875 let (bytes, value) = defer.complete(bytes, &mut handles, RecursionCounter::new())?;
876 take_padding(bytes.len()).parse(bytes)?;
877
878 if !bytes.is_empty() && (bytes.len() >= 8 || bytes.iter().any(|x| *x != 0)) {
879 Err(Error::DecodeError(format!("{} bytes left over.", bytes.len())))
880 } else if !handles.is_empty() {
881 Err(Error::DecodeError(format!("{} handles left over.", handles.len())))
882 } else {
883 Ok(value)
884 }
885}