Revize 5c81df14
Přidáno uživatelem Jan Havlíček před asi 5 roky(ů)
demo_jh/Deserializer_tests/src/SampleClassesNOK/Simple.java | ||
---|---|---|
1 |
package SampleClassesNOK; |
|
2 |
|
|
3 |
import java.io.Serializable; |
|
4 |
|
|
5 |
public class Simple implements Serializable |
|
6 |
{ |
|
7 |
private static final long serialVersionUID = 1L; |
|
8 |
|
|
9 |
private String pozdrav = "AHOJ"; |
|
10 |
private int testInt = 123; |
|
11 |
private double testDouble = 1.00; |
|
12 |
|
|
13 |
public Simple() |
|
14 |
{ |
|
15 |
int locInt = 5; |
|
16 |
} |
|
17 |
} |
demo_jh/Deserializer_tests/src/SampleClassesOK/Simple.java | ||
---|---|---|
1 |
package SampleClassesOK; |
|
2 |
|
|
3 |
import java.io.Serializable; |
|
4 |
|
|
5 |
public class Simple implements Serializable |
|
6 |
{ |
|
7 |
private static final long serialVersionUID = 1L; |
|
8 |
|
|
9 |
private String pozdrav = "AHOJ"; |
|
10 |
private int testInt = 123; |
|
11 |
private double testDouble = 1.00; |
|
12 |
|
|
13 |
public Simple() |
|
14 |
{ |
|
15 |
int locInt = 5; |
|
16 |
} |
|
17 |
} |
demo_jh/Deserializer_tests/src/app/App.java | ||
---|---|---|
16 | 16 |
* When they are |
17 | 17 |
* **/ |
18 | 18 |
public static void main(String[] args) throws Exception |
19 |
{ |
|
20 |
App thisApp = new App(); |
|
21 |
|
|
22 |
//thisApp.pureSerializationDeserialization(); |
|
23 |
|
|
24 |
//https://code.google.com/archive/p/jdeserialize/wikis/Documentation.wiki |
|
25 |
String[] myArgs= new String[1]; |
|
26 |
myArgs[0] = "serialized/simple.out"; |
|
27 |
//testing call without any options. Outputs the deserialized data into console. |
|
28 |
jdeserialize.jdeserialize.main(myArgs); |
|
29 |
} |
|
30 |
|
|
31 |
|
|
32 |
private void pureSerializationDeserialization() |
|
19 | 33 |
{ |
20 | 34 |
try{ |
21 | 35 |
System.out.println("Starting..."); |
22 | 36 |
|
23 |
App thisApp = new App(); |
|
24 |
//thisApp.Serialize(new SampleClassesOK.Simple(), "serialized/simple.out"); |
|
37 |
this.serialize(new samples.ok.Simple(), "serialized/simple.out"); |
|
25 | 38 |
|
26 |
SampleClassesOK.Simple test1 = thisApp.Deserialize("serialized/simple.out");
|
|
39 |
samples.nok.Simple test1 = this.deserialize("serialized/simple.out");
|
|
27 | 40 |
|
28 | 41 |
}catch(Exception e) |
29 | 42 |
{ |
... | ... | |
32 | 45 |
} |
33 | 46 |
} |
34 | 47 |
|
35 |
private <T> T Deserialize(String inputFilePath) |
|
48 |
/** |
|
49 |
* Standard way of deserializing objects with java. |
|
50 |
* |
|
51 |
* Taken from example method, doc |
|
52 |
**/ |
|
53 |
private <T> T deserialize(String inputFilePath) |
|
36 | 54 |
{ |
37 | 55 |
try |
38 | 56 |
{ |
... | ... | |
60 | 78 |
* |
61 | 79 |
* Taken from example method, doc |
62 | 80 |
**/ |
63 |
private void Serialize(Object obj, String outputPath)
|
|
81 |
private void serialize(Object obj, String outputPath)
|
|
64 | 82 |
{ |
65 | 83 |
try |
66 | 84 |
{ |
demo_jh/Deserializer_tests/src/jdeserialize/ExceptionReadException.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* Exception used to signal that an exception object was successfully read from the |
|
7 |
* stream. This object holds a reference to the serialized exception object. |
|
8 |
*/ |
|
9 |
public class ExceptionReadException extends IOException { |
|
10 |
public static final long serialVersionUID = 2277356908919221L; |
|
11 |
public content exceptionobj; |
|
12 |
/** |
|
13 |
* Constructor. |
|
14 |
* @param c the serialized exception object that was read |
|
15 |
*/ |
|
16 |
public ExceptionReadException(content c) { |
|
17 |
super("serialized exception read during stream"); |
|
18 |
this.exceptionobj = c; |
|
19 |
} |
|
20 |
/** |
|
21 |
* Gets the Exception object that was thrown. |
|
22 |
* @return the content representing the serialized exception object |
|
23 |
*/ |
|
24 |
public content getExceptionObject() { |
|
25 |
return exceptionobj; |
|
26 |
} |
|
27 |
} |
|
28 |
|
demo_jh/Deserializer_tests/src/jdeserialize/Getopt.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* Simple getopt()-like implementation. |
|
7 |
*/ |
|
8 |
public class Getopt { |
|
9 |
private Map<String, Integer> options; |
|
10 |
private List<String> otherargs; |
|
11 |
private Map<String, String> descriptions; |
|
12 |
private Map<String, List<String>> optvals; |
|
13 |
|
|
14 |
public class OptionParseException extends Exception { |
|
15 |
public static final long serialVersionUID = 2898924890585885551L; |
|
16 |
public OptionParseException(String message) { |
|
17 |
super(message); |
|
18 |
} |
|
19 |
} |
|
20 |
|
|
21 |
/** |
|
22 |
* Gets the list arguments specified that were *not* options or their arguments, in |
|
23 |
* the order they were specified. |
|
24 |
* |
|
25 |
* @return the list of non-option String arguments |
|
26 |
*/ |
|
27 |
public List<String> getOtherArguments() { |
|
28 |
return otherargs; |
|
29 |
} |
|
30 |
|
|
31 |
/** |
|
32 |
* Gets the set of all options specified, as well as the list of their arguments. |
|
33 |
* |
|
34 |
* @return a map of all options specified; values are lists of arguments |
|
35 |
*/ |
|
36 |
public Map<String, List<String>> getOptionValues() { |
|
37 |
return optvals; |
|
38 |
} |
|
39 |
|
|
40 |
/** |
|
41 |
* Constructor. |
|
42 |
* |
|
43 |
* @param options Map of options to parse. The key should be an option string (including |
|
44 |
* any initial dashes), and the value should be an Integer representing the number of |
|
45 |
* arguments to parse following the option. |
|
46 |
* @param descriptions Map of option descriptions. |
|
47 |
*/ |
|
48 |
public Getopt(Map<String, Integer> options, Map<String, String> descriptions) { |
|
49 |
this.options = options; |
|
50 |
this.descriptions = descriptions; |
|
51 |
} |
|
52 |
/** |
|
53 |
* Constructor. |
|
54 |
*/ |
|
55 |
public Getopt() { |
|
56 |
this.options = new HashMap<String, Integer>(); |
|
57 |
this.descriptions = new HashMap<String, String>(); |
|
58 |
} |
|
59 |
|
|
60 |
/** |
|
61 |
* Determines whether or not the option was specified when the arguments were parsed. |
|
62 |
* |
|
63 |
* @return true iff the argument was specified (with the correct number of arguments). |
|
64 |
*/ |
|
65 |
public boolean hasOption(String opt) { |
|
66 |
return optvals.containsKey(opt); |
|
67 |
} |
|
68 |
|
|
69 |
/** |
|
70 |
* Gets the list of arguments for a given option, or null if the option wasn't |
|
71 |
* specified. |
|
72 |
* |
|
73 |
* @param option the option |
|
74 |
* @return the list of arguments for option |
|
75 |
*/ |
|
76 |
public List<String> getArguments(String option) { |
|
77 |
return optvals.get(option); |
|
78 |
} |
|
79 |
|
|
80 |
/** |
|
81 |
* Add an option to the internal set, including the number of arguments and the |
|
82 |
* description. |
|
83 |
* |
|
84 |
* @param option option string, including any leading dashes |
|
85 |
* @param arguments number of arguments |
|
86 |
* @param description description of the option |
|
87 |
*/ |
|
88 |
public void addOption(String option, int arguments, String description) { |
|
89 |
options.put(option, arguments); |
|
90 |
descriptions.put(option, description); |
|
91 |
} |
|
92 |
|
|
93 |
/** |
|
94 |
* Do the parsing/validation. |
|
95 |
* @param args arguments to parse |
|
96 |
* @throws OptionParseException if a parse error occurs (the exception message will |
|
97 |
* have details) |
|
98 |
*/ |
|
99 |
public void parse(String[] args) throws OptionParseException { |
|
100 |
this.otherargs = new ArrayList<String>(); |
|
101 |
this.optvals = new HashMap<String, List<String>>(); |
|
102 |
|
|
103 |
for(int i = 0; i < args.length; i++) { |
|
104 |
if(optvals != null) { |
|
105 |
Integer count = options.get(args[i]); |
|
106 |
if(count != null) { |
|
107 |
ArrayList<String> al = new ArrayList<String>(count.intValue()); |
|
108 |
for(int j = 0; j < count; j++) { |
|
109 |
if(i+1+j >= args.length) { |
|
110 |
throw new OptionParseException("expected " + count + " arguments after " + args[i]); |
|
111 |
} |
|
112 |
al.add(args[i+1+j]); |
|
113 |
} |
|
114 |
List<String> oldal = optvals.get(args[i]); |
|
115 |
if(oldal == null) { |
|
116 |
optvals.put(args[i], al); |
|
117 |
} else { |
|
118 |
oldal.addAll(al); |
|
119 |
} |
|
120 |
i += count; |
|
121 |
continue; |
|
122 |
} |
|
123 |
} |
|
124 |
otherargs.add(args[i]); |
|
125 |
} |
|
126 |
} |
|
127 |
|
|
128 |
/** |
|
129 |
* Get a tabular description of all options and their descriptions, one per line. |
|
130 |
*/ |
|
131 |
public String getDescriptionString() { |
|
132 |
String linesep = System.getProperty("line.separator"); |
|
133 |
StringBuffer sb = new StringBuffer(); |
|
134 |
if(options != null && options.size() > 0) { |
|
135 |
sb.append("Options:").append(linesep); |
|
136 |
TreeSet<String> opts = new TreeSet<String>(this.options.keySet()); |
|
137 |
for(String opt: opts) { |
|
138 |
sb.append(" ").append(opt); |
|
139 |
for(int i = 0; i < options.get(opt); i++) { |
|
140 |
sb.append(" arg").append(i+1); |
|
141 |
} |
|
142 |
sb.append(": ").append(descriptions.get(opt)).append(linesep); |
|
143 |
} |
|
144 |
} |
|
145 |
return sb.toString(); |
|
146 |
} |
|
147 |
|
|
148 |
public static void main(String[] args) { |
|
149 |
try { |
|
150 |
HashMap<String, Integer> options = new HashMap<String, Integer>(); |
|
151 |
Getopt go = new Getopt(); |
|
152 |
go.addOption("-optzero", 0, "zero-arg constructor"); |
|
153 |
go.addOption("-optone", 1, "one-arg constructor"); |
|
154 |
go.addOption("-opttwo", 2, "two-arg constructor"); |
|
155 |
go.parse(args); |
|
156 |
System.out.println(go.getDescriptionString()); |
|
157 |
System.out.println("options:"); |
|
158 |
Map<String, List<String>> optvals = go.getOptionValues(); |
|
159 |
for(String opt: optvals.keySet()) { |
|
160 |
System.out.print(" " + opt); |
|
161 |
for(String optval: optvals.get(opt)) { |
|
162 |
System.out.print(" " + optval); |
|
163 |
} |
|
164 |
System.out.println(""); |
|
165 |
} |
|
166 |
System.out.println(""); |
|
167 |
System.out.println("otherargs:"); |
|
168 |
for(String arg: go.getOtherArguments()) { |
|
169 |
System.out.println(" " + arg); |
|
170 |
} |
|
171 |
} catch (Throwable t) { |
|
172 |
t.printStackTrace(); |
|
173 |
} |
|
174 |
} |
|
175 |
} |
demo_jh/Deserializer_tests/src/jdeserialize/LoggerInputStream.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
import java.io.*; |
|
4 |
import java.util.*; |
|
5 |
|
|
6 |
/** |
|
7 |
* <p> |
|
8 |
* An InputStream designed to record data passing through the stream after a call to |
|
9 |
* record() is made. After record() is called, the results from every read will |
|
10 |
* be stored in an * internal buffer. The contents of the buffer can be |
|
11 |
* retrieved by getRecordedData(); to stop recording and clear the internal |
|
12 |
* buffer, call stopRecording(). |
|
13 |
* </p> |
|
14 |
* |
|
15 |
* <p> |
|
16 |
* <b>Note</b>: calls to mark() and reset() are merely passed through to the inner stream; if |
|
17 |
* recording is active, the buffer won't be backtracked by reset(). |
|
18 |
* </p> |
|
19 |
*/ |
|
20 |
public class LoggerInputStream extends InputStream { |
|
21 |
private InputStream innerStream = null; |
|
22 |
private ByteArrayOutputStream baos = null; |
|
23 |
private boolean recording = false; |
|
24 |
|
|
25 |
public LoggerInputStream(InputStream innerStream) { |
|
26 |
super(); |
|
27 |
this.innerStream = innerStream; |
|
28 |
} |
|
29 |
public synchronized int read() throws IOException { |
|
30 |
int i = innerStream.read(); |
|
31 |
if(recording && i != -1) { |
|
32 |
if(i > 255 || i < 0) { |
|
33 |
throw new IOException("non-byte, non--1 value read from inner stream: " + i); |
|
34 |
} |
|
35 |
baos.write((byte)i); |
|
36 |
} |
|
37 |
return i; |
|
38 |
} |
|
39 |
public synchronized int read(byte[] b) throws IOException { |
|
40 |
return this.read(b, 0, b.length); |
|
41 |
} |
|
42 |
public synchronized int read(byte[] b, int off, int len) throws IOException { |
|
43 |
int retval = innerStream.read(b, off, len); |
|
44 |
if(recording && retval > 0) { |
|
45 |
if(retval > len) { |
|
46 |
throw new IOException("inner stream read(byte[], int, int) violating contract; return value > len: " + retval); |
|
47 |
} |
|
48 |
baos.write(b, off, retval); |
|
49 |
} |
|
50 |
return retval; |
|
51 |
} |
|
52 |
public synchronized long skip(long n) throws IOException { |
|
53 |
if(n < 0) { |
|
54 |
throw new IOException("can't skip negative number of bytes"); |
|
55 |
} |
|
56 |
if(recording == false) { |
|
57 |
return innerStream.skip(n); |
|
58 |
} |
|
59 |
long nskipped = 0; |
|
60 |
while(n > Integer.MAX_VALUE) { |
|
61 |
long ret = skip(Integer.MAX_VALUE); |
|
62 |
nskipped += ret; |
|
63 |
if(ret < Integer.MAX_VALUE) { |
|
64 |
return nskipped; |
|
65 |
} |
|
66 |
n -= ret; |
|
67 |
} |
|
68 |
int toread = (int)n, actuallyread = 0; |
|
69 |
byte[] buf = new byte[10240]; |
|
70 |
while(toread > 0) { |
|
71 |
int r = Math.min(toread, buf.length); |
|
72 |
int rret = this.read(buf, 0, r); |
|
73 |
actuallyread += rret; |
|
74 |
toread -= rret; |
|
75 |
if(rret < r) { |
|
76 |
break; |
|
77 |
} |
|
78 |
} |
|
79 |
return actuallyread; |
|
80 |
} |
|
81 |
public synchronized int available() throws IOException { |
|
82 |
return innerStream.available(); |
|
83 |
} |
|
84 |
public synchronized void close() throws IOException { |
|
85 |
innerStream.close(); |
|
86 |
} |
|
87 |
public synchronized void mark(int readlimit) { |
|
88 |
innerStream.mark(readlimit); |
|
89 |
} |
|
90 |
public synchronized void reset() throws IOException { |
|
91 |
innerStream.reset(); |
|
92 |
} |
|
93 |
public boolean markSupported() { |
|
94 |
return innerStream.markSupported(); |
|
95 |
} |
|
96 |
/** |
|
97 |
* If not currently recording, start recording. If the stream is currently recording, |
|
98 |
* the current buffer is cleared. |
|
99 |
*/ |
|
100 |
public synchronized void record() { |
|
101 |
recording = true; |
|
102 |
baos = new ByteArrayOutputStream(); |
|
103 |
} |
|
104 |
/** |
|
105 |
* Stops recording and clears the internal buffer. If recording is not active, an |
|
106 |
* IOException is thrown. |
|
107 |
* |
|
108 |
* @throws IOException if recording is not currently active |
|
109 |
*/ |
|
110 |
public synchronized void stopRecording() throws IOException { |
|
111 |
if(recording == false) { |
|
112 |
throw new IOException("recording not active"); |
|
113 |
} |
|
114 |
try { |
|
115 |
baos.close(); |
|
116 |
} catch (IOException ignore) {} |
|
117 |
baos = null; |
|
118 |
recording = false; |
|
119 |
} |
|
120 |
/** |
|
121 |
* Returns the data recorded so far; if recording is not active, an empty buffer |
|
122 |
* is returned. |
|
123 |
*/ |
|
124 |
public synchronized byte[] getRecordedData() { |
|
125 |
if(recording == false) { |
|
126 |
return new byte[0]; |
|
127 |
} |
|
128 |
return baos.toByteArray(); |
|
129 |
} |
|
130 |
} |
demo_jh/Deserializer_tests/src/jdeserialize/ValidityException.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* Exception that denotes that data in the stream did not conform to the constraints |
|
7 |
* imposed by the specification. |
|
8 |
*/ |
|
9 |
public class ValidityException extends IOException { |
|
10 |
public static final long serialVersionUID = 2277356908919241L; |
|
11 |
public ValidityException(String msg) { |
|
12 |
super(msg); |
|
13 |
} |
|
14 |
} |
|
15 |
|
demo_jh/Deserializer_tests/src/jdeserialize/arraycoll.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* <p>Typed collection used for storing the values of a serialized array. </p> |
|
7 |
* |
|
8 |
* <p>Primitive types are stored using their corresponding objects; for instance, an int is |
|
9 |
* stored as an Integer. To determine whether or not this is an array of ints or of |
|
10 |
* Integer instances, check the name in the arrayobj's class description.</p> |
|
11 |
*/ |
|
12 |
public class arraycoll extends ArrayList<Object> { |
|
13 |
public static final long serialVersionUID = 2277356908919248L; |
|
14 |
|
|
15 |
private fieldtype ftype; |
|
16 |
|
|
17 |
/** |
|
18 |
* Constructor. |
|
19 |
* @param ft field type of the array |
|
20 |
*/ |
|
21 |
public arraycoll(fieldtype ft) { |
|
22 |
super(); |
|
23 |
this.ftype = ft; |
|
24 |
} |
|
25 |
|
|
26 |
/** |
|
27 |
* Gets the field type of the array. |
|
28 |
* |
|
29 |
* @return the field type of the array |
|
30 |
*/ |
|
31 |
public fieldtype getFieldType() { |
|
32 |
return ftype; |
|
33 |
} |
|
34 |
public String toString() { |
|
35 |
StringBuffer sb = new StringBuffer(); |
|
36 |
sb.append("[arraycoll sz ").append(this.size()); |
|
37 |
boolean first = true; |
|
38 |
for(Object o: this) { |
|
39 |
if(first) { |
|
40 |
first = false; |
|
41 |
sb.append(' '); |
|
42 |
} else { |
|
43 |
sb.append(", "); |
|
44 |
} |
|
45 |
sb.append(o.toString()); |
|
46 |
} |
|
47 |
return sb.toString(); |
|
48 |
} |
|
49 |
} |
demo_jh/Deserializer_tests/src/jdeserialize/arrayobj.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* <p>Represents an array instance, including the values the comprise the array. </p> |
|
7 |
* |
|
8 |
* <p>Note that in arrays of primitives, the classdesc will be named "[x", where x is the |
|
9 |
* field type code representing the primitive type. See jdeserialize.resolveJavaType() |
|
10 |
* for an example of analysis/generation of human-readable names from these class names.</p> |
|
11 |
*/ |
|
12 |
public class arrayobj extends contentbase { |
|
13 |
/** |
|
14 |
* Type of the array instance. |
|
15 |
*/ |
|
16 |
public classdesc classdesc; |
|
17 |
|
|
18 |
/** |
|
19 |
* Values of the array, in the order they were read from the stream. |
|
20 |
*/ |
|
21 |
public arraycoll data; |
|
22 |
|
|
23 |
public arrayobj(int handle, classdesc cd, arraycoll data) { |
|
24 |
super(contenttype.ARRAY); |
|
25 |
this.handle = handle; |
|
26 |
this.classdesc = cd; |
|
27 |
this.data = data; |
|
28 |
} |
|
29 |
public String toString() { |
|
30 |
return "[array " + jdeserialize.hex(handle) + " classdesc " + classdesc.toString() + ": " |
|
31 |
+ data.toString() + "]"; |
|
32 |
} |
|
33 |
} |
|
34 |
|
demo_jh/Deserializer_tests/src/jdeserialize/blockdata.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
|
|
4 |
/** |
|
5 |
* Represents an opaque block of data written to the stream. Primarily, these are used to |
|
6 |
* write class and object annotations by ObjectOutputStream overrides; they can also occur |
|
7 |
* inside an object, when the object overrides Serializable.writeObject(). Their |
|
8 |
* interpretation is hereby left to users. |
|
9 |
*/ |
|
10 |
public class blockdata extends contentbase { |
|
11 |
/** |
|
12 |
* The block data read from the stream. |
|
13 |
*/ |
|
14 |
public byte[] buf; |
|
15 |
|
|
16 |
/** |
|
17 |
* Constructor. |
|
18 |
* |
|
19 |
* @param buf the block data |
|
20 |
*/ |
|
21 |
public blockdata(byte[] buf) { |
|
22 |
super(contenttype.BLOCKDATA); |
|
23 |
this.buf = buf; |
|
24 |
} |
|
25 |
public String toString() { |
|
26 |
return "[blockdata " + jdeserialize.hex(handle) + ": " + buf.length + " bytes]"; |
|
27 |
} |
|
28 |
} |
demo_jh/Deserializer_tests/src/jdeserialize/classdesc.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* <p> |
|
7 |
* Represents the entire serialized prototype of the class, including all fields, |
|
8 |
* inner classes, class annotations, and inheritance hierarchy. This includes proxy class |
|
9 |
* descriptions. |
|
10 |
* </p> |
|
11 |
* |
|
12 |
* <p> |
|
13 |
* Generally, this class is used to represent the type of an instance written to an |
|
14 |
* ObjectOutputStream with its writeObject() method, or of a related array or field type. |
|
15 |
* However, there's a notable exception: when instances of type java.io.ObjectStreamClass |
|
16 |
* are written with writeObject(), only their class description is written (cf. Object |
|
17 |
* Serialization Specification, 4.3). They will be represented with an instance of |
|
18 |
* classdesc as well. |
|
19 |
* </p> |
|
20 |
*/ |
|
21 |
public class classdesc extends contentbase { |
|
22 |
/** |
|
23 |
* Type of the class being represented; either a normal class or a proxy class. |
|
24 |
*/ |
|
25 |
public classdesctype classtype; |
|
26 |
|
|
27 |
/** |
|
28 |
* Class name. |
|
29 |
*/ |
|
30 |
public String name; |
|
31 |
|
|
32 |
/** |
|
33 |
* Serial version UID, as recorded in the stream. |
|
34 |
*/ |
|
35 |
public long serialVersionUID; |
|
36 |
|
|
37 |
/** |
|
38 |
* Description flags byte; this should be a mask of values from the ObjectStreamContants |
|
39 |
* class. Refer to chapter 6 of the Object Stream Serialization Protocol for details. |
|
40 |
*/ |
|
41 |
public byte descflags; |
|
42 |
|
|
43 |
/** |
|
44 |
* Array of fields in the class, in the order serialized by the stream writer. |
|
45 |
*/ |
|
46 |
public field[] fields; |
|
47 |
|
|
48 |
/** |
|
49 |
* List of inner classes, in the order serialized by the stream writer. |
|
50 |
*/ |
|
51 |
public List<classdesc> innerclasses; |
|
52 |
|
|
53 |
/** |
|
54 |
* List of annotation objects; these are *not* Java annotations, but data written by |
|
55 |
* the <pre>annotateClass(Class<?>)<pre> and <pre>annotateProxyClass(Class<?>)</pre> methods of an |
|
56 |
* ObjectOutputStream. |
|
57 |
*/ |
|
58 |
public List<content> annotations; |
|
59 |
|
|
60 |
/** |
|
61 |
* The superclass of the object, if available. |
|
62 |
*/ |
|
63 |
public classdesc superclass; |
|
64 |
|
|
65 |
/** |
|
66 |
* Array of serialized interfaces, in the order serialized by the stream writer. |
|
67 |
*/ |
|
68 |
public String[] interfaces; |
|
69 |
|
|
70 |
/** |
|
71 |
* Set of enum constants, for enum classes. |
|
72 |
*/ |
|
73 |
public Set<String> enumconstants; |
|
74 |
|
|
75 |
private boolean isInnerClass = false; |
|
76 |
/** |
|
77 |
* True if this class has been determined to be an inner class; this determination is |
|
78 |
* generally made by connectMemberClasses(). |
|
79 |
* |
|
80 |
* @return true if the class is an inner class |
|
81 |
*/ |
|
82 |
public boolean isInnerClass() { |
|
83 |
return isInnerClass; |
|
84 |
} |
|
85 |
/** |
|
86 |
* Sets the value that denotes that the class is an inner class. |
|
87 |
* |
|
88 |
* @param nis the value to set |
|
89 |
*/ |
|
90 |
public void setIsInnerClass(boolean nis) { |
|
91 |
this.isInnerClass = nis; |
|
92 |
} |
|
93 |
|
|
94 |
private boolean isLocalInnerClass = false; |
|
95 |
/** |
|
96 |
* True if this class has been determined to be a local inner class; this |
|
97 |
* determination is generally made by connectMemberClasses(). |
|
98 |
* |
|
99 |
* @return true if the class is a local inner class |
|
100 |
*/ |
|
101 |
public boolean isLocalInnerClass() { |
|
102 |
return isLocalInnerClass; |
|
103 |
} |
|
104 |
/** |
|
105 |
* Sets the flag that denotes whether this class is a local inner class. |
|
106 |
* |
|
107 |
* @param nis the value to set |
|
108 |
*/ |
|
109 |
public void setIsLocalInnerClass(boolean nis) { |
|
110 |
this.isLocalInnerClass = nis; |
|
111 |
} |
|
112 |
|
|
113 |
private boolean isStaticMemberClass = false; |
|
114 |
/** |
|
115 |
* <p> |
|
116 |
* True if this class has been determined to be a static member class; this |
|
117 |
* determination is generally made by connectMemberClasses(). |
|
118 |
* </p> |
|
119 |
* |
|
120 |
* <p> |
|
121 |
* Note that in some cases, static member classes' descriptions will be serialized |
|
122 |
* even though their enclosing class is not. In these cases, this may return false. |
|
123 |
* See connectMemberClasses() for details. |
|
124 |
* </p> |
|
125 |
* |
|
126 |
* @return true if this is a static member class |
|
127 |
*/ |
|
128 |
public boolean isStaticMemberClass() { |
|
129 |
return isStaticMemberClass; |
|
130 |
} |
|
131 |
/** |
|
132 |
* Sets the flag that denotes whether this class is a static member class. |
|
133 |
* |
|
134 |
* @param nis the value to set |
|
135 |
*/ |
|
136 |
public void setIsStaticMemberClass(boolean nis) { |
|
137 |
this.isStaticMemberClass = nis; |
|
138 |
} |
|
139 |
|
|
140 |
/** |
|
141 |
* Constructor. |
|
142 |
* |
|
143 |
* @param classtype the type of the class |
|
144 |
*/ |
|
145 |
public classdesc(classdesctype classtype) { |
|
146 |
super(contenttype.CLASSDESC); |
|
147 |
this.classtype = classtype; |
|
148 |
this.enumconstants = new HashSet<String>(); |
|
149 |
this.innerclasses = new ArrayList<classdesc>(); |
|
150 |
} |
|
151 |
|
|
152 |
/** |
|
153 |
* Add an inner class to the description's list. |
|
154 |
* @param cd inner class to add |
|
155 |
*/ |
|
156 |
public void addInnerClass(classdesc cd) { |
|
157 |
innerclasses.add(cd); |
|
158 |
} |
|
159 |
|
|
160 |
/** |
|
161 |
* Add an enum constant to the description's set. |
|
162 |
* |
|
163 |
* @param constval enum constant string |
|
164 |
*/ |
|
165 |
public void addEnum(String constval) { |
|
166 |
this.enumconstants.add(constval); |
|
167 |
} |
|
168 |
|
|
169 |
/** |
|
170 |
* Determines whether this is an array type. |
|
171 |
* @return true if this is an array type. |
|
172 |
*/ |
|
173 |
public boolean isArrayClass() { |
|
174 |
if(name != null && name.length() > 1 && name.charAt(0) == '[') { |
|
175 |
return true; |
|
176 |
} else { |
|
177 |
return false; |
|
178 |
} |
|
179 |
} |
|
180 |
public String toString() { |
|
181 |
StringBuffer sb = new StringBuffer(); |
|
182 |
sb.append("[cd ").append(jdeserialize.hex(handle)).append(": name ").append(name); |
|
183 |
sb.append(" uid ").append(serialVersionUID); |
|
184 |
sb.append("]"); |
|
185 |
return sb.toString(); |
|
186 |
} |
|
187 |
|
|
188 |
/** |
|
189 |
* Generates a list of all class descriptions in this class's hierarchy, in the order |
|
190 |
* described by the Object Stream Serialization Protocol. This is the order in which |
|
191 |
* fields are read from the stream. |
|
192 |
* |
|
193 |
* @param classes a list to be filled in with the hierarchy |
|
194 |
*/ |
|
195 |
public void getHierarchy(ArrayList<classdesc> classes) { |
|
196 |
if(superclass != null) { |
|
197 |
if(superclass.classtype == classdesctype.PROXYCLASS) { |
|
198 |
jdeserialize.debugerr("warning: hit a proxy class in superclass hierarchy"); |
|
199 |
} else { |
|
200 |
superclass.getHierarchy(classes); |
|
201 |
} |
|
202 |
} |
|
203 |
classes.add(this); |
|
204 |
} |
|
205 |
public void validate() throws ValidityException { |
|
206 |
// If neither SC_SERIALIZABLE nor SC_EXTERNALIZABLE is set, then the number of |
|
207 |
// fields is always zero. (spec section 4.3) |
|
208 |
if((descflags & (ObjectStreamConstants.SC_SERIALIZABLE | ObjectStreamConstants.SC_EXTERNALIZABLE)) == 0 && fields != null && fields.length > 0) { |
|
209 |
throw new ValidityException("non-serializable, non-externalizable class has fields!"); |
|
210 |
} |
|
211 |
if((descflags & (ObjectStreamConstants.SC_SERIALIZABLE | ObjectStreamConstants.SC_EXTERNALIZABLE)) == (ObjectStreamConstants.SC_SERIALIZABLE | ObjectStreamConstants.SC_EXTERNALIZABLE)) { |
|
212 |
throw new ValidityException("both Serializable and Externalizable are set!"); |
|
213 |
} |
|
214 |
if((descflags & ObjectStreamConstants.SC_ENUM) != 0) { |
|
215 |
// we're an enum; shouldn't have any fields/superinterfaces |
|
216 |
if((fields != null && fields.length > 0) || interfaces != null) { |
|
217 |
throw new ValidityException("enums shouldn't implement interfaces or have non-constant fields!"); |
|
218 |
} |
|
219 |
} else { |
|
220 |
// non-enums shouldn't have enum constant fields. |
|
221 |
if(enumconstants != null && enumconstants.size() > 0) { |
|
222 |
throw new ValidityException("non-enum classes shouldn't have enum constants!"); |
|
223 |
} |
|
224 |
} |
|
225 |
} |
|
226 |
} |
|
227 |
|
demo_jh/Deserializer_tests/src/jdeserialize/classdesctype.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
/** |
|
4 |
* Enum for class description types. |
|
5 |
*/ |
|
6 |
public enum classdesctype { |
|
7 |
NORMALCLASS, PROXYCLASS |
|
8 |
} |
demo_jh/Deserializer_tests/src/jdeserialize/classobj.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* This represents a Class object (i.e. an instance of type Class) serialized in the |
|
7 |
* stream. |
|
8 |
*/ |
|
9 |
public class classobj extends contentbase { |
|
10 |
/** |
|
11 |
* The class description, including its name. |
|
12 |
*/ |
|
13 |
public classdesc classdesc; |
|
14 |
|
|
15 |
/** |
|
16 |
* Constructor. |
|
17 |
* |
|
18 |
* @param handle the instance's handle |
|
19 |
* @param cd the instance's class description |
|
20 |
*/ |
|
21 |
public classobj(int handle, classdesc cd) { |
|
22 |
super(contenttype.CLASS); |
|
23 |
this.handle = handle; |
|
24 |
this.classdesc = cd; |
|
25 |
} |
|
26 |
public String toString() { |
|
27 |
return "[class " + jdeserialize.hex(handle) + ": " + classdesc.toString() + "]"; |
|
28 |
} |
|
29 |
} |
|
30 |
|
demo_jh/Deserializer_tests/src/jdeserialize/content.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* <p> |
|
7 |
* Generic interface for all data that may be read from the stream (except null). |
|
8 |
* </p> |
|
9 |
* |
|
10 |
* <p> |
|
11 |
* A successful read of the stream will result in a series of content instances or null |
|
12 |
* references. For details on specific metadata, see documentation on implementing |
|
13 |
* classes/subinterfaces. |
|
14 |
* </p> |
|
15 |
*/ |
|
16 |
public interface content { |
|
17 |
/** |
|
18 |
* @return the type of instance represented by this object. |
|
19 |
*/ |
|
20 |
public contenttype getType(); |
|
21 |
|
|
22 |
/** |
|
23 |
* <p> |
|
24 |
* Get the numeric handle by which this object was referred to in the object stream. |
|
25 |
* These handles are used internally by Object{Output,Input}Stream as a mechanism to |
|
26 |
* avoid costly duplication. |
|
27 |
* </p> |
|
28 |
* |
|
29 |
* <p> |
|
30 |
* CAUTION: they are *not* necessarily unique across all objects in a given stream! |
|
31 |
* If an exception was thrown during serialization (which is most likely to happen |
|
32 |
* during a serialized objct's writeObject() implementation), then the stream resets |
|
33 |
* before and after the exception is serialized. |
|
34 |
* </p> |
|
35 |
* |
|
36 |
* @return the handle assigned in the stream |
|
37 |
*/ |
|
38 |
public int getHandle(); |
|
39 |
|
|
40 |
/** |
|
41 |
* Performs extra object-specific validity checks. |
|
42 |
* |
|
43 |
* @throws ValidityException if the object's state is invalid |
|
44 |
*/ |
|
45 |
public void validate() throws ValidityException; |
|
46 |
|
|
47 |
/** |
|
48 |
* <p> |
|
49 |
* Tells whether or not this object is an exception that was caught during |
|
50 |
* serialization. |
|
51 |
* </p> |
|
52 |
* |
|
53 |
* <p> |
|
54 |
* <b>Note</b>: Not every Throwable or Exception in the stream will have this flag set to |
|
55 |
* true; only those which were thrown <i>during serialization</i> will |
|
56 |
* </p> |
|
57 |
* |
|
58 |
* @return true iff the object was an exception thrown during serialization |
|
59 |
*/ |
|
60 |
public boolean isExceptionObject(); |
|
61 |
|
|
62 |
/** |
|
63 |
* Sets the flag that tells whether or not this object is an exception that was caught |
|
64 |
* during serialization. |
|
65 |
* |
|
66 |
* @param value the new value to use |
|
67 |
*/ |
|
68 |
public void setIsExceptionObject(boolean value); |
|
69 |
} |
|
70 |
|
demo_jh/Deserializer_tests/src/jdeserialize/contentbase.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* Provides a skeleton content implementation. |
|
7 |
*/ |
|
8 |
public class contentbase implements content { |
|
9 |
public int handle; |
|
10 |
public boolean isExceptionObject; |
|
11 |
protected contenttype type; |
|
12 |
public contentbase(contenttype type) { |
|
13 |
this.type = type; |
|
14 |
} |
|
15 |
public boolean isExceptionObject() { |
|
16 |
return isExceptionObject; |
|
17 |
} |
|
18 |
public void setIsExceptionObject(boolean value) { |
|
19 |
isExceptionObject = value; |
|
20 |
} |
|
21 |
public contenttype getType() { |
|
22 |
return type; |
|
23 |
} |
|
24 |
public int getHandle() { |
|
25 |
return this.handle; |
|
26 |
} |
|
27 |
public void validate() throws ValidityException { |
|
28 |
} |
|
29 |
} |
|
30 |
|
demo_jh/Deserializer_tests/src/jdeserialize/contenttype.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
public enum contenttype { |
|
4 |
INSTANCE, CLASS, ARRAY, STRING, ENUM, CLASSDESC, BLOCKDATA, EXCEPTIONSTATE |
|
5 |
} |
demo_jh/Deserializer_tests/src/jdeserialize/enumobj.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* <p> |
|
7 |
* Represents an enum instance. As noted in the serialization spec, this consists of |
|
8 |
* merely the class description (represented by a classdesc) and the string corresponding |
|
9 |
* to the enum's value. No other fields are ever serialized. |
|
10 |
* </p> |
|
11 |
*/ |
|
12 |
public class enumobj extends contentbase { |
|
13 |
/** |
|
14 |
* The enum's class description. |
|
15 |
*/ |
|
16 |
public classdesc classdesc; |
|
17 |
|
|
18 |
/** |
|
19 |
* The string that represents the enum's value. |
|
20 |
*/ |
|
21 |
public stringobj value; |
|
22 |
|
|
23 |
/** |
|
24 |
* Constructor. |
|
25 |
* |
|
26 |
* @param handle the enum's handle |
|
27 |
* @param cd the enum's class description |
|
28 |
* @param so the enum's value |
|
29 |
*/ |
|
30 |
public enumobj(int handle, classdesc cd, stringobj so) { |
|
31 |
super(contenttype.ENUM); |
|
32 |
this.handle = handle; |
|
33 |
this.classdesc = cd; |
|
34 |
this.value = so; |
|
35 |
} |
|
36 |
public String toString() { |
|
37 |
return "[enum " + jdeserialize.hex(handle) + ": " + value.value + "]"; |
|
38 |
} |
|
39 |
} |
demo_jh/Deserializer_tests/src/jdeserialize/exceptionstate.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* <p> |
|
7 |
* This object contains embedded information about a serialization that failed, throwing |
|
8 |
* an exception. It includes the actual exception object (which was serialized by the |
|
9 |
* ObjectOutputStream) and the raw bytes of the stream data that was read before the |
|
10 |
* exception was recognized. |
|
11 |
* </p> |
|
12 |
* |
|
13 |
* <p> |
|
14 |
* For the mechanics of exception serialization, see the Object Serialization |
|
15 |
* Specification. |
|
16 |
* </p> |
|
17 |
*/ |
|
18 |
public class exceptionstate extends contentbase { |
|
19 |
/** |
|
20 |
* The serialized exception object. |
|
21 |
*/ |
|
22 |
public content exceptionobj; |
|
23 |
|
|
24 |
/** |
|
25 |
* <p> |
|
26 |
* An array of bytes representing the data read before the exception was encountered. |
|
27 |
* Generally, this starts with the first "tc" byte (cf. protocol spec), which is an |
|
28 |
* ObjectStreamConstants value and ends with 0x78 (the tc byte corresponding to |
|
29 |
* TC_EXCEPTION). However, this isn't guaranteed; it may include *more* data. |
|
30 |
* </p> |
|
31 |
* |
|
32 |
* <p> |
|
33 |
* In other words, this is the incomplete object that was being written while the |
|
34 |
* exception was caught by the ObjectOutputStream. It is not likely to be cleanly |
|
35 |
* parseable. |
|
36 |
* </p> |
|
37 |
* |
|
38 |
* <p> |
|
39 |
* The uncertainty centers around the fact that this data is gathered by jdeserialize |
|
40 |
* using a LoggerInputStream, and the underlying DataInputStream may have read more |
|
41 |
* than is necessary. In all tests conducted so far, the above description is |
|
42 |
* accurate. |
|
43 |
* </p> |
|
44 |
*/ |
|
45 |
public byte[] streamdata; |
|
46 |
|
|
47 |
/** |
|
48 |
* Consturctor. |
|
49 |
* @param exobj the serialized exception object |
|
50 |
* @param data the array of stream bytes that led up to the exception |
|
51 |
*/ |
|
52 |
public exceptionstate(content exobj, byte[] data) { |
|
53 |
super(contenttype.EXCEPTIONSTATE); |
|
54 |
this.exceptionobj = exobj; |
|
55 |
this.streamdata = data; |
|
56 |
this.handle = exobj.getHandle(); |
|
57 |
} |
|
58 |
public String toString() { |
|
59 |
StringBuffer sb = new StringBuffer(); |
|
60 |
sb.append("[exceptionstate object " + exceptionobj.toString() + " buflen " + streamdata.length); |
|
61 |
if(streamdata.length > 0) { |
|
62 |
for(int i = 0; i < streamdata.length; i++) { |
|
63 |
if((i % 16) == 0) { |
|
64 |
sb.append(jdeserialize.linesep).append(String.format("%7x: ", Integer.valueOf(i))); |
|
65 |
} |
|
66 |
sb.append(" ").append(jdeserialize.hexnoprefix(streamdata[i])); |
|
67 |
} |
|
68 |
sb.append(jdeserialize.linesep); |
|
69 |
} |
|
70 |
sb.append("]"); |
|
71 |
return sb.toString(); |
|
72 |
} |
|
73 |
} |
demo_jh/Deserializer_tests/src/jdeserialize/field.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* This class represents a field within a class description/declaration (classdesc). It |
|
7 |
* contains information about the type and name of the field. Fields themselves don't |
|
8 |
* have a handle; inside the stream, they exist only as part of a class description. |
|
9 |
*/ |
|
10 |
public class field { |
|
11 |
/** |
|
12 |
* The type of the field. |
|
13 |
*/ |
|
14 |
public fieldtype type; |
|
15 |
|
|
16 |
/** |
|
17 |
* The name of the field. |
|
18 |
*/ |
|
19 |
public String name; |
|
20 |
|
|
21 |
/** |
|
22 |
* The string object representing the class name. |
|
23 |
*/ |
|
24 |
public stringobj classname; |
|
25 |
|
|
26 |
private boolean isInnerClassReference = false; |
|
27 |
|
|
28 |
/** |
|
29 |
* Tells whether or not this class is an inner class reference. This value is set by |
|
30 |
* connectMemberClasses() -- if this hasn't been called, or if the field hasn't been |
|
31 |
* otherwise set by setIsInnerClassReference(), it will be false; |
|
32 |
* |
|
33 |
* @return true if the class is an inner class reference |
|
34 |
*/ |
|
35 |
public boolean isInnerClassReference() { |
|
36 |
return isInnerClassReference; |
|
37 |
} |
|
38 |
|
|
39 |
/** |
|
40 |
* Sets the flag that denotes whether this class is an inner class reference. |
|
41 |
* |
|
42 |
* @param nis the value to set; true iff the class is an inner class reference. |
|
43 |
*/ |
|
44 |
public void setIsInnerClassReference(boolean nis) { |
|
45 |
this.isInnerClassReference = nis; |
|
46 |
} |
|
47 |
|
|
48 |
/** |
|
49 |
* Constructor. |
|
50 |
* |
|
51 |
* @param type the field type |
|
52 |
* @param name the field name |
|
53 |
* @param classname the class name |
|
54 |
*/ |
|
55 |
public field(fieldtype type, String name, stringobj classname) throws ValidityException { |
|
56 |
this.type = type; |
|
57 |
this.name = name; |
|
58 |
this.classname = classname; |
|
59 |
if(classname != null) { |
|
60 |
validate(classname.value); |
|
61 |
} |
|
62 |
} |
|
63 |
|
|
64 |
/** |
|
65 |
* Constructor for simple fields. |
|
66 |
* |
|
67 |
* @param type the field type |
|
68 |
* @param name the field name |
|
69 |
*/ |
|
70 |
public field(fieldtype type, String name) throws ValidityException { |
|
71 |
this(type, name, null); |
|
72 |
} |
|
73 |
|
|
74 |
/** |
|
75 |
* Get a string representing the type for this field in Java (the language) |
|
76 |
* format. |
|
77 |
* @return a string representing the fully-qualified type of the field |
|
78 |
* @throws IOException if a validity or I/O error occurs |
|
79 |
*/ |
|
80 |
public String getJavaType() throws IOException { |
|
81 |
return jdeserialize.resolveJavaType(this.type, this.classname == null ? null : this.classname.value, true, false); |
|
82 |
} |
|
83 |
|
|
84 |
/** |
|
85 |
* Changes the name of an object reference to the name specified. This is used by |
|
86 |
* the inner-class-connection code to fix up field references. |
|
87 |
* @param newname the fully-qualified class |
|
88 |
* @throws ValidityException if the field isn't a reference type, or another |
|
89 |
* validity error occurs |
|
90 |
*/ |
|
91 |
public void setReferenceTypeName(String newname) throws ValidityException { |
|
92 |
if(this.type != fieldtype.OBJECT) { |
|
93 |
throw new ValidityException("can't fix up a non-reference field!"); |
|
94 |
} |
|
95 |
String nname = "L" + newname.replace('.', '/') + ";"; |
|
96 |
this.classname.value = nname; |
|
97 |
} |
|
98 |
public void validate(String jt) throws ValidityException { |
|
99 |
if(this.type == fieldtype.OBJECT) { |
|
100 |
if(jt == null) { |
|
101 |
throw new ValidityException("classname can't be null"); |
|
102 |
} |
|
103 |
if(jt.charAt(0) != 'L') { |
|
104 |
throw new ValidityException("invalid object field type descriptor: " + classname.value); |
|
105 |
} |
|
106 |
int end = jt.indexOf(';'); |
|
107 |
if(end == -1 || end != (jt.length()-1)) { |
|
108 |
throw new ValidityException("invalid object field type descriptor (must end with semicolon): " + classname.value); |
|
109 |
} |
|
110 |
} |
|
111 |
} |
|
112 |
} |
demo_jh/Deserializer_tests/src/jdeserialize/fieldtype.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* <p> |
|
7 |
* Enum class that describes the type of a field encoded inside a classdesc description. |
|
8 |
* </p> |
|
9 |
* |
|
10 |
* <p> |
|
11 |
* This stores both information on the type (reference/array vs. primitive) and, in cases |
|
12 |
* of reference or array types, the name of the class being referred to. |
|
13 |
* </p> |
|
14 |
*/ |
|
15 |
public enum fieldtype { |
|
16 |
BYTE ('B', "byte"), |
|
17 |
CHAR ('C', "char"), |
|
18 |
DOUBLE ('D', "double"), |
|
19 |
FLOAT ('F', "float"), |
|
20 |
INTEGER ('I', "int"), |
|
21 |
LONG ('J', "long"), |
|
22 |
SHORT ('S', "String"), |
|
23 |
BOOLEAN ('Z', "boolean"), |
|
24 |
ARRAY ('['), |
|
25 |
OBJECT ('L'); |
|
26 |
private final char ch; |
|
27 |
private final String javatype; |
|
28 |
|
|
29 |
/** |
|
30 |
* Constructor for non-object (primitive) types. |
|
31 |
* |
|
32 |
* @param ch the character representing the type (must match one of those listed in |
|
33 |
* prim_typecode or obj_typecode in the Object Serialization Stream Protocol) |
|
34 |
*/ |
|
35 |
fieldtype(char ch) { |
|
36 |
this(ch, null); |
|
37 |
} |
|
38 |
|
|
39 |
/** |
|
40 |
* Constructor. |
|
41 |
* |
|
42 |
* @param ch the character representing the type (must match one of those listed in |
|
43 |
* prim_typecode or obj_typecode in the Object Serialization Stream Protocol) |
|
44 |
* @param javatype the name of the object class, where applicable (or null if not) |
|
45 |
*/ |
|
46 |
fieldtype(char ch, String javatype) { |
|
47 |
this.ch = ch; |
|
48 |
this.javatype = javatype; |
|
49 |
} |
|
50 |
|
|
51 |
/** |
|
52 |
* Gets the class name for a reference or array type. |
|
53 |
* |
|
54 |
* @return the name of the class being referred to, or null if this is not a |
|
55 |
* reference/array type |
|
56 |
*/ |
|
57 |
public String getJavaType() { |
|
58 |
return this.javatype; |
|
59 |
} |
|
60 |
|
|
61 |
/** |
|
62 |
* Gets the type character for this field. |
|
63 |
* |
|
64 |
* @return the type code character for this field; values will be one of those in |
|
65 |
* prim_typecode or obj_typecode in the protocol spec |
|
66 |
*/ |
|
67 |
public char ch() { return ch; } |
|
68 |
|
|
69 |
/** |
|
70 |
* Given a byte containing a type code, return the corresponding enum. |
|
71 |
* |
|
72 |
* @param b the type code; must be one of the charcaters in obj_typecode or |
|
73 |
* prim_typecode in the protocol spec |
|
74 |
* @return the corresponding fieldtype enum |
|
75 |
* @throws ValidityException if the type code is invalid |
|
76 |
*/ |
|
77 |
public static fieldtype get(byte b) throws ValidityException { |
|
78 |
switch(b) { |
|
79 |
case 'B': |
|
80 |
return BYTE; |
|
81 |
case 'C': |
|
82 |
return CHAR; |
|
83 |
case 'D': |
|
84 |
return DOUBLE; |
|
85 |
case 'F': |
|
86 |
return FLOAT; |
|
87 |
case 'I': |
|
88 |
return INTEGER; |
|
89 |
case 'J': |
|
90 |
return LONG; |
|
91 |
case 'S': |
|
92 |
return SHORT; |
|
93 |
case 'Z': |
|
94 |
return BOOLEAN; |
|
95 |
case '[': |
|
96 |
return ARRAY; |
|
97 |
case 'L': |
|
98 |
return OBJECT; |
|
99 |
default: |
|
100 |
throw new ValidityException("invalid field type char: " + b); |
|
101 |
} |
|
102 |
} |
|
103 |
} |
|
104 |
|
demo_jh/Deserializer_tests/src/jdeserialize/instance.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
import java.io.*; |
|
3 |
import java.util.*; |
|
4 |
|
|
5 |
/** |
|
6 |
* Represents an instance of a non-enum, non-Class, non-ObjectStreamClass, |
|
7 |
* non-array class, including the non-transient field values, for all classes in its |
|
8 |
* hierarchy and inner classes. |
|
9 |
*/ |
|
10 |
public class instance extends contentbase { |
|
11 |
/** |
|
12 |
* Collection of field data, organized by class description. |
|
13 |
*/ |
|
14 |
public Map<classdesc, Map<field, Object>> fielddata; |
|
15 |
|
|
16 |
/** |
|
17 |
* Class description for this instance. |
|
18 |
*/ |
|
19 |
public classdesc classdesc; |
|
20 |
|
|
21 |
/** |
|
22 |
* Constructor. |
|
23 |
*/ |
|
24 |
public instance() { |
|
25 |
super(contenttype.INSTANCE); |
|
26 |
this.fielddata = new HashMap<classdesc, Map<field, Object>>(); |
|
27 |
} |
|
28 |
public String toString() { |
|
29 |
StringBuffer sb = new StringBuffer(); |
|
30 |
sb.append(classdesc.name).append(' ').append("_h").append(jdeserialize.hex(handle)) |
|
31 |
.append(" = r_").append(jdeserialize.hex(classdesc.handle)).append("; "); |
|
32 |
//sb.append("// [instance " + jdeserialize.hex(handle) + ": " + jdeserialize.hex(classdesc.handle) + "/" + classdesc.name).append("]"); |
|
33 |
return sb.toString(); |
|
34 |
} |
|
35 |
/** |
|
36 |
* Object annotation data. |
|
37 |
*/ |
|
38 |
public Map<classdesc, List<content>> annotations; |
|
39 |
} |
demo_jh/Deserializer_tests/src/jdeserialize/jdeserialize.java | ||
---|---|---|
1 |
package jdeserialize; |
|
2 |
|
|
3 |
import java.io.*; |
|
4 |
import java.util.*; |
|
5 |
import java.util.regex.*; |
|
6 |
|
|
7 |
/** |
|
8 |
* The main user-facing class for the jdeserialize library. Also the implementation of |
|
9 |
* the command-line tool.<br/> |
|
10 |
* <br/> |
|
11 |
* Library:<br/> |
|
12 |
* <br/> |
|
13 |
* The jdeserialize class parses the stream (method run()). From there, call the |
|
14 |
* getContent() method to get an itemized list of all items written to the stream, |
|
15 |
* or getHandleMaps() to get a list of all handle->content maps generated during parsing. |
|
16 |
* The objects are generally instances that implement the interface "content"; see the |
|
17 |
* documentation of various implementors to get more information about the inner |
|
18 |
* representations.<br/> |
|
19 |
* <br/> |
|
20 |
* To enable debugging on stdout, use the enableDebug() or disableDebug() options. <br/> |
|
21 |
* <br/> |
|
22 |
* <br/> |
|
23 |
* Command-line tool: <br/> |
|
24 |
* <br/> |
|
25 |
* The tool reads in a set of files and generates configurable output on stdout. The |
|
26 |
* primary output consists of three separate stages. The first stage is a textual |
|
27 |
* description of every piece of content in the stream, in the order it was written. |
|
28 |
* There is generally a one-to-one mapping between ObjectOutputStream.writeXXX() calls and |
|
29 |
* items printed in the first stage. The first stage may be suppressed with the |
|
30 |
* -nocontent command-line option. <br/> |
|
31 |
* <br/> |
|
32 |
* The second stage is a list of every class declaration serialized in the file. These |
|
33 |
* are formatted as normal Java language class declarations. Several options are |
|
34 |
* available to govern this stage, including -filter, -showarrays, -noclasses, and |
|
35 |
* -fixnames. <br/> |
|
36 |
* <br/> |
|
37 |
* The third stage is a dump of every instance embedded inside the stream, including |
|
38 |
* textual descriptions of field values. This is useful for casual viewing of class data. |
|
39 |
* To suppress this stage, use -noinstances. <br/> |
|
40 |
* <br/> |
|
41 |
* You can also get debugging information generated during the parse phase by supplying |
|
42 |
* -debug. |
|
43 |
* <br/> |
|
44 |
* The data from block data objects can be extracted with the -blockdata <file> option. |
|
45 |
* Additionally, a manifest describing the size of each individual block can be generated |
|
46 |
* with the -blockdatamanifest <file> option. |
|
47 |
* <br/> |
|
48 |
* References: <br/> |
|
49 |
* - Java Object Serialization Specification ch. 6 (Object Serialization Stream |
|
50 |
* Protocol): <br/> |
|
51 |
* http://download.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html <br/> |
|
52 |
* - "Modified UTF-8 Strings" within the JNI specification: |
|
53 |
* http://download.oracle.com/javase/1.5.0/docs/guide/jni/spec/types.html#wp16542 <br/> |
|
54 |
* - "Inner Classes Specification" within the JDK 1.1.8 docs: |
|
55 |
* http://java.sun.com/products/archive/jdk/1.1/ <br/> |
|
56 |
* - "Java Language Specification", third edition, particularly section 3: |
|
57 |
* http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html <br/> |
|
58 |
* |
|
59 |
* @see content |
|
60 |
*/ |
|
61 |
public class jdeserialize { |
|
62 |
public static final long serialVersionUID = 78790714646095L; |
|
63 |
public static final String INDENT = " "; |
|
64 |
public static final int CODEWIDTH = 90; |
|
65 |
public static final String linesep = System.getProperty("line.separator"); |
|
66 |
public static final String[] keywords = new String[] { |
|
67 |
"abstract", "continue", "for", "new", "switch", "assert", "default", "if", |
|
68 |
"package", "synchronized", "boolean", "do", "goto", "private", "this", |
|
69 |
"break", "double", "implements", "protected", "throw", "byte", "else", |
|
70 |
"import", "public", "throws", "case", "enum", "instanceof", "return", |
|
71 |
"transient", "catch", "extends", "int", "short", "try", "char", "final", |
|
72 |
"interface", "static", "void", "class", "finally", "long", "strictfp", |
|
73 |
"volatile", "const", "float", "native", "super", "while" }; |
Také k dispozici: Unified diff
#7768 Simplified jdeserialize main with args. Project implemented