mirror of
https://github.com/corda/corda.git
synced 2025-06-16 14:18:20 +00:00
flesh out serialization/deserialization code and fix build
This commit is contained in:
11
classpath/java/io/EOFException.java
Normal file
11
classpath/java/io/EOFException.java
Normal file
@ -0,0 +1,11 @@
|
||||
package java.io;
|
||||
|
||||
public class EOFException extends IOException {
|
||||
public EOFException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public EOFException() {
|
||||
this(null);
|
||||
}
|
||||
}
|
11
classpath/java/io/NotSerializableException.java
Normal file
11
classpath/java/io/NotSerializableException.java
Normal file
@ -0,0 +1,11 @@
|
||||
package java.io;
|
||||
|
||||
public class NotSerializableException extends ObjectStreamException {
|
||||
public NotSerializableException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NotSerializableException() {
|
||||
this(null);
|
||||
}
|
||||
}
|
@ -1,8 +1,13 @@
|
||||
package java.io;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class ObjectInputStream extends InputStream {
|
||||
private final InputStream in;
|
||||
private final Reader r;
|
||||
private final PushbackReader r;
|
||||
|
||||
public ObjectInputStream(InputStream in) {
|
||||
this.in = in;
|
||||
@ -21,7 +26,7 @@ public class ObjectInputStream extends InputStream {
|
||||
in.close();
|
||||
}
|
||||
|
||||
public Object readObject() throws IOException {
|
||||
public Object readObject() throws IOException, ClassNotFoundException {
|
||||
return readObject(new HashMap());
|
||||
}
|
||||
|
||||
@ -67,7 +72,7 @@ public class ObjectInputStream extends InputStream {
|
||||
|
||||
private void skipSpace() throws IOException {
|
||||
int c;
|
||||
while ((c = r.read()) != -1 && Character.isSpace((char) c));
|
||||
while ((c = r.read()) != -1 && Character.isWhitespace((char) c));
|
||||
if (c != -1) {
|
||||
r.unread(c);
|
||||
}
|
||||
@ -91,7 +96,7 @@ public class ObjectInputStream extends InputStream {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int c;
|
||||
while ((c = r.read()) != -1 && ! Character.isSpace((char) c)) {
|
||||
while ((c = r.read()) != -1 && ! Character.isWhitespace((char) c)) {
|
||||
sb.append((char) c);
|
||||
}
|
||||
if (c != -1) {
|
||||
@ -108,13 +113,15 @@ public class ObjectInputStream extends InputStream {
|
||||
return Double.parseDouble(readStringToken());
|
||||
}
|
||||
|
||||
private Object readObject(HashMap<Integer, Object> map) throws IOException {
|
||||
private Object readObject(HashMap<Integer, Object> map)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
skipSpace();
|
||||
switch (r.read()) {
|
||||
case 'a':
|
||||
return deserializeArray(map);
|
||||
case 'l':
|
||||
return deserialize(map);
|
||||
return deserializeObject(map);
|
||||
case 'n':
|
||||
return null;
|
||||
case -1:
|
||||
@ -124,153 +131,85 @@ public class ObjectInputStream extends InputStream {
|
||||
}
|
||||
}
|
||||
|
||||
private Object deserialize(HashMap<Integer, Object> map)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
skipSpace();
|
||||
|
||||
switch (r.read()) {
|
||||
case 'a':
|
||||
return deserializeArray(map);
|
||||
case 'l':
|
||||
return deserializeObject(map);
|
||||
case 'r':
|
||||
return map.get((int) readLongToken());
|
||||
case 'n':
|
||||
return null;
|
||||
case 'z':
|
||||
return (readLongToken() == 0);
|
||||
case 'b':
|
||||
return (byte) readLongToken();
|
||||
case 'c':
|
||||
return (char) readLongToken();
|
||||
case 's':
|
||||
return (short) readLongToken();
|
||||
case 'i':
|
||||
return (int) readLongToken();
|
||||
case 'j':
|
||||
return readLongToken();
|
||||
case 'f':
|
||||
return (float) readDoubleToken();
|
||||
case 'd':
|
||||
return readDoubleToken();
|
||||
case -1:
|
||||
throw new EOFException();
|
||||
default:
|
||||
throw new StreamCorruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
private Object deserializeArray(HashMap<Integer, Object> map)
|
||||
throws IOException
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
read('(');
|
||||
int id = (int) readLongToken();
|
||||
Class c = Class.forName(readStringToken());
|
||||
int length = (int) readLongToken();
|
||||
Object o = Array.newInstance(c.getComponentType(), length);
|
||||
Class t = c.getComponentType();
|
||||
Object o = Array.newInstance(t, length);
|
||||
|
||||
map.put(id, o);
|
||||
|
||||
for (int i = 0; i < length; ++i) {
|
||||
skipSpace();
|
||||
|
||||
switch (r.read()) {
|
||||
case 'a':
|
||||
Array.set(o, i, deserializeArray(map));
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
Array.set(o, i, deserialize(map));
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
Array.set(o, i, map.get((int) readLongToken()));
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
Array.set(o, i, null);
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
f.setBoolean(o, readLongToken() != 0);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
f.setByte(o, (byte) readLongToken());
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
f.setChar(o, (char) readLongToken());
|
||||
break;
|
||||
|
||||
case 's':
|
||||
f.setShort(o, (short) readLongToken());
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
f.setInt(o, (int) readLongToken());
|
||||
break;
|
||||
|
||||
case 'j':
|
||||
f.setLong(o, readLongToken());
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
f.setFloat(o, (float) readDoubleToken());
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
f.setDouble(o, readDoubleToken());
|
||||
break;
|
||||
|
||||
case -1:
|
||||
throw new EOFException();
|
||||
|
||||
default:
|
||||
throw new StreamCorruptedException();
|
||||
}
|
||||
Array.set(o, i, deserialize(map));
|
||||
}
|
||||
|
||||
read(')');
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
private Object deserialize(HashMap<Integer, Object> map)
|
||||
throws IOException
|
||||
private static native Object makeInstance(Class c);
|
||||
|
||||
private Object deserializeObject(HashMap<Integer, Object> map)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
read('(');
|
||||
int id = (int) readLongToken();
|
||||
Class c = Class.forName(readStringToken());
|
||||
Object o = c.newInstance();
|
||||
Object o = makeInstance(c);
|
||||
|
||||
map.put(id, o);
|
||||
|
||||
for (Field f: c.getFields()) {
|
||||
int modifiers = f.getModifiers();
|
||||
if ((modifiers & (Modifier.TRANSIENT | Modifier.STATIC)) == 0) {
|
||||
skipSpace();
|
||||
|
||||
switch (r.read()) {
|
||||
case 'a':
|
||||
Array.set(o, i, deserializeArray(map));
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
Array.set(o, i, deserialize(map));
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
Array.set(o, i, map.get((int) readLongToken()));
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
Array.set(o, i, null);
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
Array.setBoolean(o, i, readLongToken() != 0);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
Array.setByte(o, i, (byte) readLongToken());
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
Array.setChar(o, i, (char) readLongToken());
|
||||
break;
|
||||
|
||||
case 's':
|
||||
Array.setShort(o, i, (short) readLongToken());
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
Array.setInt(o, i, (int) readLongToken());
|
||||
break;
|
||||
|
||||
case 'j':
|
||||
Array.setLong(o, i, readLongToken());
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
Array.setFloat(o, i, (float) readDoubleToken());
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
Array.setDouble(o, i, readDoubleToken());
|
||||
break;
|
||||
|
||||
case -1:
|
||||
throw new EOFException();
|
||||
|
||||
default:
|
||||
throw new StreamCorruptedException();
|
||||
}
|
||||
f.set(o, deserialize(map));
|
||||
}
|
||||
}
|
||||
|
||||
read(')');
|
||||
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package java.io;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class ObjectOutputStream extends OutputStream {
|
||||
private final PrintStream out;
|
||||
@ -76,15 +79,15 @@ public class ObjectOutputStream extends OutputStream {
|
||||
if (o == null) {
|
||||
out.print("n");
|
||||
} else {
|
||||
Integer id = map.get(new Identity(o));
|
||||
Integer id = map.get(o);
|
||||
if (id == null) {
|
||||
map.put(new Identity(o), nextId);
|
||||
map.put(o, nextId);
|
||||
|
||||
Class c = o.getClass();
|
||||
if (c.isArray()) {
|
||||
serializeArray(o, map, nextId);
|
||||
} else if (Serializable.class.isAssignableFrom(c)) {
|
||||
serialize(o, map, nextId);
|
||||
serializeObject(o, map, nextId);
|
||||
} else {
|
||||
throw new NotSerializableException(c.getName());
|
||||
}
|
||||
@ -112,32 +115,33 @@ public class ObjectOutputStream extends OutputStream {
|
||||
|
||||
for (int i = 0; i < length; ++i) {
|
||||
out.print(" ");
|
||||
Object v = Array.get(o, i);
|
||||
if (t.equals(boolean.class)) {
|
||||
writeBoolean(Array.getBoolean(o));
|
||||
writeBoolean((Boolean) v);
|
||||
} else if (t.equals(byte.class)) {
|
||||
writeByte(Array.getByte(o));
|
||||
writeByte((Byte) v);
|
||||
} else if (t.equals(char.class)) {
|
||||
writeChar(Array.getChar(o));
|
||||
writeChar((Character) v);
|
||||
} else if (t.equals(short.class)) {
|
||||
writeShort(Array.getShort(o));
|
||||
writeShort((Short) v);
|
||||
} else if (t.equals(int.class)) {
|
||||
writeInt(Array.getInt(o));
|
||||
writeInt((Integer) v);
|
||||
} else if (t.equals(long.class)) {
|
||||
writeLong(Array.getLong(o));
|
||||
writeLong((Long) v);
|
||||
} else if (t.equals(float.class)) {
|
||||
writeFloat(Array.getFloat(o));
|
||||
writeFloat((Float) v);
|
||||
} else if (t.equals(double.class)) {
|
||||
writeDouble(Array.getDouble(o));
|
||||
writeDouble((Double) v);
|
||||
} else {
|
||||
writeObject(Array.get(o), map, nextId);
|
||||
writeObject(v, map, nextId);
|
||||
}
|
||||
}
|
||||
|
||||
out.print(")");
|
||||
}
|
||||
|
||||
private void serialize(Object o, IdentityHashMap<Object, Integer> map,
|
||||
int nextId)
|
||||
private void serializeObject(Object o, IdentityHashMap<Object, Integer> map,
|
||||
int nextId)
|
||||
throws IOException
|
||||
{
|
||||
Class c = o.getClass();
|
||||
@ -151,25 +155,26 @@ public class ObjectOutputStream extends OutputStream {
|
||||
int modifiers = f.getModifiers();
|
||||
if ((modifiers & (Modifier.TRANSIENT | Modifier.STATIC)) == 0) {
|
||||
out.print(" ");
|
||||
Object v = f.get(o);
|
||||
Class t = f.getType();
|
||||
if (t.equals(boolean.class)) {
|
||||
writeBoolean(f.getBoolean(o));
|
||||
writeBoolean((Boolean) v);
|
||||
} else if (t.equals(byte.class)) {
|
||||
writeByte(f.getByte(o));
|
||||
writeByte((Byte) v);
|
||||
} else if (t.equals(char.class)) {
|
||||
writeChar(f.getChar(o));
|
||||
writeChar((Character) v);
|
||||
} else if (t.equals(short.class)) {
|
||||
writeShort(f.getShort(o));
|
||||
writeShort((Short) v);
|
||||
} else if (t.equals(int.class)) {
|
||||
writeInt(f.getInt(o));
|
||||
writeInt((Integer) v);
|
||||
} else if (t.equals(long.class)) {
|
||||
writeLong(f.getLong(o));
|
||||
writeLong((Long) v);
|
||||
} else if (t.equals(float.class)) {
|
||||
writeFloat(f.getFloat(o));
|
||||
writeFloat((Float) v);
|
||||
} else if (t.equals(double.class)) {
|
||||
writeDouble(f.getDouble(o));
|
||||
writeDouble((Double) v);
|
||||
} else {
|
||||
writeObject(f.get(o), map, nextId);
|
||||
writeObject(v, map, nextId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
69
classpath/java/io/PushbackReader.java
Normal file
69
classpath/java/io/PushbackReader.java
Normal file
@ -0,0 +1,69 @@
|
||||
package java.io;
|
||||
|
||||
public class PushbackReader extends Reader {
|
||||
private final Reader in;
|
||||
private final char[] buffer;
|
||||
private int position;
|
||||
private int limit;
|
||||
|
||||
public PushbackReader(Reader in, int bufferSize) {
|
||||
this.in = in;
|
||||
this.buffer = new char[bufferSize];
|
||||
}
|
||||
|
||||
public PushbackReader(Reader in) {
|
||||
this(in, 1);
|
||||
}
|
||||
|
||||
public int read(char[] b, int offset, int length) throws IOException {
|
||||
int count = 0;
|
||||
|
||||
if (position < limit) {
|
||||
int remaining = limit - position;
|
||||
if (remaining > length) {
|
||||
remaining = length;
|
||||
}
|
||||
|
||||
System.arraycopy(buffer, position, b, offset, remaining);
|
||||
|
||||
count += remaining;
|
||||
position += remaining;
|
||||
offset += remaining;
|
||||
length -= remaining;
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
int c = in.read(b, offset, length);
|
||||
if (c == -1) {
|
||||
if (count == 0) {
|
||||
count = -1;
|
||||
}
|
||||
} else {
|
||||
count += c;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public void unread(char[] b, int offset, int length) throws IOException {
|
||||
if (position < length) {
|
||||
throw new IOException(length + " not in [0," + position + "]");
|
||||
} else {
|
||||
System.arraycopy(buffer, position - length, b, offset, length);
|
||||
position -= length;
|
||||
}
|
||||
}
|
||||
|
||||
public void unread(char[] b) throws IOException {
|
||||
unread(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void unread(int c) throws IOException {
|
||||
unread(new char[] { (char) c });
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
}
|
11
classpath/java/io/StreamCorruptedException.java
Normal file
11
classpath/java/io/StreamCorruptedException.java
Normal file
@ -0,0 +1,11 @@
|
||||
package java.io;
|
||||
|
||||
public class StreamCorruptedException extends IOException {
|
||||
public StreamCorruptedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public StreamCorruptedException() {
|
||||
this(null);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user