1
|
package deserialize;
|
2
|
|
3
|
import java.nio.ByteBuffer;
|
4
|
import java.util.ArrayList;
|
5
|
import java.util.HashMap;
|
6
|
import java.util.List;
|
7
|
|
8
|
import org.json.simple.JSONObject;
|
9
|
|
10
|
/**
|
11
|
* https://docs.oracle.com/javase/7/docs/platform/serialization/spec/protocol.html
|
12
|
*/
|
13
|
public class Grammar {
|
14
|
|
15
|
private final static short STREAM_MAGIC = (short) 0xACED;
|
16
|
private final static short STREAM_VERSION = 5;
|
17
|
private final static byte TC_NULL = 0x70;
|
18
|
private final static byte TC_REFERENCE = 0x71;
|
19
|
private final static byte TC_CLASSDESC = 0x72;
|
20
|
private final static byte TC_OBJECT = 0x73;
|
21
|
private final static byte TC_STRING = 0x74;
|
22
|
private final static byte TC_ARRAY = 0x75;
|
23
|
private final static byte TC_CLASS = 0x76;
|
24
|
private final static byte TC_BLOCKDATA = 0x77;
|
25
|
private final static byte TC_ENDBLOCKDATA = 0x78;
|
26
|
private final static byte TC_RESET = 0x79;
|
27
|
private final static byte TC_BLOCKDATALONG = 0x7A;
|
28
|
private final static byte TC_EXCEPTION = 0x7B;
|
29
|
private final static byte TC_LONGSTRING = 0x7C;
|
30
|
private final static byte TC_PROXYCLASSDESC = 0x7D;
|
31
|
private final static byte TC_ENUM = 0x7E;
|
32
|
private final static int baseWireHandle = (int) 0x7E0000;
|
33
|
|
34
|
final static byte SC_WRITE_METHOD = 0x01; // if SC_SERIALIZABLE
|
35
|
final static byte SC_BLOCK_DATA = 0x08; // if SC_EXTERNALIZABLE
|
36
|
final static byte SC_SERIALIZABLE = 0x02;
|
37
|
final static byte SC_EXTERNALIZABLE = 0x04;
|
38
|
final static byte SC_ENUM = 0x10;
|
39
|
|
40
|
private ByteReader reader;
|
41
|
|
42
|
public Grammar(byte buffer[]) {
|
43
|
reader = new ByteReader(buffer);
|
44
|
}
|
45
|
|
46
|
|
47
|
List<ClassDescription> classes = new ArrayList<ClassDescription>();
|
48
|
ClassDescription actClass = null;
|
49
|
|
50
|
public JSONObject process() {
|
51
|
System.out.println("Kontrola hlavicky souboru: " + (reader.readShort() == STREAM_MAGIC && reader.readShort() == STREAM_VERSION));
|
52
|
|
53
|
while (!reader.end()) {
|
54
|
try {
|
55
|
object();
|
56
|
} catch (Exception e) {
|
57
|
e.printStackTrace();
|
58
|
break;
|
59
|
}
|
60
|
}
|
61
|
|
62
|
return classes.get(0).getJSONObject();
|
63
|
// System.out.println(classes.get(0).toString());
|
64
|
}
|
65
|
|
66
|
// FOR VALUES :
|
67
|
// The size and types are described by the
|
68
|
// classDesc for the current object
|
69
|
public Object object() {
|
70
|
Object retValue;
|
71
|
byte b = reader.readByte();
|
72
|
switch (b) {
|
73
|
case TC_OBJECT: {
|
74
|
System.out.println("X1");
|
75
|
|
76
|
// Note. TC_OBJECT; classDesc(); classdata()[]; // data for each class
|
77
|
// Note. classDescFlags = (byte)
|
78
|
|
79
|
ClassDescription desc = (ClassDescription) object();
|
80
|
retValue = desc;
|
81
|
|
82
|
/*byte flags = readByte();
|
83
|
System.out.println("DEF: " + String.format("%02X", flags));
|
84
|
boolean xxx = SC_SERIALIZABLE == desc2.flags && SC_WRITE_METHOD != flags;
|
85
|
boolean xxx2 = SC_SERIALIZABLE == desc2.flags && SC_WRITE_METHOD == flags;
|
86
|
boolean xxx3 = SC_EXTERNALIZABLE == desc2.flags && SC_BLOCK_DATA != flags;
|
87
|
boolean xxx4 = SC_EXTERNALIZABLE == desc2.flags && SC_BLOCK_DATA == flags;
|
88
|
System.out.println(xxx);
|
89
|
System.out.println(xxx2);
|
90
|
System.out.println(xxx3);
|
91
|
System.out.println(xxx4);*/
|
92
|
|
93
|
/* TODO
|
94
|
classDesc(); // && (
|
95
|
|
96
|
//values() // fields in order of class descriptor // SC_SERIALIZABLE & classDescFlag &&
|
97
|
// !(SC_WRITE_METHOD & classDescFlags)
|
98
|
// OR
|
99
|
//values() fields in order of class descriptor; object(); // SC_SERIALIZABLE & classDescFlag &&
|
100
|
// SC_WRITE_METHOD & classDescFlags
|
101
|
// OR
|
102
|
//object(); // SC_EXTERNALIZABLE & classDescFlag &&
|
103
|
// !(SC_BLOCKDATA & classDescFlags
|
104
|
// OR
|
105
|
//object(); // SC_EXTERNALIZABLE & classDescFlag&&
|
106
|
// SC_BLOCKDATA & classDescFlags
|
107
|
// );*/
|
108
|
}
|
109
|
break;
|
110
|
case TC_CLASS: {
|
111
|
System.out.println("X2");
|
112
|
ClassDescription desc = (ClassDescription) object();
|
113
|
retValue = desc;
|
114
|
}
|
115
|
break;
|
116
|
case TC_ARRAY: {
|
117
|
System.out.println("X3");
|
118
|
ClassDescription desc = (ClassDescription) object();
|
119
|
// TODO int size = readInt();
|
120
|
retValue = desc; // TODO + "[" + size + "]";
|
121
|
}
|
122
|
break;
|
123
|
case TC_STRING: {
|
124
|
System.out.println("X4");
|
125
|
String str = reader.readUtf();
|
126
|
retValue = str;
|
127
|
}
|
128
|
break;
|
129
|
case TC_LONGSTRING: {
|
130
|
System.out.println("X5");
|
131
|
String str = reader.readLongUtf();
|
132
|
retValue = str;
|
133
|
}
|
134
|
break;
|
135
|
case TC_ENUM: {
|
136
|
System.out.println("X6");
|
137
|
ClassDescription desc = (ClassDescription) object();
|
138
|
desc.isClass = false;
|
139
|
retValue = desc;
|
140
|
System.out.println("enumConstName: " + (String) object());
|
141
|
}
|
142
|
break;
|
143
|
|
144
|
|
145
|
case TC_CLASSDESC: {
|
146
|
System.out.println("X7");
|
147
|
ClassDescription desc = new ClassDescription();
|
148
|
desc.className = reader.readUtf();
|
149
|
desc.serialVersionUID = reader.readLong();
|
150
|
desc.flags = reader.readByte();
|
151
|
desc.isClass = true;
|
152
|
desc.setVariables(fields());
|
153
|
|
154
|
if (actClass == null) {
|
155
|
actClass = desc;
|
156
|
}
|
157
|
// TODO
|
158
|
actClass.addParent(desc);
|
159
|
|
160
|
// TODO object(null); classDesc();
|
161
|
// TODO System.out.println(desc.toString());
|
162
|
retValue = desc;
|
163
|
}
|
164
|
break;
|
165
|
case TC_PROXYCLASSDESC: {
|
166
|
System.out.println("X8");
|
167
|
int count = reader.readInt();
|
168
|
String name = reader.readUtf();
|
169
|
retValue = name + "[" + +count + "]";
|
170
|
// TODO object(null); classDesc();
|
171
|
|
172
|
}
|
173
|
break;
|
174
|
case TC_NULL: {
|
175
|
// TODO
|
176
|
System.out.println("---NULL---");
|
177
|
retValue = null;
|
178
|
|
179
|
classes.add(actClass);
|
180
|
actClass = null;
|
181
|
while (true) {
|
182
|
Variable actVar = classes.get(classes.size() - 1).getActVariable();
|
183
|
if (actVar == null) {
|
184
|
break;
|
185
|
}
|
186
|
|
187
|
switch (actVar.getType()) {
|
188
|
case 'B': actVar.setValue(reader.readByte()); break;
|
189
|
case 'C': actVar.setValue((char) reader.readByte()); break;
|
190
|
case 'D': actVar.setValue(reader.readDouble()); break;
|
191
|
case 'F': actVar.setValue(reader.readFloat()); break;
|
192
|
case 'I': actVar.setValue(reader.readInt()); break;
|
193
|
case 'J': actVar.setValue(reader.readLong()); break;
|
194
|
case 'S': actVar.setValue(reader.readShort()); break;
|
195
|
case 'Z': actVar.setValue(reader.readBoolean()); break;
|
196
|
case '[':
|
197
|
ClassDescription desccc = (ClassDescription) object();
|
198
|
|
199
|
object(); // END BLOK
|
200
|
object(); // NULL
|
201
|
|
202
|
int count = reader.readInt();
|
203
|
System.out.println("------------- VELIKOST POLE = " + count);
|
204
|
for (int i = 0; i < count; i++) {
|
205
|
System.out.println("------------- HODNOTA = " + reader.readChar());
|
206
|
}
|
207
|
//actVar.setValue(readByte());
|
208
|
break;
|
209
|
case 'L': actVar.setValue(object()); break;
|
210
|
}
|
211
|
}
|
212
|
}
|
213
|
break;
|
214
|
case TC_REFERENCE: {
|
215
|
System.out.println("---REFERENCE---");
|
216
|
// TODO (ClassDesc) TC_REFERENCE (int)handle ?!?
|
217
|
retValue = null;
|
218
|
}
|
219
|
break;
|
220
|
|
221
|
|
222
|
case TC_EXCEPTION: {
|
223
|
// TODO (Throwable)object(null);
|
224
|
retValue = "(Throwable)";
|
225
|
}
|
226
|
break;
|
227
|
case TC_RESET: {
|
228
|
// TODO
|
229
|
System.out.println("---RESET---");
|
230
|
retValue = null;
|
231
|
}
|
232
|
break;
|
233
|
case TC_BLOCKDATA: {
|
234
|
System.out.println("X13");
|
235
|
char size = reader.readUnsignedByte();
|
236
|
// (unsigned byte)<size> (byte)[size];
|
237
|
retValue = "byte [" + (int) size + "]";
|
238
|
}
|
239
|
break;
|
240
|
case TC_BLOCKDATALONG: {
|
241
|
System.out.println("X14");
|
242
|
int size = reader.readInt();
|
243
|
// (int)<size> (byte)[size];
|
244
|
retValue = "byte [" + size + "]";
|
245
|
}
|
246
|
break;
|
247
|
case TC_ENDBLOCKDATA: {
|
248
|
// TODO
|
249
|
System.out.println("---ENDBLOCKDATA---");
|
250
|
retValue = null;
|
251
|
}
|
252
|
break;
|
253
|
default:
|
254
|
System.out.println("DEF: " + String.format("%02X", b) + " " + (char) b);
|
255
|
retValue = null;
|
256
|
}
|
257
|
|
258
|
return retValue;
|
259
|
}
|
260
|
|
261
|
public List<Variable> fields() {
|
262
|
List<Variable> variables = new ArrayList<Variable>();
|
263
|
|
264
|
short count = reader.readShort();
|
265
|
for (int i = 0; i < count; i++) {
|
266
|
char type = (char) reader.readByte();
|
267
|
String variable = reader.readUtf();
|
268
|
String typeName = null;
|
269
|
if (!DataType.isPrimaryType(type))
|
270
|
typeName = (String) object();
|
271
|
variables.add(new Variable(type, variable, typeName));
|
272
|
}
|
273
|
|
274
|
return variables;
|
275
|
}
|
276
|
|
277
|
}
|