#![allow(dead_code)]
use crate::{
chunks::{
chunk_header::ChunkHeader,
chunk_types::ChunkType,
string_pool::StringPool
},
errors::AxmlError
};
use std::io::Cursor;
use byteorder::{
LittleEndian,
ReadBytesExt
};
pub struct ResTable {
header: ChunkHeader,
pub package_count: u32,
}
impl ResTable {
pub fn parse(axml_buff: &mut Cursor<Vec<u8>>) -> Result<Self, AxmlError> {
let initial_offset = axml_buff.position();
axml_buff.set_position(initial_offset - 2);
let header = ChunkHeader::from_buff(axml_buff, ChunkType::ResTableType)?;
let package_count = axml_buff.read_u32::<LittleEndian>()?;
let mut strings = Vec::<String>::new();
for _ in 0..package_count {
let block_type = ChunkType::parse_block_type(axml_buff)?;
match block_type {
ChunkType::ResStringPoolType => {
StringPool::from_buff(axml_buff, &mut strings)?;
},
ChunkType::ResTablePackageType => {
ResTablePackage::parse(axml_buff)?;
},
_ => { panic!("######## Unexpected block type: {block_type:02X}"); }
};
}
Ok(Self {
header,
package_count
})
}
}
#[derive(Debug)]
pub struct ResTablePackage {
header: ChunkHeader,
id: u32,
name: [u16; 128],
type_strings: u32,
last_public_type: u32,
key_strings: u32,
last_public_key: u32,
type_id_offset: u32,
}
impl ResTablePackage {
pub fn parse(axml_buff: &mut Cursor<Vec<u8>>) -> Result<Self, AxmlError> {
let initial_offset = axml_buff.position();
axml_buff.set_position(initial_offset - 2);
let header = ChunkHeader::from_buff(axml_buff, ChunkType::ResTablePackageType)?;
let id = axml_buff.read_u32::<LittleEndian>()?;
let mut name: [u16; 128] = [0; 128];
for item in &mut name {
*item = axml_buff.read_u16::<LittleEndian>()?;
if *item == 0x00 {
break;
}
}
let type_strings = axml_buff.read_u32::<LittleEndian>()?;
let last_public_type = axml_buff.read_u32::<LittleEndian>()?;
let key_strings = axml_buff.read_u32::<LittleEndian>()?;
let last_public_key = axml_buff.read_u32::<LittleEndian>()?;
let type_id_offset = axml_buff.read_u32::<LittleEndian>()?;
Ok(ResTablePackage {
header,
id,
name,
type_strings,
last_public_type,
key_strings,
last_public_key,
type_id_offset
})
}
}