summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java')
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java
new file mode 100644
index 0000000..70f3f18
--- /dev/null
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java
@@ -0,0 +1,153 @@
1package cuchaz.enigma.mapping;
2
3import com.google.common.base.Charsets;
4import com.google.common.collect.Queues;
5import cuchaz.enigma.throwables.MappingConflict;
6import cuchaz.enigma.throwables.MappingParseException;
7
8import java.io.*;
9import java.util.Deque;
10
11public class MappingsEnigmaReader
12{
13
14 public Mappings read(File file) throws IOException, MappingParseException {
15 Mappings mappings;
16
17 // Multiple file
18 if (file.isDirectory())
19 {
20 mappings = new Mappings(Mappings.FormatType.ENIGMA_DIRECTORY);
21 readDirectory(mappings, file);
22 }
23 else
24 {
25 mappings = new Mappings();
26 readFile(mappings, new BufferedReader(new InputStreamReader(new FileInputStream(file), Charsets.UTF_8)));
27 }
28 return mappings;
29 }
30
31 public void readDirectory(Mappings mappings, File directory) throws IOException, MappingParseException {
32 File[] files = directory.listFiles();
33 if (files != null) {
34 for (File file : files) {
35 if (file.isFile())
36 readFile(mappings, new BufferedReader(new InputStreamReader(new FileInputStream(file), Charsets.UTF_8)));
37 else if (file.isDirectory())
38 readDirectory(mappings, file.getAbsoluteFile());
39 }
40 }
41 else
42 throw new IOException("Cannot access directory" + directory.getAbsolutePath());
43 }
44
45 public Mappings readFile(Mappings mappings, BufferedReader in) throws IOException, MappingParseException {
46
47 Deque<Object> mappingStack = Queues.newArrayDeque();
48
49 int lineNumber = 0;
50 String line;
51 while ((line = in.readLine()) != null) {
52 lineNumber++;
53
54 // strip comments
55 int commentPos = line.indexOf('#');
56 if (commentPos >= 0) {
57 line = line.substring(0, commentPos);
58 }
59
60 // skip blank lines
61 if (line.trim().length() <= 0) {
62 continue;
63 }
64
65 // get the indent of this line
66 int indent = 0;
67 for (int i = 0; i < line.length(); i++) {
68 if (line.charAt(i) != '\t') {
69 break;
70 }
71 indent++;
72 }
73
74 // handle stack pops
75 while (indent < mappingStack.size()) {
76 mappingStack.pop();
77 }
78
79 String[] parts = line.trim().split("\\s");
80 try {
81 // read the first token
82 String token = parts[0];
83
84 if (token.equalsIgnoreCase("CLASS")) {
85 ClassMapping classMapping;
86 if (indent <= 0) {
87 // outer class
88 classMapping = readClass(parts);
89 mappings.addClassMapping(classMapping);
90 } else {
91
92 // inner class
93 if (!(mappingStack.peek() instanceof ClassMapping)) {
94 throw new MappingParseException(lineNumber, "Unexpected CLASS entry here!");
95 }
96
97 classMapping = readClass(parts);
98 ((ClassMapping) mappingStack.peek()).addInnerClassMapping(classMapping);
99 }
100 mappingStack.push(classMapping);
101 } else if (token.equalsIgnoreCase("FIELD")) {
102 if (mappingStack.isEmpty() || !(mappingStack.peek() instanceof ClassMapping)) {
103 throw new MappingParseException(lineNumber, "Unexpected FIELD entry here!");
104 }
105 ((ClassMapping) mappingStack.peek()).addFieldMapping(readField(parts));
106 } else if (token.equalsIgnoreCase("METHOD")) {
107 if (mappingStack.isEmpty() || !(mappingStack.peek() instanceof ClassMapping)) {
108 throw new MappingParseException(lineNumber, "Unexpected METHOD entry here!");
109 }
110 MethodMapping methodMapping = readMethod(parts);
111 ((ClassMapping) mappingStack.peek()).addMethodMapping(methodMapping);
112 mappingStack.push(methodMapping);
113 } else if (token.equalsIgnoreCase("ARG")) {
114 if (mappingStack.isEmpty() || !(mappingStack.peek() instanceof MethodMapping)) {
115 throw new MappingParseException(lineNumber, "Unexpected ARG entry here!");
116 }
117 ((MethodMapping) mappingStack.peek()).addArgumentMapping(readArgument(parts));
118 }
119 } catch (ArrayIndexOutOfBoundsException | IllegalArgumentException ex) {
120 throw new MappingParseException(lineNumber, "Malformed line:\n" + line);
121 } catch (MappingConflict e) {
122 e.printStackTrace();
123 }
124 }
125 in.close();
126 return mappings;
127 }
128
129 private ArgumentMapping readArgument(String[] parts) {
130 return new ArgumentMapping(Integer.parseInt(parts[1]), parts[2]);
131 }
132
133 private ClassMapping readClass(String[] parts) {
134 if (parts.length == 2) {
135 return new ClassMapping(parts[1]);
136 } else {
137 return new ClassMapping(parts[1], parts[2]);
138 }
139 }
140
141 /* TEMP */
142 protected FieldMapping readField(String[] parts) {
143 return new FieldMapping(parts[1], new Type(parts[3]), parts[2]);
144 }
145
146 private MethodMapping readMethod(String[] parts) {
147 if (parts.length == 3) {
148 return new MethodMapping(parts[1], new Signature(parts[2]));
149 } else {
150 return new MethodMapping(parts[1], new Signature(parts[3]), parts[2]);
151 }
152 }
153}