aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2003-02-28 11:38:56 +0000
committerMark Wielaard <mark@gcc.gnu.org>2003-02-28 11:38:56 +0000
commit4480b3dcf640e952085da75f887d7392c5afc994 (patch)
treeeb6527381e25675338e21ca7ad2996e4d91330c8
parent28727f1fb365c5cc0d02394dd06d57a57eb0fa76 (diff)
downloadgcc-4480b3dcf640e952085da75f887d7392c5afc994.zip
gcc-4480b3dcf640e952085da75f887d7392c5afc994.tar.gz
gcc-4480b3dcf640e952085da75f887d7392c5afc994.tar.bz2
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
-rw-r--r--libjava/ChangeLog56
-rw-r--r--libjava/Makefile.am1
-rw-r--r--libjava/Makefile.in14
-rw-r--r--libjava/java/io/ObjectInputStream.java822
-rw-r--r--libjava/java/io/ObjectOutputStream.java502
-rw-r--r--libjava/java/io/ObjectStreamField.java23
-rw-r--r--libjava/java/io/natObjectInputStream.cc13
-rw-r--r--libjava/java/io/natObjectOutputStream.cc33
-rw-r--r--libjava/mauve-libgcj1
9 files changed, 812 insertions, 653 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 76f5dde..9b95932 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -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,
diff --git a/libjava/Makefile.am b/libjava/Makefile.am
index 0163416..297bc4a 100644
--- a/libjava/Makefile.am
+++ b/libjava/Makefile.am
@@ -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 \
diff --git a/libjava/Makefile.in b/libjava/Makefile.in
index 05645fd..333e0a3 100644
--- a/libjava/Makefile.in
+++ b/libjava/Makefile.in
@@ -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 \
diff --git a/libjava/java/io/ObjectInputStream.java b/libjava/java/io/ObjectInputStream.java
index 08ce401..f2b2df8e 100644
--- a/libjava/java/io/ObjectInputStream.java
+++ b/libjava/java/io/ObjectInputStream.java
@@ -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:
- {
- 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_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:
+ try
{
- 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)
+ switch (marker)
{
- 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))
+ 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);
+
+ // 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);
- // 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:
+ finally
{
- dumpElement ("EXCEPTION=");
- Exception e = (Exception)readObject ();
- dumpElementln (e.toString());
- clearHandles ();
- throw new WriteAbortedException ("Exception thrown during writing of stream", e);
+ setBlockDataMode (old_mode);
+
+ this.isDeserializing = was_deserializing;
+
+ if (! was_deserializing)
+ {
+ if (validators.size () > 0)
+ invokeValidators ();
+ }
}
-
- 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");
+ }
+ }
}
diff --git a/libjava/java/io/ObjectOutputStream.java b/libjava/java/io/ObjectOutputStream.java
index d7c893f..d522996 100644
--- a/libjava/java/io/ObjectOutputStream.java
+++ b/libjava/java/io/ObjectOutputStream.java
@@ -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
+
+ 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)
+ {
+ 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)
{
- 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[] {});
+ 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;
}
- catch (NoSuchMethodException ignore)
+
+ if (obj instanceof String)
{
+ realOutput.writeByte (TC_STRING);
+ assignNewHandle (obj);
+ realOutput.writeUTF ((String)obj);
+ break;
}
- catch (IllegalAccessException ignore)
+
+ 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;
}
- catch (InvocationTargetException ignore)
+
+ 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 (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)
+
+ 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);
+
+ setBlockDataMode (false);
+ try
{
- setBlockDataMode (false);
- drain ();
+ writeObject (e);
}
-
- break;
- }
-
- if (obj instanceof Serializable)
- {
- currentObject = obj;
- ObjectStreamClass[] hierarchy =
- ObjectStreamClass.getObjectStreamClasses (clazz);
-
- boolean has_write;
- for (int i=0; i < hierarchy.length; i++)
+ catch (IOException ioe)
{
- currentObjectStreamClass = hierarchy[i];
-
- fieldsAlreadyWritten = false;
- has_write = currentObjectStreamClass.hasWriteMethod ();
-
- writeFields (obj, currentObjectStreamClass.fields,
- has_write);
-
- if (has_write)
- {
- drain ();
- realOutput.writeByte (TC_ENDBLOCKDATA);
- }
+ throw new StreamCorruptedException ("Exception " + ioe + " thrown while exception was being written to stream.");
}
-
- currentObject = null;
- currentObjectStreamClass = null;
- currentPutField = null;
- break;
- }
-
- throw new NotSerializableException (clazz.getName ());
- } // end pseudo-loop
- }
- catch (IOException e)
- {
- realOutput.writeByte (TC_EXCEPTION);
- reset (true);
-
- try
- {
- writeObject (e);
+
+ reset (true);
}
- 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");
+ }
+ }
}
diff --git a/libjava/java/io/ObjectStreamField.java b/libjava/java/io/ObjectStreamField.java
index e0f8d61..bb78a78 100644
--- a/libjava/java/io/ObjectStreamField.java
+++ b/libjava/java/io/ObjectStreamField.java
@@ -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
}
diff --git a/libjava/java/io/natObjectInputStream.cc b/libjava/java/io/natObjectInputStream.cc
index 8240144..8b84e7e 100644
--- a/libjava/java/io/natObjectInputStream.cc
+++ b/libjava/java/io/natObjectInputStream.cc
@@ -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);
-}
diff --git a/libjava/java/io/natObjectOutputStream.cc b/libjava/java/io/natObjectOutputStream.cc
deleted file mode 100644
index 45ab753..0000000
--- a/libjava/java/io/natObjectOutputStream.cc
+++ /dev/null
@@ -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);
-}
-
diff --git a/libjava/mauve-libgcj b/libjava/mauve-libgcj
index 64ee52e..a2ccd5f 100644
--- a/libjava/mauve-libgcj
+++ b/libjava/mauve-libgcj
@@ -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)