]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
* Makefile.am (nat_source_files): Remove
authormark <mark@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 28 Feb 2003 11:38:56 +0000 (11:38 +0000)
committermark <mark@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 28 Feb 2003 11:38:56 +0000 (11:38 +0000)
        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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@63556 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/Makefile.am
libjava/Makefile.in
libjava/java/io/ObjectInputStream.java
libjava/java/io/ObjectOutputStream.java
libjava/java/io/ObjectStreamField.java
libjava/java/io/natObjectInputStream.cc
libjava/java/io/natObjectOutputStream.cc [deleted file]
libjava/mauve-libgcj

index 76f5ddec3772f92f4d2b75d6b0468c94535db9ca..9b95932ae1aa0568840d33356f48800404c4e5fc 100644 (file)
@@ -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,
index 01634166e52fa3c8646a1beea8c488a7c8c49cb4..297bc4acff8482bc2f4a99015416f1b89f753d6b 100644 (file)
@@ -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 \
index 05645fd88564b046f42eee0d7cadfdf80bbd8b1b..333e0a3659252998914bfe469e27bee9e54024b1 100644 (file)
@@ -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 \
index 08ce401fad822bc0337545aae9012376ad1d23bf..f2b2df8ed58de9aab4277c1cff50fb1afef3b224 100644 (file)
@@ -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");
+       }
+    }
 }
 
 
index d7c893f1696e3718d3d3988ccdef22988563a540..d522996d7a55a3a80e21c2e4a2f32c934d40ae53 100644 (file)
@@ -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");
+      }
+  }
 }
index e0f8d6131a891554cbcafac9bc30d551b56765e0..bb78a786c1f9b8f4fb27f3113b307599bfd153d3 100644 (file)
@@ -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
 }
index 8240144827f3bddede097d7756124b653d4a8be9..8b84e7e319973b2dc3bdae09da97da999b2990cf 100644 (file)
@@ -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 (file)
index 45ab753..0000000
+++ /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);
-}
-
index 64ee52e1cc83f3367f88f302fa79e32199283513..a2ccd5f9785b5dd91afc947ec147a04cb2ba9e15 100644 (file)
@@ -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)