ObjectInputStream.java [plain text]
package java.io;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Vector;
import gnu.java.io.ObjectIdentityWrapper;
import gnu.java.lang.reflect.TypeSignature;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import gnu.classpath.Configuration;
public class ObjectInputStream extends InputStream
implements ObjectInput, ObjectStreamConstants
{
public ObjectInputStream (InputStream in)
throws IOException, StreamCorruptedException
{
if (Configuration.DEBUG)
{
String val = System.getProperty("gcj.dumpobjects");
if (dump == false && val != null && !val.equals(""))
{
dump = true;
System.out.println ("Serialization debugging enabled");
}
else if (dump == true && (val == null || val.equals("")))
{
dump = false;
System.out.println ("Serialization debugging disabled");
}
}
this.resolveEnabled = false;
this.isDeserializing = false;
this.blockDataPosition = 0;
this.blockDataBytes = 0;
this.blockData = new byte[BUFFER_SIZE];
this.blockDataInput = new DataInputStream (this);
this.realInputStream = new DataInputStream (in);
this.nextOID = baseWireHandle;
this.objectLookupTable = new Hashtable ();
this.validators = new Vector ();
setBlockDataMode (true);
readStreamHeader ();
}
public final Object readObject () throws ClassNotFoundException, IOException
{
if (this.useSubclassMethod)
return readObjectOverride ();
boolean was_deserializing;
Object ret_val;
was_deserializing = this.isDeserializing;
boolean is_consumed = false;
boolean old_mode = setBlockDataMode (false);
this.isDeserializing = true;
byte marker = this.realInputStream.readByte ();
dumpElement ("MARKER: 0x" + Integer.toHexString(marker) + " ");
try
{
switch (marker)
{
case TC_ENDBLOCKDATA:
{
ret_val = null;
is_consumed = true;
break;
}
case TC_BLOCKDATA:
case TC_BLOCKDATALONG:
{
if (marker == TC_BLOCKDATALONG)
dumpElementln ("BLOCKDATALONG");
else
dumpElementln ("BLOCKDATA");
readNextBlock (marker);
throw new StreamCorruptedException ("Unexpected blockData");
}
case TC_NULL:
{
dumpElementln ("NULL");
ret_val = null;
break;
}
case TC_REFERENCE:
{
dumpElement ("REFERENCE ");
Integer oid = new Integer (this.realInputStream.readInt ());
dumpElementln (Integer.toHexString(oid.intValue()));
ret_val = ((ObjectIdentityWrapper)
this.objectLookupTable.get (oid)).object;
break;
}
case TC_CLASS:
{
dumpElementln ("CLASS");
ObjectStreamClass osc = (ObjectStreamClass)readObject ();
Class clazz = osc.forClass ();
assignNewHandle (clazz);
ret_val = clazz;
break;
}
case TC_PROXYCLASSDESC:
{
dumpElementln ("PROXYCLASS");
int n_intf = this.realInputStream.readInt();
String[] intfs = new String[n_intf];
for (int i = 0; i < n_intf; i++)
{
intfs[i] = this.realInputStream.readUTF();
System.out.println(intfs[i]);
}
boolean oldmode = setBlockDataMode (true);
Class cl = resolveProxyClass(intfs);
setBlockDataMode(oldmode);
ObjectStreamClass osc = ObjectStreamClass.lookup(cl);
assignNewHandle (osc);
if (!is_consumed)
{
byte b = this.realInputStream.readByte ();
if (b != TC_ENDBLOCKDATA)
throw new IOException ("Data annotated to class was not consumed." + b);
}
else
is_consumed = false;
ObjectStreamClass superosc = (ObjectStreamClass)readObject ();
osc.setSuperclass (superosc);
ret_val = osc;
break;
}
case TC_CLASSDESC:
{
dumpElement ("CLASSDESC NAME=");
String name = this.realInputStream.readUTF ();
dumpElement (name + "; UID=");
long uid = this.realInputStream.readLong ();
dumpElement (Long.toHexString(uid) + "; FLAGS=");
byte flags = this.realInputStream.readByte ();
dumpElement (Integer.toHexString(flags) + "; FIELD COUNT=");
short field_count = this.realInputStream.readShort ();
dumpElementln (Short.toString(field_count));
ObjectStreamField[] fields = new ObjectStreamField[field_count];
ObjectStreamClass osc = new ObjectStreamClass (name, uid,
flags, fields);
assignNewHandle (osc);
for (int i=0; i < field_count; i++)
{
dumpElement (" TYPE CODE=");
char type_code = (char)this.realInputStream.readByte ();
dumpElement (type_code + "; FIELD NAME=");
String field_name = this.realInputStream.readUTF ();
dumpElementln (field_name);
String class_name;
if (type_code == 'L' || type_code == '[')
class_name = (String)readObject ();
else
class_name = String.valueOf (type_code);
fields[i] =
new ObjectStreamField (field_name, class_name);
}
boolean oldmode = setBlockDataMode (true);
osc.setClass (resolveClass (osc));
setBlockDataMode (oldmode);
if (!is_consumed)
{
byte b = this.realInputStream.readByte ();
if (b != TC_ENDBLOCKDATA)
throw new IOException ("Data annotated to class was not consumed." + b);
}
else
is_consumed = false;
osc.setSuperclass ((ObjectStreamClass)readObject ());
ret_val = osc;
break;
}
case TC_STRING:
case TC_LONGSTRING:
{
dumpElement ("STRING=");
String s = this.realInputStream.readUTF ();
dumpElementln (s);
ret_val = processResolution (s, assignNewHandle (s));
break;
}
case TC_ARRAY:
{
dumpElementln ("ARRAY");
ObjectStreamClass osc = (ObjectStreamClass)readObject ();
Class componentType = osc.forClass ().getComponentType ();
dumpElement ("ARRAY LENGTH=");
int length = this.realInputStream.readInt ();
dumpElementln (length + "; COMPONENT TYPE=" + componentType);
Object array = Array.newInstance (componentType, length);
int handle = assignNewHandle (array);
readArrayElements (array, componentType);
for (int i=0, len=Array.getLength(array); i < len; i++)
dumpElementln (" ELEMENT[" + i + "]=" + Array.get(array, i));
ret_val = processResolution (array, handle);
break;
}
case TC_OBJECT:
{
dumpElementln ("OBJECT");
ObjectStreamClass osc = (ObjectStreamClass)readObject ();
Class clazz = osc.forClass ();
if (!Serializable.class.isAssignableFrom (clazz))
throw new NotSerializableException (clazz + " is not Serializable, and thus cannot be deserialized.");
if (Externalizable.class.isAssignableFrom (clazz))
{
Externalizable obj = null;
try
{
obj = (Externalizable)clazz.newInstance ();
}
catch (InstantiationException e)
{
throw new ClassNotFoundException ("Instance of " + clazz
+ " could not be created");
}
catch (IllegalAccessException e)
{
throw new ClassNotFoundException ("Instance of " + clazz
+ " could not be created because class or zero-argument constructor is not accessible");
}
catch (NoSuchMethodError e)
{
throw new ClassNotFoundException ("Instance of " + clazz
+ " could not be created because zero-argument constructor is not defined");
}
int handle = assignNewHandle (obj);
boolean read_from_blocks = ((osc.getFlags () & SC_BLOCK_DATA) != 0);
boolean oldmode = this.readDataFromBlock;
if (read_from_blocks)
setBlockDataMode (true);
obj.readExternal (this);
if (read_from_blocks)
setBlockDataMode (oldmode);
ret_val = processResolution (obj, handle);
break;
}
Class first_nonserial = clazz.getSuperclass ();
while (Serializable.class.isAssignableFrom (first_nonserial)
|| Modifier.isAbstract (first_nonserial.getModifiers ()))
first_nonserial = first_nonserial.getSuperclass ();
Object obj = null;
obj = newObject (clazz, first_nonserial);
if (obj == null)
throw new ClassNotFoundException ("Instance of " + clazz +
" could not be created");
int handle = assignNewHandle (obj);
this.currentObject = obj;
ObjectStreamClass[] hierarchy =
ObjectStreamClass.getObjectStreamClasses (clazz);
boolean has_read;
for (int i=0; i < hierarchy.length; i++)
{
this.currentObjectStreamClass = hierarchy[i];
dumpElementln ("Reading fields of "
+ this.currentObjectStreamClass.getName ());
has_read = true;
try
{
this.currentObjectStreamClass.forClass ().
getDeclaredMethod ("readObject", readObjectParams);
}
catch (NoSuchMethodException e)
{
has_read = false;
}
readFields (obj, this.currentObjectStreamClass.fields,
has_read, this.currentObjectStreamClass);
if (has_read)
{
dumpElement ("ENDBLOCKDATA? ");
try
{
if (this.realInputStream.readByte () != TC_ENDBLOCKDATA)
throw new IOException ("No end of block data seen for class with readObject (ObjectInputStream) method.");
dumpElementln ("yes");
}
catch (EOFException e)
{
dumpElementln ("no, got EOFException");
}
catch (IOException e)
{
dumpElementln ("no, got IOException");
}
}
}
this.currentObject = null;
this.currentObjectStreamClass = null;
ret_val = processResolution (obj, handle);
break;
}
case TC_RESET:
dumpElementln ("RESET");
clearHandles ();
ret_val = readObject ();
break;
case TC_EXCEPTION:
{
dumpElement ("EXCEPTION=");
Exception e = (Exception)readObject ();
dumpElementln (e.toString());
clearHandles ();
throw new WriteAbortedException ("Exception thrown during writing of stream", e);
}
default:
throw new IOException ("Unknown marker on stream: " + marker);
}
}
finally
{
setBlockDataMode (old_mode);
this.isDeserializing = was_deserializing;
if (! was_deserializing)
{
if (validators.size () > 0)
invokeValidators ();
}
}
return ret_val;
}
public void defaultReadObject ()
throws ClassNotFoundException, IOException, NotActiveException
{
if (this.currentObject == null || this.currentObjectStreamClass == null)
throw new NotActiveException ("defaultReadObject called by non-active class and/or object");
if (fieldsAlreadyRead)
throw new NotActiveException ("defaultReadObject called but fields already read from stream (by defaultReadObject or readFields)");
boolean oldmode = setBlockDataMode(false);
readFields (this.currentObject,
this.currentObjectStreamClass.fields,
false, this.currentObjectStreamClass);
setBlockDataMode(oldmode);
fieldsAlreadyRead = true;
}
public void registerValidation (ObjectInputValidation validator,
int priority)
throws InvalidObjectException, NotActiveException
{
if (this.currentObject == null || this.currentObjectStreamClass == null)
throw new NotActiveException ("registerValidation called by non-active class and/or object");
if (validator == null)
throw new InvalidObjectException ("attempt to add a null ObjectInputValidation object");
this.validators.addElement (new ValidatorAndPriority (validator,
priority));
}
protected Class resolveClass (ObjectStreamClass osc)
throws ClassNotFoundException, IOException
{
SecurityManager sm = System.getSecurityManager ();
if (sm == null)
sm = new SecurityManager () {};
ClassLoader cl = currentClassLoader (sm);
if (cl == null)
return Class.forName (osc.getName ());
else
return cl.loadClass (osc.getName ());
}
protected Object resolveObject (Object obj) throws IOException
{
return obj;
}
protected Class resolveProxyClass (String[] intfs)
throws IOException, ClassNotFoundException
{
SecurityManager sm = System.getSecurityManager ();
if (sm == null)
sm = new SecurityManager () {};
ClassLoader cl = currentClassLoader (sm);
Class[] clss = new Class[intfs.length];
if(cl == null){
for (int i = 0; i < intfs.length; i++)
clss[i] = Class.forName(intfs[i]);
cl = ClassLoader.getSystemClassLoader();
}
else
for (int i = 0; i < intfs.length; i++)
clss[i] = cl.loadClass(intfs[i]);
try {
return Proxy.getProxyClass(cl, clss);
} catch (IllegalArgumentException e) {
throw new ClassNotFoundException(null, e);
}
}
protected boolean enableResolveObject (boolean enable)
throws SecurityException
{
if (enable)
{
SecurityManager sm = System.getSecurityManager ();
if (sm != null)
sm.checkPermission (new SerializablePermission ("enableSubtitution"));
}
boolean old_val = this.resolveEnabled;
this.resolveEnabled = enable;
return old_val;
}
protected void readStreamHeader ()
throws IOException, StreamCorruptedException
{
dumpElement ("STREAM MAGIC ");
if (this.realInputStream.readShort () != STREAM_MAGIC)
throw new StreamCorruptedException ("Invalid stream magic number");
dumpElementln ("STREAM VERSION ");
if (this.realInputStream.readShort () != STREAM_VERSION)
throw new StreamCorruptedException ("Invalid stream version number");
}
public int read () throws IOException
{
if (this.readDataFromBlock)
{
if (this.blockDataPosition >= this.blockDataBytes)
readNextBlock ();
return (this.blockData[this.blockDataPosition++] & 0xff);
}
else
return this.realInputStream.read ();
}
public int read (byte[] data, int offset, int length) throws IOException
{
if (this.readDataFromBlock)
{
if (this.blockDataPosition + length > this.blockDataBytes)
{
int remain = this.blockDataBytes - this.blockDataPosition;
if (remain != 0)
{
System.arraycopy (this.blockData, this.blockDataPosition,
data, offset, remain);
offset += remain;
length -= remain;
}
readNextBlock ();
}
System.arraycopy (this.blockData, this.blockDataPosition,
data, offset, length);
this.blockDataPosition += length;
return length;
}
else
return this.realInputStream.read (data, offset, length);
}
public int available () throws IOException
{
if (this.readDataFromBlock)
{
if (this.blockDataPosition >= this.blockDataBytes)
readNextBlock ();
return this.blockDataBytes - this.blockDataPosition;
}
else
return this.realInputStream.available ();
}
public void close () throws IOException
{
this.realInputStream.close ();
}
public boolean readBoolean () throws IOException
{
return this.dataInputStream.readBoolean ();
}
public byte readByte () throws IOException
{
return this.dataInputStream.readByte ();
}
public int readUnsignedByte () throws IOException
{
return this.dataInputStream.readUnsignedByte ();
}
public short readShort () throws IOException
{
return this.dataInputStream.readShort ();
}
public int readUnsignedShort () throws IOException
{
return this.dataInputStream.readUnsignedShort ();
}
public char readChar () throws IOException
{
return this.dataInputStream.readChar ();
}
public int readInt () throws IOException
{
return this.dataInputStream.readInt ();
}
public long readLong () throws IOException
{
return this.dataInputStream.readLong ();
}
public float readFloat () throws IOException
{
return this.dataInputStream.readFloat ();
}
public double readDouble () throws IOException
{
return this.dataInputStream.readDouble ();
}
public void readFully (byte data[]) throws IOException
{
this.dataInputStream.readFully (data);
}
public void readFully (byte data[], int offset, int size)
throws IOException
{
this.dataInputStream.readFully (data, offset, size);
}
public int skipBytes (int len) throws IOException
{
return this.dataInputStream.skipBytes (len);
}
public String readLine () throws IOException
{
return this.dataInputStream.readLine ();
}
public String readUTF () throws IOException
{
return this.dataInputStream.readUTF ();
}
public static abstract class GetField
{
public abstract ObjectStreamClass getObjectStreamClass ();
public abstract boolean defaulted (String name)
throws IOException, IllegalArgumentException;
public abstract boolean get (String name, boolean defvalue)
throws IOException, IllegalArgumentException;
public abstract char get (String name, char defvalue)
throws IOException, IllegalArgumentException;
public abstract byte get (String name, byte defvalue)
throws IOException, IllegalArgumentException;
public abstract short get (String name, short defvalue)
throws IOException, IllegalArgumentException;
public abstract int get (String name, int defvalue)
throws IOException, IllegalArgumentException;
public abstract long get (String name, long defvalue)
throws IOException, IllegalArgumentException;
public abstract float get (String name, float defvalue)
throws IOException, IllegalArgumentException;
public abstract double get (String name, double defvalue)
throws IOException, IllegalArgumentException;
public abstract Object get (String name, Object defvalue)
throws IOException, IllegalArgumentException;
}
public GetField readFields ()
throws IOException, ClassNotFoundException, NotActiveException
{
if (this.currentObject == null || this.currentObjectStreamClass == null)
throw new NotActiveException ("readFields called by non-active class and/or object");
if (fieldsAlreadyRead)
throw new NotActiveException ("readFields called but fields already read from stream (by defaultReadObject or readFields)");
final ObjectStreamClass clazz = this.currentObjectStreamClass;
final byte[] prim_field_data = new byte[clazz.primFieldSize];
final Object[] objs = new Object[clazz.objectFieldCount];
boolean oldmode = setBlockDataMode (false);
readFully (prim_field_data);
for (int i = 0; i < objs.length; ++ i)
objs[i] = readObject ();
setBlockDataMode (oldmode);
return new GetField ()
{
public ObjectStreamClass getObjectStreamClass ()
{
return clazz;
}
public boolean defaulted (String name)
throws IOException, IllegalArgumentException
{
return clazz.getField (name) == null;
}
public boolean get (String name, boolean defvalue)
throws IOException, IllegalArgumentException
{
ObjectStreamField field = getField (name, Boolean.TYPE);
if (field == null)
return defvalue;
return prim_field_data[field.getOffset ()] == 0 ? false : true;
}
public char get (String name, char defvalue)
throws IOException, IllegalArgumentException
{
ObjectStreamField field = getField (name, Character.TYPE);
if (field == null)
return defvalue;
int off = field.getOffset ();
return (char)(((prim_field_data[off++] & 0xFF) << 8)
| (prim_field_data[off] & 0xFF));
}
public byte get (String name, byte defvalue)
throws IOException, IllegalArgumentException
{
ObjectStreamField field = getField (name, Byte.TYPE);
if (field == null)
return defvalue;
return prim_field_data[field.getOffset ()];
}
public short get (String name, short defvalue)
throws IOException, IllegalArgumentException
{
ObjectStreamField field = getField (name, Short.TYPE);
if (field == null)
return defvalue;
int off = field.getOffset ();
return (short)(((prim_field_data[off++] & 0xFF) << 8)
| (prim_field_data[off] & 0xFF));
}
public int get (String name, int defvalue)
throws IOException, IllegalArgumentException
{
ObjectStreamField field = getField (name, Integer.TYPE);
if (field == null)
return defvalue;
int off = field.getOffset ();
return ((prim_field_data[off++] & 0xFF) << 24)
| ((prim_field_data[off++] & 0xFF) << 16)
| ((prim_field_data[off++] & 0xFF) << 8)
| (prim_field_data[off] & 0xFF);
}
public long get (String name, long defvalue)
throws IOException, IllegalArgumentException
{
ObjectStreamField field = getField (name, Long.TYPE);
if (field == null)
return defvalue;
int off = field.getOffset ();
return (long)(((prim_field_data[off++] & 0xFF) << 56)
| ((prim_field_data[off++] & 0xFF) << 48)
| ((prim_field_data[off++] & 0xFF) << 40)
| ((prim_field_data[off++] & 0xFF) << 32)
| ((prim_field_data[off++] & 0xFF) << 24)
| ((prim_field_data[off++] & 0xFF) << 16)
| ((prim_field_data[off++] & 0xFF) << 8)
| (prim_field_data[off] & 0xFF));
}
public float get (String name, float defvalue)
throws IOException, IllegalArgumentException
{
ObjectStreamField field = getField (name, Float.TYPE);
if (field == null)
return defvalue;
int off = field.getOffset ();
return Float.intBitsToFloat (((prim_field_data[off++] & 0xFF) << 24)
| ((prim_field_data[off++] & 0xFF) << 16)
| ((prim_field_data[off++] & 0xFF) << 8)
| (prim_field_data[off] & 0xFF));
}
public double get (String name, double defvalue)
throws IOException, IllegalArgumentException
{
ObjectStreamField field = getField (name, Double.TYPE);
if (field == null)
return defvalue;
int off = field.getOffset ();
return Double.longBitsToDouble
( (long) (((prim_field_data[off++] & 0xFF) << 56)
| ((prim_field_data[off++] & 0xFF) << 48)
| ((prim_field_data[off++] & 0xFF) << 40)
| ((prim_field_data[off++] & 0xFF) << 32)
| ((prim_field_data[off++] & 0xFF) << 24)
| ((prim_field_data[off++] & 0xFF) << 16)
| ((prim_field_data[off++] & 0xFF) << 8)
| (prim_field_data[off] & 0xFF)));
}
public Object get (String name, Object defvalue)
throws IOException, IllegalArgumentException
{
ObjectStreamField field =
getField (name, defvalue == null ? null : defvalue.getClass ());
if (field == null)
return defvalue;
return objs[field.getOffset ()];
}
private ObjectStreamField getField (String name, Class type)
throws IllegalArgumentException
{
ObjectStreamField field = clazz.getField (name);
if (field == null)
return null;
Class field_type = field.getType ();
if (type == field_type ||
(type == null && ! field_type.isPrimitive ()))
return field;
throw new IllegalArgumentException ("Field requested is of type "
+ field_type.getName ()
+ ", but requested type was "
+ (type == null ?
"Object" : type.getName ()));
}
};
}
protected ObjectInputStream ()
throws IOException, SecurityException
{
SecurityManager sec_man = System.getSecurityManager ();
if (sec_man != null)
sec_man.checkPermission (SUBCLASS_IMPLEMENTATION_PERMISSION);
this.useSubclassMethod = true;
}
protected Object readObjectOverride ()
throws ClassNotFoundException, IOException, OptionalDataException
{
throw new IOException ("Subclass of ObjectInputStream must implement readObjectOverride");
}
private int assignNewHandle (Object obj)
{
this.objectLookupTable.put (new Integer (this.nextOID),
new ObjectIdentityWrapper (obj));
return this.nextOID++;
}
private Object processResolution (Object obj, int handle)
throws IOException
{
if (obj instanceof Serializable)
{
Method m = null;
try
{
Class classArgs[] = {};
m = obj.getClass ().getDeclaredMethod ("readResolve", classArgs);
obj = m.invoke (obj, new Object[] {});
}
catch (NoSuchMethodException ignore)
{
}
catch (IllegalAccessException ignore)
{
}
catch (InvocationTargetException ignore)
{
}
}
if (this.resolveEnabled)
obj = resolveObject (obj);
this.objectLookupTable.put (new Integer (handle),
new ObjectIdentityWrapper (obj));
return obj;
}
private void clearHandles ()
{
this.objectLookupTable.clear ();
this.nextOID = baseWireHandle;
}
private void readNextBlock () throws IOException
{
readNextBlock (this.realInputStream.readByte ());
}
private void readNextBlock (byte marker) throws IOException
{
if (marker == TC_BLOCKDATA)
{
dumpElement ("BLOCK DATA SIZE=");
this.blockDataBytes = this.realInputStream.readUnsignedByte ();
dumpElementln (Integer.toString(this.blockDataBytes));
}
else if (marker == TC_BLOCKDATALONG)
{
dumpElement ("BLOCK DATA LONG SIZE=");
this.blockDataBytes = this.realInputStream.readInt ();
dumpElementln (Integer.toString(this.blockDataBytes));
}
else
{
throw new EOFException ("Attempt to read primitive data, but no data block is active.");
}
if (this.blockData.length < this.blockDataBytes)
this.blockData = new byte[this.blockDataBytes];
this.realInputStream.readFully (this.blockData, 0, this.blockDataBytes);
this.blockDataPosition = 0;
}
private void readArrayElements (Object array, Class clazz)
throws ClassNotFoundException, IOException
{
if (clazz.isPrimitive ())
{
if (clazz == Boolean.TYPE)
{
boolean[] cast_array = (boolean[])array;
for (int i=0; i < cast_array.length; i++)
cast_array[i] = this.realInputStream.readBoolean ();
return;
}
if (clazz == Byte.TYPE)
{
byte[] cast_array = (byte[])array;
for (int i=0; i < cast_array.length; i++)
cast_array[i] = this.realInputStream.readByte ();
return;
}
if (clazz == Character.TYPE)
{
char[] cast_array = (char[])array;
for (int i=0; i < cast_array.length; i++)
cast_array[i] = this.realInputStream.readChar ();
return;
}
if (clazz == Double.TYPE)
{
double[] cast_array = (double[])array;
for (int i=0; i < cast_array.length; i++)
cast_array[i] = this.realInputStream.readDouble ();
return;
}
if (clazz == Float.TYPE)
{
float[] cast_array = (float[])array;
for (int i=0; i < cast_array.length; i++)
cast_array[i] = this.realInputStream.readFloat ();
return;
}
if (clazz == Integer.TYPE)
{
int[] cast_array = (int[])array;
for (int i=0; i < cast_array.length; i++)
cast_array[i] = this.realInputStream.readInt ();
return;
}
if (clazz == Long.TYPE)
{
long[] cast_array = (long[])array;
for (int i=0; i < cast_array.length; i++)
cast_array[i] = this.realInputStream.readLong ();
return;
}
if (clazz == Short.TYPE)
{
short[] cast_array = (short[])array;
for (int i=0; i < cast_array.length; i++)
cast_array[i] = this.realInputStream.readShort ();
return;
}
}
else
{
Object[] cast_array = (Object[])array;
for (int i=0; i < cast_array.length; i++)
cast_array[i] = readObject ();
}
}
private void readFields (Object obj, ObjectStreamField[] stream_fields,
boolean call_read_method,
ObjectStreamClass stream_osc)
throws ClassNotFoundException, IOException
{
if (call_read_method)
{
fieldsAlreadyRead = false;
boolean oldmode = setBlockDataMode (true);
callReadMethod (obj, stream_osc.forClass ());
setBlockDataMode (oldmode);
return;
}
ObjectStreamField[] real_fields =
ObjectStreamClass.lookup (stream_osc.forClass ()).fields;
boolean default_initialize, set_value;
String field_name = null;
Class type = null;
ObjectStreamField stream_field = null;
ObjectStreamField real_field = null;
int stream_idx = 0;
int real_idx = 0;
while (stream_idx < stream_fields.length
&& real_idx < real_fields.length)
{
default_initialize = false;
set_value = true;
if (stream_idx == stream_fields.length)
default_initialize = true;
else
{
stream_field = stream_fields[stream_idx];
type = stream_field.getType ();
}
if (real_idx == real_fields.length)
set_value = false;
else
{
real_field = real_fields[real_idx];
type = real_field.getType ();
field_name = real_field.getName ();
}
if (set_value && !default_initialize)
{
int comp_val =
real_field.compareTo (stream_field);
if (comp_val < 0)
{
default_initialize = true;
real_idx++;
}
else if (comp_val > 0)
{
set_value = false;
stream_idx++;
}
else
{
real_idx++;
stream_idx++;
}
}
try
{
if (type == Boolean.TYPE)
{
boolean value =
default_initialize ? false : this.realInputStream.readBoolean ();
if (!default_initialize && set_value)
dumpElementln (" " + field_name + ": " + value);
if (set_value)
setBooleanField (obj, field_name, value);
}
else if (type == Byte.TYPE)
{
byte value =
default_initialize ? 0 : this.realInputStream.readByte ();
if (!default_initialize && set_value)
dumpElementln (" " + field_name + ": " + value);
if (set_value)
setByteField (obj, field_name, value);
}
else if (type == Character.TYPE)
{
char value =
default_initialize ? (char)0 : this.realInputStream.readChar ();
if (!default_initialize && set_value)
dumpElementln (" " + field_name + ": " + value);
if (set_value)
setCharField (obj, field_name, value);
}
else if (type == Double.TYPE)
{
double value =
default_initialize ? 0 : this.realInputStream.readDouble ();
if (!default_initialize && set_value)
dumpElementln (" " + field_name + ": " + value);
if (set_value)
setDoubleField (obj, field_name, value);
}
else if (type == Float.TYPE)
{
float value =
default_initialize ? 0 : this.realInputStream.readFloat ();
if (!default_initialize && set_value)
dumpElementln (" " + field_name + ": " + value);
if (set_value)
setFloatField (obj, field_name, value);
}
else if (type == Integer.TYPE)
{
int value =
default_initialize ? 0 : this.realInputStream.readInt ();
if (!default_initialize && set_value)
dumpElementln (" " + field_name + ": " + value);
if (set_value)
setIntField (obj, field_name, value);
}
else if (type == Long.TYPE)
{
long value =
default_initialize ? 0 : this.realInputStream.readLong ();
if (!default_initialize && set_value)
dumpElementln (" " + field_name + ": " + value);
if (set_value)
setLongField (obj, field_name, value);
}
else if (type == Short.TYPE)
{
short value =
default_initialize ? (short)0 : this.realInputStream.readShort ();
if (!default_initialize && set_value)
dumpElementln (" " + field_name + ": " + value);
if (set_value)
setShortField (obj, field_name, value);
}
else
{
Object value =
default_initialize ? null : readObject ();
if (set_value)
setObjectField (obj, field_name,
real_field.getTypeString (), value);
}
}
catch (NoSuchFieldError e)
{
dumpElementln("XXXX " + field_name + " does not exist.");
}
}
}
private boolean setBlockDataMode (boolean on)
{
boolean oldmode = this.readDataFromBlock;
this.readDataFromBlock = on;
if (on)
this.dataInputStream = this.blockDataInput;
else
this.dataInputStream = this.realInputStream;
return oldmode;
}
private Object newObject (Class real_class, Class constructor_class)
{
try
{
Object obj = allocateObject (real_class);
callConstructor (constructor_class, obj);
return obj;
}
catch (InstantiationException e)
{
return null;
}
}
private void invokeValidators () throws InvalidObjectException
{
Object[] validators = new Object[this.validators.size ()];
this.validators.copyInto (validators);
Arrays.sort (validators);
try
{
for (int i=0; i < validators.length; i++)
((ObjectInputValidation)validators[i]).validateObject ();
}
finally
{
this.validators.removeAllElements ();
}
}
private static ClassLoader currentClassLoader (SecurityManager sm)
{
return ClassLoader.getSystemClassLoader ();
}
private static Field getField (Class klass, String name)
throws java.lang.NoSuchFieldException
{
return klass.getDeclaredField(name);
}
private static Method getMethod (Class klass, String name, Class args[])
throws java.lang.NoSuchMethodException
{
return klass.getDeclaredMethod(name, args);
}
private void callReadMethod (Object obj, Class klass) throws IOException
{
try
{
Class classArgs[] = {ObjectInputStream.class};
Method m = getMethod (klass, "readObject", classArgs);
if (m == null)
return;
Object args[] = {this};
m.invoke (obj, args);
}
catch (InvocationTargetException x)
{
Throwable exception = x.getTargetException();
if (exception instanceof RuntimeException)
throw (RuntimeException) exception;
if (exception instanceof IOException)
throw (IOException) exception;
throw new IOException ("Exception thrown from readObject() on " +
klass + ": " + exception.getClass().getName());
}
catch (Exception x)
{
throw new IOException ("Failure invoking readObject() on " +
klass + ": " + x.getClass().getName());
}
}
private native Object allocateObject (Class clazz)
throws InstantiationException;
private native void callConstructor (Class clazz, Object obj);
private void setBooleanField (Object obj, String field_name,
boolean val)
{
try
{
Class klass = obj.getClass ();
Field f = getField (klass, field_name);
f.setAccessible(true);
f.setBoolean (obj, val);
}
catch (Exception _)
{
}
}
private void setByteField (Object obj, String field_name,
byte val)
{
try
{
Class klass = obj.getClass ();
Field f = getField (klass, field_name);
f.setAccessible(true);
f.setByte (obj, val);
}
catch (Exception _)
{
}
}
private void setCharField (Object obj, String field_name,
char val)
{
try
{
Class klass = obj.getClass ();
Field f = getField (klass, field_name);
f.setAccessible(true);
f.setChar (obj, val);
}
catch (Exception _)
{
}
}
private void setDoubleField (Object obj, String field_name,
double val)
{
try
{
Class klass = obj.getClass ();
Field f = getField (klass, field_name);
f.setAccessible(true);
f.setDouble (obj, val);
}
catch (Exception _)
{
}
}
private void setFloatField (Object obj, String field_name,
float val)
{
try
{
Class klass = obj.getClass ();
Field f = getField (klass, field_name);
f.setAccessible(true);
f.setFloat (obj, val);
}
catch (Exception _)
{
}
}
private void setIntField (Object obj, String field_name,
int val)
{
try
{
Class klass = obj.getClass ();
Field f = getField (klass, field_name);
f.setAccessible(true);
f.setInt (obj, val);
}
catch (Exception _)
{
}
}
private void setLongField (Object obj, String field_name,
long val)
{
try
{
Class klass = obj.getClass ();
Field f = getField (klass, field_name);
f.setAccessible(true);
f.setLong (obj, val);
}
catch (Exception _)
{
}
}
private void setShortField (Object obj, String field_name,
short val)
{
try
{
Class klass = obj.getClass ();
Field f = getField (klass, field_name);
f.setAccessible(true);
f.setShort (obj, val);
}
catch (Exception _)
{
}
}
private void setObjectField (Object obj, String field_name, String type_code,
Object val)
{
try
{
Class klass = obj.getClass ();
Field f = getField (klass, field_name);
f.setAccessible(true);
f.set (obj, val);
}
catch (Exception _)
{
}
}
private static final int BUFFER_SIZE = 1024;
private static final Class[] readObjectParams = { ObjectInputStream.class };
private DataInputStream realInputStream;
private DataInputStream dataInputStream;
private DataInputStream blockDataInput;
private int blockDataPosition;
private int blockDataBytes;
private byte[] blockData;
private boolean useSubclassMethod;
private int nextOID;
private boolean resolveEnabled;
private Hashtable objectLookupTable;
private Object currentObject;
private ObjectStreamClass currentObjectStreamClass;
private boolean readDataFromBlock;
private boolean isDeserializing;
private boolean fieldsAlreadyRead;
private Vector validators;
private static boolean dump;
private void dumpElement (String msg)
{
if (Configuration.DEBUG && dump)
System.out.print(msg);
}
private void dumpElementln (String msg)
{
if (Configuration.DEBUG && dump)
System.out.println(msg);
}
static
{
if (Configuration.INIT_LOAD_LIBRARY)
{
System.loadLibrary ("javaio");
}
}
}
class ValidatorAndPriority implements Comparable
{
int priority;
ObjectInputValidation validator;
ValidatorAndPriority (ObjectInputValidation validator, int priority)
{
this.priority = priority;
this.validator = validator;
}
public int compareTo (Object o)
{
ValidatorAndPriority vap = (ValidatorAndPriority)o;
return this.priority - vap.priority;
}
}