1use std::io::{Seek, SeekFrom};
10use std::cmp::Ordering;
11
12use crate::error::DexError;
13use crate::dex::reader::DexReader;
14use crate::dex::types::DexTypes;
15use crate::dex::protos::DexProtos;
16use crate::dex::strings::DexStrings;
17
18#[derive(Debug)]
20struct MethodIdItem {
21 class_idx: u16,
22 proto_idx: u16,
23 name_idx: u32,
24 decoded: String
25}
26
27#[derive(Debug)]
29pub struct DexMethods {
30 pub items: Vec<String>
31}
32
33impl DexMethods {
34 fn sort(a: &MethodIdItem, b: &MethodIdItem) -> Ordering {
36 let mut order = a.class_idx.cmp(&b.class_idx);
38
39 if order == Ordering::Equal {
40 order = a.name_idx.cmp(&b.name_idx);
42 }
43
44 if order == Ordering::Equal {
45 order = a.proto_idx.cmp(&b.proto_idx);
47 }
48
49 order
50 }
51
52 pub fn build(dex_reader: &mut DexReader,
54 offset: u32,
55 size: u32,
56 types_list: &DexTypes,
57 protos_list: &DexProtos,
58 strings_list: &DexStrings) -> Result<Self, DexError> {
59 dex_reader.bytes.seek(SeekFrom::Start(offset.into()))?;
60
61 let mut methods = Vec::new();
62
63 for _ in 0..size {
64 let class_idx = dex_reader.read_u16()?;
65 let proto_idx = dex_reader.read_u16()?;
66 let name_idx = dex_reader.read_u32()?;
67
68 let mut decoded = String::new();
69 decoded.push_str(types_list.items.get(class_idx as usize).ok_or(DexError::InvalidTypeIdx)?);
70 decoded.push_str("->");
71 decoded.push_str(strings_list.strings.get(name_idx as usize).ok_or(DexError::InvalidStringIdx)?);
72 decoded.push_str(protos_list.items.get(proto_idx as usize).ok_or(DexError::InvalidTypeIdx)?);
73
74 methods.push(MethodIdItem {
75 class_idx,
76 proto_idx,
77 name_idx,
78 decoded
79 });
80 }
81
82 methods.sort_by(DexMethods::sort);
83
84 let mut items = Vec::new();
85 for dex_method in methods.into_iter() {
86 items.push(dex_method.decoded);
87 }
88 items.dedup();
89
90 Ok(DexMethods { items })
91 }
92}