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