ObjectInputStream.java (readObject): Cleaned up the class hierarchy loop.
authorJeroen Frijters <jeroen@sumatra.nl>
Fri, 14 Mar 2003 11:54:38 +0000 (12:54 +0100)
committerMark Wielaard <mark@gcc.gnu.org>
Fri, 14 Mar 2003 11:54:38 +0000 (11:54 +0000)
2003-02-14  Jeroen Frijters  <jeroen@sumatra.nl>

       * java/io/ObjectInputStream.java (readObject): Cleaned up the class
       hierarchy loop.
       (readFields(Object,ObjectStreamField[],boolean)): Changed argument
       list to Object,ObjectStreamClass, moved callReadMethod code up into
       readObject and added Class argument to all setXxxField calls.
       (callReadMethod): Changed Class argument to ObjectStreamClass to be
       consistent with ObjectOutputStream and to facilitate caching the
       Method in the future.
       (setBooleanField): Added Class argument.
       (setByteField): Likewise.
       (setCharField): Likewise.
       (setDoubleField): Likewise.
       (setFloatField): Likewise.
       (setIntField): Likewise.
       (setLongField): Likewise.
       (setShortField): Likewise.
       (setObjectField): Likewise.
       * java/io/ObjectOutputStream.java (writeObject): Cleaned up the
       class hierarchy loop.
       (defaultWriteObject): Call writeFields with new argument list.
       (writeFields(Object,ObjectStreamField[],boolean): Changed argument
       list to Object,ObjectStreamClass, moved callWriteMethod up into
       writeObject and added Class argument to all getXxxField calls.
       (callWriteMethod): Added ObjectStreamClass argument to be able to
       get the proper class to call getMethod on (each class can have (or
       not have) its own writeObject method).
       (getBooleanField): Added Class argument.
       (getByteField): Likewise.
       (getCharField): Likewise.
       (getDoubleField): Likewise.
       (getFloatField): Likewise.
       (getIntField): Likewise.
       (getLongField): Likewise.
       (getShortField): Likewise.
       (getObjectField): Likewise.
       * java/io/ObjectStreamClass.java (hasReadMethod): Added method to
       facilitate caching the Method object in the future.

From-SVN: r64351

libjava/ChangeLog
libjava/java/io/ObjectInputStream.java
libjava/java/io/ObjectOutputStream.java
libjava/java/io/ObjectStreamClass.java

index fecf74b461731e855968cb5431bfa4e439e6265f..b1d3b49939874985aede1ba3c3b754f0d0c273fe 100644 (file)
@@ -1,3 +1,43 @@
+2003-02-14  Jeroen Frijters  <jeroen@sumatra.nl>
+
+       * java/io/ObjectInputStream.java (readObject): Cleaned up the class
+       hierarchy loop.
+       (readFields(Object,ObjectStreamField[],boolean)): Changed argument
+       list to Object,ObjectStreamClass, moved callReadMethod code up into
+       readObject and added Class argument to all setXxxField calls.
+       (callReadMethod): Changed Class argument to ObjectStreamClass to be
+       consistent with ObjectOutputStream and to facilitate caching the
+       Method in the future.
+       (setBooleanField): Added Class argument.
+       (setByteField): Likewise.
+       (setCharField): Likewise.
+       (setDoubleField): Likewise.
+       (setFloatField): Likewise.
+       (setIntField): Likewise.
+       (setLongField): Likewise.
+       (setShortField): Likewise.
+       (setObjectField): Likewise.
+       * java/io/ObjectOutputStream.java (writeObject): Cleaned up the
+       class hierarchy loop.
+       (defaultWriteObject): Call writeFields with new argument list.
+       (writeFields(Object,ObjectStreamField[],boolean): Changed argument
+       list to Object,ObjectStreamClass, moved callWriteMethod up into
+       writeObject and added Class argument to all getXxxField calls.
+       (callWriteMethod): Added ObjectStreamClass argument to be able to
+       get the proper class to call getMethod on (each class can have (or
+       not have) its own writeObject method).
+       (getBooleanField): Added Class argument.
+       (getByteField): Likewise.
+       (getCharField): Likewise.
+       (getDoubleField): Likewise.
+       (getFloatField): Likewise.
+       (getIntField): Likewise.
+       (getLongField): Likewise.
+       (getShortField): Likewise.
+       (getObjectField): Likewise.
+       * java/io/ObjectStreamClass.java (hasReadMethod): Added method to
+       facilitate caching the Method object in the future.
+
 2003-03-12  Andreas Schwab  <schwab@suse.de>
 
        * configure.in: Avoid trailing /. in toolexeclibdir.
index 38c790a0ca15839dd5194265d9e26e082cb0c891..7df96e5ffe8b9b81ae13d3108b4f76106b479a5a 100644 (file)
@@ -368,35 +368,24 @@ public class ObjectInputStream extends InputStream
              ObjectStreamClass[] hierarchy =
                ObjectStreamClass.getObjectStreamClasses (clazz);
              
-             boolean has_read;
              for (int i=0; i < hierarchy.length; i++)
                {
                  this.currentObjectStreamClass = hierarchy[i];
                  
                  dumpElementln ("Reading fields of "
                                 + this.currentObjectStreamClass.getName ());
-                 
-                 has_read = true;
-                 
-                 try
-                   {
-                     this.currentObjectStreamClass.forClass ().
-                       getDeclaredMethod ("readObject", readObjectParams);
-                   }
-                 catch (NoSuchMethodException e)
-                   {
-                     has_read = false;
-                   }
 
                  // 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)
+                 
+                 if (this.currentObjectStreamClass.hasReadMethod())
                    {
+                     fieldsAlreadyRead = false;
+                     boolean oldmode = setBlockDataMode (true);
+                     callReadMethod (obj, this.currentObjectStreamClass);
+                     setBlockDataMode (oldmode);
                      dumpElement ("ENDBLOCKDATA? ");
                      try
                        {
@@ -415,6 +404,10 @@ public class ObjectInputStream extends InputStream
                          dumpElementln ("no, got IOException");
                        }
                    }
+                 else
+                   {
+                     readFields (obj, currentObjectStreamClass);
+                   }
                }
 
              this.currentObject = null;
@@ -487,9 +480,7 @@ public class ObjectInputStream extends InputStream
       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);
+    readFields (this.currentObject, this.currentObjectStreamClass);
     setBlockDataMode(oldmode);
 
     fieldsAlreadyRead = true;
@@ -1220,20 +1211,10 @@ public class ObjectInputStream extends InputStream
   }
 
 
-  private void readFields (Object obj, ObjectStreamField[] stream_fields,
-                          boolean call_read_method,
-                          ObjectStreamClass stream_osc)
+  private void readFields (Object obj, ObjectStreamClass stream_osc)
     throws ClassNotFoundException, IOException
   {
-    if (call_read_method)
-      {
-       fieldsAlreadyRead = false;
-       boolean oldmode = setBlockDataMode (true);
-       callReadMethod (obj, stream_osc.forClass ());
-       setBlockDataMode (oldmode);
-       return;
-      }
-
+    ObjectStreamField[] stream_fields = stream_osc.fields;
     ObjectStreamField[] real_fields =
       ObjectStreamClass.lookup (stream_osc.forClass ()).fields;
 
@@ -1299,7 +1280,7 @@ public class ObjectInputStream extends InputStream
                if (!default_initialize && set_value)
                  dumpElementln ("  " + field_name + ": " + value);
                if (set_value)
-                 setBooleanField (obj, field_name, value);
+                 setBooleanField (obj, stream_osc.forClass (), field_name, value);
              }
            else if (type == Byte.TYPE)
              {
@@ -1308,7 +1289,7 @@ public class ObjectInputStream extends InputStream
                if (!default_initialize && set_value)
                  dumpElementln ("  " + field_name + ": " + value);
                if (set_value)
-                 setByteField (obj, field_name, value);
+                 setByteField (obj, stream_osc.forClass (), field_name, value);
              }
            else if (type == Character.TYPE)
              {
@@ -1317,7 +1298,7 @@ public class ObjectInputStream extends InputStream
                if (!default_initialize && set_value)
                  dumpElementln ("  " + field_name + ": " + value);
                if (set_value)
-                 setCharField (obj, field_name, value);
+                 setCharField (obj, stream_osc.forClass (), field_name, value);
              }
            else if (type == Double.TYPE)
              {
@@ -1326,7 +1307,7 @@ public class ObjectInputStream extends InputStream
                if (!default_initialize && set_value)
                  dumpElementln ("  " + field_name + ": " + value);
                if (set_value)
-                 setDoubleField (obj, field_name, value);
+                 setDoubleField (obj, stream_osc.forClass (), field_name, value);
              }
            else if (type == Float.TYPE)
              {
@@ -1335,7 +1316,7 @@ public class ObjectInputStream extends InputStream
                if (!default_initialize && set_value)
                  dumpElementln ("  " + field_name + ": " + value);
                if (set_value)
-                 setFloatField (obj, field_name, value);
+                 setFloatField (obj, stream_osc.forClass (), field_name, value);
              }
            else if (type == Integer.TYPE)
              {
@@ -1344,7 +1325,7 @@ public class ObjectInputStream extends InputStream
                if (!default_initialize && set_value)
                  dumpElementln ("  " + field_name + ": " + value);
                if (set_value)
-                 setIntField (obj, field_name, value);
+                 setIntField (obj, stream_osc.forClass (), field_name, value);
              }
            else if (type == Long.TYPE)
              {
@@ -1353,7 +1334,7 @@ public class ObjectInputStream extends InputStream
                if (!default_initialize && set_value)
                  dumpElementln ("  " + field_name + ": " + value);
                if (set_value)
-                 setLongField (obj, field_name, value);
+                 setLongField (obj, stream_osc.forClass (), field_name, value);
              }
            else if (type == Short.TYPE)
              {
@@ -1362,14 +1343,14 @@ public class ObjectInputStream extends InputStream
                if (!default_initialize && set_value)
                  dumpElementln ("  " + field_name + ": " + value);
                if (set_value)
-                 setShortField (obj, field_name, value);
+                 setShortField (obj, stream_osc.forClass (), field_name, value);
              }
            else
              {
                Object value =
                  default_initialize ? null : readObject ();
                if (set_value)
-                 setObjectField (obj, field_name,
+                 setObjectField (obj, stream_osc.forClass (), field_name,
                                  real_field.getTypeString (), value);
              }
          }
@@ -1451,8 +1432,9 @@ public class ObjectInputStream extends InputStream
     return klass.getDeclaredMethod(name, args);
   }
 
-  private void callReadMethod (Object obj, Class klass) throws IOException
+  private void callReadMethod (Object obj, ObjectStreamClass osc) throws IOException
   {
+    Class klass = osc.forClass();
     try
       {
        Class classArgs[] = {ObjectInputStream.class};
@@ -1486,12 +1468,11 @@ public class ObjectInputStream extends InputStream
 
   private native void callConstructor (Class clazz, Object obj);
 
-  private void setBooleanField (Object obj, String field_name,
+  private void setBooleanField (Object obj, Class klass, String field_name,
                                boolean val)
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        f.setAccessible(true);
        f.setBoolean (obj, val);
@@ -1501,12 +1482,11 @@ public class ObjectInputStream extends InputStream
       }    
   }
 
-  private void setByteField (Object obj, String field_name,
+  private void setByteField (Object obj, Class klass, String field_name,
                             byte val)
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        f.setAccessible(true);
        f.setByte (obj, val);
@@ -1516,12 +1496,11 @@ public class ObjectInputStream extends InputStream
       }    
   }
 
-  private void setCharField (Object obj, String field_name,
+  private void setCharField (Object obj, Class klass, String field_name,
                             char val)
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        f.setAccessible(true);
        f.setChar (obj, val);
@@ -1531,12 +1510,11 @@ public class ObjectInputStream extends InputStream
       }    
   }
 
-  private void setDoubleField (Object obj, String field_name,
+  private void setDoubleField (Object obj, Class klass, String field_name,
                               double val)
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        f.setAccessible(true);
        f.setDouble (obj, val);
@@ -1546,12 +1524,11 @@ public class ObjectInputStream extends InputStream
       }    
   }
 
-  private void setFloatField (Object obj, String field_name,
+  private void setFloatField (Object obj, Class klass, String field_name,
                              float val)
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        f.setAccessible(true);
        f.setFloat (obj, val);
@@ -1561,12 +1538,11 @@ public class ObjectInputStream extends InputStream
       }    
   }
 
-  private void setIntField (Object obj, String field_name,
+  private void setIntField (Object obj, Class klass, String field_name,
                            int val)
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        f.setAccessible(true);
        f.setInt (obj, val);
@@ -1577,12 +1553,11 @@ public class ObjectInputStream extends InputStream
   }
 
 
-  private void setLongField (Object obj, String field_name,
+  private void setLongField (Object obj, Class klass, String field_name,
                             long val)
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        f.setAccessible(true);
        f.setLong (obj, val);
@@ -1593,12 +1568,11 @@ public class ObjectInputStream extends InputStream
   }
 
 
-  private void setShortField (Object obj, String field_name,
+  private void setShortField (Object obj, Class klass, String field_name,
                              short val)
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        f.setAccessible(true);
        f.setShort (obj, val);
@@ -1609,12 +1583,11 @@ public class ObjectInputStream extends InputStream
   }
 
 
-  private void setObjectField (Object obj, String field_name, String type_code,
+  private void setObjectField (Object obj, Class klass, String field_name, String type_code,
                               Object val)
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        f.setAccessible(true);
        // FIXME: We should check the type_code here
index 69f789abbf8f1588dddbae9bf83247a4fcbb0ca7..a051a96f3d8052ad28a57cee176a69e4dec57c0b 100644 (file)
@@ -354,16 +354,20 @@ public class ObjectOutputStream extends OutputStream
                ObjectStreamClass[] hierarchy =
                  ObjectStreamClass.getObjectStreamClasses (clazz);
 
-               boolean has_write;
                for (int i=0; i < hierarchy.length; i++)
                  {
                    currentObjectStreamClass = hierarchy[i];
 
                    fieldsAlreadyWritten = false;
-                   has_write = currentObjectStreamClass.hasWriteMethod ();
-
-                   writeFields (obj, currentObjectStreamClass.fields,
-                                has_write);
+                   if (currentObjectStreamClass.hasWriteMethod ())
+                     {
+                       setBlockDataMode (true);
+                       callWriteMethod (obj, currentObjectStreamClass);
+                       setBlockDataMode (false);
+                       realOutput.writeByte (TC_ENDBLOCKDATA);
+                     }
+                   else
+                     writeFields (obj, currentObjectStreamClass);
                  }
 
                currentObject = null;
@@ -424,7 +428,7 @@ public class ObjectOutputStream extends OutputStream
     throws IOException, NotActiveException
   {
     markFieldsWritten ();
-    writeFields (currentObject, currentObjectStreamClass.fields, false);
+    writeFields (currentObject, currentObjectStreamClass);
   }
 
 
@@ -1145,22 +1149,12 @@ public class ObjectOutputStream extends OutputStream
   }
 
 
-  // writes out FIELDS of OBJECT.  If CALL_WRITE_METHOD is true, use
-  // object's writeObject (ObjectOutputStream), otherwise use default
-  // serialization.  FIELDS are already in canonical order.
-  private void writeFields (Object obj,
-                           ObjectStreamField[] fields,
-                           boolean call_write_method) throws IOException
+  // writes out FIELDS of OBJECT for the specified ObjectStreamClass.
+  // FIELDS are already in canonical order.
+  private void writeFields (Object obj, ObjectStreamClass osc)
+    throws IOException
   {
-    if (call_write_method)
-      {
-       setBlockDataMode (true);
-       callWriteMethod (obj);
-       setBlockDataMode (false);
-       realOutput.writeByte (TC_ENDBLOCKDATA);
-       return;
-      }
-
+    ObjectStreamField[] fields = osc.fields;
     boolean oldmode = setBlockDataMode (false);
     String field_name;
     Class type;
@@ -1170,23 +1164,23 @@ public class ObjectOutputStream extends OutputStream
        type = fields[i].getType ();
 
        if (type == Boolean.TYPE)
-         realOutput.writeBoolean (getBooleanField (obj, field_name));
+         realOutput.writeBoolean (getBooleanField (obj, osc.forClass(), field_name));
        else if (type == Byte.TYPE)
-         realOutput.writeByte (getByteField (obj, field_name));
+         realOutput.writeByte (getByteField (obj, osc.forClass(), field_name));
        else if (type == Character.TYPE)
-         realOutput.writeChar (getCharField (obj, field_name));
+         realOutput.writeChar (getCharField (obj, osc.forClass(), field_name));
        else if (type == Double.TYPE)
-         realOutput.writeDouble (getDoubleField (obj, field_name));
+         realOutput.writeDouble (getDoubleField (obj, osc.forClass(), field_name));
        else if (type == Float.TYPE)
-         realOutput.writeFloat (getFloatField (obj, field_name));
+         realOutput.writeFloat (getFloatField (obj, osc.forClass(), field_name));
        else if (type == Integer.TYPE)
-         realOutput.writeInt (getIntField (obj, field_name));
+         realOutput.writeInt (getIntField (obj, osc.forClass(), field_name));
        else if (type == Long.TYPE)
-         realOutput.writeLong (getLongField (obj, field_name));
+         realOutput.writeLong (getLongField (obj, osc.forClass(), field_name));
        else if (type == Short.TYPE)
-         realOutput.writeShort (getShortField (obj, field_name));
+         realOutput.writeShort (getShortField (obj, osc.forClass(), field_name));
        else
-         writeObject (getObjectField (obj, field_name,
+         writeObject (getObjectField (obj, osc.forClass(), field_name,
                                       fields[i].getTypeString ()));
       }
     setBlockDataMode (oldmode);
@@ -1212,9 +1206,9 @@ public class ObjectOutputStream extends OutputStream
   }
 
 
-  private void callWriteMethod (Object obj) throws IOException
+  private void callWriteMethod (Object obj, ObjectStreamClass osc) throws IOException
   {
-    Class klass = obj.getClass ();
+    Class klass = osc.forClass();
     try
       {
        Class classArgs[] = {ObjectOutputStream.class};
@@ -1243,12 +1237,11 @@ public class ObjectOutputStream extends OutputStream
       }
   }
 
-  private boolean getBooleanField (Object obj, String field_name)
+  private boolean getBooleanField (Object obj, Class klass, String field_name)
     throws IOException
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        boolean b = f.getBoolean (obj);
        return b;
@@ -1259,11 +1252,10 @@ public class ObjectOutputStream extends OutputStream
       }    
   }
 
-  private byte getByteField (Object obj, String field_name) throws IOException
+  private byte getByteField (Object obj, Class klass, String field_name) throws IOException
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        byte b = f.getByte (obj);
        return b;
@@ -1274,11 +1266,10 @@ public class ObjectOutputStream extends OutputStream
       }    
   }
 
-  private char getCharField (Object obj, String field_name) throws IOException
+  private char getCharField (Object obj, Class klass, String field_name) throws IOException
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        char b = f.getChar (obj);
        return b;
@@ -1289,12 +1280,11 @@ public class ObjectOutputStream extends OutputStream
       }    
   }
 
-  private double getDoubleField (Object obj, String field_name)
+  private double getDoubleField (Object obj, Class klass, String field_name)
     throws IOException
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        double b = f.getDouble (obj);
        return b;
@@ -1305,12 +1295,11 @@ public class ObjectOutputStream extends OutputStream
       }    
   }
 
-  private float getFloatField (Object obj, String field_name)
+  private float getFloatField (Object obj, Class klass, String field_name)
     throws IOException
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        float b = f.getFloat (obj);
        return b;
@@ -1321,11 +1310,10 @@ public class ObjectOutputStream extends OutputStream
       }    
   }
 
-  private int getIntField (Object obj, String field_name) throws IOException
+  private int getIntField (Object obj, Class klass, String field_name) throws IOException
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        int b = f.getInt (obj);
        return b;
@@ -1336,11 +1324,10 @@ public class ObjectOutputStream extends OutputStream
       }    
   }
 
-  private long getLongField (Object obj, String field_name) throws IOException
+  private long getLongField (Object obj, Class klass, String field_name) throws IOException
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        long b = f.getLong (obj);
        return b;
@@ -1351,12 +1338,11 @@ public class ObjectOutputStream extends OutputStream
       }    
   }
 
-  private short getShortField (Object obj, String field_name)
+  private short getShortField (Object obj, Class klass, String field_name)
     throws IOException
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        short b = f.getShort (obj);
        return b;
@@ -1367,12 +1353,11 @@ public class ObjectOutputStream extends OutputStream
       }    
   }
 
-  private Object getObjectField (Object obj, String field_name,
+  private Object getObjectField (Object obj, Class klass, String field_name,
                                 String type_code) throws IOException
   {
     try
       {
-       Class klass = obj.getClass ();
        Field f = getField (klass, field_name);
        Object o = f.get (obj);
        // FIXME: We should check the type_code here
index 2111635525a675d3f5a3efe12d1fd84311d3bab5..19a69ec47bc7fa94dd2cea4c4e86d9e99f0849d3 100644 (file)
@@ -193,6 +193,28 @@ public class ObjectStreamClass implements Serializable
   }
 
 
+  // Returns true iff the class that this ObjectStreamClass represents
+  // has the following method:
+  //
+  // private void readObject (ObjectOutputStream)
+  //
+  // This method is used by the class to override default
+  // serialization behavior.
+  boolean hasReadMethod ()
+  {
+      try
+      {
+         Class[] readObjectParams = { ObjectInputStream.class };
+         forClass ().getDeclaredMethod ("readObject", readObjectParams);
+         return true;
+      }
+      catch (NoSuchMethodException e)
+      {
+         return false;
+      }
+  }
+
+
   // Returns true iff the class that this ObjectStreamClass represents
   // implements Serializable but does *not* implement Externalizable.
   boolean isSerializable ()