diff options
author | Mark Wielaard <mark@klomp.org> | 2003-02-28 11:38:56 +0000 |
---|---|---|
committer | Mark Wielaard <mark@gcc.gnu.org> | 2003-02-28 11:38:56 +0000 |
commit | 4480b3dcf640e952085da75f887d7392c5afc994 (patch) | |
tree | eb6527381e25675338e21ca7ad2996e4d91330c8 /libjava/java/io/ObjectOutputStream.java | |
parent | 28727f1fb365c5cc0d02394dd06d57a57eb0fa76 (diff) | |
download | gcc-4480b3dcf640e952085da75f887d7392c5afc994.zip gcc-4480b3dcf640e952085da75f887d7392c5afc994.tar.gz gcc-4480b3dcf640e952085da75f887d7392c5afc994.tar.bz2 |
Makefile.am (nat_source_files): Remove java/io/natObjectOutputStream.cc.
* Makefile.am (nat_source_files): Remove
java/io/natObjectOutputStream.cc.
* Makefile.in: Regenerated.
* mauve-libgcj: Don't exclude java.io.ObjectInputOutput tests.
* java/io/ObjectStreamField.java (typename): New field.
(ObjectStreamField(String, Class)): Initialize new field.
(ObjectStreamField(String, String)): New Constructor.
(getTypeCode): Use new field.
(getTypeString): Use new field.
* java/io/ObjectOutputStream.java (writeObject): Rethrow fatal
ObjectStreamExceptions. Remember and reset old BlockDataMode.
Handle reading of Proxy classes. Never drain(), just write
TC_ENDBLOCKDATA. Rethrow ObjectStreamExceptions.
(drain): Check writeDataAsBlocks before calling writeBlockDataHeader.
(flush): Call flush(), not just drain().
(writeBoolean): Always use blockDataOutput.
(writeByte): Likewise.
(writeShort): Likewise.
(writeChar): Likewise.
(writeInt): Likewise.
(writeLong): Likewise.
(writeFloat): Likewise.
(writeDouble): Likewise.
(writeBytes): Likewise.
(putfield (put(String,Object))): Throw IllegalArgumentException if
field cannot be found.
(putfield (write(ObjectOutput))): Remember old BlockDataMode.
(writeArraySizeAndElements): Write byte[] in one go.
(writeFields): Write TC_ENDBLOCKDATA when call_write_method, otherwise
set BlockDataMode to false.
(annotateProxyClass): New method.
(defaultProtocolVersion): Now defaults to PROTOCOL_VERSION_2
(getField): No longer native.
(getMethod): Likewise.
(setBlockDataMode): Always drain() on switch, return old mode.
(static): New static code block.
* java/io/natObjectOutputStream.cc: Removed.
* java/io/ObjectInputStream.java (getField): No longer native.
(getMethod): Likewise.
(readObject): Remember and reset old BlockDataMode. Track whether
object is consumed. Handle TC_ENDBLOCKDATA, TC_PROXYCLASSDESC and
TC_LONGSTRING.
(defaultReadObject): Set BlockDataMode to false during readFields.
(resolveClass): Create new SecurityManager if necessary.
Use Class.forName() if null ClassLoader found.
(read(byte[],int,int): Copy remaining bytes to data before calling
readNextBlock().
(readFields): Set and reset BlockDataMode on call_read_method.
Catch NoSuchFieldErrors.
(setBlockDataMode): Return old mode.
(static): New static code block.
* java/io/natObjectInputStream.cc (getField): Removed.
(getMethod): Likewise.
From-SVN: r63556
Diffstat (limited to 'libjava/java/io/ObjectOutputStream.java')
-rw-r--r-- | libjava/java/io/ObjectOutputStream.java | 502 |
1 files changed, 272 insertions, 230 deletions
diff --git a/libjava/java/io/ObjectOutputStream.java b/libjava/java/io/ObjectOutputStream.java index d7c893f..d522996 100644 --- a/libjava/java/io/ObjectOutputStream.java +++ b/libjava/java/io/ObjectOutputStream.java @@ -1,5 +1,5 @@ /* ObjectOutputStream.java -- Class used to write serialized objects - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -46,6 +46,7 @@ import java.util.Hashtable; import gnu.java.io.ObjectIdentityWrapper; import gnu.java.lang.reflect.TypeSignature; +import gnu.classpath.Configuration; /** An <code>ObjectOutputStream</code> can be used to write objects @@ -167,229 +168,242 @@ public class ObjectOutputStream extends OutputStream public final void writeObject (Object obj) throws IOException { if (useSubclassMethod) - { - writeObjectOverride (obj); - return; - } + { + writeObjectOverride (obj); + return; + } boolean was_serializing = isSerializing; - - if (! was_serializing) - setBlockDataMode (false); - + boolean old_mode = setBlockDataMode (false); try - { - isSerializing = true; - boolean replaceDone = false; - - drain (); - - while (true) { - if (obj == null) - { - realOutput.writeByte (TC_NULL); - break; - } - - Integer handle = findHandle (obj); - if (handle != null) - { - realOutput.writeByte (TC_REFERENCE); - realOutput.writeInt (handle.intValue ()); - break; - } - - if (obj instanceof Class) - { - realOutput.writeByte (TC_CLASS); - writeObject (ObjectStreamClass.lookup ((Class)obj)); - assignNewHandle (obj); - break; - } - - if (obj instanceof ObjectStreamClass) - { - ObjectStreamClass osc = (ObjectStreamClass)obj; - realOutput.writeByte (TC_CLASSDESC); - realOutput.writeUTF (osc.getName ()); - realOutput.writeLong (osc.getSerialVersionUID ()); - assignNewHandle (obj); - - int flags = osc.getFlags (); - - if (protocolVersion == PROTOCOL_VERSION_2 - && osc.isExternalizable ()) - flags |= SC_BLOCK_DATA; - - realOutput.writeByte (flags); - - ObjectStreamField[] fields = osc.fields; - realOutput.writeShort (fields.length); - - ObjectStreamField field; - for (int i=0; i < fields.length; i++) - { - field = fields[i]; - realOutput.writeByte (field.getTypeCode ()); - realOutput.writeUTF (field.getName ()); - - if (! field.isPrimitive ()) - writeObject (field.getTypeString ()); - } - - setBlockDataMode (true); - annotateClass (osc.forClass ()); - setBlockDataMode (false); - realOutput.writeByte (TC_ENDBLOCKDATA); - - if (osc.isSerializable ()) - writeObject (osc.getSuper ()); - else - writeObject (null); - break; - } - - + isSerializing = true; + boolean replaceDone = false; Object replacedObject = null; - - if ((replacementEnabled || obj instanceof Serializable) - && ! replaceDone) - { - replacedObject = obj; - - if (obj instanceof Serializable) - { - Method m = null; - try + + while (true) + { + if (obj == null) + { + realOutput.writeByte (TC_NULL); + break; + } + + Integer handle = findHandle (obj); + if (handle != null) + { + realOutput.writeByte (TC_REFERENCE); + realOutput.writeInt (handle.intValue ()); + break; + } + + if (obj instanceof Class) + { + Class cl = (Class)obj; + ObjectStreamClass osc = ObjectStreamClass.lookupForClassObject(cl); + assignNewHandle (obj); + realOutput.writeByte (TC_CLASS); + if (!osc.isProxyClass) + { + writeObject(osc); + } + else + { + realOutput.writeByte (TC_PROXYCLASSDESC); + Class[] intfs = cl.getInterfaces(); + realOutput.writeInt(intfs.length); + for (int i = 0; i < intfs.length; i++) + realOutput.writeUTF(intfs[i].getName()); + + boolean oldmode = setBlockDataMode (true); + annotateProxyClass(cl); + setBlockDataMode (oldmode); + realOutput.writeByte(TC_ENDBLOCKDATA); + + writeObject (osc.getSuper()); + } + break; + } + + if (obj instanceof ObjectStreamClass) + { + ObjectStreamClass osc = (ObjectStreamClass)obj; + realOutput.writeByte (TC_CLASSDESC); + realOutput.writeUTF (osc.getName ()); + realOutput.writeLong (osc.getSerialVersionUID ()); + assignNewHandle (obj); + + int flags = osc.getFlags (); + + if (protocolVersion == PROTOCOL_VERSION_2 + && osc.isExternalizable ()) + flags |= SC_BLOCK_DATA; + + realOutput.writeByte (flags); + + ObjectStreamField[] fields = osc.fields; + realOutput.writeShort (fields.length); + + ObjectStreamField field; + for (int i=0; i < fields.length; i++) + { + field = fields[i]; + realOutput.writeByte (field.getTypeCode ()); + realOutput.writeUTF (field.getName ()); + + if (! field.isPrimitive ()) + writeObject (field.getTypeString ()); + } + + boolean oldmode = setBlockDataMode (true); + annotateClass (osc.forClass ()); + setBlockDataMode (oldmode); + realOutput.writeByte (TC_ENDBLOCKDATA); + + if (osc.isSerializable ()) + writeObject (osc.getSuper ()); + else + writeObject (null); + break; + } + + if ((replacementEnabled || obj instanceof Serializable) + && ! replaceDone) { - Class classArgs[] = {}; - m = obj.getClass ().getDeclaredMethod ("writeReplace", - classArgs); - // m can't be null by definition since an exception would - // have been thrown so a check for null is not needed. - obj = m.invoke (obj, new Object[] {}); + replacedObject = obj; + + if (obj instanceof Serializable) + { + Method m = null; + try + { + Class classArgs[] = {}; + m = obj.getClass ().getDeclaredMethod ("writeReplace", + classArgs); + // m can't be null by definition since an exception would + // have been thrown so a check for null is not needed. + obj = m.invoke (obj, new Object[] {}); + } + catch (NoSuchMethodException ignore) + { + } + catch (IllegalAccessException ignore) + { + } + catch (InvocationTargetException ignore) + { + } + } + + if (replacementEnabled) + obj = replaceObject (obj); + + replaceDone = true; + continue; } - catch (NoSuchMethodException ignore) + + if (obj instanceof String) { + realOutput.writeByte (TC_STRING); + assignNewHandle (obj); + realOutput.writeUTF ((String)obj); + break; } - catch (IllegalAccessException ignore) + + Class clazz = obj.getClass (); + ObjectStreamClass osc = ObjectStreamClass.lookupForClassObject (clazz); + if (osc == null) + throw new NotSerializableException (clazz.getName ()); + + if (clazz.isArray ()) { + realOutput.writeByte (TC_ARRAY); + writeObject (osc); + assignNewHandle (obj); + writeArraySizeAndElements (obj, clazz.getComponentType ()); + break; } - catch (InvocationTargetException ignore) + + realOutput.writeByte (TC_OBJECT); + writeObject (osc); + + if (replaceDone) + assignNewHandle (replacedObject); + else + assignNewHandle (obj); + + if (obj instanceof Externalizable) { + if (protocolVersion == PROTOCOL_VERSION_2) + setBlockDataMode (true); + + ((Externalizable)obj).writeExternal (this); + + if (protocolVersion == PROTOCOL_VERSION_2) + { + setBlockDataMode (false); + realOutput.writeByte (TC_ENDBLOCKDATA); + } + + break; } - } - - if (replacementEnabled) - obj = replaceObject (obj); - - replaceDone = true; - continue; - } - - if (obj instanceof String) - { - realOutput.writeByte (TC_STRING); - assignNewHandle (obj); - realOutput.writeUTF ((String)obj); - break; - } - - Class clazz = obj.getClass (); - ObjectStreamClass osc = ObjectStreamClass.lookup (clazz); - if (osc == null) - throw new NotSerializableException (clazz.getName ()); - - if (clazz.isArray ()) - { - realOutput.writeByte (TC_ARRAY); - writeObject (osc); - assignNewHandle (obj); - writeArraySizeAndElements (obj, clazz.getComponentType ()); - break; - } - - realOutput.writeByte (TC_OBJECT); - writeObject (osc); - - if (replaceDone) - assignNewHandle (replacedObject); - else - assignNewHandle (obj); - - if (obj instanceof Externalizable) - { - if (protocolVersion == PROTOCOL_VERSION_2) - setBlockDataMode (true); - - ((Externalizable)obj).writeExternal (this); - - if (protocolVersion == PROTOCOL_VERSION_2) + + if (obj instanceof Serializable) + { + currentObject = obj; + ObjectStreamClass[] hierarchy = + ObjectStreamClass.getObjectStreamClasses (clazz); + + boolean has_write; + for (int i=0; i < hierarchy.length; i++) + { + currentObjectStreamClass = hierarchy[i]; + + fieldsAlreadyWritten = false; + has_write = currentObjectStreamClass.hasWriteMethod (); + + writeFields (obj, currentObjectStreamClass.fields, + has_write); + + } + + currentObject = null; + currentObjectStreamClass = null; + currentPutField = null; + break; + } + + throw new NotSerializableException (clazz.getName ()); + } // end pseudo-loop + } + catch (ObjectStreamException ose) + { + // Rethrow these are fatal. + throw ose; + } + catch (IOException e) + { + realOutput.writeByte (TC_EXCEPTION); + reset (true); + + setBlockDataMode (false); + try { - setBlockDataMode (false); - drain (); + writeObject (e); } - - break; - } - - if (obj instanceof Serializable) - { - currentObject = obj; - ObjectStreamClass[] hierarchy = - ObjectStreamClass.getObjectStreamClasses (clazz); - - boolean has_write; - for (int i=0; i < hierarchy.length; i++) + catch (IOException ioe) { - currentObjectStreamClass = hierarchy[i]; - - fieldsAlreadyWritten = false; - has_write = currentObjectStreamClass.hasWriteMethod (); - - writeFields (obj, currentObjectStreamClass.fields, - has_write); - - if (has_write) - { - drain (); - realOutput.writeByte (TC_ENDBLOCKDATA); - } + throw new StreamCorruptedException ("Exception " + ioe + " thrown while exception was being written to stream."); } - - currentObject = null; - currentObjectStreamClass = null; - currentPutField = null; - break; - } - - throw new NotSerializableException (clazz.getName ()); - } // end pseudo-loop - } - catch (IOException e) - { - realOutput.writeByte (TC_EXCEPTION); - reset (true); - - try - { - writeObject (e); + + reset (true); } - catch (IOException ioe) - { - throw new StreamCorruptedException ("Exception " + ioe + " thrown while exception was being written to stream."); - } - - reset (true); - } finally - { - isSerializing = was_serializing; + { + isSerializing = was_serializing; - if (! was_serializing) - setBlockDataMode (true); - } + setBlockDataMode (old_mode); + } } @@ -466,8 +480,8 @@ public class ObjectOutputStream extends OutputStream according to the specified protocol. There are currently two different protocols, specified by <code>PROTOCOL_VERSION_1</code> and <code>PROTOCOL_VERSION_2</code>. This implementation writes - data using <code>PROTOCOL_VERSION_1</code> by default, as is done - by the JDK 1.1. + data using <code>PROTOCOL_VERSION_2</code> by default, as is done + by the JDK 1.2. A non-portable method, <code>setDefaultProtocolVersion (int version)</code> is provided to change the default protocol @@ -528,6 +542,8 @@ public class ObjectOutputStream extends OutputStream protected void annotateClass (Class cl) throws IOException {} + protected void annotateProxyClass(Class cl) throws IOException + {} /** Allows subclasses to replace objects that are written to the @@ -702,7 +718,8 @@ public class ObjectOutputStream extends OutputStream if (blockDataCount == 0) return; - writeBlockDataHeader (blockDataCount); + if (writeDataAsBlocks) + writeBlockDataHeader (blockDataCount); realOutput.write (blockData, 0, blockDataCount); blockDataCount = 0; } @@ -713,7 +730,7 @@ public class ObjectOutputStream extends OutputStream */ public void close () throws IOException { - drain (); + flush (); realOutput.close (); } @@ -723,7 +740,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeBoolean (boolean data) throws IOException { - dataOutput.writeBoolean (data); + blockDataOutput.writeBoolean (data); } @@ -732,7 +749,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeByte (int data) throws IOException { - dataOutput.writeByte (data); + blockDataOutput.writeByte (data); } @@ -741,7 +758,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeShort (int data) throws IOException { - dataOutput.writeShort (data); + blockDataOutput.writeShort (data); } @@ -750,7 +767,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeChar (int data) throws IOException { - dataOutput.writeChar (data); + blockDataOutput.writeChar (data); } @@ -759,7 +776,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeInt (int data) throws IOException { - dataOutput.writeInt (data); + blockDataOutput.writeInt (data); } @@ -768,7 +785,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeLong (long data) throws IOException { - dataOutput.writeLong (data); + blockDataOutput.writeLong (data); } @@ -777,7 +794,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeFloat (float data) throws IOException { - dataOutput.writeFloat (data); + blockDataOutput.writeFloat (data); } @@ -786,7 +803,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeDouble (double data) throws IOException { - dataOutput.writeDouble (data); + blockDataOutput.writeDouble (data); } @@ -795,7 +812,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeBytes (String data) throws IOException { - dataOutput.writeBytes (data); + blockDataOutput.writeBytes (data); } @@ -965,6 +982,8 @@ public class ObjectOutputStream extends OutputStream { ObjectStreamField field = currentObjectStreamClass.getField (name); + if (field == null) + throw new IllegalArgumentException (); if (value != null && ! field.getType ().isAssignableFrom (value.getClass ())) throw new IllegalArgumentException (); @@ -976,11 +995,11 @@ public class ObjectOutputStream extends OutputStream // Apparently Block data is not used with PutField as per // empirical evidence against JDK 1.2. Also see Mauve test // java.io.ObjectInputOutput.Test.GetPutField. - setBlockDataMode (false); + boolean oldmode = setBlockDataMode (false); out.write (prim_field_data); for (int i = 0; i < objs.length; ++ i) out.writeObject (objs[i]); - setBlockDataMode (true); + setBlockDataMode (oldmode); } private void checkType (ObjectStreamField field, char type) @@ -1067,8 +1086,7 @@ public class ObjectOutputStream extends OutputStream { byte[] cast_array = (byte[])array; realOutput.writeInt (length); - for (int i=0; i < length; i++) - realOutput.writeByte (cast_array[i]); + realOutput.write(cast_array, 0, length); return; } if (clazz == Character.TYPE) @@ -1142,9 +1160,11 @@ public class ObjectOutputStream extends OutputStream setBlockDataMode (true); callWriteMethod (obj); setBlockDataMode (false); + realOutput.writeByte (TC_ENDBLOCKDATA); return; } + boolean oldmode = setBlockDataMode (false); String field_name; Class type; for (int i=0; i < fields.length; i++) @@ -1170,20 +1190,28 @@ public class ObjectOutputStream extends OutputStream realOutput.writeShort (getShortField (obj, field_name)); else writeObject (getObjectField (obj, field_name, - TypeSignature.getEncodingOfClass (type))); + fields[i].getTypeString ())); } + setBlockDataMode(oldmode); } // Toggles writing primitive data to block-data buffer. - private void setBlockDataMode (boolean on) + private boolean setBlockDataMode (boolean on) throws IOException { + if (on == writeDataAsBlocks) + return on; + + drain(); + boolean oldmode = writeDataAsBlocks; writeDataAsBlocks = on; if (on) dataOutput = blockDataOutput; else dataOutput = realOutput; + + return oldmode; } @@ -1355,16 +1383,22 @@ public class ObjectOutputStream extends OutputStream } } - private static native Field getField (Class klass, String name) - throws java.lang.NoSuchFieldException; - - private static native Method getMethod (Class klass, String name, Class[] args) - throws java.lang.NoSuchMethodException; - + private static Field getField (Class klass, String name) + throws java.lang.NoSuchFieldException + { + return klass.getDeclaredField(name); + } + + private static Method getMethod (Class klass, String name, Class[] args) + throws java.lang.NoSuchMethodException + { + return klass.getDeclaredMethod(name, args); + } + // this value comes from 1.2 spec, but is used in 1.1 as well private final static int BUFFER_SIZE = 1024; - private static int defaultProtocolVersion = PROTOCOL_VERSION_1; + private static int defaultProtocolVersion = PROTOCOL_VERSION_2; private DataOutputStream dataOutput; private boolean writeDataAsBlocks; @@ -1382,4 +1416,12 @@ public class ObjectOutputStream extends OutputStream private Hashtable OIDLookupTable; private int protocolVersion; private boolean useSubclassMethod; + + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary ("javaio"); + } + } } |