add Apk::merge
This commit is contained in:
parent
6e218f85f9
commit
64a4804371
1 changed files with 60 additions and 0 deletions
|
|
@ -3307,4 +3307,64 @@ impl Apk {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Merget two application into one.
|
||||||
|
pub fn merge(&mut self, Self { mut dex_files }: Self) -> Result<()> {
|
||||||
|
let mut i = 0;
|
||||||
|
let mut name: String = "classes.dex".into();
|
||||||
|
while self.dex_files.contains_key(&name) {
|
||||||
|
i += 1;
|
||||||
|
name = format!("classes{}.dex", i + 1);
|
||||||
|
}
|
||||||
|
let mut j = 0;
|
||||||
|
let mut other_name: String = "classes.dex".into();
|
||||||
|
while let Some(file) = dex_files.remove(&other_name) {
|
||||||
|
self.dex_files.insert(name.clone(), file);
|
||||||
|
j += 1;
|
||||||
|
other_name = format!("classes{}.dex", j + 1);
|
||||||
|
while self.dex_files.contains_key(&name) {
|
||||||
|
i += 1;
|
||||||
|
name = format!("classes{}.dex", i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maybe not a good idea reinserting invalid .dex as valid ones, so explicitly skip one
|
||||||
|
// index to keep the files invalids.
|
||||||
|
i += 1;
|
||||||
|
name = format!("classes{}.dex", i + 1);
|
||||||
|
while self.dex_files.contains_key(&name) {
|
||||||
|
i += 1;
|
||||||
|
name = format!("classes{}.dex", i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (other_name, dex) in dex_files.into_iter() {
|
||||||
|
if get_dex_name_index(&other_name).is_some() {
|
||||||
|
self.dex_files.insert(name.clone(), dex);
|
||||||
|
while self.dex_files.contains_key(&name) {
|
||||||
|
i += 1;
|
||||||
|
name = format!("classes{}.dex", i + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut new_name = other_name.clone();
|
||||||
|
let mut k = 1;
|
||||||
|
while self.dex_files.contains_key(&new_name) {
|
||||||
|
k += 1;
|
||||||
|
new_name = format!("{other_name}-{k}")
|
||||||
|
}
|
||||||
|
self.dex_files.insert(new_name, dex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse a .dex file name, and if it is a valid android file, return the index of the file.
|
||||||
|
fn get_dex_name_index(name: &str) -> Option<usize> {
|
||||||
|
if name == "classes.dex" {
|
||||||
|
return Some(0);
|
||||||
|
}
|
||||||
|
name.strip_prefix("classes")
|
||||||
|
.and_then(|name| name.strip_suffix(".dex"))
|
||||||
|
.and_then(|name| name.parse::<usize>().ok())
|
||||||
|
.and_then(|idx| if idx <= 1 { None } else { Some(idx - 1) })
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue