aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/io/ObjectOutputStream.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/io/ObjectOutputStream.java')
-rw-r--r--libjava/java/io/ObjectOutputStream.java998
1 files changed, 513 insertions, 485 deletions
diff --git a/libjava/java/io/ObjectOutputStream.java b/libjava/java/io/ObjectOutputStream.java
index d7c893f1696..a051a96f3d8 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.
@@ -7,7 +7,7 @@ GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
-
+
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@@ -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
@@ -76,22 +77,22 @@ import gnu.java.lang.reflect.TypeSignature;
in a graph lost.
Example usage:
- <pre>
- Hashtable map = new Hashtable ();
- map.put ("one", new Integer (1));
- map.put ("two", new Integer (2));
+ <pre>
+ Hashtable map = new Hashtable ();
+ map.put ("one", new Integer (1));
+ map.put ("two", new Integer (2));
- ObjectOutputStream oos =
- new ObjectOutputStream (new FileOutputStream ("numbers"));
- oos.writeObject (map);
- oos.close ();
+ ObjectOutputStream oos =
+ new ObjectOutputStream (new FileOutputStream ("numbers"));
+ oos.writeObject (map);
+ oos.close ();
- ObjectInputStream ois =
- new ObjectInputStream (new FileInputStream ("numbers"));
- Hashtable newmap = (Hashtable)ois.readObject ();
+ ObjectInputStream ois =
+ new ObjectInputStream (new FileInputStream ("numbers"));
+ Hashtable newmap = (Hashtable)ois.readObject ();
- System.out.println (newmap);
- </pre>
+ System.out.println (newmap);
+ </pre>
The default serialization can be overriden in two ways.
@@ -167,232 +168,246 @@ 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;
+
+ while (true)
+ {
+ if (obj == null)
+ {
+ realOutput.writeByte (TC_NULL);
+ break;
+ }
- if ((replacementEnabled || obj instanceof Serializable)
- && ! replaceDone)
- {
- replacedObject = obj;
+ Integer handle = findHandle (obj);
+ if (handle != null)
+ {
+ realOutput.writeByte (TC_REFERENCE);
+ realOutput.writeInt (handle.intValue ());
+ break;
+ }
- if (obj instanceof Serializable)
- {
- Method m = null;
- try
+ if (obj instanceof Class)
{
- 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[] {});
+ 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;
}
- catch (NoSuchMethodException ignore)
+
+ 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;
}
- catch (IllegalAccessException ignore)
+
+ if ((replacementEnabled || obj instanceof Serializable)
+ && ! replaceDone)
{
+ 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 (InvocationTargetException ignore)
+
+ if (obj instanceof String)
{
+ realOutput.writeByte (TC_STRING);
+ assignNewHandle (obj);
+ realOutput.writeUTF ((String)obj);
+ break;
}
- }
- if (replacementEnabled)
- obj = replaceObject (obj);
+ Class clazz = obj.getClass ();
+ ObjectStreamClass osc = ObjectStreamClass.lookupForClassObject (clazz);
+ if (osc == null)
+ throw new NotSerializableException (clazz.getName ());
- replaceDone = true;
- continue;
- }
+ if (clazz.isArray ())
+ {
+ realOutput.writeByte (TC_ARRAY);
+ writeObject (osc);
+ assignNewHandle (obj);
+ writeArraySizeAndElements (obj, clazz.getComponentType ());
+ break;
+ }
- if (obj instanceof String)
- {
- realOutput.writeByte (TC_STRING);
- assignNewHandle (obj);
- realOutput.writeUTF ((String)obj);
- break;
- }
+ realOutput.writeByte (TC_OBJECT);
+ writeObject (osc);
- Class clazz = obj.getClass ();
- ObjectStreamClass osc = ObjectStreamClass.lookup (clazz);
- if (osc == null)
- throw new NotSerializableException (clazz.getName ());
+ if (replaceDone)
+ assignNewHandle (replacedObject);
+ else
+ assignNewHandle (obj);
- if (clazz.isArray ())
- {
- realOutput.writeByte (TC_ARRAY);
- writeObject (osc);
- assignNewHandle (obj);
- writeArraySizeAndElements (obj, clazz.getComponentType ());
- break;
- }
+ if (obj instanceof Externalizable)
+ {
+ if (protocolVersion == PROTOCOL_VERSION_2)
+ setBlockDataMode (true);
- realOutput.writeByte (TC_OBJECT);
- writeObject (osc);
+ ((Externalizable)obj).writeExternal (this);
- if (replaceDone)
- assignNewHandle (replacedObject);
- else
- assignNewHandle (obj);
+ if (protocolVersion == PROTOCOL_VERSION_2)
+ {
+ setBlockDataMode (false);
+ realOutput.writeByte (TC_ENDBLOCKDATA);
+ }
- if (obj instanceof Externalizable)
- {
- if (protocolVersion == PROTOCOL_VERSION_2)
- setBlockDataMode (true);
+ break;
+ }
- ((Externalizable)obj).writeExternal (this);
+ if (obj instanceof Serializable)
+ {
+ currentObject = obj;
+ ObjectStreamClass[] hierarchy =
+ ObjectStreamClass.getObjectStreamClasses (clazz);
+
+ for (int i=0; i < hierarchy.length; i++)
+ {
+ currentObjectStreamClass = hierarchy[i];
+
+ fieldsAlreadyWritten = false;
+ if (currentObjectStreamClass.hasWriteMethod ())
+ {
+ setBlockDataMode (true);
+ callWriteMethod (obj, currentObjectStreamClass);
+ setBlockDataMode (false);
+ realOutput.writeByte (TC_ENDBLOCKDATA);
+ }
+ else
+ writeFields (obj, currentObjectStreamClass);
+ }
+
+ currentObject = null;
+ currentObjectStreamClass = null;
+ currentPutField = null;
+ break;
+ }
- if (protocolVersion == PROTOCOL_VERSION_2)
+ 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)
+ finally
{
- throw new StreamCorruptedException ("Exception " + ioe + " thrown while exception was being written to stream.");
+ isSerializing = was_serializing;
+ setBlockDataMode (old_mode);
}
-
- reset (true);
- }
- finally
- {
- isSerializing = was_serializing;
-
- if (! was_serializing)
- setBlockDataMode (true);
- }
}
-
/**
Writes the current objects non-transient, non-static fields from
the current class to the underlying output stream.
@@ -413,7 +428,7 @@ public class ObjectOutputStream extends OutputStream
throws IOException, NotActiveException
{
markFieldsWritten ();
- writeFields (currentObject, currentObjectStreamClass.fields, false);
+ writeFields (currentObject, currentObjectStreamClass);
}
@@ -450,12 +465,12 @@ public class ObjectOutputStream extends OutputStream
private void reset (boolean internal) throws IOException
{
if (!internal)
- {
- if (isSerializing)
- throw new IOException ("Reset called while serialization in progress");
+ {
+ if (isSerializing)
+ throw new IOException ("Reset called while serialization in progress");
- realOutput.writeByte (TC_RESET);
- }
+ realOutput.writeByte (TC_RESET);
+ }
clearHandles ();
}
@@ -466,8 +481,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 +543,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
@@ -633,12 +650,12 @@ public class ObjectOutputStream extends OutputStream
public void write (int data) throws IOException
{
if (writeDataAsBlocks)
- {
- if (blockDataCount == BUFFER_SIZE)
- drain ();
+ {
+ if (blockDataCount == BUFFER_SIZE)
+ drain ();
- blockData[ blockDataCount++ ] = (byte)data;
- }
+ blockData[ blockDataCount++ ] = (byte)data;
+ }
else
realOutput.write (data);
}
@@ -659,22 +676,22 @@ public class ObjectOutputStream extends OutputStream
public void write (byte[] b, int off, int len) throws IOException
{
if (writeDataAsBlocks)
- {
- if (len < 0)
- throw new IndexOutOfBoundsException ();
-
- if (blockDataCount + len < BUFFER_SIZE)
{
- System.arraycopy (b, off, blockData, blockDataCount, len);
- blockDataCount += len;
- }
- else
- {
- drain ();
- writeBlockDataHeader (len);
- realOutput.write (b, off, len);
+ if (len < 0)
+ throw new IndexOutOfBoundsException ();
+
+ if (blockDataCount + len < BUFFER_SIZE)
+ {
+ System.arraycopy (b, off, blockData, blockDataCount, len);
+ blockDataCount += len;
+ }
+ else
+ {
+ drain ();
+ writeBlockDataHeader (len);
+ realOutput.write (b, off, len);
+ }
}
- }
else
realOutput.write (b, off, len);
}
@@ -702,7 +719,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 +731,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void close () throws IOException
{
- drain ();
+ flush ();
realOutput.close ();
}
@@ -723,7 +741,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeBoolean (boolean data) throws IOException
{
- dataOutput.writeBoolean (data);
+ blockDataOutput.writeBoolean (data);
}
@@ -732,7 +750,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeByte (int data) throws IOException
{
- dataOutput.writeByte (data);
+ blockDataOutput.writeByte (data);
}
@@ -741,7 +759,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeShort (int data) throws IOException
{
- dataOutput.writeShort (data);
+ blockDataOutput.writeShort (data);
}
@@ -750,7 +768,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeChar (int data) throws IOException
{
- dataOutput.writeChar (data);
+ blockDataOutput.writeChar (data);
}
@@ -759,7 +777,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeInt (int data) throws IOException
{
- dataOutput.writeInt (data);
+ blockDataOutput.writeInt (data);
}
@@ -768,7 +786,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeLong (long data) throws IOException
{
- dataOutput.writeLong (data);
+ blockDataOutput.writeLong (data);
}
@@ -777,7 +795,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeFloat (float data) throws IOException
{
- dataOutput.writeFloat (data);
+ blockDataOutput.writeFloat (data);
}
@@ -786,7 +804,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeDouble (double data) throws IOException
{
- dataOutput.writeDouble (data);
+ blockDataOutput.writeDouble (data);
}
@@ -795,7 +813,7 @@ public class ObjectOutputStream extends OutputStream
*/
public void writeBytes (String data) throws IOException
{
- dataOutput.writeBytes (data);
+ blockDataOutput.writeBytes (data);
}
@@ -854,141 +872,143 @@ public class ObjectOutputStream extends OutputStream
currentPutField = new PutField ()
{
private byte[] prim_field_data
- = new byte[currentObjectStreamClass.primFieldSize];
+ = new byte[currentObjectStreamClass.primFieldSize];
private Object[] objs
- = new Object[currentObjectStreamClass.objectFieldCount];
+ = new Object[currentObjectStreamClass.objectFieldCount];
public void put (String name, boolean value)
throws IOException, IllegalArgumentException
- {
- ObjectStreamField field
- = currentObjectStreamClass.getField (name);
- checkType (field, 'Z');
- prim_field_data[field.getOffset ()] = (byte)(value ? 1 : 0);
- }
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'Z');
+ prim_field_data[field.getOffset ()] = (byte)(value ? 1 : 0);
+ }
public void put (String name, byte value)
throws IOException, IllegalArgumentException
- {
- ObjectStreamField field
- = currentObjectStreamClass.getField (name);
- checkType (field, 'B');
- prim_field_data[field.getOffset ()] = value;
- }
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'B');
+ prim_field_data[field.getOffset ()] = value;
+ }
public void put (String name, char value)
throws IOException, IllegalArgumentException
- {
- ObjectStreamField field
- = currentObjectStreamClass.getField (name);
- checkType (field, 'C');
- int off = field.getOffset ();
- prim_field_data[off++] = (byte)(value >>> 8);
- prim_field_data[off] = (byte)value;
- }
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'C');
+ int off = field.getOffset ();
+ prim_field_data[off++] = (byte)(value >>> 8);
+ prim_field_data[off] = (byte)value;
+ }
public void put (String name, double value)
throws IOException, IllegalArgumentException
- {
- ObjectStreamField field
- = currentObjectStreamClass.getField (name);
- checkType (field, 'D');
- int off = field.getOffset ();
- long l_value = Double.doubleToLongBits (value);
- prim_field_data[off++] = (byte)(l_value >>> 52);
- prim_field_data[off++] = (byte)(l_value >>> 48);
- prim_field_data[off++] = (byte)(l_value >>> 40);
- prim_field_data[off++] = (byte)(l_value >>> 32);
- prim_field_data[off++] = (byte)(l_value >>> 24);
- prim_field_data[off++] = (byte)(l_value >>> 16);
- prim_field_data[off++] = (byte)(l_value >>> 8);
- prim_field_data[off] = (byte)l_value;
- }
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'D');
+ int off = field.getOffset ();
+ long l_value = Double.doubleToLongBits (value);
+ prim_field_data[off++] = (byte)(l_value >>> 52);
+ prim_field_data[off++] = (byte)(l_value >>> 48);
+ prim_field_data[off++] = (byte)(l_value >>> 40);
+ prim_field_data[off++] = (byte)(l_value >>> 32);
+ prim_field_data[off++] = (byte)(l_value >>> 24);
+ prim_field_data[off++] = (byte)(l_value >>> 16);
+ prim_field_data[off++] = (byte)(l_value >>> 8);
+ prim_field_data[off] = (byte)l_value;
+ }
public void put (String name, float value)
throws IOException, IllegalArgumentException
- {
- ObjectStreamField field
- = currentObjectStreamClass.getField (name);
- checkType (field, 'F');
- int off = field.getOffset ();
- int i_value = Float.floatToIntBits (value);
- prim_field_data[off++] = (byte)(i_value >>> 24);
- prim_field_data[off++] = (byte)(i_value >>> 16);
- prim_field_data[off++] = (byte)(i_value >>> 8);
- prim_field_data[off] = (byte)i_value;
- }
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'F');
+ int off = field.getOffset ();
+ int i_value = Float.floatToIntBits (value);
+ prim_field_data[off++] = (byte)(i_value >>> 24);
+ prim_field_data[off++] = (byte)(i_value >>> 16);
+ prim_field_data[off++] = (byte)(i_value >>> 8);
+ prim_field_data[off] = (byte)i_value;
+ }
public void put (String name, int value)
throws IOException, IllegalArgumentException
- {
- ObjectStreamField field
- = currentObjectStreamClass.getField (name);
- checkType (field, 'I');
- int off = field.getOffset ();
- prim_field_data[off++] = (byte)(value >>> 24);
- prim_field_data[off++] = (byte)(value >>> 16);
- prim_field_data[off++] = (byte)(value >>> 8);
- prim_field_data[off] = (byte)value;
- }
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'I');
+ int off = field.getOffset ();
+ prim_field_data[off++] = (byte)(value >>> 24);
+ prim_field_data[off++] = (byte)(value >>> 16);
+ prim_field_data[off++] = (byte)(value >>> 8);
+ prim_field_data[off] = (byte)value;
+ }
public void put (String name, long value)
throws IOException, IllegalArgumentException
- {
- ObjectStreamField field
- = currentObjectStreamClass.getField (name);
- checkType (field, 'J');
- int off = field.getOffset ();
- prim_field_data[off++] = (byte)(value >>> 52);
- prim_field_data[off++] = (byte)(value >>> 48);
- prim_field_data[off++] = (byte)(value >>> 40);
- prim_field_data[off++] = (byte)(value >>> 32);
- prim_field_data[off++] = (byte)(value >>> 24);
- prim_field_data[off++] = (byte)(value >>> 16);
- prim_field_data[off++] = (byte)(value >>> 8);
- prim_field_data[off] = (byte)value;
- }
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'J');
+ int off = field.getOffset ();
+ prim_field_data[off++] = (byte)(value >>> 52);
+ prim_field_data[off++] = (byte)(value >>> 48);
+ prim_field_data[off++] = (byte)(value >>> 40);
+ prim_field_data[off++] = (byte)(value >>> 32);
+ prim_field_data[off++] = (byte)(value >>> 24);
+ prim_field_data[off++] = (byte)(value >>> 16);
+ prim_field_data[off++] = (byte)(value >>> 8);
+ prim_field_data[off] = (byte)value;
+ }
public void put (String name, short value)
throws IOException, IllegalArgumentException
- {
- ObjectStreamField field
- = currentObjectStreamClass.getField (name);
- checkType (field, 'S');
- int off = field.getOffset ();
- prim_field_data[off++] = (byte)(value >>> 8);
- prim_field_data[off] = (byte)value;
- }
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ checkType (field, 'S');
+ int off = field.getOffset ();
+ prim_field_data[off++] = (byte)(value >>> 8);
+ prim_field_data[off] = (byte)value;
+ }
public void put (String name, Object value)
throws IOException, IllegalArgumentException
- {
- ObjectStreamField field
- = currentObjectStreamClass.getField (name);
- if (value != null &&
- ! field.getType ().isAssignableFrom (value.getClass ()))
- throw new IllegalArgumentException ();
- objs[field.getOffset ()] = value;
- }
+ {
+ ObjectStreamField field
+ = currentObjectStreamClass.getField (name);
+ if (field == null)
+ throw new IllegalArgumentException ();
+ if (value != null &&
+ ! field.getType ().isAssignableFrom (value.getClass ()))
+ throw new IllegalArgumentException ();
+ objs[field.getOffset ()] = value;
+ }
public void write (ObjectOutput out) throws IOException
- {
- // 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);
- out.write (prim_field_data);
- for (int i = 0; i < objs.length; ++ i)
- out.writeObject (objs[i]);
- setBlockDataMode (true);
- }
+ {
+ // 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.
+ boolean oldmode = setBlockDataMode (false);
+ out.write (prim_field_data);
+ for (int i = 0; i < objs.length; ++ i)
+ out.writeObject (objs[i]);
+ setBlockDataMode (oldmode);
+ }
private void checkType (ObjectStreamField field, char type)
throws IllegalArgumentException
- {
- if (TypeSignature.getEncodingOfClass (field.getType ()).charAt (0) != type)
- throw new IllegalArgumentException ();
- }
+ {
+ if (TypeSignature.getEncodingOfClass (field.getType ()).charAt (0) != type)
+ throw new IllegalArgumentException ();
+ }
};
// end PutFieldImpl
@@ -1010,15 +1030,15 @@ public class ObjectOutputStream extends OutputStream
private void writeBlockDataHeader (int size) throws IOException
{
if (size < 256)
- {
- realOutput.writeByte (TC_BLOCKDATA);
- realOutput.write (size);
- }
+ {
+ realOutput.writeByte (TC_BLOCKDATA);
+ realOutput.write (size);
+ }
else
- {
- realOutput.writeByte (TC_BLOCKDATALONG);
- realOutput.writeInt (size);
- }
+ {
+ realOutput.writeByte (TC_BLOCKDATALONG);
+ realOutput.writeInt (size);
+ }
}
@@ -1054,142 +1074,141 @@ public class ObjectOutputStream extends OutputStream
int length = Array.getLength (array);
if (clazz.isPrimitive ())
- {
- if (clazz == Boolean.TYPE)
- {
- boolean[] cast_array = (boolean[])array;
- realOutput.writeInt (length);
- for (int i=0; i < length; i++)
- realOutput.writeBoolean (cast_array[i]);
- return;
- }
- if (clazz == Byte.TYPE)
- {
- byte[] cast_array = (byte[])array;
- realOutput.writeInt (length);
- for (int i=0; i < length; i++)
- realOutput.writeByte (cast_array[i]);
- return;
- }
- if (clazz == Character.TYPE)
- {
- char[] cast_array = (char[])array;
- realOutput.writeInt (length);
- for (int i=0; i < length; i++)
- realOutput.writeChar (cast_array[i]);
- return;
- }
- if (clazz == Double.TYPE)
- {
- double[] cast_array = (double[])array;
- realOutput.writeInt (length);
- for (int i=0; i < length; i++)
- realOutput.writeDouble (cast_array[i]);
- return;
- }
- if (clazz == Float.TYPE)
- {
- float[] cast_array = (float[])array;
- realOutput.writeInt (length);
- for (int i=0; i < length; i++)
- realOutput.writeFloat (cast_array[i]);
- return;
- }
- if (clazz == Integer.TYPE)
- {
- int[] cast_array = (int[])array;
- realOutput.writeInt (length);
- for (int i=0; i < length; i++)
- realOutput.writeInt (cast_array[i]);
- return;
- }
- if (clazz == Long.TYPE)
{
- long[] cast_array = (long[])array;
- realOutput.writeInt (length);
- for (int i=0; i < length; i++)
- realOutput.writeLong (cast_array[i]);
- return;
+ if (clazz == Boolean.TYPE)
+ {
+ boolean[] cast_array = (boolean[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeBoolean (cast_array[i]);
+ return;
+ }
+ if (clazz == Byte.TYPE)
+ {
+ byte[] cast_array = (byte[])array;
+ realOutput.writeInt (length);
+ realOutput.write(cast_array, 0, length);
+ return;
+ }
+ if (clazz == Character.TYPE)
+ {
+ char[] cast_array = (char[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeChar (cast_array[i]);
+ return;
+ }
+ if (clazz == Double.TYPE)
+ {
+ double[] cast_array = (double[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeDouble (cast_array[i]);
+ return;
+ }
+ if (clazz == Float.TYPE)
+ {
+ float[] cast_array = (float[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeFloat (cast_array[i]);
+ return;
+ }
+ if (clazz == Integer.TYPE)
+ {
+ int[] cast_array = (int[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeInt (cast_array[i]);
+ return;
+ }
+ if (clazz == Long.TYPE)
+ {
+ long[] cast_array = (long[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeLong (cast_array[i]);
+ return;
+ }
+ if (clazz == Short.TYPE)
+ {
+ short[] cast_array = (short[])array;
+ realOutput.writeInt (length);
+ for (int i=0; i < length; i++)
+ realOutput.writeShort (cast_array[i]);
+ return;
+ }
}
- if (clazz == Short.TYPE)
+ else
{
- short[] cast_array = (short[])array;
+ Object[] cast_array = (Object[])array;
realOutput.writeInt (length);
for (int i=0; i < length; i++)
- realOutput.writeShort (cast_array[i]);
- return;
+ writeObject (cast_array[i]);
}
- }
- else
- {
- Object[] cast_array = (Object[])array;
- realOutput.writeInt (length);
- for (int i=0; i < length; i++)
- writeObject (cast_array[i]);
- }
}
- // 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);
- return;
- }
-
+ ObjectStreamField[] fields = osc.fields;
+ boolean oldmode = setBlockDataMode (false);
String field_name;
Class type;
for (int i=0; i < fields.length; i++)
- {
- field_name = fields[i].getName ();
- type = fields[i].getType ();
-
- if (type == Boolean.TYPE)
- realOutput.writeBoolean (getBooleanField (obj, field_name));
- else if (type == Byte.TYPE)
- realOutput.writeByte (getByteField (obj, field_name));
- else if (type == Character.TYPE)
- realOutput.writeChar (getCharField (obj, field_name));
- else if (type == Double.TYPE)
- realOutput.writeDouble (getDoubleField (obj, field_name));
- else if (type == Float.TYPE)
- realOutput.writeFloat (getFloatField (obj, field_name));
- else if (type == Integer.TYPE)
- realOutput.writeInt (getIntField (obj, field_name));
- else if (type == Long.TYPE)
- realOutput.writeLong (getLongField (obj, field_name));
- else if (type == Short.TYPE)
- realOutput.writeShort (getShortField (obj, field_name));
- else
- writeObject (getObjectField (obj, field_name,
- TypeSignature.getEncodingOfClass (type)));
- }
+ {
+ field_name = fields[i].getName ();
+ type = fields[i].getType ();
+
+ if (type == Boolean.TYPE)
+ realOutput.writeBoolean (getBooleanField (obj, osc.forClass(), field_name));
+ else if (type == Byte.TYPE)
+ realOutput.writeByte (getByteField (obj, osc.forClass(), field_name));
+ else if (type == Character.TYPE)
+ realOutput.writeChar (getCharField (obj, osc.forClass(), field_name));
+ else if (type == Double.TYPE)
+ realOutput.writeDouble (getDoubleField (obj, osc.forClass(), field_name));
+ else if (type == Float.TYPE)
+ realOutput.writeFloat (getFloatField (obj, osc.forClass(), field_name));
+ else if (type == Integer.TYPE)
+ realOutput.writeInt (getIntField (obj, osc.forClass(), field_name));
+ else if (type == Long.TYPE)
+ realOutput.writeLong (getLongField (obj, osc.forClass(), field_name));
+ else if (type == Short.TYPE)
+ realOutput.writeShort (getShortField (obj, osc.forClass(), field_name));
+ else
+ writeObject (getObjectField (obj, osc.forClass(), field_name,
+ 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;
}
- 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};
@@ -1218,11 +1237,11 @@ public class ObjectOutputStream extends OutputStream
}
}
- private boolean getBooleanField (Object obj, String field_name) throws IOException
+ 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;
@@ -1233,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;
@@ -1248,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;
@@ -1263,11 +1280,11 @@ public class ObjectOutputStream extends OutputStream
}
}
- private double getDoubleField (Object obj, String field_name) throws IOException
+ 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;
@@ -1278,11 +1295,11 @@ public class ObjectOutputStream extends OutputStream
}
}
- private float getFloatField (Object obj, String field_name) throws IOException
+ 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;
@@ -1293,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;
@@ -1308,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;
@@ -1323,11 +1338,11 @@ public class ObjectOutputStream extends OutputStream
}
}
- private short getShortField (Object obj, String field_name) throws IOException
+ 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;
@@ -1338,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
@@ -1355,16 +1369,22 @@ public class ObjectOutputStream extends OutputStream
}
}
- private static native Field getField (Class klass, String name)
- throws java.lang.NoSuchFieldException;
+ private static Field getField (Class klass, String name)
+ throws java.lang.NoSuchFieldException
+ {
+ return klass.getDeclaredField(name);
+ }
- private static native Method getMethod (Class klass, String name, Class[] args)
- throws java.lang.NoSuchMethodException;
+ 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 +1402,12 @@ public class ObjectOutputStream extends OutputStream
private Hashtable OIDLookupTable;
private int protocolVersion;
private boolean useSubclassMethod;
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary ("javaio");
+ }
+ }
}