Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4c8e273 authored by Steven Moreland's avatar Steven Moreland Committed by Automerger Merge Worker
Browse files

Merge "binder_rs: Add in-place deserialization methods" am: 9d5c8102

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1692854

Change-Id: I87bbb550c6b7363a2881273c54a8b0db71d47d70
parents 5f3a3f9f 9d5c8102
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -219,6 +219,13 @@ impl Parcel {
        D::deserialize(self)
        D::deserialize(self)
    }
    }


    /// Attempt to read a type that implements [`Deserialize`] from this
    /// `Parcel` onto an existing value. This operation will overwrite the old
    /// value partially or completely, depending on how much data is available.
    pub fn read_onto<D: Deserialize>(&self, x: &mut D) -> Result<()> {
        x.deserialize_from(self)
    }

    /// Read a vector size from the `Parcel` and resize the given output vector
    /// Read a vector size from the `Parcel` and resize the given output vector
    /// to be correctly sized for that amount of data.
    /// to be correctly sized for that amount of data.
    ///
    ///
+85 −0
Original line number Original line Diff line number Diff line
@@ -39,6 +39,14 @@ pub trait Serialize {
pub trait Deserialize: Sized {
pub trait Deserialize: Sized {
    /// Deserialize an instance from the given [`Parcel`].
    /// Deserialize an instance from the given [`Parcel`].
    fn deserialize(parcel: &Parcel) -> Result<Self>;
    fn deserialize(parcel: &Parcel) -> Result<Self>;

    /// Deserialize an instance from the given [`Parcel`] onto the
    /// current object. This operation will overwrite the old value
    /// partially or completely, depending on how much data is available.
    fn deserialize_from(&mut self, parcel: &Parcel) -> Result<()> {
        *self = Self::deserialize(parcel)?;
        Ok(())
    }
}
}


/// Helper trait for types that can be serialized as arrays.
/// Helper trait for types that can be serialized as arrays.
@@ -184,6 +192,14 @@ pub trait DeserializeOption: Deserialize {
            parcel.read().map(Some)
            parcel.read().map(Some)
        }
        }
    }
    }

    /// Deserialize an Option of this type from the given [`Parcel`] onto the
    /// current object. This operation will overwrite the current value
    /// partially or completely, depending on how much data is available.
    fn deserialize_option_from(this: &mut Option<Self>, parcel: &Parcel) -> Result<()> {
        *this = Self::deserialize_option(parcel)?;
        Ok(())
    }
}
}


/// Callback to allocate a vector for parcel array read functions.
/// Callback to allocate a vector for parcel array read functions.
@@ -677,6 +693,75 @@ impl<T: DeserializeOption> Deserialize for Option<T> {
    fn deserialize(parcel: &Parcel) -> Result<Self> {
    fn deserialize(parcel: &Parcel) -> Result<Self> {
        DeserializeOption::deserialize_option(parcel)
        DeserializeOption::deserialize_option(parcel)
    }
    }

    fn deserialize_from(&mut self, parcel: &Parcel) -> Result<()> {
        DeserializeOption::deserialize_option_from(self, parcel)
    }
}

/// Implement `Deserialize` trait and friends for a parcelable
///
/// This is an internal macro used by the AIDL compiler to implement
/// `Deserialize`, `DeserializeArray` and `DeserializeOption` for
/// structured parcelables. The target type must implement a
/// `deserialize_parcelable` method with the following signature:
/// ```no_run
/// fn deserialize_parcelable(
///     &mut self,
///     parcel: &binder::parcel::Parcelable,
/// ) -> binder::Result<()> {
///     // ...
/// }
/// ```
#[macro_export]
macro_rules! impl_deserialize_for_parcelable {
    ($parcelable:ident) => {
        impl $crate::parcel::Deserialize for $parcelable {
            fn deserialize(
                parcel: &$crate::parcel::Parcel,
            ) -> $crate::Result<Self> {
                $crate::parcel::DeserializeOption::deserialize_option(parcel)
                    .transpose()
                    .unwrap_or(Err($crate::StatusCode::UNEXPECTED_NULL))
            }
            fn deserialize_from(
                &mut self,
                parcel: &$crate::parcel::Parcel,
            ) -> $crate::Result<()> {
                let status: i32 = parcel.read()?;
                if status == 0 {
                    Err($crate::StatusCode::UNEXPECTED_NULL)
                } else {
                    self.deserialize_parcelable(parcel)
                }
            }
        }

        impl $crate::parcel::DeserializeArray for $parcelable {}

        impl $crate::parcel::DeserializeOption for $parcelable {
            fn deserialize_option(
                parcel: &$crate::parcel::Parcel,
            ) -> $crate::Result<Option<Self>> {
                let mut result = None;
                Self::deserialize_option_from(&mut result, parcel)?;
                Ok(result)
            }
            fn deserialize_option_from(
                this: &mut Option<Self>,
                parcel: &$crate::parcel::Parcel,
            ) -> $crate::Result<()> {
                let status: i32 = parcel.read()?;
                if status == 0 {
                    *this = None;
                    Ok(())
                } else {
                    this.get_or_insert_with(Self::default)
                        .deserialize_parcelable(parcel)
                }
            }
        }
    }
}
}


#[test]
#[test]