From 70e2e8dc1dcf67876829f1ff69fe77258613394b Mon Sep 17 00:00:00 2001 From: Jeroen Frijters Date: Fri, 14 Mar 2003 12:54:38 +0100 Subject: [PATCH] ObjectInputStream.java (readObject): Cleaned up the class hierarchy loop. 2003-02-14 Jeroen Frijters * 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 | 40 +++++++++++ libjava/java/io/ObjectInputStream.java | 93 +++++++++---------------- libjava/java/io/ObjectOutputStream.java | 85 ++++++++++------------ libjava/java/io/ObjectStreamClass.java | 22 ++++++ 4 files changed, 130 insertions(+), 110 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index fecf74b4617..b1d3b499398 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,43 @@ +2003-02-14 Jeroen Frijters + + * 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 * configure.in: Avoid trailing /. in toolexeclibdir. diff --git a/libjava/java/io/ObjectInputStream.java b/libjava/java/io/ObjectInputStream.java index 38c790a0ca1..7df96e5ffe8 100644 --- a/libjava/java/io/ObjectInputStream.java +++ b/libjava/java/io/ObjectInputStream.java @@ -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 diff --git a/libjava/java/io/ObjectOutputStream.java b/libjava/java/io/ObjectOutputStream.java index 69f789abbf8..a051a96f3d8 100644 --- a/libjava/java/io/ObjectOutputStream.java +++ b/libjava/java/io/ObjectOutputStream.java @@ -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 diff --git a/libjava/java/io/ObjectStreamClass.java b/libjava/java/io/ObjectStreamClass.java index 2111635525a..19a69ec47bc 100644 --- a/libjava/java/io/ObjectStreamClass.java +++ b/libjava/java/io/ObjectStreamClass.java @@ -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 ()