aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/io/ObjectOutputStream.java
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2003-02-28 11:38:56 +0000
committerMark Wielaard <mark@gcc.gnu.org>2003-02-28 11:38:56 +0000
commit4480b3dcf640e952085da75f887d7392c5afc994 (patch)
treeeb6527381e25675338e21ca7ad2996e4d91330c8 /libjava/java/io/ObjectOutputStream.java
parent28727f1fb365c5cc0d02394dd06d57a57eb0fa76 (diff)
downloadgcc-4480b3dcf640e952085da75f887d7392c5afc994.zip
gcc-4480b3dcf640e952085da75f887d7392c5afc994.tar.gz
gcc-4480b3dcf640e952085da75f887d7392c5afc994.tar.bz2
Makefile.am (nat_source_files): Remove java/io/natObjectOutputStream.cc.
* Makefile.am (nat_source_files): Remove java/io/natObjectOutputStream.cc. * Makefile.in: Regenerated. * mauve-libgcj: Don't exclude java.io.ObjectInputOutput tests. * java/io/ObjectStreamField.java (typename): New field. (ObjectStreamField(String, Class)): Initialize new field. (ObjectStreamField(String, String)): New Constructor. (getTypeCode): Use new field. (getTypeString): Use new field. * java/io/ObjectOutputStream.java (writeObject): Rethrow fatal ObjectStreamExceptions. Remember and reset old BlockDataMode. Handle reading of Proxy classes. Never drain(), just write TC_ENDBLOCKDATA. Rethrow ObjectStreamExceptions. (drain): Check writeDataAsBlocks before calling writeBlockDataHeader. (flush): Call flush(), not just drain(). (writeBoolean): Always use blockDataOutput. (writeByte): Likewise. (writeShort): Likewise. (writeChar): Likewise. (writeInt): Likewise. (writeLong): Likewise. (writeFloat): Likewise. (writeDouble): Likewise. (writeBytes): Likewise. (putfield (put(String,Object))): Throw IllegalArgumentException if field cannot be found. (putfield (write(ObjectOutput))): Remember old BlockDataMode. (writeArraySizeAndElements): Write byte[] in one go. (writeFields): Write TC_ENDBLOCKDATA when call_write_method, otherwise set BlockDataMode to false. (annotateProxyClass): New method. (defaultProtocolVersion): Now defaults to PROTOCOL_VERSION_2 (getField): No longer native. (getMethod): Likewise. (setBlockDataMode): Always drain() on switch, return old mode. (static): New static code block. * java/io/natObjectOutputStream.cc: Removed. * java/io/ObjectInputStream.java (getField): No longer native. (getMethod): Likewise. (readObject): Remember and reset old BlockDataMode. Track whether object is consumed. Handle TC_ENDBLOCKDATA, TC_PROXYCLASSDESC and TC_LONGSTRING. (defaultReadObject): Set BlockDataMode to false during readFields. (resolveClass): Create new SecurityManager if necessary. Use Class.forName() if null ClassLoader found. (read(byte[],int,int): Copy remaining bytes to data before calling readNextBlock(). (readFields): Set and reset BlockDataMode on call_read_method. Catch NoSuchFieldErrors. (setBlockDataMode): Return old mode. (static): New static code block. * java/io/natObjectInputStream.cc (getField): Removed. (getMethod): Likewise. From-SVN: r63556
Diffstat (limited to 'libjava/java/io/ObjectOutputStream.java')
-rw-r--r--libjava/java/io/ObjectOutputStream.java502
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");
+ }
+ }
}