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.java1335
1 files changed, 0 insertions, 1335 deletions
diff --git a/libjava/java/io/ObjectOutputStream.java b/libjava/java/io/ObjectOutputStream.java
deleted file mode 100644
index 23bcce49d76..00000000000
--- a/libjava/java/io/ObjectOutputStream.java
+++ /dev/null
@@ -1,1335 +0,0 @@
-/* ObjectOutputStream.java -- Class used to write serialized objects
- Copyright (C) 1998, 1999, 2000 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.
-
-As a special exception, if you link this library with other files to
-produce an executable, this library does not by itself cause the
-resulting executable to be covered by the GNU General Public License.
-This exception does not however invalidate any other reasons why the
-executable file might be covered by the GNU General Public License. */
-
-
-package java.io;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Hashtable;
-
-import gnu.java.io.ObjectIdentityWrapper;
-import gnu.java.lang.reflect.TypeSignature;
-
-/**
- An <code>ObjectOutputStream</code> can be used to write objects
- as well as primitive data in a platform-independent manner to an
- <code>OutputStream</code>.
-
- The data produced by an <code>ObjectOutputStream</code> can be read
- and reconstituted by an <code>ObjectInputStream</code>.
-
- <code>writeObject (Object)</code> is used to write Objects, the
- <code>write&lt;type&gt;</code> methods are used to write primitive
- data (as in <code>DataOutputStream</code>). Strings can be written
- as objects or as primitive data.
-
- Not all objects can be written out using an
- <code>ObjectOutputStream</code>. Only those objects that are an
- instance of <code>java.io.Serializable</code> 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, the 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:
- <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 ();
-
- ObjectInputStream ois =
- new ObjectInputStream (new FileInputStream ("numbers"));
- Hashtable newmap = (Hashtable)ois.readObject ();
-
- System.out.println (newmap);
- </pre>
-
- The default serialization can be overriden in two ways.
-
- By defining a method <code>private void
- writeObject (ObjectOutputStream)</code>, a class can dictate exactly
- how information about itself is written.
- <code>defaultWriteObject ()</code> 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 <code>java.io.Externalizable</code>. 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
- <code>java.io.Externalizable</code>.
-
- @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 <code>ObjectOutputStream</code> that will do all of
- its writing onto <code>out</code>. 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 <code>obj</code> 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,
- the are written out in the same manner.
-
- This method can be overriden by a class by implementing
- <code>private void writeObject (ObjectOutputStream)</code>.
-
- 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 <code>Object</code> that is not serializable.
-
- @exception IOException Exception from underlying
- <code>OutputStream</code>.
- */
- 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 Replaceable)
- && ! replaceDone)
- {
- replacedObject = obj;
-
- if (obj instanceof Replaceable)
- obj = ((Replaceable)obj).writeReplace ();
-
- 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 ("The class "
- + clazz.getName ()
- + " is not Serializable");
-
- 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];
-
- has_write = currentObjectStreamClass.hasWriteMethod ();
- writeFields (obj, currentObjectStreamClass.fields,
- has_write);
-
- fieldsAlreadyWritten = false;
-
- if (has_write)
- {
- drain ();
- realOutput.writeByte (TC_ENDBLOCKDATA);
- }
- }
-
- currentObject = null;
- currentObjectStreamClass = null;
- currentPutField = null;
- break;
- }
-
- throw new NotSerializableException ("Instances of the class "
- + clazz.getName ()
- + " are not Serializable");
- } // 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
- <code>private void writeObject (ObjectOutputStream)</code>
- method.
-
- @exception NotActiveException This method was called from a
- context other than from the current object's and current class's
- <code>private void writeObject (ObjectOutputStream)</code>
- method.
-
- @exception IOException Exception from underlying
- <code>OutputStream</code>.
- */
- 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
- <code>OutputStream</code> 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 <code>ObjectOutputStream</code> to write data
- 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.
-
- A non-portable method, <code>setDefaultProtocolVersion (int
- version)</code> 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 <code>version</code> 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;
- }
-
-
- /**
- <em>GNU $classpath specific</em>
-
- Changes the default stream protocol used by all
- <code>ObjectOutputStream</code>s. There are currently two
- different protocols, specified by <code>PROTOCOL_VERSION_1</code>
- and <code>PROTOCOL_VERSION_2</code>. The default default is
- <code>PROTOCOL_VERSION_1</code>.
-
- @exception IOException if <code>version</code> 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
- <code>OutputStream</code>.
-
- @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
- <code>OutputStream</code>.
-
- @see enableReplaceObject (boolean)
- */
- protected Object replaceObject (Object obj) throws IOException
- {
- return obj;
- }
-
-
- /**
- If <code>enable</code> is <code>true</code> and this object is
- trusted, then <code>replaceObject (Object)</code> will be called
- in subsequent calls to <code>writeObject (Object)</code>.
- Otherwise, <code>replaceObject (Object)</code> will not be called.
-
- @exception SecurityException This class is not trusted.
- */
- protected boolean enableReplaceObject (boolean enable)
- throws SecurityException
- {
- if (enable)
- if (getClass ().getClassLoader () != null)
- throw new SecurityException ("Untrusted ObjectOutputStream subclass attempted to enable object replacement");
-
- 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
- <code>OutputStream</code>.
- */
- 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 <code>writeObject (Object)</code>. This
- method does a security check <i>NOTE: currently not
- implemented</i>, then sets a flag that informs
- <code>writeObject (Object)</code> to call the subclasses
- <code>writeObjectOverride (Object)</code> 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
- <code>ObjectOutputStream</code>. 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
- <code>OutputStream</code>.
- */
- 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, 'B');
- 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, 'B');
- 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, 'B');
- 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, 'B');
- 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, 'B');
- 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, 'B');
- 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 (! field.getType ().isAssignableFrom (value.getClass ()))
- throw new IllegalArgumentException ();
- objs[field.getOffset ()] = value;
- }
-
- public void write (ObjectOutput out) throws IOException
- {
- out.write (prim_field_data);
- for (int i = 0; i < objs.length; ++ i)
- out.writeObject (objs[i]);
- }
-
- 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
- {
- try
- {
- Class classArgs[] = {Class.forName ("java.io.ObjectOutputStream")};
- Class klass = obj.getClass ();
- Method m = getMethod (klass, "writeObject", classArgs);
- if (m == null)
- return;
- Object args[] = {this};
- m.invoke (obj, args);
- }
- catch (Exception _)
- {
- throw new IOException ();
- }
- }
-
- 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;
-}