resources: initial version of .arsc file decode

This commit is contained in:
Skylot
2015-10-09 21:41:38 +03:00
parent e4fef402c9
commit ef8a685621
18 changed files with 480 additions and 96 deletions
@@ -1,8 +1,10 @@
package jadx.gui.treemodel;
import jadx.api.ResourceFile;
import jadx.api.ResourceFileContent;
import jadx.api.ResourceType;
import jadx.core.codegen.CodeWriter;
import jadx.core.xmlgen.ResContainer;
import jadx.gui.utils.OverlayIcon;
import jadx.gui.utils.Utils;
@@ -31,6 +33,7 @@ public class JResource extends JNode implements Comparable<JResource> {
}
private final String name;
private final String shortName;
private final List<JResource> files = new ArrayList<JResource>(1);
private final JResType type;
private final ResourceFile resFile;
@@ -40,12 +43,18 @@ public class JResource extends JNode implements Comparable<JResource> {
private Map<Integer, Integer> lineMapping;
public JResource(ResourceFile resFile, String name, JResType type) {
this(resFile, name, name, type);
}
public JResource(ResourceFile resFile, String name, String shortName, JResType type) {
this.resFile = resFile;
this.name = name;
this.shortName = shortName;
this.type = type;
}
public final void update() {
loadContent();
removeAllChildren();
for (JResource res : files) {
res.update();
@@ -53,6 +62,13 @@ public class JResource extends JNode implements Comparable<JResource> {
}
}
protected void loadContent() {
getContent();
for (JResource res : files) {
res.loadContent();
}
}
public String getName() {
return name;
}
@@ -65,16 +81,64 @@ public class JResource extends JNode implements Comparable<JResource> {
if (!loaded && resFile != null && type == JResType.FILE) {
loaded = true;
if (isSupportedForView(resFile.getType())) {
CodeWriter cw = resFile.getContent();
if (cw != null) {
lineMapping = cw.getLineMapping();
content = cw.toString();
ResContainer rc = resFile.getContent();
if (rc != null) {
addSubFiles(rc, this, 0);
}
}
}
return content;
}
protected void addSubFiles(ResContainer rc, JResource root, int depth) {
CodeWriter cw = rc.getContent();
if (cw != null) {
if (depth == 0) {
root.lineMapping = cw.getLineMapping();
root.content = cw.toString();
} else {
String name = rc.getName();
String[] path = name.split("/");
String shortName = path.length == 0 ? name : path[path.length - 1];
ResourceFileContent fileContent = new ResourceFileContent(shortName, ResourceType.XML, cw);
addPath(path, root, new JResource(fileContent, name, shortName, JResType.FILE));
}
}
List<ResContainer> subFiles = rc.getSubFiles();
if (!subFiles.isEmpty()) {
for (ResContainer subFile : subFiles) {
addSubFiles(subFile, root, depth + 1);
}
}
}
private static void addPath(String[] path, JResource root, JResource jResource) {
if (path.length == 1) {
root.getFiles().add(jResource);
return;
}
int last = path.length - 1;
for (int i = 0; i <= last; i++) {
String f = path[i];
if (i == last) {
root.getFiles().add(jResource);
} else {
root = getResDir(root, f);
}
}
}
private static JResource getResDir(JResource root, String dirName) {
for (JResource file : root.getFiles()) {
if (file.getName().equals(dirName)) {
return file;
}
}
JResource resDir = new JResource(null, dirName, JResType.DIR);
root.getFiles().add(resDir);
return resDir;
}
@Override
public Integer getSourceLine(int line) {
if (lineMapping == null) {
@@ -170,7 +234,7 @@ public class JResource extends JNode implements Comparable<JResource> {
@Override
public String makeString() {
return name;
return shortName;
}
@Override