summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/analysis/JarClassIterator.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuchaz/enigma/analysis/JarClassIterator.java')
-rw-r--r--src/cuchaz/enigma/analysis/JarClassIterator.java107
1 files changed, 41 insertions, 66 deletions
diff --git a/src/cuchaz/enigma/analysis/JarClassIterator.java b/src/cuchaz/enigma/analysis/JarClassIterator.java
index f65b8e7..8d9947c 100644
--- a/src/cuchaz/enigma/analysis/JarClassIterator.java
+++ b/src/cuchaz/enigma/analysis/JarClassIterator.java
@@ -30,132 +30,107 @@ import com.google.common.collect.Lists;
30import cuchaz.enigma.Constants; 30import cuchaz.enigma.Constants;
31import cuchaz.enigma.mapping.ClassEntry; 31import cuchaz.enigma.mapping.ClassEntry;
32 32
33public class JarClassIterator implements Iterator<CtClass> 33public class JarClassIterator implements Iterator<CtClass> {
34{ 34
35 private JarFile m_jar; 35 private JarFile m_jar;
36 private Iterator<JarEntry> m_iter; 36 private Iterator<JarEntry> m_iter;
37 37
38 public JarClassIterator( JarFile jar ) 38 public JarClassIterator(JarFile jar) {
39 {
40 m_jar = jar; 39 m_jar = jar;
41 40
42 // get the jar entries that correspond to classes 41 // get the jar entries that correspond to classes
43 List<JarEntry> classEntries = Lists.newArrayList(); 42 List<JarEntry> classEntries = Lists.newArrayList();
44 Enumeration<JarEntry> entries = m_jar.entries(); 43 Enumeration<JarEntry> entries = m_jar.entries();
45 while( entries.hasMoreElements() ) 44 while (entries.hasMoreElements()) {
46 {
47 JarEntry entry = entries.nextElement(); 45 JarEntry entry = entries.nextElement();
48 46
49 // is this a class file? 47 // is this a class file?
50 if( entry.getName().endsWith( ".class" ) ) 48 if (entry.getName().endsWith(".class")) {
51 { 49 classEntries.add(entry);
52 classEntries.add( entry );
53 } 50 }
54 } 51 }
55 m_iter = classEntries.iterator(); 52 m_iter = classEntries.iterator();
56 } 53 }
57 54
58 @Override 55 @Override
59 public boolean hasNext( ) 56 public boolean hasNext() {
60 {
61 return m_iter.hasNext(); 57 return m_iter.hasNext();
62 } 58 }
63 59
64 @Override 60 @Override
65 public CtClass next( ) 61 public CtClass next() {
66 {
67 JarEntry entry = m_iter.next(); 62 JarEntry entry = m_iter.next();
68 try 63 try {
69 { 64 return getClass(m_jar, entry);
70 return getClass( m_jar, entry ); 65 } catch (IOException | NotFoundException ex) {
71 } 66 throw new Error("Unable to load class: " + entry.getName());
72 catch( IOException | NotFoundException ex )
73 {
74 throw new Error( "Unable to load class: " + entry.getName() );
75 } 67 }
76 } 68 }
77 69
78 @Override 70 @Override
79 public void remove( ) 71 public void remove() {
80 {
81 throw new UnsupportedOperationException(); 72 throw new UnsupportedOperationException();
82 } 73 }
83 74
84 public static List<ClassEntry> getClassEntries( JarFile jar ) 75 public static List<ClassEntry> getClassEntries(JarFile jar) {
85 {
86 List<ClassEntry> classEntries = Lists.newArrayList(); 76 List<ClassEntry> classEntries = Lists.newArrayList();
87 Enumeration<JarEntry> entries = jar.entries(); 77 Enumeration<JarEntry> entries = jar.entries();
88 while( entries.hasMoreElements() ) 78 while (entries.hasMoreElements()) {
89 {
90 JarEntry entry = entries.nextElement(); 79 JarEntry entry = entries.nextElement();
91 80
92 // is this a class file? 81 // is this a class file?
93 if( !entry.isDirectory() && entry.getName().endsWith( ".class" ) ) 82 if (!entry.isDirectory() && entry.getName().endsWith(".class")) {
94 { 83 classEntries.add(getClassEntry(entry));
95 classEntries.add( getClassEntry( entry ) );
96 } 84 }
97 } 85 }
98 return classEntries; 86 return classEntries;
99 } 87 }
100 88
101 public static Iterable<CtClass> classes( final JarFile jar ) 89 public static Iterable<CtClass> classes(final JarFile jar) {
102 { 90 return new Iterable<CtClass>() {
103 return new Iterable<CtClass>( )
104 {
105 @Override 91 @Override
106 public Iterator<CtClass> iterator( ) 92 public Iterator<CtClass> iterator() {
107 { 93 return new JarClassIterator(jar);
108 return new JarClassIterator( jar );
109 } 94 }
110 }; 95 };
111 } 96 }
112 97
113 public static CtClass getClass( JarFile jar, ClassEntry classEntry ) 98 public static CtClass getClass(JarFile jar, ClassEntry classEntry) {
114 { 99 try {
115 try 100 return getClass(jar, new JarEntry(classEntry.getName() + ".class"));
116 { 101 } catch (IOException | NotFoundException ex) {
117 return getClass( jar, new JarEntry( classEntry.getName() + ".class" ) ); 102 throw new Error("Unable to load class: " + classEntry.getName());
118 }
119 catch( IOException | NotFoundException ex )
120 {
121 throw new Error( "Unable to load class: " + classEntry.getName() );
122 } 103 }
123 } 104 }
124 105
125 private static CtClass getClass( JarFile jar, JarEntry entry ) 106 private static CtClass getClass(JarFile jar, JarEntry entry) throws IOException, NotFoundException {
126 throws IOException, NotFoundException
127 {
128 // read the class into a buffer 107 // read the class into a buffer
129 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 108 ByteArrayOutputStream bos = new ByteArrayOutputStream();
130 byte[] buf = new byte[Constants.KiB]; 109 byte[] buf = new byte[Constants.KiB];
131 int totalNumBytesRead = 0; 110 int totalNumBytesRead = 0;
132 InputStream in = jar.getInputStream( entry ); 111 InputStream in = jar.getInputStream(entry);
133 while( in.available() > 0 ) 112 while (in.available() > 0) {
134 { 113 int numBytesRead = in.read(buf);
135 int numBytesRead = in.read( buf ); 114 if (numBytesRead < 0) {
136 if( numBytesRead < 0 )
137 {
138 break; 115 break;
139 } 116 }
140 bos.write( buf, 0, numBytesRead ); 117 bos.write(buf, 0, numBytesRead);
141 118
142 // sanity checking 119 // sanity checking
143 totalNumBytesRead += numBytesRead; 120 totalNumBytesRead += numBytesRead;
144 if( totalNumBytesRead > Constants.MiB ) 121 if (totalNumBytesRead > Constants.MiB) {
145 { 122 throw new Error("Class file " + entry.getName() + " larger than 1 MiB! Something is wrong!");
146 throw new Error( "Class file " + entry.getName() + " larger than 1 MiB! Something is wrong!" );
147 } 123 }
148 } 124 }
149 125
150 // get a javassist handle for the class 126 // get a javassist handle for the class
151 String className = Descriptor.toJavaName( getClassEntry( entry ).getName() ); 127 String className = Descriptor.toJavaName(getClassEntry(entry).getName());
152 ClassPool classPool = new ClassPool(); 128 ClassPool classPool = new ClassPool();
153 classPool.insertClassPath( new ByteArrayClassPath( className, bos.toByteArray() ) ); 129 classPool.insertClassPath(new ByteArrayClassPath(className, bos.toByteArray()));
154 return classPool.get( className ); 130 return classPool.get(className);
155 } 131 }
156 132
157 private static ClassEntry getClassEntry( JarEntry entry ) 133 private static ClassEntry getClassEntry(JarEntry entry) {
158 { 134 return new ClassEntry(entry.getName().substring(0, entry.getName().length() - ".class".length()));
159 return new ClassEntry( entry.getName().substring( 0, entry.getName().length() - ".class".length() ) );
160 } 135 }
161} 136}