This commit is contained in:
Jean-Marie Mineau 2023-09-05 17:52:21 +02:00
parent 23c5181269
commit 1bf328d44e
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2

View file

@ -4,6 +4,7 @@ use pyo3::exceptions::PyTypeError;
use pyo3::prelude::*; use pyo3::prelude::*;
use crate::DexString; use crate::DexString;
use androscalpel_serializer::{StringDataItem, Uleb128};
/// Represent a field. /// Represent a field.
#[pyclass] #[pyclass]
@ -281,9 +282,9 @@ impl DexDouble {
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct DexMethodType { pub struct DexMethodType {
/// Type formated as described by <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor> /// Type formated as described by <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
shorty: DexString, pub(crate) shorty: DexString,
return_type: DexType, pub(crate) return_type: DexType,
parameters: Vec<DexType>, pub(crate) parameters: Vec<DexType>,
} }
#[pymethods] #[pymethods]
@ -382,6 +383,74 @@ impl DexType {
Self(ty) Self(ty)
} }
/// Return the void type (for return type)
#[staticmethod]
pub fn void() -> Self {
Self("V".into())
}
/// Return the boolean type
#[staticmethod]
pub fn boolean() -> Self {
Self("Z".into())
}
/// Return the byte type
#[staticmethod]
pub fn byte() -> Self {
Self("B".into())
}
/// Return the short type
#[staticmethod]
pub fn short() -> Self {
Self("S".into())
}
/// Return the char type
#[staticmethod]
pub fn char() -> Self {
Self("C".into())
}
/// Return the int type
#[staticmethod]
pub fn int() -> Self {
Self("I".into())
}
/// Return the long type
#[staticmethod]
pub fn long() -> Self {
Self("J".into())
}
/// Return the float type
#[staticmethod]
pub fn float() -> Self {
Self("F".into())
}
/// Return the double type
#[staticmethod]
pub fn double() -> Self {
Self("D".into())
}
/// Return the type for the class of fully qualified name `name`
#[staticmethod]
pub fn class(name: &str) -> Self {
Self(format!("L{name}").into())
}
/// Return the type for an array of the specify `type_`
#[staticmethod]
pub fn array(type_: &DexType) -> Self {
let mut ty = type_.clone();
ty.0 .0.utf16_size.0 += 1;
ty.0 .0.data.insert(0, 0x5b);
ty
}
pub fn get_name(&self) -> DexString { pub fn get_name(&self) -> DexString {
self.0.clone() self.0.clone()
} }
@ -394,6 +463,102 @@ impl DexType {
let name: String = (&self.0).into(); let name: String = (&self.0).into();
format!("DexType({name})") format!("DexType({name})")
} }
/// Check if the type is void (return type)
pub fn is_void(&self) -> bool {
self == &Self::void()
}
/// Check if the type is boolean
pub fn is_boolean(&self) -> bool {
self == &Self::boolean()
}
/// Check if the type is byte
pub fn is_byte(&self) -> bool {
self == &Self::byte()
}
/// Check if the type is short
pub fn is_short(&self) -> bool {
self == &Self::short()
}
/// Check if the type is char
pub fn is_char(&self) -> bool {
self == &Self::char()
}
/// Check if the type is int
pub fn is_int(&self) -> bool {
self == &Self::int()
}
/// Check if the type is long
pub fn is_long(&self) -> bool {
self == &Self::long()
}
/// Check if the type is float
pub fn is_float(&self) -> bool {
self == &Self::float()
}
/// Check if the type is double
pub fn is_double(&self) -> bool {
self == &Self::double()
}
/// Check if the type is a class
pub fn is_class(&self) -> bool {
self.0.get_utf16_size() == 0
&& self.0.get_bytes().is_empty()
&& self.0.get_bytes()[0] != 0x76
// Check if first char is an L
}
/// Check if the type is an array
pub fn is_array(&self) -> bool {
self.0.get_utf16_size() == 0
&& self.0.get_bytes().is_empty()
&& self.0.get_bytes()[0] != 0x5b
// Check if first char is an [
}
/// If the type is a class, return the name of the class,
/// else None.
pub fn get_class_name(&self) -> Option<DexString> {
if self.is_class() {
Some(
StringDataItem {
utf16_size: Uleb128(self.0.get_utf16_size() - 1),
data: self.0.get_bytes()[1..].to_vec(),
}
.into(),
)
} else {
None
}
}
/// If the type is a array, return the type of the elements,
/// else None.
pub fn get_element_type(&self) -> Option<Self> {
if self.is_array() {
Some(Self(
StringDataItem {
utf16_size: Uleb128(self.0.get_utf16_size() - 1),
data: self.0.get_bytes()[1..].to_vec(),
}
.into(),
))
} else {
None
}
}
// TODO: TESTS
// TODO: move to another mod
} }
#[pyclass] #[pyclass]