mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-12-15 23:41:50 +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 (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
let sum = gen_size_sum(&input.data);
|
|
||||||
let encode = gen_encode(&input.data);
|
let encode = gen_encode(&input.data);
|
||||||
let decode = gen_decode(&input.data);
|
let decode = gen_decode(&input.data);
|
||||||
|
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
// The generated impl.
|
// The generated impl.
|
||||||
impl #impl_generics crate::socket::Encodable for #name #ty_generics #where_clause {
|
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<()> {
|
fn encode(&self, w: &mut impl std::io::Write) -> std::io::Result<()> {
|
||||||
#encode
|
#encode
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -45,32 +41,6 @@ pub(crate) fn derive_decodable(input: proc_macro::TokenStream) -> proc_macro::To
|
|||||||
proc_macro::TokenStream::from(expanded)
|
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.
|
// Generate an expression to encode each field.
|
||||||
fn gen_encode(data: &Data) -> TokenStream {
|
fn gen_encode(data: &Data) -> TokenStream {
|
||||||
match *data {
|
match *data {
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ use std::os::fd::{FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
|||||||
use std::os::unix::net::{AncillaryData, SocketAncillary, UnixStream};
|
use std::os::unix::net::{AncillaryData, SocketAncillary, UnixStream};
|
||||||
|
|
||||||
pub trait Encodable {
|
pub trait Encodable {
|
||||||
#[allow(dead_code)]
|
|
||||||
fn encoded_len(&self) -> usize;
|
|
||||||
fn encode(&self, w: &mut impl Write) -> io::Result<()>;
|
fn encode(&self, w: &mut impl Write) -> io::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,11 +17,6 @@ pub trait Decodable: Sized + Encodable {
|
|||||||
macro_rules! impl_pod_encodable {
|
macro_rules! impl_pod_encodable {
|
||||||
($($t:ty)*) => ($(
|
($($t:ty)*) => ($(
|
||||||
impl Encodable for $t {
|
impl Encodable for $t {
|
||||||
#[inline(always)]
|
|
||||||
fn encoded_len(&self) -> usize {
|
|
||||||
size_of::<Self>()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
||||||
w.write_pod(self)
|
w.write_pod(self)
|
||||||
@@ -43,11 +36,6 @@ macro_rules! impl_pod_encodable {
|
|||||||
impl_pod_encodable! { u8 u32 i32 usize }
|
impl_pod_encodable! { u8 u32 i32 usize }
|
||||||
|
|
||||||
impl Encodable for bool {
|
impl Encodable for bool {
|
||||||
#[inline(always)]
|
|
||||||
fn encoded_len(&self) -> usize {
|
|
||||||
size_of::<u8>()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
||||||
match *self {
|
match *self {
|
||||||
@@ -64,11 +52,24 @@ impl Decodable for bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Decodable> Encodable for Vec<T> {
|
// impl<E: Encodable, T: AsRef<E>> Encodable for T
|
||||||
fn encoded_len(&self) -> usize {
|
macro_rules! impl_encodable_as_ref {
|
||||||
size_of::<i32>() + size_of::<T>() * self.len()
|
($( ($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<()> {
|
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
||||||
(self.len() as i32).encode(w)?;
|
(self.len() as i32).encode(w)?;
|
||||||
self.iter().try_for_each(|e| e.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 {
|
impl Encodable for str {
|
||||||
fn encoded_len(&self) -> usize {
|
|
||||||
size_of::<i32>() + self.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
fn encode(&self, w: &mut impl Write) -> io::Result<()> {
|
||||||
(self.len() as i32).encode(w)?;
|
(self.len() as i32).encode(w)?;
|
||||||
w.write_all(self.as_bytes())
|
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 {
|
impl Decodable for String {
|
||||||
fn decode(r: &mut impl Read) -> io::Result<String> {
|
fn decode(r: &mut impl Read) -> io::Result<String> {
|
||||||
let len = i32::decode(r)?;
|
let len = i32::decode(r)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user