Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 0286c04b

Přidáno uživatelem Michal Horký před více než 4 roky(ů)

#7767

Zjednodušení gramatiky, částečné zprovoznění s exportem do konzole.

Zobrazit rozdíly:

demo_mh/Deserializer/src/deserialize/Grammar.java
1 1
package deserialize;
2 2

  
3
import java.io.ByteArrayInputStream;
4
import java.io.DataInputStream;
5
import java.nio.ByteBuffer;
6
import java.util.ArrayList;
3 7
import java.util.HashMap;
8
import java.util.List;
4 9

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

  
35 40
	HashMap<Character, String> primTypeCodes;
36 41
	HashMap<Character, String> objTypeCodes;
......
39 44
	// Note. (XXX) This token has the XXX type specified
40 45
	
41 46
	
42
	public Grammar() {
47
	private List<Byte> buffer;
48
	public Grammar(List<Byte> buffer) {
49
		this.buffer = buffer;
50
		
43 51
		primTypeCodes = new HashMap<Character, String>();
44 52
		primTypeCodes.put('B', "byte");
45 53
		primTypeCodes.put('C', "char");
......
49 57
		primTypeCodes.put('J', "long");
50 58
		primTypeCodes.put('S', "short");
51 59
		primTypeCodes.put('Z', "boolean");
60
		
52 61
		objTypeCodes = new HashMap<Character, String>();
53 62
		objTypeCodes.put('[', "array");
54 63
		objTypeCodes.put('L', "object");
55 64
	}
56 65
	
57 66
	
58
	
59
	
60
	public void stream() {
61
		short x = STREAM_MAGIC; x = STREAM_VERSION; contents();
67
	private byte takeFirst() {
68
		return buffer.remove(0);
62 69
	}
63 70
	
64
	public void contents() {
65
		content();
66
		// OR
67
		contents(); content();
71
	public byte readByte() {
72
		return takeFirst();
68 73
	}
69 74
	
70
	public void content() {
71
		object();
72
		// OR
73
		byte x = TC_BLOCKDATA; // TODO (unsigned byte)<size> (byte)[size];
74
		// OR
75
		x = TC_BLOCKDATALONG; // TODO (int)<size> (byte)[size];
75
	private long readNumber(int bytes) {
76
		long result = 0;
77
		for (int i = (bytes - 1) * Byte.SIZE; i >= 0; i -= Byte.SIZE) {
78
			result = result | ((takeFirst() & 0xFF) << i);
79
		}
80
		return result;
76 81
	}
77 82
	
78
	public void object() {
79
		byte x = TC_OBJECT; classDesc(); newHandle(); classdata()/* TODO []*/;  // data for each class
80
		// OR
81
		x = TC_CLASS; classDesc(); newHandle();
82
		// OR
83
		x = TC_ARRAY; classDesc(); newHandle(); /* TODO (int)<size>*/ values()/*[size]*/;
84
		// OR
85
		x = TC_STRING; newHandle(); // TODO (utf) read 16-bit integer (string length)
86
		// OR
87
		x = TC_LONGSTRING; newHandle(); // TODO (long-utf) read 64-bit integer (string length)
88
		// OR
89
		x = TC_ENUM; classDesc(); newHandle(); /* TODO (String)*/ object();
90
		// OR
91
		newClassDesc();
92
		// OR
93
		x = TC_REFERENCE; // TODO (int) handle ?!?;
94
		// OR
95
		x = TC_NULL;
96
		// OR
97
		x = TC_EXCEPTION; reset(); /* TODO (Throwable)*/object(); reset();
98
		// OR
99
		x = TC_RESET;
83
	public char readUnsignedByte() {
84
		return (char) readNumber(Byte.BYTES);
100 85
	}
101 86
	
102
	public void classDesc() {
103
		newClassDesc();
104
		// OR
105
		byte x = TC_NULL;
106
		// OR
107
		/* TODO (ClassDesc)*/ x = TC_REFERENCE; // TODO (int) handle ?!?;
87
	public short readShort() {
88
		return (short) readNumber(Short.BYTES);
108 89
	}
109 90
	
110
	public void newClassDesc() {
111
		byte x = TC_CLASSDESC; /* TODO (utf) read 16-bit integer (string length); (long)*/; newHandle(); classDescFlags(); fields(); classAnnotation(); classDesc();
112
		// OR
113
		x = TC_PROXYCLASSDESC; newHandle(); /* TODO (int)<count> => read int as count /(utf) read 16-bit integer (string length)/ [count]*/; classAnnotation(); classDesc();
91
	public int readInt() {
92
		return (int) readNumber(Integer.BYTES);
114 93
	}
115 94
	
116
	public void classDescFlags() {
117
		// TODO (byte)
95
	public long readLong() {
96
		return readNumber(Long.BYTES);
118 97
	}
119 98
	
120
	public void fields() {
121
		/* TODO (short)<count> =>  read short as count */ fieldDesc() /*[count]*/;
99
	public String readString(long length) {
100
		String str = "";
101
		for (int i = 0; i < length; i++) {
102
			str += (char) readByte();
103
		}
104
		return str;
122 105
	}
123 106
	
124
	public void fieldDesc() {
125
		// TODO primTypeCodes.get(key); (utf) read 16-bit integer (string length);
126
		// OR
127
		/* TODO objTypeCodes.get(key) - array or object; (utf) read 16-bit integer (string length);*/ /*(String)*/object();		// String containing the field's type,
128
																															// in field descriptor format
129
	}
130 107
	
131
	public void classAnnotation() {
132
		byte x = TC_ENDBLOCKDATA;
133
		// OR
134
		contents(); x = TC_ENDBLOCKDATA;      // contents written by annotateClass
135
	}
136 108
	
137
	public void classdata() {
138
		values(); // fields in order of class descriptor    // SC_SERIALIZABLE & classDescFlag &&
139
															// !(SC_WRITE_METHOD & classDescFlags)
140
		// OR
141
		values() /* fields in order of class descriptor*/; objectAnnotation();  // SC_SERIALIZABLE & classDescFlag &&
142
																				// SC_WRITE_METHOD & classDescFlags
143
		// OR
144
		externalContents();          // SC_EXTERNALIZABLE & classDescFlag &&
145
								// !(SC_BLOCKDATA  & classDescFlags
146
		// OR
147
		objectAnnotation();          // SC_EXTERNALIZABLE & classDescFlag&&
148
								// SC_BLOCKDATA & classDescFlags
149
	}
150 109
	
151
	public void objectAnnotation() {
152
		byte x = TC_ENDBLOCKDATA;
153
		// OR
154
		contents(); x = TC_ENDBLOCKDATA;     // contents written by writeObject
155
		                            // or writeExternal PROTOCOL_VERSION_2.
156
	}
157 110
	
158
	public void externalContent() { // Only parseable by readExternal
159
		// TODO  ( bytes)                // primitive data
160
		// OR 
161
		object();
111
	public String readUtf() {
112
		short length = readShort();
113
		return readString(length);
162 114
	}
163 115
	
164
	public void externalContents() {// externalContent written by 
165
		externalContent();        // writeExternal in PROTOCOL_VERSION_1.
166
		// OR
167
		externalContents(); externalContent();
116
	public String readLongUtf() {
117
		long length = readLong();
118
		return readString(length);
168 119
	}
169 120
	
170
	public void values() {
171
		// The size and types are described by the
172
        // classDesc for the current object
121
	
122
	
123
	
124
	
125
	
126
	
127
	
128
	public void start() {
129
		System.out.println("Kontrola hlavicky souboru: " + (readShort() == STREAM_MAGIC && readShort() == STREAM_VERSION));
130
		while (!buffer.isEmpty()) {
131
			object();
132
		}
173 133
	}
174 134
	
175
	public void newHandle() {
176
		// The next number in sequence is assigned
177
        // to the object being serialized or deserialized
135
	// FOR VALUES : 
136
	// The size and types are described by the
137
    // classDesc for the current object
138
	public Object object() {
139
		Object retValue;
140
		byte b = readByte();
141
		switch (b) {
142
			case TC_OBJECT: {
143
					System.out.println("X1");
144
					
145
					// Note. TC_OBJECT; classDesc(); classdata()[]; // data for each class
146
					// Note. classDescFlags = (byte)
147
					
148
					ClassDescription desc = (ClassDescription) object();
149
					retValue = desc;
150
					
151
					/*byte flags = readByte();
152
					System.out.println("DEF: " + String.format("%02X", flags));
153
					boolean xxx = SC_SERIALIZABLE == desc2.flags && SC_WRITE_METHOD != flags;
154
					boolean xxx2 = SC_SERIALIZABLE == desc2.flags && SC_WRITE_METHOD == flags;
155
					boolean xxx3 = SC_EXTERNALIZABLE == desc2.flags && SC_BLOCK_DATA != flags;
156
					boolean xxx4 = SC_EXTERNALIZABLE == desc2.flags && SC_BLOCK_DATA == flags;
157
					System.out.println(xxx);
158
					System.out.println(xxx2);
159
					System.out.println(xxx3);
160
					System.out.println(xxx4);*/
161
					
162
					/* TODO
163
					classDesc(); // && (
164
							
165
							//values() // fields in order of class descriptor    // SC_SERIALIZABLE & classDescFlag &&
166
																				// !(SC_WRITE_METHOD & classDescFlags)
167
							// OR
168
							//values() fields in order of class descriptor; object();  // SC_SERIALIZABLE & classDescFlag &&
169
																	// SC_WRITE_METHOD & classDescFlags
170
							// OR
171
							//object();          // SC_EXTERNALIZABLE & classDescFlag &&
172
														// !(SC_BLOCKDATA  & classDescFlags
173
							// OR
174
							//object();          // SC_EXTERNALIZABLE & classDescFlag&&
175
														// SC_BLOCKDATA & classDescFlags
176
							// );*/
177
				}
178
				break;
179
			case TC_CLASS: {
180
					System.out.println("X2");
181
					ClassDescription desc = (ClassDescription) object();
182
					retValue = desc;
183
				}
184
				break;
185
			case TC_ARRAY: {
186
					System.out.println("X3");
187
					ClassDescription desc = (ClassDescription) object();
188
					int size = readInt();
189
					retValue = desc.className + "[" + size + "]";
190
				}
191
				break;
192
			case TC_STRING: {
193
					String str = readUtf();
194
					System.out.println("X4 " + str);
195
					retValue = str;
196
				}
197
				break;
198
			case TC_LONGSTRING: {
199
					System.out.println("X5");
200
					String str = readLongUtf();
201
					retValue = str;
202
				}
203
				break;
204
			case TC_ENUM: {
205
					System.out.println("X6");
206
					ClassDescription desc = (ClassDescription) object();
207
					desc.isClass = false;
208
					retValue = desc;
209
					System.out.println("enumConstName: " + (String) object());
210
				}
211
				break;
212
				
213
				
214
			case TC_CLASSDESC: {
215
					System.out.println("X7");
216
					ClassDescription desc = new ClassDescription();
217
					desc.className = readUtf();
218
					desc.serialVersionUID = readLong();
219
					desc.flags = readByte();
220
					desc.isClass = true;
221
					desc.variables = fields();
222
					// TODO object(null); classDesc();
223
					System.out.println(desc.toString());
224
					retValue = desc;
225
				}
226
				break;
227
			case TC_PROXYCLASSDESC: {
228
					System.out.println("X8");
229
					int count = readInt();
230
					String name = readUtf();
231
					retValue = name + "[" + +count + "]";
232
					// TODO object(null); classDesc();
233
					
234
				}
235
				break;
236
			case TC_NULL: {
237
					// TODO
238
					System.out.println("---NULL---");
239
					retValue = null;
240
				}
241
				break;
242
			case TC_REFERENCE: {
243
					System.out.println("---REFERENCE---");
244
					// TODO (ClassDesc) TC_REFERENCE (int)handle ?!?
245
					retValue = null;
246
				}
247
				break;
248
				
249
				
250
			case TC_EXCEPTION: {
251
					// TODO (Throwable)object(null);
252
					retValue = "(Throwable)";
253
				}
254
				break;
255
			case TC_RESET: {
256
					// TODO
257
					System.out.println("---RESET---");
258
					retValue = null;
259
				}
260
				break;
261
			case TC_BLOCKDATA: {
262
					System.out.println("X13");
263
					char size = readUnsignedByte();
264
					// (unsigned byte)<size> (byte)[size];
265
					retValue = "byte [" + (int) size + "]";
266
				}
267
				break;
268
			case TC_BLOCKDATALONG: {
269
					System.out.println("X14");
270
					int size = readInt();
271
					// (int)<size> (byte)[size];
272
					retValue = "byte [" + size + "]";
273
				}
274
				break;
275
			case TC_ENDBLOCKDATA: {
276
					// TODO
277
					System.out.println("---ENDBLOCKDATA---");
278
					retValue = null;
279
				}
280
				break;
281
			default:
282
				System.out.println("DEF: " + String.format("%02X", b) + " " + (char) b);
283
				retValue = null;
284
		}
285
		
286
		return retValue;
178 287
	}
179 288
	
180
	public void reset() {
181
		// The set of known objects is discarded
182
        // so the objects of the exception do not
183
        // overlap with the previously sent objects 
184
        // or with objects that may be sent after 
185
        // the exception
289
	public List<String> fields() {
290
		List<String> rows = new ArrayList<String>();
291
		
292
		short count = readShort();
293
		for (int i = 0; i < count; i++) {
294
			char type = (char) readByte();
295
			
296
			String row;
297
			if (primTypeCodes.containsKey(type)) {
298
				row = primTypeCodes.get(type) + " " + readUtf();
299
			} else {
300
				String variable = readUtf();
301
				String dataType = (String) object();
302
				dataType = dataType.substring(1);
303
				
304
				if (primTypeCodes.containsKey(dataType.charAt(0)))
305
					dataType = primTypeCodes.get(dataType.charAt(0)); // remove type
306
				
307
				row = dataType + " " + variable;
308
				if (objTypeCodes.get(type) == "array")
309
					row += "[]";
310
			}
311
			
312
			rows.add(row);
313
		}
314
		
315
		return rows;
186 316
	}
317
	
187 318
}

Také k dispozici: Unified diff