implement annotation
This commit is contained in:
parent
1b503549b3
commit
d5b8222491
3 changed files with 65 additions and 14 deletions
|
|
@ -1,18 +1,69 @@
|
||||||
use crate::{ReadSeek, Result, Serializable};
|
use crate::{EncodedValue, Error, ReadSeek, Result, Serializable, Uleb128};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
|
// To derive Serializable
|
||||||
|
use crate as androscalpel_serializer;
|
||||||
|
|
||||||
|
/// Encoded Annotation https://source.android.com/docs/core/runtime/dex-format#encoded-annotation
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct EncodedAnnotation;
|
pub struct EncodedAnnotation {
|
||||||
|
/// Type of the annotation. This must be a class (not array or primitive) type.
|
||||||
|
pub type_idx: Uleb128, // TODO: check it's a class
|
||||||
|
//pub size: Uleb128,
|
||||||
|
pub elements: Vec<AnnotationElement>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EncodedAnnotation {
|
||||||
|
/// Return the size field
|
||||||
|
pub fn size_field(&self) -> Uleb128 {
|
||||||
|
Uleb128(self.elements.len() as u32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Annotation: https://source.android.com/docs/core/runtime/dex-format#annotation-element
|
||||||
|
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct AnnotationElement {
|
||||||
|
pub name_idx: Uleb128,
|
||||||
|
pub value: EncodedValue,
|
||||||
|
}
|
||||||
|
|
||||||
impl Serializable for EncodedAnnotation {
|
impl Serializable for EncodedAnnotation {
|
||||||
fn serialize(&self, _output: &mut dyn Write) -> Result<()> {
|
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
||||||
todo!()
|
let Self { type_idx, elements } = self;
|
||||||
|
// Check if the element are sorted
|
||||||
|
if !elements.is_empty() {
|
||||||
|
let mut idx_0 = elements[0].name_idx;
|
||||||
|
for idx_1 in elements.iter().map(|elt| elt.name_idx).skip(1) {
|
||||||
|
if idx_0 > idx_1 {
|
||||||
|
return Err(Error::SerializationError(format!(
|
||||||
|
"Failed to serialize EncodedAnnotation: element must be sorted in increasing order by string_id index, found {idx_0:?} before {idx_1:?}"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
idx_0 = idx_1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type_idx.serialize(output)?;
|
||||||
|
self.size_field().serialize(output)?;
|
||||||
|
for elt in elements {
|
||||||
|
elt.serialize(output)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
fn deserialize(_input: &mut dyn ReadSeek) -> Result<Self> {
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
todo!()
|
let type_idx = Uleb128::deserialize(input)?;
|
||||||
|
let Uleb128(size) = Uleb128::deserialize(input)?;
|
||||||
|
let mut elements = vec![];
|
||||||
|
for _ in 0..size {
|
||||||
|
elements.push(AnnotationElement::deserialize(input)?);
|
||||||
|
}
|
||||||
|
Ok(Self { type_idx, elements })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> usize {
|
fn size(&self) -> usize {
|
||||||
todo!()
|
self.type_idx.size()
|
||||||
|
+ self.size_field().size()
|
||||||
|
+ self.elements.iter().map(|val| val.size()).sum::<usize>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add tests
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,15 @@ pub struct EncodedArray {
|
||||||
|
|
||||||
impl EncodedArray {
|
impl EncodedArray {
|
||||||
/// Return the size field
|
/// Return the size field
|
||||||
pub fn size(&self) -> Uleb128 {
|
pub fn size_field(&self) -> Uleb128 {
|
||||||
Uleb128(self.values.len() as u32)
|
Uleb128(self.values.len() as u32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serializable for EncodedArray {
|
impl Serializable for EncodedArray {
|
||||||
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
||||||
self.size().serialize(output)?;
|
self.size_field().serialize(output)?;
|
||||||
for value in self.values {
|
for value in &self.values {
|
||||||
value.serialize(output)?;
|
value.serialize(output)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -38,6 +38,6 @@ impl Serializable for EncodedArray {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> usize {
|
fn size(&self) -> usize {
|
||||||
self.size().size() + self.values.iter().map(|val| val.size()).sum::<usize>()
|
self.size_field().size() + self.values.iter().map(|val| val.size()).sum::<usize>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,15 @@ use std::io::Write;
|
||||||
use crate::{Error, ReadSeek, Result, Serializable};
|
use crate::{Error, ReadSeek, Result, Serializable};
|
||||||
|
|
||||||
/// Signed LEB128, variable-length
|
/// Signed LEB128, variable-length
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct Sleb128(pub i32);
|
pub struct Sleb128(pub i32);
|
||||||
|
|
||||||
/// Unsigned LEB128, variable-length
|
/// Unsigned LEB128, variable-length
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct Uleb128(pub u32);
|
pub struct Uleb128(pub u32);
|
||||||
|
|
||||||
/// Unsigned LEB128 plus 1, variable-length
|
/// Unsigned LEB128 plus 1, variable-length
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct Uleb128p1(pub u32);
|
pub struct Uleb128p1(pub u32);
|
||||||
|
|
||||||
impl Sleb128 {
|
impl Sleb128 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue