mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-18 00:04:14 +08:00
Makefile.am (nat_source_files): Remove java/io/natObjectOutputStream.cc.
* Makefile.am (nat_source_files): Remove java/io/natObjectOutputStream.cc. * Makefile.in: Regenerated. * mauve-libgcj: Don't exclude java.io.ObjectInputOutput tests. * java/io/ObjectStreamField.java (typename): New field. (ObjectStreamField(String, Class)): Initialize new field. (ObjectStreamField(String, String)): New Constructor. (getTypeCode): Use new field. (getTypeString): Use new field. * java/io/ObjectOutputStream.java (writeObject): Rethrow fatal ObjectStreamExceptions. Remember and reset old BlockDataMode. Handle reading of Proxy classes. Never drain(), just write TC_ENDBLOCKDATA. Rethrow ObjectStreamExceptions. (drain): Check writeDataAsBlocks before calling writeBlockDataHeader. (flush): Call flush(), not just drain(). (writeBoolean): Always use blockDataOutput. (writeByte): Likewise. (writeShort): Likewise. (writeChar): Likewise. (writeInt): Likewise. (writeLong): Likewise. (writeFloat): Likewise. (writeDouble): Likewise. (writeBytes): Likewise. (putfield (put(String,Object))): Throw IllegalArgumentException if field cannot be found. (putfield (write(ObjectOutput))): Remember old BlockDataMode. (writeArraySizeAndElements): Write byte[] in one go. (writeFields): Write TC_ENDBLOCKDATA when call_write_method, otherwise set BlockDataMode to false. (annotateProxyClass): New method. (defaultProtocolVersion): Now defaults to PROTOCOL_VERSION_2 (getField): No longer native. (getMethod): Likewise. (setBlockDataMode): Always drain() on switch, return old mode. (static): New static code block. * java/io/natObjectOutputStream.cc: Removed. * java/io/ObjectInputStream.java (getField): No longer native. (getMethod): Likewise. (readObject): Remember and reset old BlockDataMode. Track whether object is consumed. Handle TC_ENDBLOCKDATA, TC_PROXYCLASSDESC and TC_LONGSTRING. (defaultReadObject): Set BlockDataMode to false during readFields. (resolveClass): Create new SecurityManager if necessary. Use Class.forName() if null ClassLoader found. (read(byte[],int,int): Copy remaining bytes to data before calling readNextBlock(). (readFields): Set and reset BlockDataMode on call_read_method. Catch NoSuchFieldErrors. (setBlockDataMode): Return old mode. (static): New static code block. * java/io/natObjectInputStream.cc (getField): Removed. (getMethod): Likewise. From-SVN: r63556
This commit is contained in:
parent
28727f1fb3
commit
4480b3dcf6
@ -1,3 +1,59 @@
|
||||
2003-02-28 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
* Makefile.am (nat_source_files): Remove
|
||||
java/io/natObjectOutputStream.cc.
|
||||
* Makefile.in: Regenerated.
|
||||
* mauve-libgcj: Don't exclude java.io.ObjectInputOutput tests.
|
||||
* java/io/ObjectStreamField.java (typename): New field.
|
||||
(ObjectStreamField(String, Class)): Initialize new field.
|
||||
(ObjectStreamField(String, String)): New Constructor.
|
||||
(getTypeCode): Use new field.
|
||||
(getTypeString): Use new field.
|
||||
* java/io/ObjectOutputStream.java (writeObject): Rethrow fatal
|
||||
ObjectStreamExceptions. Remember and reset old BlockDataMode.
|
||||
Handle reading of Proxy classes. Never drain(), just write
|
||||
TC_ENDBLOCKDATA. Rethrow ObjectStreamExceptions.
|
||||
(drain): Check writeDataAsBlocks before calling writeBlockDataHeader.
|
||||
(flush): Call flush(), not just drain().
|
||||
(writeBoolean): Always use blockDataOutput.
|
||||
(writeByte): Likewise.
|
||||
(writeShort): Likewise.
|
||||
(writeChar): Likewise.
|
||||
(writeInt): Likewise.
|
||||
(writeLong): Likewise.
|
||||
(writeFloat): Likewise.
|
||||
(writeDouble): Likewise.
|
||||
(writeBytes): Likewise.
|
||||
(putfield (put(String,Object))): Throw IllegalArgumentException if
|
||||
field cannot be found.
|
||||
(putfield (write(ObjectOutput))): Remember old BlockDataMode.
|
||||
(writeArraySizeAndElements): Write byte[] in one go.
|
||||
(writeFields): Write TC_ENDBLOCKDATA when call_write_method, otherwise
|
||||
set BlockDataMode to false.
|
||||
(annotateProxyClass): New method.
|
||||
(defaultProtocolVersion): Now defaults to PROTOCOL_VERSION_2
|
||||
(getField): No longer native.
|
||||
(getMethod): Likewise.
|
||||
(setBlockDataMode): Always drain() on switch, return old mode.
|
||||
(static): New static code block.
|
||||
* java/io/natObjectOutputStream.cc: Removed.
|
||||
* java/io/ObjectInputStream.java (getField): No longer native.
|
||||
(getMethod): Likewise.
|
||||
(readObject): Remember and reset old BlockDataMode. Track whether
|
||||
object is consumed. Handle TC_ENDBLOCKDATA, TC_PROXYCLASSDESC and
|
||||
TC_LONGSTRING.
|
||||
(defaultReadObject): Set BlockDataMode to false during readFields.
|
||||
(resolveClass): Create new SecurityManager if necessary.
|
||||
Use Class.forName() if null ClassLoader found.
|
||||
(read(byte[],int,int): Copy remaining bytes to data before calling
|
||||
readNextBlock().
|
||||
(readFields): Set and reset BlockDataMode on call_read_method.
|
||||
Catch NoSuchFieldErrors.
|
||||
(setBlockDataMode): Return old mode.
|
||||
(static): New static code block.
|
||||
* java/io/natObjectInputStream.cc (getField): Removed.
|
||||
(getMethod): Likewise.
|
||||
|
||||
2003-02-27 Michael Koch <konqueror@gmx.de>
|
||||
|
||||
* java/beans/Beans.java,
|
||||
|
@ -2496,7 +2496,6 @@ gnu/java/nio/natSocketChannelImpl.cc \
|
||||
java/io/natFile.cc \
|
||||
java/io/natFileDescriptor.cc \
|
||||
java/io/natObjectInputStream.cc \
|
||||
java/io/natObjectOutputStream.cc \
|
||||
java/io/natVMObjectStreamClass.cc \
|
||||
java/lang/natCharacter.cc \
|
||||
java/lang/natClass.cc \
|
||||
|
@ -2257,7 +2257,6 @@ gnu/java/nio/natSocketChannelImpl.cc \
|
||||
java/io/natFile.cc \
|
||||
java/io/natFileDescriptor.cc \
|
||||
java/io/natObjectInputStream.cc \
|
||||
java/io/natObjectOutputStream.cc \
|
||||
java/io/natVMObjectStreamClass.cc \
|
||||
java/lang/natCharacter.cc \
|
||||
java/lang/natClass.cc \
|
||||
@ -2432,11 +2431,11 @@ gnu/java/nio/natIntBufferImpl.lo gnu/java/nio/natLongBufferImpl.lo \
|
||||
gnu/java/nio/natSelectorImpl.lo gnu/java/nio/natShortBufferImpl.lo \
|
||||
gnu/java/nio/natSocketChannelImpl.lo java/io/natFile.lo \
|
||||
java/io/natFileDescriptor.lo java/io/natObjectInputStream.lo \
|
||||
java/io/natObjectOutputStream.lo java/io/natVMObjectStreamClass.lo \
|
||||
java/lang/natCharacter.lo java/lang/natClass.lo \
|
||||
java/lang/natClassLoader.lo java/lang/natConcreteProcess.lo \
|
||||
java/lang/natDouble.lo java/lang/natFloat.lo java/lang/natMath.lo \
|
||||
java/lang/natObject.lo java/lang/natRuntime.lo java/lang/natString.lo \
|
||||
java/io/natVMObjectStreamClass.lo java/lang/natCharacter.lo \
|
||||
java/lang/natClass.lo java/lang/natClassLoader.lo \
|
||||
java/lang/natConcreteProcess.lo java/lang/natDouble.lo \
|
||||
java/lang/natFloat.lo java/lang/natMath.lo java/lang/natObject.lo \
|
||||
java/lang/natRuntime.lo java/lang/natString.lo \
|
||||
java/lang/natStringBuffer.lo java/lang/natSystem.lo \
|
||||
java/lang/natThread.lo java/lang/natVMSecurityManager.lo \
|
||||
java/lang/ref/natReference.lo java/lang/reflect/natArray.lo \
|
||||
@ -2599,7 +2598,7 @@ libgcj-test.spec.in libgcj.spec.in
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = gtar
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
DIST_SUBDIRS = @DIRLTDL@ testsuite gcj include @DIRLTDL@ gcj include
|
||||
DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||
@ -3270,7 +3269,6 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||
.deps/java/io/WriteAbortedException.P .deps/java/io/Writer.P \
|
||||
.deps/java/io/natFile.P .deps/java/io/natFileDescriptor.P \
|
||||
.deps/java/io/natObjectInputStream.P \
|
||||
.deps/java/io/natObjectOutputStream.P \
|
||||
.deps/java/io/natVMObjectStreamClass.P \
|
||||
.deps/java/lang/AbstractMethodError.P \
|
||||
.deps/java/lang/ArithmeticException.P \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ObjectInputStream.java -- Class used to read serialized objects
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -38,8 +38,6 @@ exception statement from your version. */
|
||||
|
||||
package java.io;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Proxy;
|
||||
@ -53,7 +51,7 @@ 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
|
||||
@ -130,286 +128,343 @@ public class ObjectInputStream extends InputStream
|
||||
Object ret_val;
|
||||
was_deserializing = this.isDeserializing;
|
||||
|
||||
if (! was_deserializing)
|
||||
setBlockDataMode (false);
|
||||
boolean is_consumed = false;
|
||||
boolean old_mode = setBlockDataMode (false);
|
||||
|
||||
this.isDeserializing = true;
|
||||
|
||||
byte marker = this.realInputStream.readByte ();
|
||||
dumpElement ("MARKER: 0x" + Integer.toHexString(marker) + " ");
|
||||
|
||||
switch (marker)
|
||||
{
|
||||
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:
|
||||
try
|
||||
{
|
||||
dumpElement ("REFERENCE ");
|
||||
Integer oid = new Integer (this.realInputStream.readInt ());
|
||||
dumpElementln (Integer.toHexString(oid.intValue()));
|
||||
ret_val = ((ObjectIdentityWrapper)
|
||||
this.objectLookupTable.get (oid)).object;
|
||||
break;
|
||||
}
|
||||
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_CLASS:
|
||||
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);
|
||||
|
||||
// There're many cases you can't get java.lang.Class from
|
||||
// typename if your context class loader can't load it,
|
||||
// then use typename to construct the field
|
||||
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;
|
||||
} // end if (Externalizable.class.isAssignableFrom (clazz))
|
||||
|
||||
// find the first non-serializable, non-abstract
|
||||
// class in clazz's inheritance hierarchy
|
||||
Class first_nonserial = clazz.getSuperclass ();
|
||||
while (Serializable.class.isAssignableFrom (first_nonserial)
|
||||
|| Modifier.isAbstract (first_nonserial.getModifiers ()))
|
||||
first_nonserial = first_nonserial.getSuperclass ();
|
||||
|
||||
// DEBUGln ("Using " + first_nonserial
|
||||
// + " as starting point for constructing " + clazz);
|
||||
|
||||
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);
|
||||
|
||||
// DEBUGln ("Got class hierarchy of depth " + hierarchy.length);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// XXX: should initialize fields in classes in the hierarchy
|
||||
// that aren't in the stream
|
||||
// should skip over classes in the stream that aren't in the
|
||||
// real classes hierarchy
|
||||
readFields (obj, this.currentObjectStreamClass.fields,
|
||||
has_read, this.currentObjectStreamClass);
|
||||
|
||||
if (has_read)
|
||||
{
|
||||
dumpElement ("ENDBLOCKDATA? ");
|
||||
try
|
||||
{
|
||||
// FIXME: XXX: This try block is to catch EOF which is
|
||||
// thrown for some objects. That indicates a bug in the logic.
|
||||
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
|
||||
{
|
||||
dumpElementln ("CLASS");
|
||||
ObjectStreamClass osc = (ObjectStreamClass)readObject ();
|
||||
Class clazz = osc.forClass ();
|
||||
assignNewHandle (clazz);
|
||||
ret_val = clazz;
|
||||
break;
|
||||
setBlockDataMode (old_mode);
|
||||
|
||||
this.isDeserializing = was_deserializing;
|
||||
|
||||
if (! was_deserializing)
|
||||
{
|
||||
if (validators.size () > 0)
|
||||
invokeValidators ();
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
TypeSignature.getClassForEncoding
|
||||
(class_name));
|
||||
}
|
||||
|
||||
Class cl = resolveClass (osc);
|
||||
osc.setClass (cl);
|
||||
setBlockDataMode (false);
|
||||
|
||||
if (this.realInputStream.readByte () != TC_ENDBLOCKDATA)
|
||||
throw new IOException ("Data annotated to class was not consumed.");
|
||||
dumpElementln ("ENDBLOCKDATA ");
|
||||
|
||||
osc.setSuperclass ((ObjectStreamClass)readObject ());
|
||||
ret_val = osc;
|
||||
break;
|
||||
}
|
||||
|
||||
case TC_STRING:
|
||||
{
|
||||
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);
|
||||
|
||||
if (read_from_blocks)
|
||||
setBlockDataMode (true);
|
||||
|
||||
obj.readExternal (this);
|
||||
|
||||
if (read_from_blocks)
|
||||
setBlockDataMode (false);
|
||||
|
||||
ret_val = processResolution (obj, handle);
|
||||
break;
|
||||
} // end if (Externalizable.class.isAssignableFrom (clazz))
|
||||
|
||||
// find the first non-serializable, non-abstract
|
||||
// class in clazz's inheritance hierarchy
|
||||
Class first_nonserial = clazz.getSuperclass ();
|
||||
while (Serializable.class.isAssignableFrom (first_nonserial)
|
||||
|| Modifier.isAbstract (first_nonserial.getModifiers ()))
|
||||
first_nonserial = first_nonserial.getSuperclass ();
|
||||
|
||||
// DEBUGln ("Using " + first_nonserial
|
||||
// + " as starting point for constructing " + clazz);
|
||||
|
||||
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);
|
||||
|
||||
// DEBUGln ("Got class hierarchy of depth " + hierarchy.length);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// XXX: should initialize fields in classes in the hierarchy
|
||||
// that aren't in the stream
|
||||
// should skip over classes in the stream that aren't in the
|
||||
// real classes hierarchy
|
||||
readFields (obj, this.currentObjectStreamClass.fields,
|
||||
has_read, this.currentObjectStreamClass);
|
||||
|
||||
if (has_read)
|
||||
{
|
||||
dumpElement ("ENDBLOCKDATA? ");
|
||||
try
|
||||
{
|
||||
// FIXME: XXX: This try block is to catch EOF which is
|
||||
// thrown for some objects. That indicates a bug in the logic.
|
||||
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");
|
||||
}
|
||||
|
||||
this.isDeserializing = was_deserializing;
|
||||
|
||||
if (! was_deserializing)
|
||||
{
|
||||
setBlockDataMode (true);
|
||||
|
||||
if (validators.size () > 0)
|
||||
invokeValidators ();
|
||||
}
|
||||
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Reads the current objects non-transient, non-static fields from
|
||||
@ -439,9 +494,11 @@ public class ObjectInputStream extends InputStream
|
||||
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;
|
||||
}
|
||||
@ -500,13 +557,18 @@ public class ObjectInputStream extends InputStream
|
||||
throws ClassNotFoundException, IOException
|
||||
{
|
||||
SecurityManager sm = System.getSecurityManager ();
|
||||
if (sm == null)
|
||||
sm = new SecurityManager () {};
|
||||
|
||||
// FIXME: currentClassLoader doesn't yet do anything useful. We need
|
||||
// to call forName() with the classloader of the class which called
|
||||
// readObject(). See SecurityManager.getClassContext().
|
||||
ClassLoader cl = currentClassLoader (sm);
|
||||
|
||||
return Class.forName (osc.getName (), true, cl);
|
||||
if (cl == null)
|
||||
return Class.forName (osc.getName ());
|
||||
else
|
||||
return cl.loadClass (osc.getName ());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -617,7 +679,17 @@ public class ObjectInputStream extends InputStream
|
||||
if (this.readDataFromBlock)
|
||||
{
|
||||
if (this.blockDataPosition + length > this.blockDataBytes)
|
||||
readNextBlock ();
|
||||
{
|
||||
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);
|
||||
@ -785,11 +857,11 @@ public class ObjectInputStream extends InputStream
|
||||
// Apparently Block data is not used with GetField as per
|
||||
// empirical evidence against JDK 1.2. Also see Mauve test
|
||||
// java.io.ObjectInputOutput.Test.GetPutField.
|
||||
setBlockDataMode (false);
|
||||
boolean oldmode = setBlockDataMode (false);
|
||||
readFully (prim_field_data);
|
||||
for (int i = 0; i < objs.length; ++ i)
|
||||
objs[i] = readObject ();
|
||||
setBlockDataMode (true);
|
||||
setBlockDataMode (oldmode);
|
||||
|
||||
return new GetField ()
|
||||
{
|
||||
@ -990,7 +1062,7 @@ public class ObjectInputStream extends InputStream
|
||||
de serialization mechanism provided by
|
||||
<code>ObjectInputStream</code>. To make this method be used for
|
||||
writing objects, subclasses must invoke the 0-argument
|
||||
constructor on this class from there constructor.
|
||||
constructor on this class from their constructor.
|
||||
|
||||
@see ObjectInputStream ()
|
||||
*/
|
||||
@ -1175,9 +1247,9 @@ public class ObjectInputStream extends InputStream
|
||||
{
|
||||
// DEBUGln (" call_read_method is true");
|
||||
fieldsAlreadyRead = false;
|
||||
setBlockDataMode (true);
|
||||
boolean oldmode = setBlockDataMode (true);
|
||||
callReadMethod (obj, stream_osc.forClass ());
|
||||
setBlockDataMode (false);
|
||||
setBlockDataMode (oldmode);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1237,101 +1309,109 @@ public class ObjectInputStream extends InputStream
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Toggles writing primitive data to block-data buffer.
|
||||
private void setBlockDataMode (boolean on)
|
||||
private boolean setBlockDataMode (boolean on)
|
||||
{
|
||||
// DEBUGln ("Setting block data mode to " + on);
|
||||
|
||||
boolean oldmode = this.readDataFromBlock;
|
||||
this.readDataFromBlock = on;
|
||||
|
||||
if (on)
|
||||
this.dataInputStream = this.blockDataInput;
|
||||
else
|
||||
this.dataInputStream = this.realInputStream;
|
||||
return oldmode;
|
||||
}
|
||||
|
||||
|
||||
@ -1380,12 +1460,18 @@ public class ObjectInputStream extends InputStream
|
||||
return ClassLoader.getSystemClassLoader ();
|
||||
}
|
||||
|
||||
private static native Field getField (Class klass, String name)
|
||||
throws java.lang.NoSuchFieldException;
|
||||
|
||||
private static native Method getMethod (Class klass, String name, Class args[])
|
||||
throws java.lang.NoSuchMethodException;
|
||||
|
||||
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
|
||||
@ -1593,6 +1679,14 @@ public class ObjectInputStream extends InputStream
|
||||
if (Configuration.DEBUG && dump)
|
||||
System.out.println(msg);
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary ("javaio");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ObjectOutputStream.java -- Class used to write serialized objects
|
||||
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -46,6 +46,7 @@ import java.util.Hashtable;
|
||||
|
||||
import gnu.java.io.ObjectIdentityWrapper;
|
||||
import gnu.java.lang.reflect.TypeSignature;
|
||||
import gnu.classpath.Configuration;
|
||||
|
||||
/**
|
||||
An <code>ObjectOutputStream</code> can be used to write objects
|
||||
@ -167,229 +168,242 @@ public class ObjectOutputStream extends OutputStream
|
||||
public final void writeObject (Object obj) throws IOException
|
||||
{
|
||||
if (useSubclassMethod)
|
||||
{
|
||||
writeObjectOverride (obj);
|
||||
return;
|
||||
}
|
||||
{
|
||||
writeObjectOverride (obj);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean was_serializing = isSerializing;
|
||||
|
||||
if (! was_serializing)
|
||||
setBlockDataMode (false);
|
||||
|
||||
boolean old_mode = setBlockDataMode (false);
|
||||
try
|
||||
{
|
||||
isSerializing = true;
|
||||
boolean replaceDone = false;
|
||||
|
||||
drain ();
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
realOutput.writeByte (TC_NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
Integer handle = findHandle (obj);
|
||||
if (handle != null)
|
||||
{
|
||||
realOutput.writeByte (TC_REFERENCE);
|
||||
realOutput.writeInt (handle.intValue ());
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj instanceof Class)
|
||||
{
|
||||
realOutput.writeByte (TC_CLASS);
|
||||
writeObject (ObjectStreamClass.lookup ((Class)obj));
|
||||
assignNewHandle (obj);
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj instanceof ObjectStreamClass)
|
||||
{
|
||||
ObjectStreamClass osc = (ObjectStreamClass)obj;
|
||||
realOutput.writeByte (TC_CLASSDESC);
|
||||
realOutput.writeUTF (osc.getName ());
|
||||
realOutput.writeLong (osc.getSerialVersionUID ());
|
||||
assignNewHandle (obj);
|
||||
|
||||
int flags = osc.getFlags ();
|
||||
|
||||
if (protocolVersion == PROTOCOL_VERSION_2
|
||||
&& osc.isExternalizable ())
|
||||
flags |= SC_BLOCK_DATA;
|
||||
|
||||
realOutput.writeByte (flags);
|
||||
|
||||
ObjectStreamField[] fields = osc.fields;
|
||||
realOutput.writeShort (fields.length);
|
||||
|
||||
ObjectStreamField field;
|
||||
for (int i=0; i < fields.length; i++)
|
||||
{
|
||||
field = fields[i];
|
||||
realOutput.writeByte (field.getTypeCode ());
|
||||
realOutput.writeUTF (field.getName ());
|
||||
|
||||
if (! field.isPrimitive ())
|
||||
writeObject (field.getTypeString ());
|
||||
}
|
||||
|
||||
setBlockDataMode (true);
|
||||
annotateClass (osc.forClass ());
|
||||
setBlockDataMode (false);
|
||||
realOutput.writeByte (TC_ENDBLOCKDATA);
|
||||
|
||||
if (osc.isSerializable ())
|
||||
writeObject (osc.getSuper ());
|
||||
else
|
||||
writeObject (null);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
isSerializing = true;
|
||||
boolean replaceDone = false;
|
||||
Object replacedObject = null;
|
||||
|
||||
if ((replacementEnabled || obj instanceof Serializable)
|
||||
&& ! replaceDone)
|
||||
{
|
||||
replacedObject = obj;
|
||||
|
||||
if (obj instanceof Serializable)
|
||||
{
|
||||
Method m = null;
|
||||
try
|
||||
{
|
||||
Class classArgs[] = {};
|
||||
m = obj.getClass ().getDeclaredMethod ("writeReplace",
|
||||
classArgs);
|
||||
// m can't be null by definition since an exception would
|
||||
// have been thrown so a check for null is not needed.
|
||||
obj = m.invoke (obj, new Object[] {});
|
||||
}
|
||||
catch (NoSuchMethodException ignore)
|
||||
{
|
||||
}
|
||||
catch (IllegalAccessException ignore)
|
||||
{
|
||||
}
|
||||
catch (InvocationTargetException ignore)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (replacementEnabled)
|
||||
obj = replaceObject (obj);
|
||||
|
||||
replaceDone = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (obj instanceof String)
|
||||
{
|
||||
realOutput.writeByte (TC_STRING);
|
||||
assignNewHandle (obj);
|
||||
realOutput.writeUTF ((String)obj);
|
||||
break;
|
||||
}
|
||||
|
||||
Class clazz = obj.getClass ();
|
||||
ObjectStreamClass osc = ObjectStreamClass.lookup (clazz);
|
||||
if (osc == null)
|
||||
throw new NotSerializableException (clazz.getName ());
|
||||
|
||||
if (clazz.isArray ())
|
||||
{
|
||||
realOutput.writeByte (TC_ARRAY);
|
||||
writeObject (osc);
|
||||
assignNewHandle (obj);
|
||||
writeArraySizeAndElements (obj, clazz.getComponentType ());
|
||||
break;
|
||||
}
|
||||
|
||||
realOutput.writeByte (TC_OBJECT);
|
||||
writeObject (osc);
|
||||
|
||||
if (replaceDone)
|
||||
assignNewHandle (replacedObject);
|
||||
else
|
||||
assignNewHandle (obj);
|
||||
|
||||
if (obj instanceof Externalizable)
|
||||
{
|
||||
if (protocolVersion == PROTOCOL_VERSION_2)
|
||||
setBlockDataMode (true);
|
||||
|
||||
((Externalizable)obj).writeExternal (this);
|
||||
|
||||
if (protocolVersion == PROTOCOL_VERSION_2)
|
||||
|
||||
while (true)
|
||||
{
|
||||
setBlockDataMode (false);
|
||||
drain ();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj instanceof Serializable)
|
||||
{
|
||||
currentObject = obj;
|
||||
ObjectStreamClass[] hierarchy =
|
||||
ObjectStreamClass.getObjectStreamClasses (clazz);
|
||||
|
||||
boolean has_write;
|
||||
for (int i=0; i < hierarchy.length; i++)
|
||||
{
|
||||
currentObjectStreamClass = hierarchy[i];
|
||||
|
||||
fieldsAlreadyWritten = false;
|
||||
has_write = currentObjectStreamClass.hasWriteMethod ();
|
||||
|
||||
writeFields (obj, currentObjectStreamClass.fields,
|
||||
has_write);
|
||||
|
||||
if (has_write)
|
||||
{
|
||||
drain ();
|
||||
realOutput.writeByte (TC_ENDBLOCKDATA);
|
||||
}
|
||||
}
|
||||
|
||||
currentObject = null;
|
||||
currentObjectStreamClass = null;
|
||||
currentPutField = null;
|
||||
break;
|
||||
}
|
||||
|
||||
throw new NotSerializableException (clazz.getName ());
|
||||
} // end pseudo-loop
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
realOutput.writeByte (TC_NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
Integer handle = findHandle (obj);
|
||||
if (handle != null)
|
||||
{
|
||||
realOutput.writeByte (TC_REFERENCE);
|
||||
realOutput.writeInt (handle.intValue ());
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj instanceof Class)
|
||||
{
|
||||
Class cl = (Class)obj;
|
||||
ObjectStreamClass osc = ObjectStreamClass.lookupForClassObject(cl);
|
||||
assignNewHandle (obj);
|
||||
realOutput.writeByte (TC_CLASS);
|
||||
if (!osc.isProxyClass)
|
||||
{
|
||||
writeObject(osc);
|
||||
}
|
||||
else
|
||||
{
|
||||
realOutput.writeByte (TC_PROXYCLASSDESC);
|
||||
Class[] intfs = cl.getInterfaces();
|
||||
realOutput.writeInt(intfs.length);
|
||||
for (int i = 0; i < intfs.length; i++)
|
||||
realOutput.writeUTF(intfs[i].getName());
|
||||
|
||||
boolean oldmode = setBlockDataMode (true);
|
||||
annotateProxyClass(cl);
|
||||
setBlockDataMode (oldmode);
|
||||
realOutput.writeByte(TC_ENDBLOCKDATA);
|
||||
|
||||
writeObject (osc.getSuper());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj instanceof ObjectStreamClass)
|
||||
{
|
||||
ObjectStreamClass osc = (ObjectStreamClass)obj;
|
||||
realOutput.writeByte (TC_CLASSDESC);
|
||||
realOutput.writeUTF (osc.getName ());
|
||||
realOutput.writeLong (osc.getSerialVersionUID ());
|
||||
assignNewHandle (obj);
|
||||
|
||||
int flags = osc.getFlags ();
|
||||
|
||||
if (protocolVersion == PROTOCOL_VERSION_2
|
||||
&& osc.isExternalizable ())
|
||||
flags |= SC_BLOCK_DATA;
|
||||
|
||||
realOutput.writeByte (flags);
|
||||
|
||||
ObjectStreamField[] fields = osc.fields;
|
||||
realOutput.writeShort (fields.length);
|
||||
|
||||
ObjectStreamField field;
|
||||
for (int i=0; i < fields.length; i++)
|
||||
{
|
||||
field = fields[i];
|
||||
realOutput.writeByte (field.getTypeCode ());
|
||||
realOutput.writeUTF (field.getName ());
|
||||
|
||||
if (! field.isPrimitive ())
|
||||
writeObject (field.getTypeString ());
|
||||
}
|
||||
|
||||
boolean oldmode = setBlockDataMode (true);
|
||||
annotateClass (osc.forClass ());
|
||||
setBlockDataMode (oldmode);
|
||||
realOutput.writeByte (TC_ENDBLOCKDATA);
|
||||
|
||||
if (osc.isSerializable ())
|
||||
writeObject (osc.getSuper ());
|
||||
else
|
||||
writeObject (null);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((replacementEnabled || obj instanceof Serializable)
|
||||
&& ! replaceDone)
|
||||
{
|
||||
replacedObject = obj;
|
||||
|
||||
if (obj instanceof Serializable)
|
||||
{
|
||||
Method m = null;
|
||||
try
|
||||
{
|
||||
Class classArgs[] = {};
|
||||
m = obj.getClass ().getDeclaredMethod ("writeReplace",
|
||||
classArgs);
|
||||
// m can't be null by definition since an exception would
|
||||
// have been thrown so a check for null is not needed.
|
||||
obj = m.invoke (obj, new Object[] {});
|
||||
}
|
||||
catch (NoSuchMethodException ignore)
|
||||
{
|
||||
}
|
||||
catch (IllegalAccessException ignore)
|
||||
{
|
||||
}
|
||||
catch (InvocationTargetException ignore)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (replacementEnabled)
|
||||
obj = replaceObject (obj);
|
||||
|
||||
replaceDone = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (obj instanceof String)
|
||||
{
|
||||
realOutput.writeByte (TC_STRING);
|
||||
assignNewHandle (obj);
|
||||
realOutput.writeUTF ((String)obj);
|
||||
break;
|
||||
}
|
||||
|
||||
Class clazz = obj.getClass ();
|
||||
ObjectStreamClass osc = ObjectStreamClass.lookupForClassObject (clazz);
|
||||
if (osc == null)
|
||||
throw new NotSerializableException (clazz.getName ());
|
||||
|
||||
if (clazz.isArray ())
|
||||
{
|
||||
realOutput.writeByte (TC_ARRAY);
|
||||
writeObject (osc);
|
||||
assignNewHandle (obj);
|
||||
writeArraySizeAndElements (obj, clazz.getComponentType ());
|
||||
break;
|
||||
}
|
||||
|
||||
realOutput.writeByte (TC_OBJECT);
|
||||
writeObject (osc);
|
||||
|
||||
if (replaceDone)
|
||||
assignNewHandle (replacedObject);
|
||||
else
|
||||
assignNewHandle (obj);
|
||||
|
||||
if (obj instanceof Externalizable)
|
||||
{
|
||||
if (protocolVersion == PROTOCOL_VERSION_2)
|
||||
setBlockDataMode (true);
|
||||
|
||||
((Externalizable)obj).writeExternal (this);
|
||||
|
||||
if (protocolVersion == PROTOCOL_VERSION_2)
|
||||
{
|
||||
setBlockDataMode (false);
|
||||
realOutput.writeByte (TC_ENDBLOCKDATA);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj instanceof Serializable)
|
||||
{
|
||||
currentObject = obj;
|
||||
ObjectStreamClass[] hierarchy =
|
||||
ObjectStreamClass.getObjectStreamClasses (clazz);
|
||||
|
||||
boolean has_write;
|
||||
for (int i=0; i < hierarchy.length; i++)
|
||||
{
|
||||
currentObjectStreamClass = hierarchy[i];
|
||||
|
||||
fieldsAlreadyWritten = false;
|
||||
has_write = currentObjectStreamClass.hasWriteMethod ();
|
||||
|
||||
writeFields (obj, currentObjectStreamClass.fields,
|
||||
has_write);
|
||||
|
||||
}
|
||||
|
||||
currentObject = null;
|
||||
currentObjectStreamClass = null;
|
||||
currentPutField = null;
|
||||
break;
|
||||
}
|
||||
|
||||
throw new NotSerializableException (clazz.getName ());
|
||||
} // end pseudo-loop
|
||||
}
|
||||
catch (ObjectStreamException ose)
|
||||
{
|
||||
// Rethrow these are fatal.
|
||||
throw ose;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
realOutput.writeByte (TC_EXCEPTION);
|
||||
reset (true);
|
||||
|
||||
try
|
||||
{
|
||||
writeObject (e);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new StreamCorruptedException ("Exception " + ioe + " thrown while exception was being written to stream.");
|
||||
}
|
||||
realOutput.writeByte (TC_EXCEPTION);
|
||||
reset (true);
|
||||
|
||||
reset (true);
|
||||
}
|
||||
setBlockDataMode (false);
|
||||
try
|
||||
{
|
||||
writeObject (e);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new StreamCorruptedException ("Exception " + ioe + " thrown while exception was being written to stream.");
|
||||
}
|
||||
|
||||
reset (true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
isSerializing = was_serializing;
|
||||
{
|
||||
isSerializing = was_serializing;
|
||||
|
||||
if (! was_serializing)
|
||||
setBlockDataMode (true);
|
||||
}
|
||||
setBlockDataMode (old_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -466,8 +480,8 @@ public class ObjectOutputStream extends OutputStream
|
||||
according to the specified protocol. There are currently two
|
||||
different protocols, specified by <code>PROTOCOL_VERSION_1</code>
|
||||
and <code>PROTOCOL_VERSION_2</code>. This implementation writes
|
||||
data using <code>PROTOCOL_VERSION_1</code> by default, as is done
|
||||
by the JDK 1.1.
|
||||
data using <code>PROTOCOL_VERSION_2</code> by default, as is done
|
||||
by the JDK 1.2.
|
||||
|
||||
A non-portable method, <code>setDefaultProtocolVersion (int
|
||||
version)</code> is provided to change the default protocol
|
||||
@ -528,6 +542,8 @@ public class ObjectOutputStream extends OutputStream
|
||||
protected void annotateClass (Class cl) throws IOException
|
||||
{}
|
||||
|
||||
protected void annotateProxyClass(Class cl) throws IOException
|
||||
{}
|
||||
|
||||
/**
|
||||
Allows subclasses to replace objects that are written to the
|
||||
@ -702,7 +718,8 @@ public class ObjectOutputStream extends OutputStream
|
||||
if (blockDataCount == 0)
|
||||
return;
|
||||
|
||||
writeBlockDataHeader (blockDataCount);
|
||||
if (writeDataAsBlocks)
|
||||
writeBlockDataHeader (blockDataCount);
|
||||
realOutput.write (blockData, 0, blockDataCount);
|
||||
blockDataCount = 0;
|
||||
}
|
||||
@ -713,7 +730,7 @@ public class ObjectOutputStream extends OutputStream
|
||||
*/
|
||||
public void close () throws IOException
|
||||
{
|
||||
drain ();
|
||||
flush ();
|
||||
realOutput.close ();
|
||||
}
|
||||
|
||||
@ -723,7 +740,7 @@ public class ObjectOutputStream extends OutputStream
|
||||
*/
|
||||
public void writeBoolean (boolean data) throws IOException
|
||||
{
|
||||
dataOutput.writeBoolean (data);
|
||||
blockDataOutput.writeBoolean (data);
|
||||
}
|
||||
|
||||
|
||||
@ -732,7 +749,7 @@ public class ObjectOutputStream extends OutputStream
|
||||
*/
|
||||
public void writeByte (int data) throws IOException
|
||||
{
|
||||
dataOutput.writeByte (data);
|
||||
blockDataOutput.writeByte (data);
|
||||
}
|
||||
|
||||
|
||||
@ -741,7 +758,7 @@ public class ObjectOutputStream extends OutputStream
|
||||
*/
|
||||
public void writeShort (int data) throws IOException
|
||||
{
|
||||
dataOutput.writeShort (data);
|
||||
blockDataOutput.writeShort (data);
|
||||
}
|
||||
|
||||
|
||||
@ -750,7 +767,7 @@ public class ObjectOutputStream extends OutputStream
|
||||
*/
|
||||
public void writeChar (int data) throws IOException
|
||||
{
|
||||
dataOutput.writeChar (data);
|
||||
blockDataOutput.writeChar (data);
|
||||
}
|
||||
|
||||
|
||||
@ -759,7 +776,7 @@ public class ObjectOutputStream extends OutputStream
|
||||
*/
|
||||
public void writeInt (int data) throws IOException
|
||||
{
|
||||
dataOutput.writeInt (data);
|
||||
blockDataOutput.writeInt (data);
|
||||
}
|
||||
|
||||
|
||||
@ -768,7 +785,7 @@ public class ObjectOutputStream extends OutputStream
|
||||
*/
|
||||
public void writeLong (long data) throws IOException
|
||||
{
|
||||
dataOutput.writeLong (data);
|
||||
blockDataOutput.writeLong (data);
|
||||
}
|
||||
|
||||
|
||||
@ -777,7 +794,7 @@ public class ObjectOutputStream extends OutputStream
|
||||
*/
|
||||
public void writeFloat (float data) throws IOException
|
||||
{
|
||||
dataOutput.writeFloat (data);
|
||||
blockDataOutput.writeFloat (data);
|
||||
}
|
||||
|
||||
|
||||
@ -786,7 +803,7 @@ public class ObjectOutputStream extends OutputStream
|
||||
*/
|
||||
public void writeDouble (double data) throws IOException
|
||||
{
|
||||
dataOutput.writeDouble (data);
|
||||
blockDataOutput.writeDouble (data);
|
||||
}
|
||||
|
||||
|
||||
@ -795,7 +812,7 @@ public class ObjectOutputStream extends OutputStream
|
||||
*/
|
||||
public void writeBytes (String data) throws IOException
|
||||
{
|
||||
dataOutput.writeBytes (data);
|
||||
blockDataOutput.writeBytes (data);
|
||||
}
|
||||
|
||||
|
||||
@ -965,6 +982,8 @@ public class ObjectOutputStream extends OutputStream
|
||||
{
|
||||
ObjectStreamField field
|
||||
= currentObjectStreamClass.getField (name);
|
||||
if (field == null)
|
||||
throw new IllegalArgumentException ();
|
||||
if (value != null &&
|
||||
! field.getType ().isAssignableFrom (value.getClass ()))
|
||||
throw new IllegalArgumentException ();
|
||||
@ -976,11 +995,11 @@ public class ObjectOutputStream extends OutputStream
|
||||
// Apparently Block data is not used with PutField as per
|
||||
// empirical evidence against JDK 1.2. Also see Mauve test
|
||||
// java.io.ObjectInputOutput.Test.GetPutField.
|
||||
setBlockDataMode (false);
|
||||
boolean oldmode = setBlockDataMode (false);
|
||||
out.write (prim_field_data);
|
||||
for (int i = 0; i < objs.length; ++ i)
|
||||
out.writeObject (objs[i]);
|
||||
setBlockDataMode (true);
|
||||
setBlockDataMode (oldmode);
|
||||
}
|
||||
|
||||
private void checkType (ObjectStreamField field, char type)
|
||||
@ -1067,8 +1086,7 @@ public class ObjectOutputStream extends OutputStream
|
||||
{
|
||||
byte[] cast_array = (byte[])array;
|
||||
realOutput.writeInt (length);
|
||||
for (int i=0; i < length; i++)
|
||||
realOutput.writeByte (cast_array[i]);
|
||||
realOutput.write(cast_array, 0, length);
|
||||
return;
|
||||
}
|
||||
if (clazz == Character.TYPE)
|
||||
@ -1142,9 +1160,11 @@ public class ObjectOutputStream extends OutputStream
|
||||
setBlockDataMode (true);
|
||||
callWriteMethod (obj);
|
||||
setBlockDataMode (false);
|
||||
realOutput.writeByte (TC_ENDBLOCKDATA);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean oldmode = setBlockDataMode (false);
|
||||
String field_name;
|
||||
Class type;
|
||||
for (int i=0; i < fields.length; i++)
|
||||
@ -1170,20 +1190,28 @@ public class ObjectOutputStream extends OutputStream
|
||||
realOutput.writeShort (getShortField (obj, field_name));
|
||||
else
|
||||
writeObject (getObjectField (obj, field_name,
|
||||
TypeSignature.getEncodingOfClass (type)));
|
||||
fields[i].getTypeString ()));
|
||||
}
|
||||
setBlockDataMode(oldmode);
|
||||
}
|
||||
|
||||
|
||||
// Toggles writing primitive data to block-data buffer.
|
||||
private void setBlockDataMode (boolean on)
|
||||
private boolean setBlockDataMode (boolean on) throws IOException
|
||||
{
|
||||
if (on == writeDataAsBlocks)
|
||||
return on;
|
||||
|
||||
drain();
|
||||
boolean oldmode = writeDataAsBlocks;
|
||||
writeDataAsBlocks = on;
|
||||
|
||||
if (on)
|
||||
dataOutput = blockDataOutput;
|
||||
else
|
||||
dataOutput = realOutput;
|
||||
|
||||
return oldmode;
|
||||
}
|
||||
|
||||
|
||||
@ -1355,16 +1383,22 @@ public class ObjectOutputStream extends OutputStream
|
||||
}
|
||||
}
|
||||
|
||||
private static native Field getField (Class klass, String name)
|
||||
throws java.lang.NoSuchFieldException;
|
||||
|
||||
private static native Method getMethod (Class klass, String name, Class[] args)
|
||||
throws java.lang.NoSuchMethodException;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// this value comes from 1.2 spec, but is used in 1.1 as well
|
||||
private final static int BUFFER_SIZE = 1024;
|
||||
|
||||
private static int defaultProtocolVersion = PROTOCOL_VERSION_1;
|
||||
private static int defaultProtocolVersion = PROTOCOL_VERSION_2;
|
||||
|
||||
private DataOutputStream dataOutput;
|
||||
private boolean writeDataAsBlocks;
|
||||
@ -1382,4 +1416,12 @@ public class ObjectOutputStream extends OutputStream
|
||||
private Hashtable OIDLookupTable;
|
||||
private int protocolVersion;
|
||||
private boolean useSubclassMethod;
|
||||
|
||||
static
|
||||
{
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary ("javaio");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,8 +47,23 @@ public class ObjectStreamField implements java.lang.Comparable
|
||||
{
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.typename = TypeSignature.getEncodingOfClass(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* There're many cases you can't get java.lang.Class from typename if your context
|
||||
* class loader can't load it, then use typename to construct the field
|
||||
*/
|
||||
ObjectStreamField (String name, String typename){
|
||||
this.name = name;
|
||||
this.typename = typename;
|
||||
try{
|
||||
type = TypeSignature.getClassForEncoding(typename);
|
||||
}catch(ClassNotFoundException e){
|
||||
type = Object.class; //??
|
||||
}
|
||||
}
|
||||
|
||||
public String getName ()
|
||||
{
|
||||
return name;
|
||||
@ -61,12 +76,13 @@ public class ObjectStreamField implements java.lang.Comparable
|
||||
|
||||
public char getTypeCode ()
|
||||
{
|
||||
return TypeSignature.getEncodingOfClass (type).charAt (0);
|
||||
return typename.charAt (0);
|
||||
}
|
||||
|
||||
public String getTypeString ()
|
||||
{
|
||||
return TypeSignature.getEncodingOfClass (type);
|
||||
// use intern()
|
||||
return typename.intern();
|
||||
}
|
||||
|
||||
public int getOffset ()
|
||||
@ -106,5 +122,6 @@ public class ObjectStreamField implements java.lang.Comparable
|
||||
|
||||
private String name;
|
||||
private Class type;
|
||||
private String typename;
|
||||
private int offset = -1; // XXX make sure this is correct
|
||||
}
|
||||
|
@ -69,16 +69,3 @@ java::io::ObjectInputStream::callConstructor (jclass klass, jobject obj)
|
||||
+ m->offset);
|
||||
_Jv_CallAnyMethodA (obj, JvPrimClass (void), meth, false, arg_types, NULL);
|
||||
}
|
||||
|
||||
java::lang::reflect::Field *
|
||||
java::io::ObjectInputStream::getField (jclass klass, jstring name)
|
||||
{
|
||||
return klass->getPrivateField (name);
|
||||
}
|
||||
|
||||
java::lang::reflect::Method *
|
||||
java::io::ObjectInputStream::getMethod (jclass klass, jstring name,
|
||||
JArray<jclass> *arg_types)
|
||||
{
|
||||
return klass->getPrivateMethod (name, arg_types);
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
// natObjectOutputStream.cc - Native part of ObjectOutputStream class.
|
||||
|
||||
/* Copyright (C) 1998, 1999 Free Software Foundation
|
||||
|
||||
This ObjectOutputStream is part of libgcj.
|
||||
|
||||
This software is copyrighted work licensed under the terms of the
|
||||
Libgcj License. Please consult the ObjectOutputStream "LIBGCJ_LICENSE" for
|
||||
details. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <gcj/cni.h>
|
||||
#include <jvm.h>
|
||||
#include <java/io/ObjectOutputStream$PutField.h>
|
||||
#include <java/io/ObjectOutputStream.h>
|
||||
#include <java/io/IOException.h>
|
||||
#include <java/lang/Class.h>
|
||||
|
||||
|
||||
java::lang::reflect::Field *
|
||||
java::io::ObjectOutputStream::getField (jclass klass, jstring name)
|
||||
{
|
||||
return klass->getPrivateField (name);
|
||||
}
|
||||
|
||||
java::lang::reflect::Method *
|
||||
java::io::ObjectOutputStream::getMethod (jclass klass, jstring name,
|
||||
JArray<jclass> *arg_types)
|
||||
{
|
||||
return klass->getPrivateMethod (name, arg_types);
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ JDBC2.0
|
||||
|
||||
# The following tests seem to hang or crash the testsuite.
|
||||
# This a problem when running Mauve "standalone".
|
||||
!java.io.ObjectInputOutput
|
||||
!java.lang.reflect.Array.newInstance
|
||||
|
||||
# Character.unicode seems to be very broken (the test)
|
||||
|
Loading…
Reference in New Issue
Block a user