1
|
package deserialize;
|
2
|
|
3
|
import java.util.HashMap;
|
4
|
|
5
|
/**
|
6
|
* https://docs.oracle.com/javase/7/docs/platform/serialization/spec/protocol.html
|
7
|
*/
|
8
|
public class Grammar {
|
9
|
|
10
|
private final static short STREAM_MAGIC = (short) 0xACED;
|
11
|
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;
|
34
|
|
35
|
HashMap<Character, String> primTypeCodes;
|
36
|
HashMap<Character, String> objTypeCodes;
|
37
|
|
38
|
|
39
|
// Note. (XXX) This token has the XXX type specified
|
40
|
|
41
|
|
42
|
public Grammar() {
|
43
|
primTypeCodes = new HashMap<Character, String>();
|
44
|
primTypeCodes.put('B', "byte");
|
45
|
primTypeCodes.put('C', "char");
|
46
|
primTypeCodes.put('D', "double");
|
47
|
primTypeCodes.put('F', "float");
|
48
|
primTypeCodes.put('I', "integer");
|
49
|
primTypeCodes.put('J', "long");
|
50
|
primTypeCodes.put('S', "short");
|
51
|
primTypeCodes.put('Z', "boolean");
|
52
|
objTypeCodes = new HashMap<Character, String>();
|
53
|
objTypeCodes.put('[', "array");
|
54
|
objTypeCodes.put('L', "object");
|
55
|
}
|
56
|
|
57
|
|
58
|
|
59
|
|
60
|
public void stream() {
|
61
|
short x = STREAM_MAGIC; x = STREAM_VERSION; contents();
|
62
|
}
|
63
|
|
64
|
public void contents() {
|
65
|
content();
|
66
|
// OR
|
67
|
contents(); content();
|
68
|
}
|
69
|
|
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];
|
76
|
}
|
77
|
|
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;
|
100
|
}
|
101
|
|
102
|
public void classDesc() {
|
103
|
newClassDesc();
|
104
|
// OR
|
105
|
byte x = TC_NULL;
|
106
|
// OR
|
107
|
/* TODO (ClassDesc)*/ x = TC_REFERENCE; // TODO (int) handle ?!?;
|
108
|
}
|
109
|
|
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();
|
114
|
}
|
115
|
|
116
|
public void classDescFlags() {
|
117
|
// TODO (byte)
|
118
|
}
|
119
|
|
120
|
public void fields() {
|
121
|
/* TODO (short)<count> => read short as count */ fieldDesc() /*[count]*/;
|
122
|
}
|
123
|
|
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
|
|
131
|
public void classAnnotation() {
|
132
|
byte x = TC_ENDBLOCKDATA;
|
133
|
// OR
|
134
|
contents(); x = TC_ENDBLOCKDATA; // contents written by annotateClass
|
135
|
}
|
136
|
|
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
|
|
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
|
|
158
|
public void externalContent() { // Only parseable by readExternal
|
159
|
// TODO ( bytes) // primitive data
|
160
|
// OR
|
161
|
object();
|
162
|
}
|
163
|
|
164
|
public void externalContents() {// externalContent written by
|
165
|
externalContent(); // writeExternal in PROTOCOL_VERSION_1.
|
166
|
// OR
|
167
|
externalContents(); externalContent();
|
168
|
}
|
169
|
|
170
|
public void values() {
|
171
|
// The size and types are described by the
|
172
|
// classDesc for the current object
|
173
|
}
|
174
|
|
175
|
public void newHandle() {
|
176
|
// The next number in sequence is assigned
|
177
|
// to the object being serialized or deserialized
|
178
|
}
|
179
|
|
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
|
186
|
}
|
187
|
}
|