implement map item

This commit is contained in:
Jean-Marie Mineau 2023-08-25 14:42:20 +02:00
parent 52447aef42
commit 9fe2652448
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
2 changed files with 102 additions and 0 deletions

View file

@ -0,0 +1,100 @@
//! The map item: https://source.android.com/docs/core/runtime/dex-format#map-list
use crate as androscalpel_serializer;
use crate::core::{ReadSeek, Result, Serializable};
use std::io::Write;
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct MapList {
// pub size: u32,
pub list: Vec<MapItem>,
}
/// The location and size of an item: https://source.android.com/docs/core/runtime/dex-format#map-item
#[derive(Serializable, Clone, PartialEq, Eq, Debug)]
pub struct MapItem {
pub type_: MapItemType,
pub unused: u16,
pub size: u32,
pub offset: u32,
}
/// The type of the items refered by a [`MapItem`]: https://source.android.com/docs/core/runtime/dex-format#type-codes
#[derive(Serializable, Clone, Copy, PartialEq, Eq, Debug)]
#[prefix_type(u16)]
pub enum MapItemType {
#[prefix(0x0000)]
HeaderItem,
#[prefix(0x0001)]
StringIdItem,
#[prefix(0x0002)]
TypeIdItem,
#[prefix(0x0003)]
ProtoIdItem,
#[prefix(0x0004)]
FieldIdItem,
#[prefix(0x0005)]
MethodIdItem,
#[prefix(0x0006)]
ClassDefItem,
#[prefix(0x0007)]
CallSiteIdItem,
#[prefix(0x0008)]
MethodHandleItem,
#[prefix(0x1000)]
MapList,
#[prefix(0x1001)]
TypeList,
#[prefix(0x1002)]
AnnotationSetRefList,
#[prefix(0x1003)]
AnnotationSetItem,
#[prefix(0x2000)]
ClassDataItem,
#[prefix(0x2001)]
CodeItem,
#[prefix(0x2002)]
StringDataItem,
#[prefix(0x2003)]
DebugInfoItem,
#[prefix(0x2004)]
AnnotationItem,
#[prefix(0x2005)]
EncodedArrayItem,
#[prefix(0x2006)]
AnnotationsDirectoryItem,
#[prefix(0xF000)]
HiddenapiClassDataItem,
}
impl MapList {
/// The size field of a MapList.
pub fn size_field(&self) -> u32 {
self.list.len() as u32
}
}
impl Serializable for MapList {
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
self.size_field().serialize(output)?;
for map_item in self.list {
map_item.serialize(output)?;
}
Ok(())
}
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
let size = u32::deserialize(input)?;
let mut list = vec![];
for _ in 0..size {
list.push(MapItem::deserialize(input)?);
}
Ok(Self { list })
}
fn size(&self) -> usize {
self.size_field().size() + self.list.iter().map(|item| item.size()).sum::<usize>()
}
}
// TODO: add tests

View file

@ -2,6 +2,7 @@ pub mod annotation;
pub mod array;
pub mod constant;
pub mod core;
pub mod items;
pub mod value;
pub use androscalpel_serializer_derive::*;
@ -10,4 +11,5 @@ pub use crate::core::*;
pub use annotation::*;
pub use array::*;
pub use constant::*;
pub use items::*;
pub use value::*;