1use std::io::{Seek, SeekFrom};
7
8use crate::dex::reader::DexReader;
9use crate::dex::strings::DexStrings;
10use crate::error::DexError;
11
12#[derive(Debug)]
14struct DexTypeItem {
15 offset: u32,
16 str_type: String,
17}
18
19#[derive(Debug)]
21pub struct DexTypes{
22 pub items: Vec<String>
23}
24
25impl DexTypes {
26 pub fn build(dex_reader: &mut DexReader,
28 offset: u32,
29 size: u32,
30 strings_list: &DexStrings) -> Result<Self, DexError> {
31 dex_reader.bytes.seek(SeekFrom::Start(offset.into()))?;
32
33 let mut types = Vec::new();
34
35 for _ in 0..size {
36 let offset = dex_reader.read_u32()?;
37 let str_type = strings_list.strings.get(offset as usize).ok_or(DexError::InvalidStringIdx)?;
38 types.push(DexTypeItem {
39 offset,
40 str_type: str_type.to_string(),
41 });
42 }
43 types.sort_by(|a, b| a.offset.cmp(&b.offset));
44
45 let mut items = Vec::new();
46 for dex_type in types.into_iter() {
47 items.push(dex_type.str_type);
48 }
49 items.dedup();
50
51 Ok(DexTypes { items })
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn test_build_dex_types_empty() {
61 let dex_data = vec![
62 0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
68
69 let mut dex_reader = DexReader::build(dex_data).unwrap();
70 let strings_list = DexStrings { strings: Vec::new() };
71
72 let dex_types = DexTypes::build(&mut dex_reader, 0, 0, &strings_list).unwrap();
73
74 assert_eq!(dex_types.items.len(), 0);
75 }
76
77 #[test]
78 fn test_build_dex_types() {
79 let dex_data = vec![
80 0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, ];
90
91 let mut dex_reader = DexReader::build(dex_data).unwrap();
92 let strings_list = DexStrings { strings: vec![
93 "Type0".to_string(),
94 "Type1".to_string(),
95 "Type2".to_string(),
96 "Type3".to_string(),
97 ]
98 };
99
100 let dex_types = DexTypes::build(&mut dex_reader, 50, 4, &strings_list).unwrap();
101
102 assert_eq!(dex_types.items.len(), 4);
103 assert_eq!(dex_types.items[0], "Type0");
104 assert_eq!(dex_types.items[1], "Type1");
105 assert_eq!(dex_types.items[2], "Type2");
106 assert_eq!(dex_types.items[3], "Type3");
107 }
108
109 #[test]
110 fn test_build_dex_types_duplicates() {
111 let dex_data = vec![
112 0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, ];
121
122 let mut dex_reader = DexReader::build(dex_data).unwrap();
123 let strings_list = DexStrings { strings: vec![
124 "Type0".to_string(),
125 "Type1".to_string(),
126 "Type1".to_string(),
127 ]
128 };
129
130 let dex_types = DexTypes::build(&mut dex_reader, 50, 2, &strings_list).unwrap();
131
132 assert_eq!(dex_types.items.len(), 2);
133 assert_eq!(dex_types.items[0], "Type0");
134 assert_eq!(dex_types.items[1], "Type1");
135 }
136}