summaryrefslogtreecommitdiff
path: root/libjava/java/io/ObjectInputStream.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/io/ObjectInputStream.java')
-rw-r--r--libjava/java/io/ObjectInputStream.java1979
1 files changed, 0 insertions, 1979 deletions
diff --git a/libjava/java/io/ObjectInputStream.java b/libjava/java/io/ObjectInputStream.java
deleted file mode 100644
index 54661a9bc53..00000000000
--- a/libjava/java/io/ObjectInputStream.java
+++ /dev/null
@@ -1,1979 +0,0 @@
-/* ObjectInputStream.java -- Class used to read serialized objects
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005
- 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., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 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 gnu.classpath.Configuration;
-import gnu.java.io.ObjectIdentityWrapper;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Proxy;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Arrays;
-import java.util.Hashtable;
-import java.util.Vector;
-
-public class ObjectInputStream extends InputStream
- implements ObjectInput, ObjectStreamConstants
-{
- /**
- * Creates a new <code>ObjectInputStream</code> that will do all of
- * its reading from <code>in</code>. This method also checks
- * the stream by reading the header information (stream magic number
- * and stream version).
- *
- * @exception IOException Reading stream header from underlying
- * stream cannot be completed.
- *
- * @exception StreamCorruptedException An invalid stream magic
- * number or stream version was read from the stream.
- *
- * @see #readStreamHeader()
- */
- public ObjectInputStream(InputStream in)
- throws IOException, StreamCorruptedException
- {
- if (Configuration.DEBUG)
- {
- String val = System.getProperty("gcj.dumpobjects");
- if (dump == false && val != null && !val.equals(""))
- {
- dump = true;
- System.out.println ("Serialization debugging enabled");
- }
- else if (dump == true && (val == null || val.equals("")))
- {
- dump = false;
- System.out.println ("Serialization debugging disabled");
- }
- }
-
- this.resolveEnabled = false;
- this.isDeserializing = false;
- this.blockDataPosition = 0;
- this.blockDataBytes = 0;
- this.blockData = new byte[BUFFER_SIZE];
- this.blockDataInput = new DataInputStream(this);
- this.realInputStream = new DataInputStream(in);
- this.nextOID = baseWireHandle;
- this.objectLookupTable = new Hashtable();
- this.validators = new Vector();
- this.classLookupTable = new Hashtable();
- setBlockDataMode(true);
- readStreamHeader();
- }
-
-
- /**
- * Returns the next deserialized object read from the underlying stream.
- *
- * This method can be overriden by a class by implementing
- * <code>private void readObject (ObjectInputStream)</code>.
- *
- * If an exception is thrown from this method, the stream is left in
- * an undefined state. This method can also throw Errors and
- * RuntimeExceptions if caused by existing readResolve() user code.
- *
- * @return The object read from the underlying stream.
- *
- * @exception ClassNotFoundException The class that an object being
- * read in belongs to cannot be found.
- *
- * @exception IOException Exception from underlying
- * <code>InputStream</code>.
- */
- public final Object readObject() throws ClassNotFoundException, IOException
- {
- if (this.useSubclassMethod)
- return readObjectOverride();
-
- boolean was_deserializing;
-
- Object ret_val;
- was_deserializing = this.isDeserializing;
-
- boolean is_consumed = false;
- boolean old_mode = setBlockDataMode(false);
-
- this.isDeserializing = true;
-
- byte marker = this.realInputStream.readByte();
-
- depth += 2;
-
- if(dump) dumpElement("MARKER: 0x" + Integer.toHexString(marker) + " ");
-
- try
- {
- switch (marker)
- {
- case TC_ENDBLOCKDATA:
- {
- ret_val = null;
- is_consumed = true;
- break;
- }
-
- case TC_BLOCKDATA:
- case TC_BLOCKDATALONG:
- {
- if (marker == TC_BLOCKDATALONG)
- { if(dump) dumpElementln("BLOCKDATALONG"); }
- else
- { if(dump) dumpElementln("BLOCKDATA"); }
- readNextBlock(marker);
- throw new StreamCorruptedException("Unexpected blockData");
- }
-
- case TC_NULL:
- {
- if(dump) dumpElementln("NULL");
- ret_val = null;
- break;
- }
-
- case TC_REFERENCE:
- {
- if(dump) dumpElement("REFERENCE ");
- Integer oid = new Integer(this.realInputStream.readInt());
- if(dump) dumpElementln(Integer.toHexString(oid.intValue()));
- ret_val = ((ObjectIdentityWrapper)
- this.objectLookupTable.get(oid)).object;
- break;
- }
-
- case TC_CLASS:
- {
- if(dump) dumpElementln("CLASS");
- ObjectStreamClass osc = (ObjectStreamClass)readObject();
- Class clazz = osc.forClass();
- assignNewHandle(clazz);
- ret_val = clazz;
- break;
- }
-
- case TC_PROXYCLASSDESC:
- {
- if(dump) dumpElementln("PROXYCLASS");
- int n_intf = this.realInputStream.readInt();
- String[] intfs = new String[n_intf];
- for (int i = 0; i < n_intf; i++)
- {
- intfs[i] = this.realInputStream.readUTF();
- }
-
- boolean oldmode = setBlockDataMode(true);
- Class cl = resolveProxyClass(intfs);
- setBlockDataMode(oldmode);
-
- ObjectStreamClass osc = lookupClass(cl);
- if (osc.firstNonSerializableParentConstructor == null)
- {
- osc.realClassIsSerializable = true;
- osc.fields = osc.fieldMapping = new ObjectStreamField[0];
- try
- {
- osc.firstNonSerializableParentConstructor =
- Object.class.getConstructor(new Class[0]);
- }
- catch (NoSuchMethodException x)
- {
- throw (InternalError)
- new InternalError("Object ctor missing").initCause(x);
- }
- }
- assignNewHandle(osc);
-
- if (!is_consumed)
- {
- byte b = this.realInputStream.readByte();
- if (b != TC_ENDBLOCKDATA)
- throw new IOException("Data annotated to class was not consumed." + b);
- }
- else
- is_consumed = false;
- ObjectStreamClass superosc = (ObjectStreamClass)readObject();
- osc.setSuperclass(superosc);
- ret_val = osc;
- break;
- }
-
- case TC_CLASSDESC:
- {
- ObjectStreamClass osc = readClassDescriptor();
-
- if (!is_consumed)
- {
- byte b = this.realInputStream.readByte();
- if (b != TC_ENDBLOCKDATA)
- throw new IOException("Data annotated to class was not consumed." + b);
- }
- else
- is_consumed = false;
-
- osc.setSuperclass ((ObjectStreamClass)readObject());
- ret_val = osc;
- break;
- }
-
- case TC_STRING:
- case TC_LONGSTRING:
- {
- if(dump) dumpElement("STRING=");
- String s = this.realInputStream.readUTF();
- if(dump) dumpElementln(s);
- ret_val = processResolution(null, s, assignNewHandle(s));
- break;
- }
-
- case TC_ARRAY:
- {
- if(dump) dumpElementln("ARRAY");
- ObjectStreamClass osc = (ObjectStreamClass)readObject();
- Class componentType = osc.forClass().getComponentType();
- if(dump) dumpElement("ARRAY LENGTH=");
- int length = this.realInputStream.readInt();
- if(dump) dumpElementln (length + "; COMPONENT TYPE=" + componentType);
- Object array = Array.newInstance(componentType, length);
- int handle = assignNewHandle(array);
- readArrayElements(array, componentType);
- if(dump)
- for (int i = 0, len = Array.getLength(array); i < len; i++)
- dumpElementln(" ELEMENT[" + i + "]=" + Array.get(array, i));
- ret_val = processResolution(null, array, handle);
- break;
- }
-
- case TC_OBJECT:
- {
- if(dump) dumpElementln("OBJECT");
- ObjectStreamClass osc = (ObjectStreamClass)readObject();
- Class clazz = osc.forClass();
-
- if (!osc.realClassIsSerializable)
- throw new NotSerializableException
- (clazz + " is not Serializable, and thus cannot be deserialized.");
-
- if (osc.realClassIsExternalizable)
- {
- Externalizable obj = osc.newInstance();
-
- int handle = assignNewHandle(obj);
-
- boolean read_from_blocks = ((osc.getFlags() & SC_BLOCK_DATA) != 0);
-
- boolean oldmode = this.readDataFromBlock;
- if (read_from_blocks)
- setBlockDataMode(true);
-
- obj.readExternal(this);
-
- if (read_from_blocks)
- {
- setBlockDataMode(oldmode);
- if (!oldmode)
- if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
- throw new IOException("No end of block data seen for class with readExternal (ObjectInputStream) method.");
- }
-
- ret_val = processResolution(osc, obj, handle);
- break;
- } // end if (osc.realClassIsExternalizable)
-
- Object obj = newObject(clazz, osc.firstNonSerializableParentConstructor);
-
- int handle = assignNewHandle(obj);
- Object prevObject = this.currentObject;
- ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
-
- this.currentObject = obj;
- ObjectStreamClass[] hierarchy =
- inputGetObjectStreamClasses(clazz);
-
- for (int i = 0; i < hierarchy.length; i++)
- {
- this.currentObjectStreamClass = hierarchy[i];
-
- if(dump) dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ());
-
- // XXX: should initialize fields in classes in the hierarchy
- // that aren't in the stream
- // should skip over classes in the stream that aren't in the
- // real classes hierarchy
-
- Method readObjectMethod = this.currentObjectStreamClass.readObjectMethod;
- if (readObjectMethod != null)
- {
- fieldsAlreadyRead = false;
- boolean oldmode = setBlockDataMode(true);
- callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);
- setBlockDataMode(oldmode);
- }
- else
- {
- readFields(obj, currentObjectStreamClass);
- }
-
- if (this.currentObjectStreamClass.hasWriteMethod())
- {
- if(dump) dumpElement("ENDBLOCKDATA? ");
- try
- {
- // FIXME: XXX: This try block is to
- // catch EOF which is thrown for some
- // objects. That indicates a bug in
- // the logic.
-
- if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
- throw new IOException
- ("No end of block data seen for class with readObject (ObjectInputStream) method.");
- if(dump) dumpElementln("yes");
- }
-// catch (EOFException e)
-// {
-// if(dump) dumpElementln("no, got EOFException");
-// }
- catch (IOException e)
- {
- if(dump) dumpElementln("no, got IOException");
- }
- }
- }
-
- this.currentObject = prevObject;
- this.currentObjectStreamClass = prevObjectStreamClass;
- ret_val = processResolution(osc, obj, handle);
-
- break;
- }
-
- case TC_RESET:
- if(dump) dumpElementln("RESET");
- clearHandles();
- ret_val = readObject();
- break;
-
- case TC_EXCEPTION:
- {
- if(dump) dumpElement("EXCEPTION=");
- Exception e = (Exception)readObject();
- if(dump) dumpElementln(e.toString());
- clearHandles();
- throw new WriteAbortedException("Exception thrown during writing of stream", e);
- }
-
- default:
- throw new IOException("Unknown marker on stream: " + marker);
- }
- }
- finally
- {
- setBlockDataMode(old_mode);
-
- this.isDeserializing = was_deserializing;
-
- depth -= 2;
-
- if (! was_deserializing)
- {
- if (validators.size() > 0)
- invokeValidators();
- }
- }
-
- return ret_val;
- }
-
- /**
- * This method makes a partial check of types for the fields
- * contained given in arguments. It checks primitive types of
- * fields1 against non primitive types of fields2. This method
- * assumes the two lists has already been sorted according to
- * the Java specification.
- *
- * @param name Name of the class owning the given fields.
- * @param fields1 First list to check.
- * @param fields2 Second list to check.
- * @throws InvalidClassException if a field in fields1, which has a primitive type, is a present
- * in the non primitive part in fields2.
- */
- private void checkTypeConsistency(String name, ObjectStreamField[] fields1, ObjectStreamField[] fields2)
- throws InvalidClassException
- {
- int nonPrimitive = 0;
-
- for (nonPrimitive = 0;
- nonPrimitive < fields1.length
- && fields1[nonPrimitive].isPrimitive(); nonPrimitive++)
- {
- }
-
- if (nonPrimitive == fields1.length)
- return;
-
- int i = 0;
- ObjectStreamField f1;
- ObjectStreamField f2;
-
- while (i < fields2.length
- && nonPrimitive < fields1.length)
- {
- f1 = fields1[nonPrimitive];
- f2 = fields2[i];
-
- if (!f2.isPrimitive())
- break;
-
- int compVal = f1.getName().compareTo (f2.getName());
-
- if (compVal < 0)
- {
- nonPrimitive++;
- }
- else if (compVal > 0)
- {
- i++;
- }
- else
- {
- throw new InvalidClassException
- ("invalid field type for " + f2.getName() +
- " in class " + name);
- }
- }
- }
-
- /**
- * This method reads a class descriptor from the real input stream
- * and use these data to create a new instance of ObjectStreamClass.
- * Fields are sorted and ordered for the real read which occurs for
- * each instance of the described class. Be aware that if you call that
- * method you must ensure that the stream is synchronized, in the other
- * case it may be completely desynchronized.
- *
- * @return A new instance of ObjectStreamClass containing the freshly
- * created descriptor.
- * @throws ClassNotFoundException if the required class to build the
- * descriptor has not been found in the system.
- * @throws IOException An input/output error occured.
- * @throws InvalidClassException If there was a compatibility problem
- * between the class present in the system and the serialized class.
- */
- protected ObjectStreamClass readClassDescriptor()
- throws ClassNotFoundException, IOException
- {
- if(dump) dumpElement("CLASSDESC NAME=");
- String name = this.realInputStream.readUTF();
- if(dump) dumpElement(name + "; UID=");
- long uid = this.realInputStream.readLong ();
- if(dump) dumpElement(Long.toHexString(uid) + "; FLAGS=");
- byte flags = this.realInputStream.readByte ();
- if(dump) dumpElement(Integer.toHexString(flags) + "; FIELD COUNT=");
- short field_count = this.realInputStream.readShort();
- if(dump) dumpElementln(Short.toString(field_count));
- ObjectStreamField[] fields = new ObjectStreamField[field_count];
- ObjectStreamClass osc = new ObjectStreamClass(name, uid,
- flags, fields);
- assignNewHandle(osc);
-
- if (callersClassLoader == null)
- callersClassLoader = currentLoader();
-
- for (int i = 0; i < field_count; i++)
- {
- if(dump) dumpElement(" TYPE CODE=");
- char type_code = (char)this.realInputStream.readByte();
- if(dump) dumpElement(type_code + "; FIELD NAME=");
- String field_name = this.realInputStream.readUTF();
- if(dump) dumpElementln(field_name);
- String class_name;
-
- // If the type code is an array or an object we must
- // decode a String here. In the other case we convert
- // the type code and pass it to ObjectStreamField.
- // Type codes are decoded by gnu.java.lang.reflect.TypeSignature.
- if (type_code == 'L' || type_code == '[')
- class_name = (String)readObject();
- else
- class_name = String.valueOf(type_code);
-
- fields[i] =
- new ObjectStreamField(field_name, class_name, callersClassLoader);
- }
-
- /* Now that fields have been read we may resolve the class
- * (and read annotation if needed). */
- Class clazz;
- try
- {
- clazz = resolveClass(osc);
- }
- catch (ClassNotFoundException cnfe)
- {
- // Maybe it was an primitive class?
- if (name.equals("void"))
- clazz = Void.TYPE;
- else if (name.equals("boolean"))
- clazz = Boolean.TYPE;
- else if (name.equals("byte"))
- clazz = Byte.TYPE;
- else if (name.equals("short"))
- clazz = Short.TYPE;
- else if (name.equals("char"))
- clazz = Character.TYPE;
- else if (name.equals("int"))
- clazz = Integer.TYPE;
- else if (name.equals("long"))
- clazz = Long.TYPE;
- else if (name.equals("float"))
- clazz = Float.TYPE;
- else if (name.equals("double"))
- clazz = Double.TYPE;
- else
- throw cnfe;
- }
-
- boolean oldmode = setBlockDataMode(true);
- osc.setClass(clazz, lookupClass(clazz.getSuperclass()));
- classLookupTable.put(clazz, osc);
- setBlockDataMode(oldmode);
-
- // find the first non-serializable, non-abstract
- // class in clazz's inheritance hierarchy
- Class first_nonserial = clazz.getSuperclass();
- // Maybe it is a primitive class, those don't have a super class,
- // or Object itself. Otherwise we can keep getting the superclass
- // till we hit the Object class, or some other non-serializable class.
-
- if (first_nonserial == null)
- first_nonserial = clazz;
- else
- while (Serializable.class.isAssignableFrom(first_nonserial)
- || Modifier.isAbstract(first_nonserial.getModifiers()))
- first_nonserial = first_nonserial.getSuperclass();
-
- final Class local_constructor_class = first_nonserial;
-
- osc.firstNonSerializableParentConstructor =
- (Constructor)AccessController.doPrivileged(new PrivilegedAction()
- {
- public Object run()
- {
- try
- {
- Constructor c = local_constructor_class.
- getDeclaredConstructor(new Class[0]);
- if (Modifier.isPrivate(c.getModifiers()))
- return null;
- return c;
- }
- catch (NoSuchMethodException e)
- {
- // error will be reported later, in newObject()
- return null;
- }
- }
- });
-
- osc.realClassIsSerializable = Serializable.class.isAssignableFrom(clazz);
- osc.realClassIsExternalizable = Externalizable.class.isAssignableFrom(clazz);
-
- ObjectStreamField[] stream_fields = osc.fields;
- ObjectStreamField[] real_fields = ObjectStreamClass.lookupForClassObject(clazz).fields;
- ObjectStreamField[] fieldmapping = new ObjectStreamField[2 * Math.max(stream_fields.length, real_fields.length)];
-
- int stream_idx = 0;
- int real_idx = 0;
- int map_idx = 0;
-
- /*
- * Check that there is no type inconsistencies between the lists.
- * A special checking must be done for the two groups: primitive types and
- * not primitive types.
- */
- checkTypeConsistency(name, real_fields, stream_fields);
- checkTypeConsistency(name, stream_fields, real_fields);
-
-
- while (stream_idx < stream_fields.length
- || real_idx < real_fields.length)
- {
- ObjectStreamField stream_field = null;
- ObjectStreamField real_field = null;
-
- if (stream_idx == stream_fields.length)
- {
- real_field = real_fields[real_idx++];
- }
- else if (real_idx == real_fields.length)
- {
- stream_field = stream_fields[stream_idx++];
- }
- else
- {
- int comp_val =
- real_fields[real_idx].compareTo (stream_fields[stream_idx]);
-
- if (comp_val < 0)
- {
- real_field = real_fields[real_idx++];
- }
- else if (comp_val > 0)
- {
- stream_field = stream_fields[stream_idx++];
- }
- else
- {
- stream_field = stream_fields[stream_idx++];
- real_field = real_fields[real_idx++];
- if (stream_field.getType() != real_field.getType())
- throw new InvalidClassException
- ("invalid field type for " + real_field.getName() +
- " in class " + name);
- }
- }
-
- /* If some of stream_fields does not correspond to any of real_fields,
- * or the opposite, then fieldmapping will go short.
- */
- if (map_idx == fieldmapping.length)
- {
- ObjectStreamField[] newfieldmapping =
- new ObjectStreamField[fieldmapping.length + 2];
- System.arraycopy(fieldmapping, 0,
- newfieldmapping, 0, fieldmapping.length);
- fieldmapping = newfieldmapping;
- }
- fieldmapping[map_idx++] = stream_field;
- fieldmapping[map_idx++] = real_field;
- }
- osc.fieldMapping = fieldmapping;
-
- return osc;
- }
-
- /**
- * Reads the current objects non-transient, non-static fields from
- * the current class from the underlying output stream.
- *
- * This method is intended to be called from within a object's
- * <code>private void readObject (ObjectInputStream)</code>
- * method.
- *
- * @exception ClassNotFoundException The class that an object being
- * read in belongs to cannot be found.
- *
- * @exception NotActiveException This method was called from a
- * context other than from the current object's and current class's
- * <code>private void readObject (ObjectInputStream)</code>
- * method.
- *
- * @exception IOException Exception from underlying
- * <code>OutputStream</code>.
- */
- public void defaultReadObject()
- throws ClassNotFoundException, IOException, NotActiveException
- {
- if (this.currentObject == null || this.currentObjectStreamClass == null)
- throw new NotActiveException("defaultReadObject called by non-active"
- + " class and/or object");
-
- if (fieldsAlreadyRead)
- throw new NotActiveException("defaultReadObject called but fields "
- + "already read from stream (by "
- + "defaultReadObject or readFields)");
-
- boolean oldmode = setBlockDataMode(false);
- readFields(this.currentObject, this.currentObjectStreamClass);
- setBlockDataMode(oldmode);
-
- fieldsAlreadyRead = true;
- }
-
-
- /**
- * Registers a <code>ObjectInputValidation</code> to be carried out
- * on the object graph currently being deserialized before it is
- * returned to the original caller of <code>readObject ()</code>.
- * The order of validation for multiple
- * <code>ObjectInputValidation</code>s can be controled using
- * <code>priority</code>. Validators with higher priorities are
- * called first.
- *
- * @see java.io.ObjectInputValidation
- *
- * @exception InvalidObjectException <code>validator</code> is
- * <code>null</code>
- *
- * @exception NotActiveException an attempt was made to add a
- * validator outside of the <code>readObject</code> method of the
- * object currently being deserialized
- */
- public void registerValidation(ObjectInputValidation validator,
- int priority)
- throws InvalidObjectException, NotActiveException
- {
- if (this.currentObject == null || this.currentObjectStreamClass == null)
- throw new NotActiveException("registerValidation called by non-active "
- + "class and/or object");
-
- if (validator == null)
- throw new InvalidObjectException("attempt to add a null "
- + "ObjectInputValidation object");
-
- this.validators.addElement(new ValidatorAndPriority (validator,
- priority));
- }
-
-
- /**
- * Called when a class is being deserialized. This is a hook to
- * allow subclasses to read in information written by the
- * <code>annotateClass (Class)</code> method of an
- * <code>ObjectOutputStream</code>.
- *
- * This implementation looks up the active call stack for a
- * <code>ClassLoader</code>; if a <code>ClassLoader</code> is found,
- * it is used to load the class associated with <code>osc</code>,
- * otherwise, the default system <code>ClassLoader</code> is used.
- *
- * @exception IOException Exception from underlying
- * <code>OutputStream</code>.
- *
- * @see java.io.ObjectOutputStream#annotateClass (java.lang.Class)
- */
- protected Class resolveClass(ObjectStreamClass osc)
- throws ClassNotFoundException, IOException
- {
- if (callersClassLoader == null)
- {
- callersClassLoader = currentLoader ();
- if (Configuration.DEBUG && dump)
- {
- dumpElementln ("CallersClassLoader = " + callersClassLoader);
- }
- }
-
- return Class.forName(osc.getName(), true, callersClassLoader);
- }
-
- /**
- * Returns the most recent user defined ClassLoader on the execution stack
- * or null if none is found.
- */
- // GCJ LOCAL: native method.
- private native ClassLoader currentLoader();
-
- /**
- * Lookup a class stored in the local hashtable. If it is not
- * use the global lookup function in ObjectStreamClass to build
- * the ObjectStreamClass. This method is requested according to
- * the behaviour detected in the JDK by Kaffe's team.
- *
- * @param clazz Class to lookup in the hash table or for which
- * we must build a descriptor.
- * @return A valid instance of ObjectStreamClass corresponding
- * to the specified class.
- */
- private ObjectStreamClass lookupClass(Class clazz)
- {
- if (clazz == null)
- return null;
-
- ObjectStreamClass oclazz;
- oclazz = (ObjectStreamClass)classLookupTable.get(clazz);
- if (oclazz == null)
- return ObjectStreamClass.lookup(clazz);
- else
- return oclazz;
- }
-
- /**
- * Reconstruct class hierarchy the same way
- * {@link java.io.ObjectStreamClass.getObjectStreamClasses(java.lang.Class)} does
- * but using lookupClass instead of ObjectStreamClass.lookup. This
- * dup is necessary localize the lookup table. Hopefully some future
- * rewritings will be able to prevent this.
- *
- * @param clazz This is the class for which we want the hierarchy.
- *
- * @return An array of valid {@link java.io.ObjectStreamClass} instances which
- * represent the class hierarchy for clazz.
- */
- private ObjectStreamClass[] inputGetObjectStreamClasses(Class clazz)
- {
- ObjectStreamClass osc = lookupClass(clazz);
-
- if (osc == null)
- return new ObjectStreamClass[0];
- else
- {
- Vector oscs = new Vector();
-
- while (osc != null)
- {
- oscs.addElement(osc);
- osc = osc.getSuper();
- }
-
- int count = oscs.size();
- ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[count];
-
- for (int i = count - 1; i >= 0; i--)
- sorted_oscs[count - i - 1] = (ObjectStreamClass) oscs.elementAt(i);
-
- return sorted_oscs;
- }
- }
-
- /**
- * Allows subclasses to resolve objects that are read from the
- * stream with other objects to be returned in their place. This
- * method is called the first time each object is encountered.
- *
- * This method must be enabled before it will be called in the
- * serialization process.
- *
- * @exception IOException Exception from underlying
- * <code>OutputStream</code>.
- *
- * @see #enableResolveObject(boolean)
- */
- protected Object resolveObject(Object obj) throws IOException
- {
- return obj;
- }
-
-
- protected Class resolveProxyClass(String[] intfs)
- throws IOException, ClassNotFoundException
- {
- ClassLoader cl = currentLoader();
-
- Class[] clss = new Class[intfs.length];
- if(cl == null)
- {
- for (int i = 0; i < intfs.length; i++)
- clss[i] = Class.forName(intfs[i]);
- cl = ClassLoader.getSystemClassLoader();
- }
- else
- for (int i = 0; i < intfs.length; i++)
- clss[i] = cl.loadClass(intfs[i]);
- try
- {
- return Proxy.getProxyClass(cl, clss);
- }
- catch (IllegalArgumentException e)
- {
- throw new ClassNotFoundException(null, e);
- }
- }
-
- /**
- * If <code>enable</code> is <code>true</code> and this object is
- * trusted, then <code>resolveObject (Object)</code> will be called
- * in subsequent calls to <code>readObject (Object)</code>.
- * Otherwise, <code>resolveObject (Object)</code> will not be called.
- *
- * @exception SecurityException This class is not trusted.
- */
- protected boolean enableResolveObject (boolean enable)
- throws SecurityException
- {
- if (enable)
- {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkPermission(new SerializablePermission("enableSubstitution"));
- }
-
- boolean old_val = this.resolveEnabled;
- this.resolveEnabled = enable;
- return old_val;
- }
-
- /**
- * Reads stream magic and stream version information from the
- * underlying stream.
- *
- * @exception IOException Exception from underlying stream.
- *
- * @exception StreamCorruptedException An invalid stream magic
- * number or stream version was read from the stream.
- */
- protected void readStreamHeader()
- throws IOException, StreamCorruptedException
- {
- if(dump) dumpElement("STREAM MAGIC ");
- if (this.realInputStream.readShort() != STREAM_MAGIC)
- throw new StreamCorruptedException("Invalid stream magic number");
-
- if(dump) dumpElementln("STREAM VERSION ");
- if (this.realInputStream.readShort() != STREAM_VERSION)
- throw new StreamCorruptedException("Invalid stream version number");
- }
-
- public int read() throws IOException
- {
- if (this.readDataFromBlock)
- {
- if (this.blockDataPosition >= this.blockDataBytes)
- readNextBlock();
- return (this.blockData[this.blockDataPosition++] & 0xff);
- }
- else
- return this.realInputStream.read();
- }
-
- public int read(byte[] data, int offset, int length) throws IOException
- {
- if (this.readDataFromBlock)
- {
- if (this.blockDataPosition + length > this.blockDataBytes)
- {
- int remain = this.blockDataBytes - this.blockDataPosition;
- if (remain != 0)
- {
- System.arraycopy(this.blockData, this.blockDataPosition,
- data, offset, remain);
- offset += remain;
- length -= remain;
- }
- readNextBlock ();
- }
-
- System.arraycopy(this.blockData, this.blockDataPosition,
- data, offset, length);
- this.blockDataPosition += length;
-
- return length;
- }
- else
- return this.realInputStream.read(data, offset, length);
- }
-
- public int available() throws IOException
- {
- if (this.readDataFromBlock)
- {
- if (this.blockDataPosition >= this.blockDataBytes)
- readNextBlock ();
-
- return this.blockDataBytes - this.blockDataPosition;
- }
- else
- return this.realInputStream.available();
- }
-
- public void close() throws IOException
- {
- this.realInputStream.close();
- }
-
- public boolean readBoolean() throws IOException
- {
- boolean switchmode = true;
- boolean oldmode = this.readDataFromBlock;
- if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
- switchmode = false;
- if (switchmode)
- oldmode = setBlockDataMode (true);
- boolean value = this.dataInputStream.readBoolean ();
- if (switchmode)
- setBlockDataMode (oldmode);
- return value;
- }
-
- public byte readByte() throws IOException
- {
- boolean switchmode = true;
- boolean oldmode = this.readDataFromBlock;
- if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
- switchmode = false;
- if (switchmode)
- oldmode = setBlockDataMode(true);
- byte value = this.dataInputStream.readByte();
- if (switchmode)
- setBlockDataMode(oldmode);
- return value;
- }
-
- public int readUnsignedByte() throws IOException
- {
- boolean switchmode = true;
- boolean oldmode = this.readDataFromBlock;
- if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
- switchmode = false;
- if (switchmode)
- oldmode = setBlockDataMode(true);
- int value = this.dataInputStream.readUnsignedByte();
- if (switchmode)
- setBlockDataMode(oldmode);
- return value;
- }
-
- public short readShort() throws IOException
- {
- boolean switchmode = true;
- boolean oldmode = this.readDataFromBlock;
- if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
- switchmode = false;
- if (switchmode)
- oldmode = setBlockDataMode(true);
- short value = this.dataInputStream.readShort();
- if (switchmode)
- setBlockDataMode(oldmode);
- return value;
- }
-
- public int readUnsignedShort() throws IOException
- {
- boolean switchmode = true;
- boolean oldmode = this.readDataFromBlock;
- if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
- switchmode = false;
- if (switchmode)
- oldmode = setBlockDataMode(true);
- int value = this.dataInputStream.readUnsignedShort();
- if (switchmode)
- setBlockDataMode(oldmode);
- return value;
- }
-
- public char readChar() throws IOException
- {
- boolean switchmode = true;
- boolean oldmode = this.readDataFromBlock;
- if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
- switchmode = false;
- if (switchmode)
- oldmode = setBlockDataMode(true);
- char value = this.dataInputStream.readChar();
- if (switchmode)
- setBlockDataMode(oldmode);
- return value;
- }
-
- public int readInt() throws IOException
- {
- boolean switchmode = true;
- boolean oldmode = this.readDataFromBlock;
- if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 4)
- switchmode = false;
- if (switchmode)
- oldmode = setBlockDataMode(true);
- int value = this.dataInputStream.readInt();
- if (switchmode)
- setBlockDataMode(oldmode);
- return value;
- }
-
- public long readLong() throws IOException
- {
- boolean switchmode = true;
- boolean oldmode = this.readDataFromBlock;
- if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 8)
- switchmode = false;
- if (switchmode)
- oldmode = setBlockDataMode(true);
- long value = this.dataInputStream.readLong();
- if (switchmode)
- setBlockDataMode(oldmode);
- return value;
- }
-
- public float readFloat() throws IOException
- {
- boolean switchmode = true;
- boolean oldmode = this.readDataFromBlock;
- if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 4)
- switchmode = false;
- if (switchmode)
- oldmode = setBlockDataMode(true);
- float value = this.dataInputStream.readFloat();
- if (switchmode)
- setBlockDataMode(oldmode);
- return value;
- }
-
- public double readDouble() throws IOException
- {
- boolean switchmode = true;
- boolean oldmode = this.readDataFromBlock;
- if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 8)
- switchmode = false;
- if (switchmode)
- oldmode = setBlockDataMode(true);
- double value = this.dataInputStream.readDouble();
- if (switchmode)
- setBlockDataMode(oldmode);
- return value;
- }
-
- public void readFully(byte data[]) throws IOException
- {
- this.dataInputStream.readFully(data);
- }
-
- public void readFully(byte data[], int offset, int size)
- throws IOException
- {
- this.dataInputStream.readFully(data, offset, size);
- }
-
- public int skipBytes(int len) throws IOException
- {
- return this.dataInputStream.skipBytes(len);
- }
-
- /**
- * @deprecated
- * @see java.io.DataInputStream#readLine ()
- */
- public String readLine() throws IOException
- {
- return this.dataInputStream.readLine();
- }
-
- public String readUTF() throws IOException
- {
- return this.dataInputStream.readUTF();
- }
-
- /**
- * This class allows a class to specify exactly which fields should
- * be read, and what values should be read for these fields.
- *
- * XXX: finish up comments
- */
- public abstract static class GetField
- {
- public abstract ObjectStreamClass getObjectStreamClass();
-
- public abstract boolean defaulted(String name)
- throws IOException, IllegalArgumentException;
-
- public abstract boolean get(String name, boolean defvalue)
- throws IOException, IllegalArgumentException;
-
- public abstract char get(String name, char defvalue)
- throws IOException, IllegalArgumentException;
-
- public abstract byte get(String name, byte defvalue)
- throws IOException, IllegalArgumentException;
-
- public abstract short get(String name, short defvalue)
- throws IOException, IllegalArgumentException;
-
- public abstract int get(String name, int defvalue)
- throws IOException, IllegalArgumentException;
-
- public abstract long get(String name, long defvalue)
- throws IOException, IllegalArgumentException;
-
- public abstract float get(String name, float defvalue)
- throws IOException, IllegalArgumentException;
-
- public abstract double get(String name, double defvalue)
- throws IOException, IllegalArgumentException;
-
- public abstract Object get(String name, Object defvalue)
- throws IOException, IllegalArgumentException;
- }
-
- /**
- * This method should be called by a method called 'readObject' in the
- * deserializing class (if present). It cannot (and should not)be called
- * outside of it. Its goal is to read all fields in the real input stream
- * and keep them accessible through the {@link #GetField} class. Calling
- * this method will not alter the deserializing object.
- *
- * @return A valid freshly created 'GetField' instance to get access to
- * the deserialized stream.
- * @throws IOException An input/output exception occured.
- * @throws ClassNotFoundException
- * @throws NotActiveException
- */
- public GetField readFields()
- throws IOException, ClassNotFoundException, NotActiveException
- {
- if (this.currentObject == null || this.currentObjectStreamClass == null)
- throw new NotActiveException("readFields called by non-active class and/or object");
-
- if (prereadFields != null)
- return prereadFields;
-
- if (fieldsAlreadyRead)
- throw new NotActiveException("readFields called but fields already read from"
- + " stream (by defaultReadObject or readFields)");
-
- final ObjectStreamClass clazz = this.currentObjectStreamClass;
- final byte[] prim_field_data = new byte[clazz.primFieldSize];
- final Object[] objs = new Object[clazz.objectFieldCount];
-
- // Apparently Block data is not used with GetField as per
- // empirical evidence against JDK 1.2. Also see Mauve test
- // java.io.ObjectInputOutput.Test.GetPutField.
- boolean oldmode = setBlockDataMode(false);
- readFully(prim_field_data);
- for (int i = 0; i < objs.length; ++ i)
- objs[i] = readObject();
- setBlockDataMode(oldmode);
-
- prereadFields = new GetField()
- {
- public ObjectStreamClass getObjectStreamClass()
- {
- return clazz;
- }
-
- public boolean defaulted(String name)
- throws IOException, IllegalArgumentException
- {
- ObjectStreamField f = clazz.getField(name);
-
- /* First if we have a serialized field use the descriptor */
- if (f != null)
- {
- /* It is in serialPersistentFields but setClass tells us
- * it should not be set. This value is defaulted.
- */
- if (f.isPersistent() && !f.isToSet())
- return true;
-
- return false;
- }
-
- /* This is not a serialized field. There should be
- * a default value only if the field really exists.
- */
- try
- {
- return (clazz.forClass().getDeclaredField (name) != null);
- }
- catch (NoSuchFieldException e)
- {
- throw new IllegalArgumentException(e.getMessage());
- }
- }
-
- public boolean get(String name, boolean defvalue)
- throws IOException, IllegalArgumentException
- {
- ObjectStreamField field = getField(name, Boolean.TYPE);
-
- if (field == null)
- return defvalue;
-
- return prim_field_data[field.getOffset()] == 0 ? false : true;
- }
-
- public char get(String name, char defvalue)
- throws IOException, IllegalArgumentException
- {
- ObjectStreamField field = getField(name, Character.TYPE);
-
- if (field == null)
- return defvalue;
-
- int off = field.getOffset();
-
- return (char)(((prim_field_data[off++] & 0xFF) << 8)
- | (prim_field_data[off] & 0xFF));
- }
-
- public byte get(String name, byte defvalue)
- throws IOException, IllegalArgumentException
- {
- ObjectStreamField field = getField(name, Byte.TYPE);
-
- if (field == null)
- return defvalue;
-
- return prim_field_data[field.getOffset()];
- }
-
- public short get(String name, short defvalue)
- throws IOException, IllegalArgumentException
- {
- ObjectStreamField field = getField(name, Short.TYPE);
-
- if (field == null)
- return defvalue;
-
- int off = field.getOffset();
-
- return (short)(((prim_field_data[off++] & 0xFF) << 8)
- | (prim_field_data[off] & 0xFF));
- }
-
- public int get(String name, int defvalue)
- throws IOException, IllegalArgumentException
- {
- ObjectStreamField field = getField(name, Integer.TYPE);
-
- if (field == null)
- return defvalue;
-
- int off = field.getOffset();
-
- return ((prim_field_data[off++] & 0xFF) << 24)
- | ((prim_field_data[off++] & 0xFF) << 16)
- | ((prim_field_data[off++] & 0xFF) << 8)
- | (prim_field_data[off] & 0xFF);
- }
-
- public long get(String name, long defvalue)
- throws IOException, IllegalArgumentException
- {
- ObjectStreamField field = getField(name, Long.TYPE);
-
- if (field == null)
- return defvalue;
-
- int off = field.getOffset();
-
- return (long)(((prim_field_data[off++] & 0xFFL) << 56)
- | ((prim_field_data[off++] & 0xFFL) << 48)
- | ((prim_field_data[off++] & 0xFFL) << 40)
- | ((prim_field_data[off++] & 0xFFL) << 32)
- | ((prim_field_data[off++] & 0xFF) << 24)
- | ((prim_field_data[off++] & 0xFF) << 16)
- | ((prim_field_data[off++] & 0xFF) << 8)
- | (prim_field_data[off] & 0xFF));
- }
-
- public float get(String name, float defvalue)
- throws IOException, IllegalArgumentException
- {
- ObjectStreamField field = getField(name, Float.TYPE);
-
- if (field == null)
- return defvalue;
-
- int off = field.getOffset();
-
- return Float.intBitsToFloat(((prim_field_data[off++] & 0xFF) << 24)
- | ((prim_field_data[off++] & 0xFF) << 16)
- | ((prim_field_data[off++] & 0xFF) << 8)
- | (prim_field_data[off] & 0xFF));
- }
-
- public double get(String name, double defvalue)
- throws IOException, IllegalArgumentException
- {
- ObjectStreamField field = getField(name, Double.TYPE);
-
- if (field == null)
- return defvalue;
-
- int off = field.getOffset();
-
- return Double.longBitsToDouble
- ( (long) (((prim_field_data[off++] & 0xFFL) << 56)
- | ((prim_field_data[off++] & 0xFFL) << 48)
- | ((prim_field_data[off++] & 0xFFL) << 40)
- | ((prim_field_data[off++] & 0xFFL) << 32)
- | ((prim_field_data[off++] & 0xFF) << 24)
- | ((prim_field_data[off++] & 0xFF) << 16)
- | ((prim_field_data[off++] & 0xFF) << 8)
- | (prim_field_data[off] & 0xFF)));
- }
-
- public Object get(String name, Object defvalue)
- throws IOException, IllegalArgumentException
- {
- ObjectStreamField field =
- getField(name, defvalue == null ? null : defvalue.getClass ());
-
- if (field == null)
- return defvalue;
-
- return objs[field.getOffset()];
- }
-
- private ObjectStreamField getField(String name, Class type)
- throws IllegalArgumentException
- {
- ObjectStreamField field = clazz.getField(name);
- boolean illegal = false;
-
- try
- {
- try
- {
- Class field_type = field.getType();
-
- if (type == field_type ||
- (type == null && !field_type.isPrimitive()))
- {
- /* See defaulted */
- return field;
- }
-
- illegal = true;
- throw new IllegalArgumentException
- ("Field requested is of type "
- + field_type.getName()
- + ", but requested type was "
- + (type == null ? "Object" : type.getName()));
- }
- catch (NullPointerException _)
- {
- /* Here we catch NullPointerException, because it may
- only come from the call 'field.getType()'. If field
- is null, we have to return null and classpath ethic
- say we must try to avoid 'if (xxx == null)'.
- */
- }
- catch (IllegalArgumentException e)
- {
- throw e;
- }
-
- return null;
- }
- finally
- {
- /* If this is an unassigned field we should return
- * the default value.
- */
- if (!illegal && field != null && !field.isToSet() && field.isPersistent())
- return null;
-
- /* We do not want to modify transient fields. They should
- * be left to 0.
- */
- try
- {
- Field f = clazz.forClass().getDeclaredField(name);
- if (Modifier.isTransient(f.getModifiers()))
- throw new IllegalArgumentException
- ("no such field (non transient) " + name);
- if (field == null && f.getType() != type)
- throw new IllegalArgumentException
- ("Invalid requested type for field " + name);
- }
- catch (NoSuchFieldException e)
- {
- if (field == null)
- throw new IllegalArgumentException(e.getMessage());
- }
-
- }
- }
- };
-
- fieldsAlreadyRead = true;
- return prereadFields;
- }
-
- /**
- * Protected constructor that allows subclasses to override
- * deserialization. This constructor should be called by subclasses
- * that wish to override <code>readObject (Object)</code>. This
- * method does a security check <i>NOTE: currently not
- * implemented</i>, then sets a flag that informs
- * <code>readObject (Object)</code> to call the subclasses
- * <code>readObjectOverride (Object)</code> method.
- *
- * @see #readObjectOverride()
- */
- protected ObjectInputStream()
- throws IOException, SecurityException
- {
- SecurityManager sec_man = System.getSecurityManager();
- if (sec_man != null)
- sec_man.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
- this.useSubclassMethod = true;
- }
-
- /**
- * This method allows subclasses to override the default
- * de serialization mechanism provided by
- * <code>ObjectInputStream</code>. To make this method be used for
- * writing objects, subclasses must invoke the 0-argument
- * constructor on this class from their constructor.
- *
- * @see #ObjectInputStream()
- */
- protected Object readObjectOverride()
- throws ClassNotFoundException, IOException, OptionalDataException
- {
- throw new IOException("Subclass of ObjectInputStream must implement readObjectOverride");
- }
-
- /**
- * Assigns the next available handle to <code>obj</code>.
- *
- * @param obj The object for which we want a new handle.
- * @return A valid handle for the specified object.
- */
- private int assignNewHandle(Object obj)
- {
- this.objectLookupTable.put(new Integer(this.nextOID),
- new ObjectIdentityWrapper(obj));
- return this.nextOID++;
- }
-
- private Object processResolution(ObjectStreamClass osc, Object obj, int handle)
- throws IOException
- {
- if (osc != null && obj instanceof Serializable)
- {
- try
- {
- Method m = osc.readResolveMethod;
- if(m != null)
- {
- obj = m.invoke(obj, new Object[] {});
- }
- }
- catch (IllegalAccessException ignore)
- {
- }
- catch (InvocationTargetException exception)
- {
- Throwable cause = exception.getCause();
- if (cause instanceof ObjectStreamException)
- throw (ObjectStreamException) cause;
- else if (cause instanceof RuntimeException)
- throw (RuntimeException) cause;
- else if (cause instanceof Error)
- throw (Error) cause;
- }
- }
-
- if (this.resolveEnabled)
- obj = resolveObject(obj);
-
- this.objectLookupTable.put(new Integer(handle),
- new ObjectIdentityWrapper(obj));
-
- return obj;
- }
-
- private void clearHandles()
- {
- this.objectLookupTable.clear();
- this.nextOID = baseWireHandle;
- }
-
- private void readNextBlock() throws IOException
- {
- readNextBlock(this.realInputStream.readByte());
- }
-
- private void readNextBlock(byte marker) throws IOException
- {
- if (marker == TC_BLOCKDATA)
- {
- if(dump) dumpElement("BLOCK DATA SIZE=");
- this.blockDataBytes = this.realInputStream.readUnsignedByte();
- if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
- }
- else if (marker == TC_BLOCKDATALONG)
- {
- if(dump) dumpElement("BLOCK DATA LONG SIZE=");
- this.blockDataBytes = this.realInputStream.readInt();
- if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
- }
- else
- {
- throw new EOFException("Attempt to read primitive data, but no data block is active.");
- }
-
- if (this.blockData.length < this.blockDataBytes)
- this.blockData = new byte[this.blockDataBytes];
-
- this.realInputStream.readFully (this.blockData, 0, this.blockDataBytes);
- this.blockDataPosition = 0;
- }
-
- private void readArrayElements (Object array, Class clazz)
- throws ClassNotFoundException, IOException
- {
- if (clazz.isPrimitive())
- {
- if (clazz == Boolean.TYPE)
- {
- boolean[] cast_array = (boolean[])array;
- for (int i=0; i < cast_array.length; i++)
- cast_array[i] = this.realInputStream.readBoolean();
- return;
- }
- if (clazz == Byte.TYPE)
- {
- byte[] cast_array = (byte[])array;
- for (int i=0; i < cast_array.length; i++)
- cast_array[i] = this.realInputStream.readByte();
- return;
- }
- if (clazz == Character.TYPE)
- {
- char[] cast_array = (char[])array;
- for (int i=0; i < cast_array.length; i++)
- cast_array[i] = this.realInputStream.readChar();
- return;
- }
- if (clazz == Double.TYPE)
- {
- double[] cast_array = (double[])array;
- for (int i=0; i < cast_array.length; i++)
- cast_array[i] = this.realInputStream.readDouble();
- return;
- }
- if (clazz == Float.TYPE)
- {
- float[] cast_array = (float[])array;
- for (int i=0; i < cast_array.length; i++)
- cast_array[i] = this.realInputStream.readFloat();
- return;
- }
- if (clazz == Integer.TYPE)
- {
- int[] cast_array = (int[])array;
- for (int i=0; i < cast_array.length; i++)
- cast_array[i] = this.realInputStream.readInt();
- return;
- }
- if (clazz == Long.TYPE)
- {
- long[] cast_array = (long[])array;
- for (int i=0; i < cast_array.length; i++)
- cast_array[i] = this.realInputStream.readLong();
- return;
- }
- if (clazz == Short.TYPE)
- {
- short[] cast_array = (short[])array;
- for (int i=0; i < cast_array.length; i++)
- cast_array[i] = this.realInputStream.readShort();
- return;
- }
- }
- else
- {
- Object[] cast_array = (Object[])array;
- for (int i=0; i < cast_array.length; i++)
- cast_array[i] = readObject();
- }
- }
-
- private void readFields (Object obj, ObjectStreamClass stream_osc)
- throws ClassNotFoundException, IOException
- {
- ObjectStreamField[] fields = stream_osc.fieldMapping;
-
- for (int i = 0; i < fields.length; i += 2)
- {
- ObjectStreamField stream_field = fields[i];
- ObjectStreamField real_field = fields[i + 1];
- boolean read_value = (stream_field != null && stream_field.getOffset() >= 0 && stream_field.isToSet());
- boolean set_value = (real_field != null && real_field.isToSet());
- String field_name;
- char type;
-
- if (stream_field != null)
- {
- field_name = stream_field.getName();
- type = stream_field.getTypeCode();
- }
- else
- {
- field_name = real_field.getName();
- type = real_field.getTypeCode();
- }
-
- switch(type)
- {
- case 'Z':
- {
- boolean value =
- read_value ? this.realInputStream.readBoolean() : false;
- if (dump && read_value && set_value)
- dumpElementln(" " + field_name + ": " + value);
- if (set_value)
- real_field.setBooleanField(obj, value);
- break;
- }
- case 'B':
- {
- byte value =
- read_value ? this.realInputStream.readByte() : 0;
- if (dump && read_value && set_value)
- dumpElementln(" " + field_name + ": " + value);
- if (set_value)
- real_field.setByteField(obj, value);
- break;
- }
- case 'C':
- {
- char value =
- read_value ? this.realInputStream.readChar(): 0;
- if (dump && read_value && set_value)
- dumpElementln(" " + field_name + ": " + value);
- if (set_value)
- real_field.setCharField(obj, value);
- break;
- }
- case 'D':
- {
- double value =
- read_value ? this.realInputStream.readDouble() : 0;
- if (dump && read_value && set_value)
- dumpElementln(" " + field_name + ": " + value);
- if (set_value)
- real_field.setDoubleField(obj, value);
- break;
- }
- case 'F':
- {
- float value =
- read_value ? this.realInputStream.readFloat() : 0;
- if (dump && read_value && set_value)
- dumpElementln(" " + field_name + ": " + value);
- if (set_value)
- real_field.setFloatField(obj, value);
- break;
- }
- case 'I':
- {
- int value =
- read_value ? this.realInputStream.readInt() : 0;
- if (dump && read_value && set_value)
- dumpElementln(" " + field_name + ": " + value);
- if (set_value)
- real_field.setIntField(obj, value);
- break;
- }
- case 'J':
- {
- long value =
- read_value ? this.realInputStream.readLong() : 0;
- if (dump && read_value && set_value)
- dumpElementln(" " + field_name + ": " + value);
- if (set_value)
- real_field.setLongField(obj, value);
- break;
- }
- case 'S':
- {
- short value =
- read_value ? this.realInputStream.readShort() : 0;
- if (dump && read_value && set_value)
- dumpElementln(" " + field_name + ": " + value);
- if (set_value)
- real_field.setShortField(obj, value);
- break;
- }
- case 'L':
- case '[':
- {
- Object value =
- read_value ? readObject() : null;
- if (set_value)
- real_field.setObjectField(obj, value);
- break;
- }
- default:
- throw new InternalError("Invalid type code: " + type);
- }
- }
- }
-
- // Toggles writing primitive data to block-data buffer.
- private boolean setBlockDataMode (boolean on)
- {
- boolean oldmode = this.readDataFromBlock;
- this.readDataFromBlock = on;
-
- if (on)
- this.dataInputStream = this.blockDataInput;
- else
- this.dataInputStream = this.realInputStream;
- return oldmode;
- }
-
- // returns a new instance of REAL_CLASS that has been constructed
- // only to the level of CONSTRUCTOR_CLASS (a super class of REAL_CLASS)
- private Object newObject (Class real_class, Constructor constructor)
- throws ClassNotFoundException, IOException
- {
- if (constructor == null)
- throw new InvalidClassException("Missing accessible no-arg base class constructor for " + real_class.getName());
- try
- {
- return allocateObject(real_class, constructor.getDeclaringClass(), constructor);
- }
- catch (InstantiationException e)
- {
- throw new ClassNotFoundException
- ("Instance of " + real_class + " could not be created");
- }
- }
-
- // runs all registered ObjectInputValidations in prioritized order
- // on OBJ
- private void invokeValidators() throws InvalidObjectException
- {
- Object[] validators = new Object[this.validators.size()];
- this.validators.copyInto (validators);
- Arrays.sort (validators);
-
- try
- {
- for (int i=0; i < validators.length; i++)
- ((ObjectInputValidation)validators[i]).validateObject();
- }
- finally
- {
- this.validators.removeAllElements();
- }
- }
-
- private void callReadMethod (Method readObject, Class klass, Object obj)
- throws ClassNotFoundException, IOException
- {
- try
- {
- readObject.invoke(obj, new Object[] { this });
- }
- catch (InvocationTargetException x)
- {
- /* Rethrow if possible. */
- Throwable exception = x.getTargetException();
- if (exception instanceof RuntimeException)
- throw (RuntimeException) exception;
- if (exception instanceof IOException)
- throw (IOException) exception;
- if (exception instanceof ClassNotFoundException)
- throw (ClassNotFoundException) exception;
-
- throw new IOException("Exception thrown from readObject() on " +
- klass + ": " + exception.getClass().getName());
- }
- catch (Exception x)
- {
- throw new IOException("Failure invoking readObject() on " +
- klass + ": " + x.getClass().getName());
- }
-
- // Invalidate fields which has been read through readFields.
- prereadFields = null;
- }
-
- private native Object allocateObject(Class clazz, Class constr_clazz, Constructor constructor)
- throws InstantiationException;
-
- private static final int BUFFER_SIZE = 1024;
-
- private DataInputStream realInputStream;
- private DataInputStream dataInputStream;
- private DataInputStream blockDataInput;
- private int blockDataPosition;
- private int blockDataBytes;
- private byte[] blockData;
- private boolean useSubclassMethod;
- private int nextOID;
- private boolean resolveEnabled;
- private Hashtable objectLookupTable;
- private Object currentObject;
- private ObjectStreamClass currentObjectStreamClass;
- private boolean readDataFromBlock;
- private boolean isDeserializing;
- private boolean fieldsAlreadyRead;
- private Vector validators;
- private Hashtable classLookupTable;
- private GetField prereadFields;
-
- private ClassLoader callersClassLoader;
- private static boolean dump;
-
- // The nesting depth for debugging output
- private int depth = 0;
-
- private void dumpElement (String msg)
- {
- System.out.print(msg);
- }
-
- private void dumpElementln (String msg)
- {
- System.out.println(msg);
- for (int i = 0; i < depth; i++)
- System.out.print (" ");
- System.out.print (Thread.currentThread() + ": ");
- }
-
- static
- {
- if (Configuration.INIT_LOAD_LIBRARY)
- {
- System.loadLibrary ("javaio");
- }
- }
-
- // used to keep a prioritized list of object validators
- private static final class ValidatorAndPriority implements Comparable
- {
- int priority;
- ObjectInputValidation validator;
-
- ValidatorAndPriority (ObjectInputValidation validator, int priority)
- {
- this.priority = priority;
- this.validator = validator;
- }
-
- public int compareTo (Object o)
- {
- ValidatorAndPriority vap = (ValidatorAndPriority)o;
- return this.priority - vap.priority;
- }
- }
-}
-