mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-10-27 12:59:34 +00:00
Improve Encodable/Decodable impls
This commit is contained in:
@@ -20,16 +20,12 @@ pub(crate) fn derive_decodable(input: proc_macro::TokenStream) -> proc_macro::To
|
||||
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let sum = gen_size_sum(&input.data);
|
||||
let encode = gen_encode(&input.data);
|
||||
let decode = gen_decode(&input.data);
|
||||
|
||||
let expanded = quote! {
|
||||
// The generated impl.
|
||||
impl #impl_generics crate::socket::Encodable for #name #ty_generics #where_clause {
|
||||
fn encoded_len(&self) -> usize {
|
||||
#sum
|
||||
}
|
||||
fn encode(&self, w: &mut impl std::io::Write) -> std::io::Result<()> {
|
||||
#encode
|
||||
Ok(())
|
||||
@@ -45,32 +41,6 @@ pub(crate) fn derive_decodable(input: proc_macro::TokenStream) -> proc_macro::To
|
||||
proc_macro::TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
// Generate an expression to sum up the size of each field.
|
||||
fn gen_size_sum(data: &Data) -> TokenStream {
|
||||
match *data {
|
||||
Data::Struct(ref data) => {
|
||||
match data.fields {
|
||||
Fields::Named(ref fields) => {
|
||||
// Expands to an expression like
|
||||
//
|
||||
// 0 + self.x.encoded_len() + self.y.encoded_len() + self.z.encoded_len()
|
||||
let recurse = fields.named.iter().map(|f| {
|
||||
let name = &f.ident;
|
||||
quote_spanned! { f.span() =>
|
||||
crate::socket::Encodable::encoded_len(&self.#name)
|
||||
}
|
||||
});
|
||||
quote! {
|
||||
0 #(+ #recurse)*
|
||||
}
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
Data::Enum(_) | Data::Union(_) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
// Generate an expression to encode each field.
|
||||
fn gen_encode(data: &Data) -> TokenStream {
|
||||
match *data {
|
||||
|
||||
@@ -7,8 +7,6 @@ use std::os::fd::{FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
||||
use std::os::unix::net::{AncillaryData, SocketAncillary, UnixStream};
|
||||
|
||||
pub trait Encodable {
|
||||
#[allow(dead_code)]
|
||||
fn encoded_len(&self) -> usize;
|
||||
fn encode(&self, w: &mut impl Write) -> io::Result<()>;
|
||||
}
|
||||
|
||||
@@ -19,11 +17,6 @@ pub trait Decodable: Sized + Encodable {
|
||||
macro_rules! impl_pod_encodable {
|
||||
($($t:ty)*) => ($(
|
||||
impl Encodable for $t {
|
||||
#[inline(always)]
|
||||
fn encoded_len(&self) -> usize {
|
||||
size_of::<Self>()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
||||
w.write_pod(self)
|
||||
@@ -43,11 +36,6 @@ macro_rules! impl_pod_encodable {
|
||||
impl_pod_encodable! { u8 u32 i32 usize }
|
||||
|
||||
impl Encodable for bool {
|
||||
#[inline(always)]
|
||||
fn encoded_len(&self) -> usize {
|
||||
size_of::<u8>()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
||||
match *self {
|
||||
@@ -64,11 +52,24 @@ impl Decodable for bool {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Decodable> Encodable for Vec<T> {
|
||||
fn encoded_len(&self) -> usize {
|
||||
size_of::<i32>() + size_of::<T>() * self.len()
|
||||
}
|
||||
// impl<E: Encodable, T: AsRef<E>> Encodable for T
|
||||
macro_rules! impl_encodable_as_ref {
|
||||
($( ($t:ty, $e:ty, $($g:tt)*) )*) => ($(
|
||||
impl<$($g)*> Encodable for $t {
|
||||
#[inline(always)]
|
||||
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
||||
AsRef::<$e>::as_ref(self).encode(w)
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
impl_encodable_as_ref! {
|
||||
(String, str,)
|
||||
(Vec<T>, [T], T: Encodable)
|
||||
}
|
||||
|
||||
impl<T: Encodable> Encodable for [T] {
|
||||
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
||||
(self.len() as i32).encode(w)?;
|
||||
self.iter().try_for_each(|e| e.encode(w))
|
||||
@@ -87,26 +88,12 @@ impl<T: Decodable> Decodable for Vec<T> {
|
||||
}
|
||||
|
||||
impl Encodable for str {
|
||||
fn encoded_len(&self) -> usize {
|
||||
size_of::<i32>() + self.len()
|
||||
}
|
||||
|
||||
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
||||
(self.len() as i32).encode(w)?;
|
||||
w.write_all(self.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for String {
|
||||
fn encoded_len(&self) -> usize {
|
||||
self.as_str().encoded_len()
|
||||
}
|
||||
|
||||
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
||||
self.as_str().encode(w)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for String {
|
||||
fn decode(r: &mut impl Read) -> io::Result<String> {
|
||||
let len = i32::decode(r)?;
|
||||
|
||||
Reference in New Issue
Block a user