Projekt

Obecné

Profil

Stáhnout (8.88 KB) Statistiky
| Větev: | Tag: | Revize:
1
package deserialize;
2

    
3
import java.util.ArrayList;
4
import java.util.Arrays;
5
import java.util.List;
6

    
7
import org.codehaus.jackson.JsonNode;
8

    
9
/**
10
 * https://docs.oracle.com/javase/7/docs/platform/serialization/spec/protocol.html
11
 */
12
public class Grammar {
13
	
14
	private final static short STREAM_MAGIC = (short) 0xACED;
15
	private final static short STREAM_VERSION = 5;
16
	private final static byte TC_NULL = 0x70;
17
	private final static byte TC_REFERENCE = 0x71;
18
	private final static byte TC_CLASSDESC = 0x72;
19
	private final static byte TC_OBJECT = 0x73;
20
	private final static byte TC_STRING = 0x74;
21
	private final static byte TC_ARRAY = 0x75;
22
	private final static byte TC_CLASS = 0x76;
23
	private final static byte TC_BLOCKDATA = 0x77;
24
	private final static byte TC_ENDBLOCKDATA = 0x78;
25
	private final static byte TC_RESET = 0x79;
26
	private final static byte TC_BLOCKDATALONG = 0x7A;
27
	private final static byte TC_EXCEPTION = 0x7B;
28
	private final static byte TC_LONGSTRING = 0x7C;
29
	private final static byte TC_PROXYCLASSDESC = 0x7D;
30
	private final static byte TC_ENUM = 0x7E;
31
	private final static int baseWireHandle = (int) 0x7E0000;
32
	
33
	final static byte SC_WRITE_METHOD = 0x01; // if SC_SERIALIZABLE
34
	final static byte SC_BLOCK_DATA = 0x08; // if SC_EXTERNALIZABLE
35
	final static byte SC_SERIALIZABLE = 0x02;
36
	final static byte SC_EXTERNALIZABLE = 0x04;
37
	final static byte SC_ENUM = 0x10;
38

    
39
	private ByteReader reader;
40
	
41
	public Grammar(byte buffer[]) {
42
		reader = new ByteReader(buffer);
43
	}
44
	
45

    
46
	List<ClassDescription> classes = new ArrayList<ClassDescription>();
47
	ClassDescription actClass = null;
48
	
49
	public JsonNode process() {
50
		System.out.println("Kontrola hlavicky souboru: " + (reader.readShort() == STREAM_MAGIC && reader.readShort() == STREAM_VERSION));
51
		
52
		while (!reader.end()) {
53
			try {
54
				object();
55
			} catch (Exception e) {
56
				e.printStackTrace();
57
				break;
58
			}
59
		}
60
		
61
		return classes.get(0).getJsonNode();
62
		// System.out.println(classes.get(0).toString());
63
	}
64
	
65
	// FOR VALUES : 
66
	// The size and types are described by the
67
    // classDesc for the current object
68
	public Object object() {
69
		Object retValue;
70
		byte b = reader.readByte();
71
		switch (b) {
72
			case TC_OBJECT: {
73
					System.out.println("X1");
74
					
75
					// Note. TC_OBJECT; classDesc(); classdata()[]; // data for each class
76
					// Note. classDescFlags = (byte)
77
					
78
					ClassDescription desc = (ClassDescription) object();
79
					retValue = desc;
80
					
81
					/*byte flags = readByte();
82
					System.out.println("DEF: " + String.format("%02X", flags));
83
					boolean xxx = SC_SERIALIZABLE == desc2.flags && SC_WRITE_METHOD != flags;
84
					boolean xxx2 = SC_SERIALIZABLE == desc2.flags && SC_WRITE_METHOD == flags;
85
					boolean xxx3 = SC_EXTERNALIZABLE == desc2.flags && SC_BLOCK_DATA != flags;
86
					boolean xxx4 = SC_EXTERNALIZABLE == desc2.flags && SC_BLOCK_DATA == flags;
87
					System.out.println(xxx);
88
					System.out.println(xxx2);
89
					System.out.println(xxx3);
90
					System.out.println(xxx4);*/
91
					
92
					/* TODO
93
					classDesc(); // && (
94
							
95
							//values() // fields in order of class descriptor    // SC_SERIALIZABLE & classDescFlag &&
96
																				// !(SC_WRITE_METHOD & classDescFlags)
97
							// OR
98
							//values() fields in order of class descriptor; object();  // SC_SERIALIZABLE & classDescFlag &&
99
																	// SC_WRITE_METHOD & classDescFlags
100
							// OR
101
							//object();          // SC_EXTERNALIZABLE & classDescFlag &&
102
														// !(SC_BLOCKDATA  & classDescFlags
103
							// OR
104
							//object();          // SC_EXTERNALIZABLE & classDescFlag&&
105
														// SC_BLOCKDATA & classDescFlags
106
							// );*/
107
				}
108
				break;
109
			case TC_CLASS: {
110
					System.out.println("X2");
111
					ClassDescription desc = (ClassDescription) object();
112
					retValue = desc;
113
				}
114
				break;
115
			case TC_ARRAY: {
116
					ClassDescription desc = (ClassDescription) object();
117
					System.out.println("X3 " /*+ desc*/);
118
					// TODO int size = readInt();
119
					retValue = desc; // TODO + "[" + size + "]";
120
				}
121
				break;
122
			case TC_STRING: {
123
					String str = reader.readUtf();
124
					System.out.println("X4 " + str);
125
					retValue = str;
126
				}
127
				break;
128
			case TC_LONGSTRING: {
129
					System.out.println("X5");
130
					String str = reader.readLongUtf();
131
					retValue = str;
132
				}
133
				break;
134
			case TC_ENUM: {
135
					System.out.println("X6");
136
					ClassDescription desc = (ClassDescription) object();
137
					desc.isClass = false;
138
					retValue = desc;
139
					System.out.println("enumConstName: " + (String) object());
140
				}
141
				break;
142
				
143
				
144
			case TC_CLASSDESC: {
145
					System.out.println("X7");
146
					ClassDescription desc = new ClassDescription();
147
					desc.className = reader.readUtf();
148
					desc.serialVersionUID = reader.readLong();
149
					desc.flags = reader.readByte();
150
					desc.isClass = true;
151
					desc.setVariables(fields());
152
					
153
					if (actClass == null) {
154
						actClass = desc;
155
					}
156
					// TODO
157
					actClass.addParent(desc);
158
					
159
					// TODO object(null); classDesc();
160
					// TODO System.out.println(desc.toString());
161
					retValue = desc;
162
				}
163
				break;
164
			case TC_PROXYCLASSDESC: {
165
					System.out.println("X8");
166
					int count = reader.readInt();
167
					String name = reader.readUtf();
168
					retValue = name + "[" + count + "]";
169
					// TODO object(null); classDesc();
170
				}
171
				break;
172
			case TC_NULL: {
173
					// TODO
174
					System.out.println("---NULL---");
175
					retValue = null;
176
					
177
					classes.add(actClass);
178
					actClass = null;
179
					while (true) {
180
						Variable actVar = classes.get(classes.size() - 1).getActVariable();
181
						if (actVar == null) {
182
							break;
183
						}
184
						
185
						switch (actVar.getType()) {
186
						case 'B': actVar.setValue(reader.readByte()); break;
187
						case 'C': actVar.setValue((char) reader.readByte()); break;
188
						case 'D': actVar.setValue(reader.readDouble()); break;
189
						case 'F': actVar.setValue(reader.readFloat()); break;
190
						case 'I': actVar.setValue(reader.readInt()); break;
191
						case 'J': actVar.setValue(reader.readLong()); break;
192
						case 'S': actVar.setValue(reader.readShort()); break;
193
						case 'Z': actVar.setValue(reader.readBoolean()); break;
194
						case '[':
195
							ClassDescription desccc = (ClassDescription) object();
196
							
197
							object(); // END BLOK
198
							object(); // NULL
199
							
200
							String dataType = desccc.className.substring(1);
201
							
202
							Object array[] = new Object[reader.readInt()];
203
							for (int i = 0; i < array.length; i++) {
204
								Object element = null;
205
								switch (dataType.charAt(0)) {
206
								case 'B': element = reader.readByte(); break;
207
								case 'C': element = reader.readChar(); break;
208
								case 'D': element = reader.readDouble(); break;
209
								case 'F': element = reader.readFloat(); break;
210
								case 'I': element = reader.readInt(); break;
211
								case 'J': element = reader.readLong(); break;
212
								case 'S': element = reader.readShort(); break;
213
								case 'Z': element = reader.readBoolean(); break;
214
								case '[': object(); break; // TODO
215
								case 'L': element = object(); break;
216
								}
217
								array[i] = element;
218
							}
219
							
220
							System.out.println(Arrays.toString(array));
221
							actVar.setValue(array);
222
							break;
223
						case 'L': actVar.setValue(object()); break;
224
						}
225
					}
226
				}
227
				break;
228
			case TC_REFERENCE: {
229
					System.out.println("---REFERENCE---");
230
					int ref = reader.readInt();
231
					System.out.println(String.format("%X", ref));
232
					int num = reader.readInt();
233
					System.out.println(String.format("%X", num));
234
					// TODO (ClassDesc) TC_REFERENCE (int)handle ?!?
235
					retValue = null;
236
				}
237
				break;
238
				
239
				
240
			case TC_EXCEPTION: {
241
					// (Throwable)object;
242
					retValue = (Throwable) object();
243
				}
244
				break;
245
			case TC_RESET: {
246
					// TODO
247
					System.out.println("---RESET---");
248
					retValue = null;
249
				}
250
				break;
251
			case TC_BLOCKDATA: {
252
					System.out.println("X13");
253
					char size = reader.readUnsignedByte();
254
					byte[] data = new byte[size];
255
					for (int i = 0; i < size; i++) {
256
						data[i] = reader.readByte();
257
					}
258
					// (unsigned byte)<size> (byte)[size];
259
					retValue = data;
260
				}
261
				break;
262
			case TC_BLOCKDATALONG: {
263
					System.out.println("X14");
264
					int size = reader.readInt();
265
					byte[] data = new byte[size];
266
					for (int i = 0; i < size; i++) {
267
						data[i] = reader.readByte();
268
					}
269
					// (int)<size> (byte)[size];
270
					retValue = data;
271
				}
272
				break;
273
			case TC_ENDBLOCKDATA: {
274
					// TODO
275
					System.out.println("---ENDBLOCKDATA---");
276
					retValue = null;
277
				}
278
				break;
279
			default:
280
				System.out.println("DEF: " + String.format("%02X", b) + " " + (char) b);
281
				retValue = null;
282
		}
283
		
284
		return retValue;
285
	}
286
	
287
	public List<Variable> fields() {
288
		List<Variable> variables = new ArrayList<Variable>();
289
		
290
		short count = reader.readShort();
291
		for (int i = 0; i < count; i++) {
292
			char type = (char) reader.readByte();
293
			String variable = reader.readUtf();
294
			String typeName = null;
295
			if (!DataType.isPrimaryType(type))
296
				typeName = (String) object();
297
			variables.add(new Variable(type, variable, typeName));
298
		}
299
		
300
		return variables;
301
	}
302
	
303
}
(5-5/8)