X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=libjava%2Fjava%2Fio%2FObjectOutputStream.java;fp=libjava%2Fjava%2Fio%2FObjectOutputStream.java;h=0000000000000000000000000000000000000000;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=d7c893f1696e3718d3d3988ccdef22988563a540;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/libjava/java/io/ObjectOutputStream.java b/libjava/java/io/ObjectOutputStream.java deleted file mode 100644 index d7c893f1..00000000 --- a/libjava/java/io/ObjectOutputStream.java +++ /dev/null @@ -1,1385 +0,0 @@ -/* ObjectOutputStream.java -- Class used to write serialized objects - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -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 -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.io; - -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; -import java.util.Hashtable; - -import gnu.java.io.ObjectIdentityWrapper; -import gnu.java.lang.reflect.TypeSignature; - -/** - An ObjectOutputStream can be used to write objects - as well as primitive data in a platform-independent manner to an - OutputStream. - - The data produced by an ObjectOutputStream can be read - and reconstituted by an ObjectInputStream. - - writeObject (Object) is used to write Objects, the - write<type> methods are used to write primitive - data (as in DataOutputStream). Strings can be written - as objects or as primitive data. - - Not all objects can be written out using an - ObjectOutputStream. Only those objects that are an - instance of java.io.Serializable can be written. - - Using default serialization, information about the class of an - object is written, all of the non-transient, non-static fields of - the object are written, if any of these fields are objects, they are - written out in the same manner. - - An object is only written out the first time it is encountered. If - the object is encountered later, a reference to it is written to - the underlying stream. Thus writing circular object graphs - does not present a problem, nor are relationships between objects - in a graph lost. - - Example usage: -
-     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 ();
-
-     ObjectInputStream ois =
-       new ObjectInputStream (new FileInputStream ("numbers"));
-     Hashtable newmap = (Hashtable)ois.readObject ();
-
-     System.out.println (newmap);
-     
- - The default serialization can be overriden in two ways. - - By defining a method private void - writeObject (ObjectOutputStream), a class can dictate exactly - how information about itself is written. - defaultWriteObject () may be called from this method to - carry out default serialization. This method is not - responsible for dealing with fields of super-classes or subclasses. - - By implementing java.io.Externalizable. This gives - the class complete control over the way it is written to the - stream. If this approach is used the burden of writing superclass - and subclass data is transfered to the class implementing - java.io.Externalizable. - - @see java.io.DataOutputStream - @see java.io.Externalizable - @see java.io.ObjectInputStream - @see java.io.Serializable - @see XXX: java serialization spec -*/ -public class ObjectOutputStream extends OutputStream - implements ObjectOutput, ObjectStreamConstants -{ - /** - Creates a new ObjectOutputStream that will do all of - its writing onto out. This method also initializes - the stream by writing the header information (stream magic number - and stream version). - - @exception IOException Writing stream header to underlying - stream cannot be completed. - - @see writeStreamHeader () - */ - public ObjectOutputStream (OutputStream out) throws IOException - { - realOutput = new DataOutputStream (out); - blockData = new byte[ BUFFER_SIZE ]; - blockDataCount = 0; - blockDataOutput = new DataOutputStream (this); - setBlockDataMode (true); - replacementEnabled = false; - isSerializing = false; - nextOID = baseWireHandle; - OIDLookupTable = new Hashtable (); - protocolVersion = defaultProtocolVersion; - useSubclassMethod = false; - writeStreamHeader (); - } - - - /** - Writes a representation of obj to the underlying - output stream by writing out information about its class, then - writing out each of the objects non-transient, non-static - fields. If any of these fields are other objects, - they are written out in the same manner. - - This method can be overriden by a class by implementing - private void writeObject (ObjectOutputStream). - - If an exception is thrown from this method, the stream is left in - an undefined state. - - @exception NotSerializableException An attempt was made to - serialize an Object that is not serializable. - - @exception IOException Exception from underlying - OutputStream. - */ - public final void writeObject (Object obj) throws IOException - { - if (useSubclassMethod) - { - writeObjectOverride (obj); - return; - } - - boolean was_serializing = isSerializing; - - if (! was_serializing) - 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; - } - - - Object replacedObject = null; - - 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; - } - - 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) - { - setBlockDataMode (false); - drain (); - } - - 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); - - if (has_write) - { - drain (); - realOutput.writeByte (TC_ENDBLOCKDATA); - } - } - - 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); - } - catch (IOException ioe) - { - throw new StreamCorruptedException ("Exception " + ioe + " thrown while exception was being written to stream."); - } - - 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. - - This method is intended to be called from within a object's - private void writeObject (ObjectOutputStream) - method. - - @exception NotActiveException This method was called from a - context other than from the current object's and current class's - private void writeObject (ObjectOutputStream) - method. - - @exception IOException Exception from underlying - OutputStream. - */ - public void defaultWriteObject () - throws IOException, NotActiveException - { - markFieldsWritten (); - writeFields (currentObject, currentObjectStreamClass.fields, false); - } - - - private void markFieldsWritten () throws IOException - { - if (currentObject == null || currentObjectStreamClass == null) - throw new NotActiveException ("defaultWriteObject called by non-active class and/or object"); - - if (fieldsAlreadyWritten) - throw new IOException ("Only one of putFields and defaultWriteObject may be called, and it may only be called once"); - - fieldsAlreadyWritten = true; - } - - - /** - Resets stream to state equivalent to the state just after it was - constructed. - - Causes all objects previously written to the stream to be - forgotten. A notification of this reset is also written to the - underlying stream. - - @exception IOException Exception from underlying - OutputStream or reset called while serialization is - in progress. - */ - public void reset () throws IOException - { - reset (false); - } - - - private void reset (boolean internal) throws IOException - { - if (!internal) - { - if (isSerializing) - throw new IOException ("Reset called while serialization in progress"); - - realOutput.writeByte (TC_RESET); - } - - clearHandles (); - } - - - /** - Informs this ObjectOutputStream to write data - according to the specified protocol. There are currently two - different protocols, specified by PROTOCOL_VERSION_1 - and PROTOCOL_VERSION_2. This implementation writes - data using PROTOCOL_VERSION_1 by default, as is done - by the JDK 1.1. - - A non-portable method, setDefaultProtocolVersion (int - version) is provided to change the default protocol - version. - - For an explination of the differences beween the two protocols - see XXX: the Java ObjectSerialization Specification. - - @exception IOException if version is not a valid - protocol - - @see setDefaultProtocolVersion (int) - */ - public void useProtocolVersion (int version) throws IOException - { - if (version != PROTOCOL_VERSION_1 && version != PROTOCOL_VERSION_2) - throw new IOException ("Invalid protocol version requested."); - - protocolVersion = version; - } - - - /** - GNU $classpath specific - - Changes the default stream protocol used by all - ObjectOutputStreams. There are currently two - different protocols, specified by PROTOCOL_VERSION_1 - and PROTOCOL_VERSION_2. The default default is - PROTOCOL_VERSION_1. - - @exception IOException if version is not a valid - protocol - - @see useProtocolVersion (int) - */ - public static void setDefaultProtocolVersion (int version) - throws IOException - { - if (version != PROTOCOL_VERSION_1 && version != PROTOCOL_VERSION_2) - throw new IOException ("Invalid protocol version requested."); - - defaultProtocolVersion = version; - } - - - /** - An empty hook that allows subclasses to write extra information - about classes to the stream. This method is called the first - time each class is seen, and after all of the standard - information about the class has been written. - - @exception IOException Exception from underlying - OutputStream. - - @see java.io.ObjectInputStream#resolveClass (java.io.ObjectStreamClass) - */ - protected void annotateClass (Class cl) throws IOException - {} - - - /** - Allows subclasses to replace objects that are written to the - stream with other objects to be written in their place. This - method is called the first time each object is encountered - (modulo reseting of the stream). - - This method must be enabled before it will be called in the - serialization process. - - @exception IOException Exception from underlying - OutputStream. - - @see enableReplaceObject (boolean) - */ - protected Object replaceObject (Object obj) throws IOException - { - return obj; - } - - - /** - If enable is true and this object is - trusted, then replaceObject (Object) will be called - in subsequent calls to writeObject (Object). - Otherwise, replaceObject (Object) will not be called. - - @exception SecurityException This class is not trusted. - */ - protected boolean enableReplaceObject (boolean enable) - throws SecurityException - { - if (enable) - { - SecurityManager sm = System.getSecurityManager (); - if (sm != null) - sm.checkPermission (new SerializablePermission ("enableSubstitution")); - } - - boolean old_val = replacementEnabled; - replacementEnabled = enable; - return old_val; - } - - - /** - Writes stream magic and stream version information to the - underlying stream. - - @exception IOException Exception from underlying - OutputStream. - */ - protected void writeStreamHeader () throws IOException - { - realOutput.writeShort (STREAM_MAGIC); - realOutput.writeShort (STREAM_VERSION); - } - - - - /** - Protected constructor that allows subclasses to override - serialization. This constructor should be called by subclasses - that wish to override writeObject (Object). This - method does a security check NOTE: currently not - implemented, then sets a flag that informs - writeObject (Object) to call the subclasses - writeObjectOverride (Object) method. - - @see writeObjectOverride (Object) - */ - protected ObjectOutputStream () throws IOException, SecurityException - { - SecurityManager sec_man = System.getSecurityManager (); - if (sec_man != null) - sec_man.checkPermission (SUBCLASS_IMPLEMENTATION_PERMISSION); - useSubclassMethod = true; - } - - - /** - This method allows subclasses to override the default - serialization mechanism provided by - ObjectOutputStream. To make this method be used for - writing objects, subclasses must invoke the 0-argument - constructor on this class from there constructor. - - @see ObjectOutputStream () - - @exception NotActiveException Subclass has arranged for this - method to be called, but did not implement this method. - */ - protected void writeObjectOverride (Object obj) throws NotActiveException, - IOException - { - throw new NotActiveException ("Subclass of ObjectOutputStream must implement writeObjectOverride"); - } - - - /** - @see java.io.DataOutputStream#write (int) - */ - public void write (int data) throws IOException - { - if (writeDataAsBlocks) - { - if (blockDataCount == BUFFER_SIZE) - drain (); - - blockData[ blockDataCount++ ] = (byte)data; - } - else - realOutput.write (data); - } - - - /** - @see java.io.DataOutputStream#write (byte[]) - */ - public void write (byte[] b) throws IOException - { - write (b, 0, b.length); - } - - - /** - @see java.io.DataOutputStream#write (byte[],int,int) - */ - 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); - } - } - else - realOutput.write (b, off, len); - } - - - /** - @see java.io.DataOutputStream#flush () - */ - public void flush () throws IOException - { - drain (); - realOutput.flush (); - } - - - /** - Causes the block-data buffer to be written to the underlying - stream, but does not flush underlying stream. - - @exception IOException Exception from underlying - OutputStream. - */ - protected void drain () throws IOException - { - if (blockDataCount == 0) - return; - - writeBlockDataHeader (blockDataCount); - realOutput.write (blockData, 0, blockDataCount); - blockDataCount = 0; - } - - - /** - @see java.io.DataOutputStream#close () - */ - public void close () throws IOException - { - drain (); - realOutput.close (); - } - - - /** - @see java.io.DataOutputStream#writeBoolean (boolean) - */ - public void writeBoolean (boolean data) throws IOException - { - dataOutput.writeBoolean (data); - } - - - /** - @see java.io.DataOutputStream#writeByte (int) - */ - public void writeByte (int data) throws IOException - { - dataOutput.writeByte (data); - } - - - /** - @see java.io.DataOutputStream#writeShort (int) - */ - public void writeShort (int data) throws IOException - { - dataOutput.writeShort (data); - } - - - /** - @see java.io.DataOutputStream#writeChar (int) - */ - public void writeChar (int data) throws IOException - { - dataOutput.writeChar (data); - } - - - /** - @see java.io.DataOutputStream#writeInt (int) - */ - public void writeInt (int data) throws IOException - { - dataOutput.writeInt (data); - } - - - /** - @see java.io.DataOutputStream#writeLong (long) - */ - public void writeLong (long data) throws IOException - { - dataOutput.writeLong (data); - } - - - /** - @see java.io.DataOutputStream#writeFloat (float) - */ - public void writeFloat (float data) throws IOException - { - dataOutput.writeFloat (data); - } - - - /** - @see java.io.DataOutputStream#writeDouble (double) - */ - public void writeDouble (double data) throws IOException - { - dataOutput.writeDouble (data); - } - - - /** - @see java.io.DataOutputStream#writeBytes (java.lang.String) - */ - public void writeBytes (String data) throws IOException - { - dataOutput.writeBytes (data); - } - - - /** - @see java.io.DataOutputStream#writeChars (java.lang.String) - */ - public void writeChars (String data) throws IOException - { - dataOutput.writeChars (data); - } - - - /** - @see java.io.DataOutputStream#writeUTF (java.lang.String) - */ - public void writeUTF (String data) throws IOException - { - dataOutput.writeUTF (data); - } - - - /** - This class allows a class to specify exactly which fields should - be written, and what values should be written for these fields. - - XXX: finish up comments - */ - public static abstract class PutField - { - public abstract void put (String name, boolean value) - throws IOException, IllegalArgumentException; - public abstract void put (String name, byte value) - throws IOException, IllegalArgumentException; - public abstract void put (String name, char value) - throws IOException, IllegalArgumentException; - public abstract void put (String name, double value) - throws IOException, IllegalArgumentException; - public abstract void put (String name, float value) - throws IOException, IllegalArgumentException; - public abstract void put (String name, int value) - throws IOException, IllegalArgumentException; - public abstract void put (String name, long value) - throws IOException, IllegalArgumentException; - public abstract void put (String name, short value) - throws IOException, IllegalArgumentException; - public abstract void put (String name, Object value) - throws IOException, IllegalArgumentException; - public abstract void write (ObjectOutput out) throws IOException; - } - - - public PutField putFields () throws IOException - { - markFieldsWritten (); - - currentPutField = new PutField () - { - private byte[] prim_field_data - = new byte[currentObjectStreamClass.primFieldSize]; - private Object[] objs - = 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); - } - - public void put (String name, byte value) - throws IOException, IllegalArgumentException - { - 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; - } - - 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; - } - - 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; - } - - 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; - } - - 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; - } - - 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; - } - - 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; - } - - 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); - } - - private void checkType (ObjectStreamField field, char type) - throws IllegalArgumentException - { - if (TypeSignature.getEncodingOfClass (field.getType ()).charAt (0) != type) - throw new IllegalArgumentException (); - } - }; - // end PutFieldImpl - - return currentPutField; - } - - - public void writeFields () throws IOException - { - if (currentPutField == null) - throw new NotActiveException ("writeFields can only be called after putFields has been called"); - - currentPutField.write (this); - } - - - // write out the block-data buffer, picking the correct header - // depending on the size of the buffer - private void writeBlockDataHeader (int size) throws IOException - { - if (size < 256) - { - realOutput.writeByte (TC_BLOCKDATA); - realOutput.write (size); - } - else - { - realOutput.writeByte (TC_BLOCKDATALONG); - realOutput.writeInt (size); - } - } - - - // lookup the handle for OBJ, return null if OBJ doesn't have a - // handle yet - private Integer findHandle (Object obj) - { - return (Integer)OIDLookupTable.get (new ObjectIdentityWrapper (obj)); - } - - - // assigns the next availible handle to OBJ - private int assignNewHandle (Object obj) - { - OIDLookupTable.put (new ObjectIdentityWrapper (obj), - new Integer (nextOID)); - return nextOID++; - } - - - // resets mapping from objects to handles - private void clearHandles () - { - nextOID = baseWireHandle; - OIDLookupTable.clear (); - } - - - // write out array size followed by each element of the array - private void writeArraySizeAndElements (Object array, Class clazz) - throws IOException - { - 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 == Short.TYPE) - { - short[] cast_array = (short[])array; - realOutput.writeInt (length); - for (int i=0; i < length; i++) - realOutput.writeShort (cast_array[i]); - return; - } - } - 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 - { - if (call_write_method) - { - setBlockDataMode (true); - callWriteMethod (obj); - setBlockDataMode (false); - return; - } - - 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))); - } - } - - - // Toggles writing primitive data to block-data buffer. - private void setBlockDataMode (boolean on) - { - writeDataAsBlocks = on; - - if (on) - dataOutput = blockDataOutput; - else - dataOutput = realOutput; - } - - - private void callWriteMethod (Object obj) throws IOException - { - Class klass = obj.getClass (); - try - { - Class classArgs[] = {ObjectOutputStream.class}; - Method m = getMethod (klass, "writeObject", classArgs); - if (m == null) - return; - Object args[] = {this}; - m.invoke (obj, args); - } - catch (InvocationTargetException x) - { - /* Rethrow if possible. */ - Throwable exception = x.getTargetException(); - if (exception instanceof RuntimeException) - throw (RuntimeException) exception; - if (exception instanceof IOException) - throw (IOException) exception; - - throw new IOException ("Exception thrown from writeObject() on " + - klass + ": " + exception.getClass().getName()); - } - catch (Exception x) - { - throw new IOException ("Failure invoking writeObject() on " + - klass + ": " + x.getClass().getName()); - } - } - - private boolean getBooleanField (Object obj, String field_name) throws IOException - { - try - { - Class klass = obj.getClass (); - Field f = getField (klass, field_name); - boolean b = f.getBoolean (obj); - return b; - } - catch (Exception _) - { - throw new IOException (); - } - } - - private byte getByteField (Object obj, String field_name) throws IOException - { - try - { - Class klass = obj.getClass (); - Field f = getField (klass, field_name); - byte b = f.getByte (obj); - return b; - } - catch (Exception _) - { - throw new IOException (); - } - } - - private char getCharField (Object obj, String field_name) throws IOException - { - try - { - Class klass = obj.getClass (); - Field f = getField (klass, field_name); - char b = f.getChar (obj); - return b; - } - catch (Exception _) - { - throw new IOException (); - } - } - - private double getDoubleField (Object obj, String field_name) throws IOException - { - try - { - Class klass = obj.getClass (); - Field f = getField (klass, field_name); - double b = f.getDouble (obj); - return b; - } - catch (Exception _) - { - throw new IOException (); - } - } - - private float getFloatField (Object obj, String field_name) throws IOException - { - try - { - Class klass = obj.getClass (); - Field f = getField (klass, field_name); - float b = f.getFloat (obj); - return b; - } - catch (Exception _) - { - throw new IOException (); - } - } - - private int getIntField (Object obj, String field_name) throws IOException - { - try - { - Class klass = obj.getClass (); - Field f = getField (klass, field_name); - int b = f.getInt (obj); - return b; - } - catch (Exception _) - { - throw new IOException (); - } - } - - private long getLongField (Object obj, String field_name) throws IOException - { - try - { - Class klass = obj.getClass (); - Field f = getField (klass, field_name); - long b = f.getLong (obj); - return b; - } - catch (Exception _) - { - throw new IOException (); - } - } - - private short getShortField (Object obj, String field_name) throws IOException - { - try - { - Class klass = obj.getClass (); - Field f = getField (klass, field_name); - short b = f.getShort (obj); - return b; - } - catch (Exception _) - { - throw new IOException (); - } - } - - private Object getObjectField (Object obj, 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 - return o; - } - catch (Exception _) - { - throw new IOException (); - } - } - - 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; - - // 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 DataOutputStream dataOutput; - private boolean writeDataAsBlocks; - private DataOutputStream realOutput; - private DataOutputStream blockDataOutput; - private byte[] blockData; - private int blockDataCount; - private Object currentObject; - private ObjectStreamClass currentObjectStreamClass; - private PutField currentPutField; - private boolean fieldsAlreadyWritten; - private boolean replacementEnabled; - private boolean isSerializing; - private int nextOID; - private Hashtable OIDLookupTable; - private int protocolVersion; - private boolean useSubclassMethod; -}