summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/analysis/ParsedJar.java
diff options
context:
space:
mode:
authorGravatar asie2018-12-08 11:21:18 +0100
committerGravatar asie2018-12-08 11:21:18 +0100
commit4bc3afe4ff08b9f0c08952ec7f6e0ac930280cc5 (patch)
tree99e43aa385d7fa1248c7fe474c022db55c364592 /src/main/java/cuchaz/enigma/analysis/ParsedJar.java
parentwork around Procyon weirdness (diff)
downloadenigma-fork-4bc3afe4ff08b9f0c08952ec7f6e0ac930280cc5.tar.gz
enigma-fork-4bc3afe4ff08b9f0c08952ec7f6e0ac930280cc5.tar.xz
enigma-fork-4bc3afe4ff08b9f0c08952ec7f6e0ac930280cc5.zip
add barebones plugin framework, cleanup
Diffstat (limited to 'src/main/java/cuchaz/enigma/analysis/ParsedJar.java')
-rw-r--r--src/main/java/cuchaz/enigma/analysis/ParsedJar.java58
1 files changed, 39 insertions, 19 deletions
diff --git a/src/main/java/cuchaz/enigma/analysis/ParsedJar.java b/src/main/java/cuchaz/enigma/analysis/ParsedJar.java
index 55f2141..86655d0 100644
--- a/src/main/java/cuchaz/enigma/analysis/ParsedJar.java
+++ b/src/main/java/cuchaz/enigma/analysis/ParsedJar.java
@@ -11,8 +11,10 @@
11 11
12package cuchaz.enigma.analysis; 12package cuchaz.enigma.analysis;
13 13
14import com.google.common.io.ByteStreams;
14import cuchaz.enigma.mapping.entry.ClassEntry; 15import cuchaz.enigma.mapping.entry.ClassEntry;
15import org.objectweb.asm.ClassReader; 16import org.objectweb.asm.ClassReader;
17import org.objectweb.asm.ClassVisitor;
16import org.objectweb.asm.tree.ClassNode; 18import org.objectweb.asm.tree.ClassNode;
17 19
18import java.io.BufferedInputStream; 20import java.io.BufferedInputStream;
@@ -20,14 +22,17 @@ import java.io.IOException;
20import java.io.InputStream; 22import java.io.InputStream;
21import java.util.*; 23import java.util.*;
22import java.util.function.Consumer; 24import java.util.function.Consumer;
25import java.util.function.Function;
23import java.util.jar.JarEntry; 26import java.util.jar.JarEntry;
24import java.util.jar.JarFile; 27import java.util.jar.JarFile;
25import java.util.jar.JarInputStream; 28import java.util.jar.JarInputStream;
26 29
27public class ParsedJar { 30public class ParsedJar {
28 private final Map<String, ClassNode> nodes = new LinkedHashMap<>(); 31 private final Map<String, byte[]> classBytes;
32 private final Map<String, ClassNode> nodeCache = new HashMap<>();
29 33
30 public ParsedJar(JarFile jar) throws IOException { 34 public ParsedJar(JarFile jar) throws IOException {
35 Map<String, byte[]> uClassBytes = new LinkedHashMap<>();;
31 try { 36 try {
32 // get the jar entries that correspond to classes 37 // get the jar entries that correspond to classes
33 Enumeration<JarEntry> entries = jar.entries(); 38 Enumeration<JarEntry> entries = jar.entries();
@@ -36,60 +41,75 @@ public class ParsedJar {
36 // is this a class file? 41 // is this a class file?
37 if (entry.getName().endsWith(".class")) { 42 if (entry.getName().endsWith(".class")) {
38 try (InputStream input = new BufferedInputStream(jar.getInputStream(entry))) { 43 try (InputStream input = new BufferedInputStream(jar.getInputStream(entry))) {
39 // read the ClassNode from the jar
40 ClassReader reader = new ClassReader(input);
41 ClassNode node = new ClassNode();
42 reader.accept(node, 0);
43 String path = entry.getName().substring(0, entry.getName().length() - ".class".length()); 44 String path = entry.getName().substring(0, entry.getName().length() - ".class".length());
44 nodes.put(path, node); 45 uClassBytes.put(path, ByteStreams.toByteArray(input));
45 } 46 }
46 } 47 }
47 } 48 }
48 } finally { 49 } finally {
49 jar.close(); 50 jar.close();
51 classBytes = Collections.unmodifiableMap(uClassBytes);
50 } 52 }
51 } 53 }
52 54
53 public ParsedJar(JarInputStream jar) throws IOException { 55 public ParsedJar(JarInputStream jar) throws IOException {
56 Map<String, byte[]> uClassBytes = new LinkedHashMap<>();
54 try { 57 try {
55 // get the jar entries that correspond to classes 58 // get the jar entries that correspond to classes
56 JarEntry entry; 59 JarEntry entry;
57 while ((entry = jar.getNextJarEntry()) != null) { 60 while ((entry = jar.getNextJarEntry()) != null) {
58 // is this a class file? 61 // is this a class file?
59 if (entry.getName().endsWith(".class")) { 62 if (entry.getName().endsWith(".class")) {
60 // read the ClassNode from the jar
61 ClassReader reader = new ClassReader(jar);
62 ClassNode node = new ClassNode();
63 reader.accept(node, 0);
64 String path = entry.getName().substring(0, entry.getName().length() - ".class".length()); 63 String path = entry.getName().substring(0, entry.getName().length() - ".class".length());
65 nodes.put(path, node); 64 uClassBytes.put(path, ByteStreams.toByteArray(jar));
66 jar.closeEntry(); 65 jar.closeEntry();
67 } 66 }
68 } 67 }
69 } finally { 68 } finally {
70 jar.close(); 69 jar.close();
70 classBytes = Collections.unmodifiableMap(uClassBytes);
71 } 71 }
72 } 72 }
73 73
74 public void visit(Consumer<ClassNode> visitor) { 74 public void visitReader(Function<String, ClassVisitor> visitorFunction, int options) {
75 for (ClassNode node : nodes.values()) { 75 for (String s : classBytes.keySet()) {
76 visitor.accept(node); 76 ClassNode nodeCached = nodeCache.get(s);
77 if (nodeCached != null) {
78 nodeCached.accept(visitorFunction.apply(s));
79 } else {
80 new ClassReader(classBytes.get(s)).accept(visitorFunction.apply(s), options);
81 }
82 }
83 }
84
85 public void visitNode(Consumer<ClassNode> consumer) {
86 for (String s : classBytes.keySet()) {
87 consumer.accept(getClassNode(s));
77 } 88 }
78 } 89 }
79 90
80 public int getClassCount() { 91 public int getClassCount() {
81 return nodes.size(); 92 return classBytes.size();
82 } 93 }
83 94
84 public List<ClassEntry> getClassEntries() { 95 public List<ClassEntry> getClassEntries() {
85 List<ClassEntry> entries = new ArrayList<>(nodes.size()); 96 List<ClassEntry> entries = new ArrayList<>(classBytes.size());
86 for (ClassNode node : nodes.values()) { 97 for (String s : classBytes.keySet()) {
87 entries.add(new ClassEntry(node.name)); 98 entries.add(new ClassEntry(s));
88 } 99 }
89 return entries; 100 return entries;
90 } 101 }
91 102
92 public ClassNode getClassNode(String name) { 103 public ClassNode getClassNode(String name) {
93 return nodes.get(name); 104 return nodeCache.computeIfAbsent(name, (n) -> {
105 ClassReader reader = new ClassReader(classBytes.get(name));
106 ClassNode node = new ClassNode();
107 reader.accept(node, 0);
108 return node;
109 });
94 } 110 }
111
112 public Map<String, byte[]> getClassDataMap() {
113 return classBytes;
114 }
95} 115}