Add optional method to read into existing unstructured parcelable.
This is an optimisation which may save some time creating a new
instance.
Bug: 303064346
Test: atest aidl_integration_test
Change-Id: Ib1a30033310269aa51177d271bebe0a0d671fcaf
diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs
index df25fac..33dfe19 100644
--- a/libs/binder/rust/src/parcel/parcelable.rs
+++ b/libs/binder/rust/src/parcel/parcelable.rs
@@ -67,6 +67,16 @@
/// generally preferred over calling this function, since the former also parse the additional
/// header.
fn from_parcel(parcel: &BorrowedParcel<'_>) -> Result<Self>;
+
+ /// Internal deserialization function for parcelables.
+ ///
+ /// This method is mainly for internal use. `Deserialize::deserialize_from` and its variants are
+ /// generally preferred over calling this function, since the former also parse the additional
+ /// header.
+ fn read_from_parcel(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()> {
+ *self = Self::from_parcel(parcel)?;
+ Ok(())
+ }
}
/// A struct whose instances can be written to a [`crate::parcel::Parcel`].
@@ -1084,6 +1094,18 @@
.transpose()
.unwrap_or(Err($crate::StatusCode::UNEXPECTED_NULL))
}
+ fn deserialize_from(
+ &mut self,
+ parcel: &$crate::binder_impl::BorrowedParcel<'_>,
+ ) -> std::result::Result<(), $crate::StatusCode> {
+ let status: i32 = parcel.read()?;
+ if status == $crate::binder_impl::NULL_PARCELABLE_FLAG {
+ Err($crate::StatusCode::UNEXPECTED_NULL)
+ } else {
+ use $crate::binder_impl::UnstructuredParcelable;
+ self.read_from_parcel(parcel)
+ }
+ }
}
impl < $($param: Default),* > $crate::binder_impl::DeserializeArray for $parcelable < $($param),* > {}
@@ -1102,6 +1124,28 @@
_ => Err(StatusCode::BAD_VALUE),
}
}
+ fn deserialize_option_from(
+ this: &mut Option<Self>,
+ parcel: &$crate::binder_impl::BorrowedParcel<'_>,
+ ) -> std::result::Result<(), $crate::StatusCode> {
+ let present: i32 = parcel.read()?;
+ match present {
+ $crate::binder_impl::NULL_PARCELABLE_FLAG => {
+ *this = None;
+ Ok(())
+ }
+ $crate::binder_impl::NON_NULL_PARCELABLE_FLAG => {
+ use $crate::binder_impl::UnstructuredParcelable;
+ if let Some(this) = this {
+ this.read_from_parcel(parcel)?;
+ } else {
+ *this = Some(Self::from_parcel(parcel)?);
+ }
+ Ok(())
+ }
+ _ => Err(StatusCode::BAD_VALUE),
+ }
+ }
}
};
}