diff options
Diffstat (limited to 'libjava/java/io/ObjectOutputStream.java')
-rw-r--r-- | libjava/java/io/ObjectOutputStream.java | 963 |
1 files changed, 503 insertions, 460 deletions
diff --git a/libjava/java/io/ObjectOutputStream.java b/libjava/java/io/ObjectOutputStream.java index d7c893f1696..69f789abbf8 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,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; + + 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; + } + + 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; + } - ((Externalizable)obj).writeExternal (this); + 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); - if (protocolVersion == PROTOCOL_VERSION_2) + 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. @@ -450,12 +461,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 +477,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 +539,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 +646,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 +672,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 +715,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 +727,7 @@ public class ObjectOutputStream extends OutputStream */ public void close () throws IOException { - drain (); + flush (); realOutput.close (); } @@ -723,7 +737,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeBoolean (boolean data) throws IOException { - dataOutput.writeBoolean (data); + blockDataOutput.writeBoolean (data); } @@ -732,7 +746,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeByte (int data) throws IOException { - dataOutput.writeByte (data); + blockDataOutput.writeByte (data); } @@ -741,7 +755,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeShort (int data) throws IOException { - dataOutput.writeShort (data); + blockDataOutput.writeShort (data); } @@ -750,7 +764,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeChar (int data) throws IOException { - dataOutput.writeChar (data); + blockDataOutput.writeChar (data); } @@ -759,7 +773,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeInt (int data) throws IOException { - dataOutput.writeInt (data); + blockDataOutput.writeInt (data); } @@ -768,7 +782,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeLong (long data) throws IOException { - dataOutput.writeLong (data); + blockDataOutput.writeLong (data); } @@ -777,7 +791,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeFloat (float data) throws IOException { - dataOutput.writeFloat (data); + blockDataOutput.writeFloat (data); } @@ -786,7 +800,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeDouble (double data) throws IOException { - dataOutput.writeDouble (data); + blockDataOutput.writeDouble (data); } @@ -795,7 +809,7 @@ public class ObjectOutputStream extends OutputStream */ public void writeBytes (String data) throws IOException { - dataOutput.writeBytes (data); + blockDataOutput.writeBytes (data); } @@ -854,141 +868,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 +1026,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,79 +1070,78 @@ 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]); - } } @@ -1138,52 +1153,62 @@ public class ObjectOutputStream extends OutputStream boolean call_write_method) throws IOException { if (call_write_method) - { - setBlockDataMode (true); - callWriteMethod (obj); - setBlockDataMode (false); - return; - } + { + 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++) - { - 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, 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, + 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; } @@ -1218,7 +1243,8 @@ public class ObjectOutputStream extends OutputStream } } - private boolean getBooleanField (Object obj, String field_name) throws IOException + private boolean getBooleanField (Object obj, String field_name) + throws IOException { try { @@ -1263,7 +1289,8 @@ public class ObjectOutputStream extends OutputStream } } - private double getDoubleField (Object obj, String field_name) throws IOException + private double getDoubleField (Object obj, String field_name) + throws IOException { try { @@ -1278,7 +1305,8 @@ public class ObjectOutputStream extends OutputStream } } - private float getFloatField (Object obj, String field_name) throws IOException + private float getFloatField (Object obj, String field_name) + throws IOException { try { @@ -1323,7 +1351,8 @@ public class ObjectOutputStream extends OutputStream } } - private short getShortField (Object obj, String field_name) throws IOException + private short getShortField (Object obj, String field_name) + throws IOException { try { @@ -1355,16 +1384,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 +1417,12 @@ public class ObjectOutputStream extends OutputStream private Hashtable OIDLookupTable; private int protocolVersion; private boolean useSubclassMethod; + + static + { + if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary ("javaio"); + } + } } |