harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From telli...@apache.org
Subject svn commit: r405203 [2/3] - in /incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java: java/io/ObjectInputStream.java org/apache/harmony/luni/util/ExternalMessages.properties
Date Mon, 08 May 2006 22:32:46 GMT

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/ObjectInputStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/ObjectInputStream.java?rev=405203&r1=405202&r2=405203&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/ObjectInputStream.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/ObjectInputStream.java Mon May  8 15:32:45 2006
@@ -15,7 +15,7 @@
 
 package java.io;
 
-
+import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -28,6 +28,8 @@
 import java.util.IdentityHashMap;
 import java.util.Iterator;
 
+import org.apache.harmony.kernel.vm.VM;
+import org.apache.harmony.luni.util.Msg;
 import org.apache.harmony.luni.util.PriviAction;
 
 /**
@@ -42,2506 +44,2465 @@
  * @see Externalizable
  */
 public class ObjectInputStream extends InputStream implements ObjectInput,
-		ObjectStreamConstants {
-	private static InputStream emptyStream = new ByteArrayInputStream(
-			new byte[0]);
-
-	private boolean hasPushbackTC; // If the receiver has already read & not
-									// consumed a TC code
-
-	private byte pushbackTC; // Pushback TC code if teh variable above is
-								// true
-
-	private int nestedLevels; // How many nested levels to readObject. When we
-								// reach 0 we have to validate the graph then
-								// reset it
-
-	private int currentHandle; // All objects are assigned an ID (integer
-								// handle)
-
-	private DataInputStream input; // Where we read from
-
-	private DataInputStream primitiveTypes; // Where we read primitive types
-											// from
-
-	private InputStream primitiveData = emptyStream;// Where we keep primitive
-													// type data
-
-	private boolean enableResolve; // Resolve object is a mechanism for
-									// replacement
-
-	private Hashtable<Integer,Object> objectsRead; // Table mapping Integer (handle) -> Object
-
-	private Object currentObject; // Used by defaultReadObject
-
-	private ObjectStreamClass currentClass; // Used by defaultReadObject
-
-	private InputValidationDesc[] validations; // All validations to be
-												// executed when the complete
-												// graph is read. See inner type
-												// below.
-
-	private boolean subclassOverridingImplementation;// Allows the receiver
-														// to decide if it needs
-														// to call
-														// readObjectOverride
-
-	private ClassLoader callerClassLoader; // Original caller's class loader,
-											// used to perform class lookups
-
-	private boolean mustResolve = true; // false when reading missing fields
-
-	private Integer descriptorHandle; // Handle for the current class
-										// descriptor
-
-	private IdentityHashMap readResolveCache; // cache for readResolve methods
-
-	// Internal type used to keep track of validators & corresponding priority
-	class InputValidationDesc {
-		ObjectInputValidation validator;
-
-		int priority;
-	}
-
-	/**
-	 * Inner class to provide access to serializable fields
-	 */
-	abstract static public class GetField {
-		/**
-		 * @return ObjectStreamClass
-		 */
-		public abstract ObjectStreamClass getObjectStreamClass();
-
-		/**
-		 * @param name
-		 * @return <code>true</code> if the default value is set,
-		 *         <code>false</code> otherwise
-		 * 
-		 * @throws IOException
-		 * @throws IllegalArgumentException
-		 */
-		public abstract boolean defaulted(String name) throws IOException,
-				IllegalArgumentException;
-
-		/**
-		 * @param name
-		 * @param defaultValue
-		 * @return the value
-		 * 
-		 * @throws IOException
-		 * @throws IllegalArgumentException
-		 */
-		public abstract boolean get(String name, boolean defaultValue)
-				throws IOException, IllegalArgumentException;
-
-		/**
-		 * @param name
-		 * @param defaultValue
-		 * @return the value
-		 * 
-		 * @throws IOException
-		 * @throws IllegalArgumentException
-		 */
-		public abstract char get(String name, char defaultValue)
-				throws IOException, IllegalArgumentException;
-
-		/**
-		 * @param name
-		 * @param defaultValue
-		 * @return the value
-		 * 
-		 * @throws IOException
-		 * @throws IllegalArgumentException
-		 */
-		public abstract byte get(String name, byte defaultValue)
-				throws IOException, IllegalArgumentException;
-
-		/**
-		 * @param name
-		 * @param defaultValue
-		 * @return the value
-		 * 
-		 * @throws IOException
-		 * @throws IllegalArgumentException
-		 */
-		public abstract short get(String name, short defaultValue)
-				throws IOException, IllegalArgumentException;
-
-		/**
-		 * @param name
-		 * @param defaultValue
-		 * @return the value
-		 * 
-		 * @throws IOException
-		 * @throws IllegalArgumentException
-		 */
-		public abstract int get(String name, int defaultValue)
-				throws IOException, IllegalArgumentException;
-
-		/**
-		 * @param name
-		 * @param defaultValue
-		 * @return the value
-		 * 
-		 * @throws IOException
-		 * @throws IllegalArgumentException
-		 */
-		public abstract long get(String name, long defaultValue)
-				throws IOException, IllegalArgumentException;
-
-		/**
-		 * @param name
-		 * @param defaultValue
-		 * @return the value
-		 * 
-		 * @throws IOException
-		 * @throws IllegalArgumentException
-		 */
-		public abstract float get(String name, float defaultValue)
-				throws IOException, IllegalArgumentException;
-
-		/**
-		 * @param name
-		 * @param defaultValue
-		 * @return the value
-		 * 
-		 * @throws IOException
-		 * @throws IllegalArgumentException
-		 */
-		public abstract double get(String name, double defaultValue)
-				throws IOException, IllegalArgumentException;
-
-		/**
-		 * @param name
-		 * @param defaultValue
-		 * @return the value
-		 * 
-		 * @throws IOException
-		 * @throws IllegalArgumentException
-		 */
-		public abstract Object get(String name, Object defaultValue)
-				throws IOException, IllegalArgumentException;
-	}
-
-	/**
-	 * Constructs a new ObjectInputStream. The representation and proper
-	 * initialization is on the hands of subclasses.
-	 * 
-	 * @throws IOException
-	 *             If not called from a subclass
-	 * @throws SecurityException
-	 *             If subclasses are not allowed
-	 * 
-	 * @see SecurityManager#checkPermission(java.security.Permission)
-	 */
-	protected ObjectInputStream() throws IOException, SecurityException {
-		super();
-		SecurityManager currentManager = System.getSecurityManager();
-		if (currentManager != null)
-			currentManager.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
-		// WARNING - we should throw IOException if not called from a subclass
-		// according to the JavaDoc. Add the test.
-		this.subclassOverridingImplementation = true;
-	}
-
-	/**
-	 * Constructs a new ObjectInputStream on the InputStream <code>input</code>.
-	 * All reads are now filtered through this stream.
-	 * 
-	 * @param input
-	 *            The non-null InputStream to filter reads on.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the stream header.
-	 * @throws StreamCorruptedException
-	 *             If the underlying stream does not contain serialized objects
-	 *             that can be read.
-	 */
-	public ObjectInputStream(InputStream input)
-			throws StreamCorruptedException, IOException {
-		final Class implementationClass = getClass();
-		final Class thisClass = ObjectInputStream.class;
-		SecurityManager sm = System.getSecurityManager();
-		if (sm != null && implementationClass != thisClass) {
-			boolean mustCheck = (AccessController
-					.doPrivileged(new PrivilegedAction<Boolean>() {
-						public Boolean run() {
-							try {
-								Method method = implementationClass
-										.getMethod(
-												"readFields", //$NON-NLS-1$
-												ObjectStreamClass.EMPTY_CONSTRUCTOR_PARAM_TYPES);
-								if (method.getDeclaringClass() != thisClass) {
-									return Boolean.TRUE;
-								}
-							} catch (NoSuchMethodException e) {
-							}
-							try {
-								Method method = implementationClass
-										.getMethod(
-												"readUnshared", //$NON-NLS-1$
-												ObjectStreamClass.EMPTY_CONSTRUCTOR_PARAM_TYPES);
-								if (method.getDeclaringClass() != thisClass) {
-									return Boolean.TRUE;
-								}
-							} catch (NoSuchMethodException e) {
-							}
-							return Boolean.FALSE;
-						}
-					})).booleanValue();
-			if (mustCheck) {
-				sm
-						.checkPermission(ObjectStreamConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
-			}
-		}
-		this.input = (input instanceof DataInputStream) ? (DataInputStream) input
-				: new DataInputStream(input);
-		primitiveTypes = new DataInputStream(this);
-		enableResolve = false;
-		this.subclassOverridingImplementation = false;
-		this.readResolveCache = new IdentityHashMap();
-		resetState();
-		nestedLevels = 0;
-		// So read...() methods can be used by
-		// subclasses during readStreamHeader()
-		primitiveData = this.input;
-		// Has to be done here according to the specification
-		readStreamHeader();
-		primitiveData = emptyStream;
-	}
-
-	/**
-	 * Returns the number of bytes of primitive data available from the
-	 * receiver. It should not be used at any arbitrary position; just when
-	 * reading primitive data types (ints, chars, etc).
-	 * 
-	 * @return the number of available primitive data bytes
-	 * 
-	 * @throws IOException
-	 *             If any IO problem occurred when trying to compute the bytes
-	 *             available.
-	 */
-	public int available() throws IOException {
-		// returns 0 if next data is an object, or N if reading primitive types
-		checkReadPrimitiveTypes();
-		return primitiveData.available();
-	}
-
-	/**
-	 * Checks to see if it is ok to read primitive types at this point from the
-	 * receiver. One is not supposed to read primitive types when about to read
-	 * an object, for example, so an exception has to be thrown.
-	 * 
-	 * @throws IOException
-	 *             If any IO problem occurred when trying to read primitive type
-	 *             or if it is illegal to read primitive types
-	 */
-	private void checkReadPrimitiveTypes() throws IOException {
-		// If we still have primitive data, it is ok to read primitive data
-		if (primitiveData == input || primitiveData.available() > 0)
-			return;
-
-		// If we got here either we had no Stream previously created or
-		// we no longer have data in that one, so get more bytes
-
-		do {
-			int next = 0;
-			if (hasPushbackTC) {
-				hasPushbackTC = false;
-			} else {
-				next = input.read();
-				pushbackTC = (byte) next;
-			}
-			switch (pushbackTC) {
-			case TC_BLOCKDATA:
-				primitiveData = new ByteArrayInputStream(readBlockData());
-				return;
-			case TC_BLOCKDATALONG:
-				primitiveData = new ByteArrayInputStream(readBlockDataLong());
-				return;
-			case TC_RESET:
-				resetState();
-				break;
-			default:
-				if (next != -1)
-					pushbackTC();
-				return;
-			}
-			// Only TC_RESET falls through
-		} while (true);
-	}
-
-	/**
-	 * Close this ObjectInputStream. This implementation closes the target
-	 * stream.
-	 * 
-	 * @throws IOException
-	 *             If an error occurs attempting to close this stream.
-	 */
-	public void close() throws IOException {
-		input.close();
-	}
-
-	/**
-	 * Default method to read objects from the receiver. Fields defined in the
-	 * object's class and superclasses (which are Serializable) will be read.
-	 * 
-	 * @throws IOException
-	 *             If an IO error occurs attempting to read the object data
-	 * @throws ClassNotFoundException
-	 *             If the class of the object cannot be found
-	 * @throws NotActiveException
-	 *             If this method is not called from readObject()
-	 * 
-	 * @see ObjectOutputStream#defaultWriteObject
-	 */
-	public void defaultReadObject() throws IOException, ClassNotFoundException,
-			NotActiveException {
-		// We can't be called from just anywhere. There are rules.
-		if (currentObject != null || !mustResolve)
-			readFieldValues(currentObject, currentClass);
-		else
-			throw new NotActiveException();
-	}
-
-	/**
-	 * Enables/disables object replacement for the receiver. By default this is
-	 * not enabled. Only trusted subclasses (loaded with system class loader)
-	 * can override this behavior.
-	 * 
-	 * @param enable
-	 *            if true, enables replacement. If false, disables replacement.
-	 * @return the previous configuration (if it was enabled or disabled)
-	 * 
-	 * @throws SecurityException
-	 *             If the class of the receiver is not trusted
-	 * 
-	 * @see #resolveObject
-	 * @see ObjectOutputStream#enableReplaceObject
-	 */
-
-	protected boolean enableResolveObject(boolean enable)
-			throws SecurityException {
-		if (enable) {
-			// The Stream has to be trusted for this feature to be enabled.
-			// trusted means the stream's classloader has to be null
-			SecurityManager currentManager = System.getSecurityManager();
-			if (currentManager != null)
-				currentManager.checkPermission(SUBSTITUTION_PERMISSION);
-		}
-		boolean originalValue = enableResolve;
-		enableResolve = enable;
-		return originalValue;
-	}
-
-	/**
-	 * Checks if two classes belong to the same package and returns true in the
-	 * positive case. Return false otherwise.
-	 * 
-	 * @param c1
-	 *            one of the classes to test
-	 * @param c2
-	 *            the other class to test
-	 * @return <code>true</code> if the two classes belong to the same
-	 *         package, <code>false</code> otherwise
-	 */
-	private boolean inSamePackage(Class c1, Class c2) {
-		String nameC1 = c1.getName();
-		String nameC2 = c2.getName();
-		int indexDotC1 = nameC1.lastIndexOf('.');
-		int indexDotC2 = nameC2.lastIndexOf('.');
-		if (indexDotC1 != indexDotC1)
-			return false; // cannot be in the same package if indices are not
-							// the same
-		if (indexDotC1 < 0)
-			return true; // both of them are in default package
-		return nameC1.substring(0, indexDotC1).equals(
-				nameC2.substring(0, indexDotC2));
-	}
-
-	/**
-	 * Create and return a new instance of class <code>instantiationClass</code>
-	 * but running the constructor defined in class
-	 * <code>constructorClass</code> (same as <code>instantiationClass</code>
-	 * or a superclass).
-	 * 
-	 * Has to be native to avoid visibility rules and to be able to have
-	 * <code>instantiationClass</code> not the same as
-	 * <code>constructorClass</code> (no such API in java.lang.reflect).
-	 * 
-	 * @param instantiationClass
-	 *            The new object will be an instance of this class
-	 * @param constructorClass
-	 *            The empty constructor to run will be in this class
-	 * @return the object created from <code>instantiationClass</code>
-	 */
-	private static native Object newInstance(Class instantiationClass,
-			Class constructorClass);
-
-	/**
-	 * Return the next <code>int</code> handle to be used to indicate cyclic
-	 * references being loaded from the stream.
-	 * 
-	 * @return the next handle to represent the next cyclic reference
-	 */
-	private int nextHandle() {
-		return this.currentHandle++;
-	}
-
-	/**
-	 * Return the next token code (TC) from the receiver, which indicates what
-	 * kind of object follows
-	 * 
-	 * @return the next TC from the receiver
-	 * 
-	 * @throws IOException
-	 *             If an IO error occurs
-	 * 
-	 * @see ObjectStreamConstants
-	 */
-	private byte nextTC() throws IOException {
-		if (hasPushbackTC)
-			hasPushbackTC = false; // We are consuming it
-		else
-			// Just in case a later call decides to really push it back,
-			// we don't require the caller to pass it as parameter
-			pushbackTC = input.readByte();
-		return pushbackTC;
-	}
-
-	/**
-	 * Pushes back the last TC code read
-	 * 
-	 */
-	private void pushbackTC() {
-		hasPushbackTC = true;
-	}
-
-	/**
-	 * Reads a single byte from the receiver and returns the result as an int.
-	 * The low-order byte is returned or -1 of the end of stream was
-	 * encountered.
-	 * 
-	 * @return The byte read or -1 if end of stream.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public int read() throws IOException {
-		checkReadPrimitiveTypes();
-		return primitiveData.read();
-	}
-
-	/**
-	 * Reads at most <code>length</code> bytes from the receiver and stores
-	 * them in byte array <code>buffer</code> starting at offset
-	 * <code>offset</code>. Answer the number of bytes actually read or -1 if
-	 * no bytes were read and end of stream was encountered.
-	 * 
-	 * @param buffer
-	 *            the byte array in which to store the read bytes.
-	 * @param offset
-	 *            the offset in <code>buffer</code> to store the read bytes.
-	 * @param length
-	 *            the maximum number of bytes to store in <code>buffer</code>.
-	 * @return The number of bytes actually read or -1 if end of stream.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public int read(byte[] buffer, int offset, int length) throws IOException {
-		if (buffer != null) {
-			// avoid int overflow
-			if (0 <= offset && offset <= buffer.length && 0 <= length
-					&& length <= buffer.length - offset) {
-				if (length == 0)
-					return 0;
-				checkReadPrimitiveTypes();
-				return primitiveData.read(buffer, offset, length);
-			}
-			throw new ArrayIndexOutOfBoundsException();
-		}
-		throw new NullPointerException();
-	}
-
-	/**
-	 * Reads and returns an array of raw bytes with primitive data. The array
-	 * will have up to 255 bytes. The primitive data will be in the format
-	 * described by <code>DataOutputStream</code>.
-	 * 
-	 * @return The primitive data read, as raw bytes
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	private byte[] readBlockData() throws IOException {
-		byte[] result = new byte[input.readByte() & 0xff];
-		input.readFully(result);
-		return result;
-	}
-
-	/**
-	 * Reads and returns an array of raw bytes with primitive data. The array
-	 * will have more than 255 bytes. The primitive data will be in the format
-	 * described by <code>DataOutputStream</code>.
-	 * 
-	 * @return The primitive data read, as raw bytes
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	private byte[] readBlockDataLong() throws IOException {
-		byte[] result = new byte[input.readInt()];
-		input.readFully(result);
-		return result;
-	}
-
-	/**
-	 * Reads and returns primitive data of type boolean read from the receiver
-	 * 
-	 * @return A boolean saved as primitive data using
-	 *         <code>ObjectOutputStream.writeBoolean()</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public boolean readBoolean() throws IOException {
-		return primitiveTypes.readBoolean();
-	}
-
-	/**
-	 * Reads and returns primitive data of type byte read from the receiver
-	 * 
-	 * @return A byte saved as primitive data using
-	 *         <code>ObjectOutputStream.writeByte()</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public byte readByte() throws IOException {
-		return primitiveTypes.readByte();
-	}
-
-	/**
-	 * Reads and returns primitive data of type char read from the receiver
-	 * 
-	 * @return A char saved as primitive data using
-	 *         <code>ObjectOutputStream.writeChar()</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public char readChar() throws IOException {
-		return primitiveTypes.readChar();
-	}
-
-	/**
-	 * Reads and discards block data and objects until TC_ENDBLOCKDATA is found.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the optional class
-	 *             annotation.
-	 * @throws ClassNotFoundException
-	 *             If the class corresponding to the class descriptor could not
-	 *             be found.
-	 */
-	private void discardData() throws ClassNotFoundException, IOException {
-		primitiveData = emptyStream;
-		boolean resolve = mustResolve;
-		mustResolve = false;
-		do {
-			byte tc = nextTC();
-			if (tc == TC_ENDBLOCKDATA) {
-				mustResolve = resolve;
-				return; // End of annotation
-			}
-			readContent(tc);
-		} while (true);
-	}
-
-	/**
-	 * Reads a class descriptor (an <code>ObjectStreamClass</code>) from the
-	 * stream.
-	 * 
-	 * @return the class descriptor read from the stream
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the class
-	 *             descriptor.
-	 * @throws ClassNotFoundException
-	 *             If the class corresponding to the class descriptor could not
-	 *             be found.
-	 */
-	private ObjectStreamClass readClassDesc() throws ClassNotFoundException,
-			IOException {
-		byte tc = nextTC();
-		switch (tc) {
-		case TC_CLASSDESC:
-			return readNewClassDesc(false);
-		case TC_PROXYCLASSDESC:
-			Class proxyClass = readNewProxyClassDesc();
-			ObjectStreamClass streamClass = ObjectStreamClass
-					.lookup(proxyClass);
-			streamClass.setLoadFields(new ObjectStreamField[0]);
-			registerObjectRead(streamClass, new Integer(nextHandle()));
-			streamClass.setSuperclass(readClassDesc());
-			return streamClass;
-		case TC_REFERENCE:
-			return (ObjectStreamClass) readCyclicReference();
-		case TC_NULL:
-			return null;
-		default:
-			throw new StreamCorruptedException(org.apache.harmony.luni.util.Msg.getString(
-					"K00d2", Integer.toHexString(tc & 0xff))); //$NON-NLS-1$
-		}
-	}
-
-	/**
-	 * Reads the content of the receiver based on the previously read token
-	 * <code>tc</code>.
-	 * 
-	 * @param tc
-	 *            The token code for the next item in the stream
-	 * @return the object read from the stream
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the class
-	 *             descriptor.
-	 * @throws ClassNotFoundException
-	 *             If the class corresponding to the object being read could not
-	 *             be found.
-	 */
-	private Object readContent(byte tc) throws ClassNotFoundException,
-			IOException {
-		switch (tc) {
-		case TC_BLOCKDATA:
-			return readBlockData();
-		case TC_BLOCKDATALONG:
-			return readBlockDataLong();
-		case TC_CLASS:
-			return readNewClass(false);
-		case TC_CLASSDESC:
-			return readNewClassDesc(false);
-		case TC_ARRAY:
-			return readNewArray(false);
-		case TC_OBJECT:
-			return readNewObject(false);
-		case TC_STRING:
-			return readNewString(false);
-		case TC_LONGSTRING:
-			return readNewLongString(false);
-		case TC_REFERENCE:
-			return readCyclicReference();
-		case TC_NULL:
-			return null;
-		case TC_EXCEPTION:
-			Exception exc = readException();
-			throw new WriteAbortedException(org.apache.harmony.luni.util.Msg
-					.getString("K00d3"), exc); //$NON-NLS-1$
-		case TC_RESET:
-			resetState();
-			return null;
-		default:
-			throw new StreamCorruptedException(org.apache.harmony.luni.util.Msg.getString(
-					"K00d2", Integer.toHexString(tc & 0xff))); //$NON-NLS-1$
-		}
-	}
-
-	/**
-	 * Reads the content of the receiver based on the previously read token
-	 * <code>tc</code>. Primitive data content is considered an error.
-	 * 
-	 * @param unshared
-	 *            read the object unshared
-	 * @return the object read from the stream
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the class
-	 *             descriptor.
-	 * @throws ClassNotFoundException
-	 *             If the class corresponding to the object being read could not
-	 *             be found.
-	 */
-	private Object readNonPrimitiveContent(boolean unshared)
-			throws ClassNotFoundException, IOException {
-		checkReadPrimitiveTypes();
-		if (primitiveData.available() > 0) {
-			OptionalDataException e = new OptionalDataException();
-			e.length = primitiveData.available();
-			throw e;
-		}
-
-		do {
-			byte tc = nextTC();
-			switch (tc) {
-			case TC_CLASS:
-				return readNewClass(unshared);
-			case TC_CLASSDESC:
-				return readNewClassDesc(unshared);
-			case TC_ARRAY:
-				return readNewArray(unshared);
-			case TC_OBJECT:
-				return readNewObject(unshared);
-			case TC_STRING:
-				return readNewString(unshared);
-			case TC_LONGSTRING:
-				return readNewLongString(unshared);
-			case TC_REFERENCE:
-				if (unshared) {
-					readNewHandle();
-					throw new InvalidObjectException(
-							"Unshared read of back reference"); //$NON-NLS-1$
-				}
-				return readCyclicReference();
-			case TC_NULL:
-				return null;
-			case TC_EXCEPTION:
-				Exception exc = readException();
-				throw new WriteAbortedException(org.apache.harmony.luni.util.Msg
-						.getString("K00d3"), exc); //$NON-NLS-1$
-			case TC_RESET:
-				resetState();
-				break;
-			case TC_ENDBLOCKDATA: // Can occur reading class annotation
-				pushbackTC();
-				OptionalDataException e = new OptionalDataException();
-				e.eof = true;
-				throw e;
-			default:
-				throw new StreamCorruptedException(org.apache.harmony.luni.util.Msg
-						.getString("K00d2", Integer.toHexString(tc & 0xff))); //$NON-NLS-1$
-			}
-			// Only TC_RESET falls through
-		} while (true);
-	}
-
-	/**
-	 * Reads the next item from the stream assuming it is a cyclic reference to
-	 * an object previouly read. Return the actual object previously read.
-	 * 
-	 * @return the object previously read from the stream
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the class
-	 *             descriptor.
-	 * @throws InvalidObjectException
-	 *             If the cyclic reference is not valid.
-	 */
-	private Object readCyclicReference() throws InvalidObjectException,
-			IOException {
-		return registeredObjectRead(readNewHandle());
-	}
-
-	/**
-	 * Reads and returns primitive data of type double read from the receiver
-	 * 
-	 * @return A double saved as primitive data using
-	 *         <code>ObjectOutputStream.writeDouble()</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public double readDouble() throws IOException {
-		return primitiveTypes.readDouble();
-	}
-
-	/**
-	 * Read the next item assuming it is an exception. The exception is not a
-	 * regular instance in the object graph, but the exception instance that
-	 * happened (if any) when dumping the original object graph. The set of seen
-	 * objects will be reset just before and just after loading this exception
-	 * object.
-	 * <p>
-	 * When exceptions are found normally in the object graph, they are loaded
-	 * as a regular object, and not by this method. In that case, the set of
-	 * "known objects" is not reset.
-	 * 
-	 * 
-	 * @return the exception read
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the exception
-	 *             object.
-	 * @throws ClassNotFoundException
-	 *             If a class could not be found when reading the object graph
-	 *             for the exception
-	 * @throws OptionalDataException
-	 *             If optional data could not be found when reading the
-	 *             exception graph
-	 * @throws WriteAbortedException
-	 *             If another exception was caused when dumping this exception
-	 */
-	private Exception readException() throws WriteAbortedException,
-			OptionalDataException, ClassNotFoundException, IOException {
-		resetSeenObjects();
-
-		// Now we read the Throwable object that was saved
-		// WARNING - the grammar says it is a Throwable, but the
-		// WriteAbortedException
-		// constructor takes an Exception. So, we read an Exception from the
-		// stream
-		Exception exc = (Exception) readObject();
-
-		// We reset the receiver's state (the grammar has "reset" in normal
-		// font)
-		resetSeenObjects();
-		return exc;
-	}
-
-	/**
-	 * Reads a collection of field descriptors (name, type name, etc) for the
-	 * class descriptor <code>cDesc</code> (an <code>ObjectStreamClass</code>)
-	 * 
-	 * @param cDesc
-	 *            The class descriptor (an <code>ObjectStreamClass</code>)
-	 *            for which to write field information
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the field
-	 *             descriptors.
-	 * @throws ClassNotFoundException
-	 *             If a class for one of the field types could not be found
-	 * 
-	 * @see #readObject()
-	 */
-	private void readFieldDescriptors(ObjectStreamClass cDesc)
-			throws ClassNotFoundException, IOException {
-		short numFields = input.readShort();
-		ObjectStreamField[] fields = new ObjectStreamField[numFields];
-
-		// We set it now, but each element will be inserted in the array further
-		// down
-		cDesc.setLoadFields(fields);
-
-		// Check ObjectOutputStream.writeFieldDescriptors
-		for (short i = 0; i < numFields; i++) {
-			char typecode = (char) input.readByte();
-			String fieldName = input.readUTF();
-			boolean isPrimType = ObjectStreamClass.isPrimitiveType(typecode);
-			String classSig;
-			if (isPrimType) {
-				classSig = String.valueOf(typecode);
-			} else {
-				// The spec says it is a UTF, but experience shows they dump
-				// this String
-				// using writeObject (unlike the field name, which is saved with
-				// writeUTF)
-				classSig = (String) readObject();
-			}
-			ObjectStreamField f = new ObjectStreamField(classSig, fieldName);
-			fields[i] = f;
-		}
-	}
-
-	/**
-	 * Reads the fields of the object being read from the stream. The stream
-	 * will use the currently active <code>getField</code> object, allowing
-	 * users to load emulated fields, for cross-loading compatibility when a
-	 * class definition changes.
-	 * 
-	 * @return the fields being read
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened
-	 * @throws ClassNotFoundException
-	 *             If a class of an object being de-serialized can not be found
-	 * @throws NotActiveException
-	 *             If there is no object currently being loaded (invalid to call
-	 *             this method)
-	 */
-
-	public GetField readFields() throws IOException, ClassNotFoundException,
-			NotActiveException {
-		// We can't be called from just anywhere. There are rules.
-		if (currentObject != null) {
-			EmulatedFieldsForLoading result = new EmulatedFieldsForLoading(
-					currentClass);
-			readFieldValues(result);
-			return result;
-		}
-		throw new NotActiveException();
-	}
-
-	/**
-	 * reads a collection of field values for the emulated fields
-	 * <code>emulatedFields</code>
-	 * 
-	 * @param emulatedFields
-	 *            an <code>EmulatedFieldsForLoading</code>, concrete subclass
-	 *            of <code>GetField</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the field values.
-	 * @throws InvalidClassException
-	 *             If an incompatible type is being assigned to an emulated
-	 *             field.
-	 * @throws OptionalDataException
-	 *             If optional data could not be found when reading the
-	 *             exception graph
-	 * 
-	 * @see #readFields
-	 * @see #readObject()
-	 */
-	private void readFieldValues(EmulatedFieldsForLoading emulatedFields)
-			throws OptionalDataException, InvalidClassException, IOException {
-		EmulatedFields.ObjectSlot[] slots = emulatedFields.emulatedFields()
-				.slots();
-		for (int i = 0; i < slots.length; i++) {
-			slots[i].defaulted = false;
-			Class type = slots[i].field.getType();
-			if (type == Integer.TYPE) {
-				slots[i].fieldValue = new Integer(input.readInt());
-			} else if (type == Byte.TYPE) {
-				slots[i].fieldValue = new Byte(input.readByte());
-			} else if (type == Character.TYPE) {
-				slots[i].fieldValue = new Character(input.readChar());
-			} else if (type == Short.TYPE) {
-				slots[i].fieldValue = new Short(input.readShort());
-			} else if (type == Boolean.TYPE) {
-				slots[i].fieldValue = new Boolean(input.readBoolean());
-			} else if (type == Long.TYPE) {
-				slots[i].fieldValue = new Long(input.readLong());
-			} else if (type == Float.TYPE) {
-				slots[i].fieldValue = new Float(input.readFloat());
-			} else if (type == Double.TYPE) {
-				slots[i].fieldValue = new Double(input.readDouble());
-			} else {
-				// Either array or Object
-				try {
-					slots[i].fieldValue = readObject();
-				} catch (ClassNotFoundException cnf) {
-					throw new InvalidClassException(cnf.toString()); // WARNING-
-																		// Not
-																		// sure
-																		// this
-																		// is
-																		// the
-																		// right
-																		// thing
-																		// to
-																		// do.
-																		// Write
-																		// test
-																		// case.
-				}
-			}
-		}
-	}
-
-	/**
-	 * Reads a collection of field values for the class descriptor
-	 * <code>classDesc</code> (an <code>ObjectStreamClass</code>). The
-	 * values will be used to set instance fields in object <code>obj</code>.
-	 * This is the default mechanism, when emulated fields (an
-	 * <code>GetField</code>) are not used. Actual values to load are stored
-	 * directly into the object <code>obj</code>.
-	 * 
-	 * @param obj
-	 *            Instance in which the fields will be set.
-	 * @param classDesc
-	 *            A class descriptor (an <code>ObjectStreamClass</code>)
-	 *            defining which fields should be loaded.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the field values.
-	 * @throws InvalidClassException
-	 *             If an incompatible type is being assigned to an emulated
-	 *             field.
-	 * @throws OptionalDataException
-	 *             If optional data could not be found when reading the
-	 *             exception graph
-	 * @throws ClassNotFoundException
-	 *             If a class of an object being de-serialized can not be found
-	 * 
-	 * @see #readFields
-	 * @see #readObject()
-	 */
-	private void readFieldValues(Object obj, ObjectStreamClass classDesc)
-			throws OptionalDataException, ClassNotFoundException, IOException {
-		// Now we must read all fields and assign them to the receiver
-		ObjectStreamField[] fields = classDesc.getLoadFields();
-		Class declaringClass = classDesc.forClass();
-		if (declaringClass == null && mustResolve)
-			throw new ClassNotFoundException(classDesc.getName());
-
-		for (int i = 0; i < fields.length; i++) {
-			ObjectStreamField fieldDesc = fields[i];
-			// Now we read&set the instance field whose name is described by the
-			// fieldDesc we read before
-
-			// Code duplication starts, just because Java is typed
-			if (fieldDesc.isPrimitive()) {
-				try {
-					switch (fieldDesc.getTypeCode()) {
-					case 'B':
-						setField(obj, declaringClass, fieldDesc.getName(),
-								input.readByte());
-						break;
-					case 'C':
-						setField(obj, declaringClass, fieldDesc.getName(),
-								input.readChar());
-						break;
-					case 'D':
-						setField(obj, declaringClass, fieldDesc.getName(),
-								input.readDouble());
-						break;
-					case 'F':
-						setField(obj, declaringClass, fieldDesc.getName(),
-								input.readFloat());
-						break;
-					case 'I':
-						setField(obj, declaringClass, fieldDesc.getName(),
-								input.readInt());
-						break;
-					case 'J':
-						setField(obj, declaringClass, fieldDesc.getName(),
-								input.readLong());
-						break;
-					case 'S':
-						setField(obj, declaringClass, fieldDesc.getName(),
-								input.readShort());
-						break;
-					case 'Z':
-						setField(obj, declaringClass, fieldDesc.getName(),
-								input.readBoolean());
-						break;
-					default:
-						throw new StreamCorruptedException(org.apache.harmony.luni.util.Msg
-								.getString("K00d5", fieldDesc.getTypeCode())); //$NON-NLS-1$
-					}
-				} catch (NoSuchFieldError err) {
-				}
-			} else {
-				// Object type (array included).
-				String fieldName = fieldDesc.getName();
-				boolean setBack = false;
-				ObjectStreamField field = classDesc.getField(fieldName);
-				if (mustResolve && field == null) {
-					setBack = true;
-					mustResolve = false;
-				}
-				Object toSet;
-				if (field != null && field.isUnshared())
-					toSet = readUnshared();
-				else
-					toSet = readObject();
-				if (setBack)
-					mustResolve = true;
-				if (field != null) {
-					if (toSet != null) {
-						Class fieldType = field.getType();
-						Class valueType = toSet.getClass();
-						if (!fieldType.isAssignableFrom(valueType))
-							throw new ClassCastException(org.apache.harmony.luni.util.Msg
-									.getString("K00d4", new String[] { //$NON-NLS-1$
-											fieldType.toString(),
-											valueType.toString(),
-											classDesc.getName() + "." //$NON-NLS-1$
-													+ fieldName }));
-						try {
-							objSetField(obj, declaringClass, fieldName, field
-									.getTypeString(), toSet);
-						} catch (NoSuchFieldError e) {
-						}
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * Reads and returns primitive data of type float read from the receiver
-	 * 
-	 * @return A float saved as primitive data using
-	 *         <code>ObjectOutputStream.writeFloat()</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public float readFloat() throws IOException {
-		return primitiveTypes.readFloat();
-	}
-
-	/**
-	 * Reads bytes from the receiver into the byte array <code>buffer</code>.
-	 * This method will block until <code>buffer.length</code> number of bytes
-	 * have been read.
-	 * 
-	 * @param buffer
-	 *            the buffer to read bytes into
-	 * 
-	 * @throws IOException
-	 *             if a problem occurs reading from this stream.
-	 */
-	public void readFully(byte[] buffer) throws IOException {
-		primitiveTypes.readFully(buffer);
-	}
-
-	/**
-	 * Reads bytes from the receiver into the byte array <code>buffer</code>.
-	 * This method will block until <code>length</code> number of bytes have
-	 * been read.
-	 * 
-	 * @param buffer
-	 *            the byte array in which to store the read bytes.
-	 * @param offset
-	 *            the offset in <code>buffer</code> to store the read bytes.
-	 * @param length
-	 *            the maximum number of bytes to store in <code>buffer</code>.
-	 * 
-	 * @throws IOException
-	 *             if a problem occurs reading from this stream.
-	 */
-	public void readFully(byte[] buffer, int offset, int length)
-			throws IOException {
-		primitiveTypes.readFully(buffer, offset, length);
-	}
-
-	/**
-	 * Walks the hierarchy of classes described by class descriptor
-	 * <code>classDesc</code> and reads the field values corresponding to
-	 * fields declared by the corresponding class descriptor. The instance to
-	 * store field values into is <code>object</code>. If the class
-	 * (corresponding to class descriptor <code>classDesc</code>) defines
-	 * private instance method <code>readObject</code> it will be used to load
-	 * field values.
-	 * 
-	 * @param object
-	 *            Instance into which stored field values loaded.
-	 * @param classDesc
-	 *            A class descriptor (an <code>ObjectStreamClass</code>)
-	 *            defining which fields should be loaded.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the field values in
-	 *             the hierarchy.
-	 * @throws ClassNotFoundException
-	 *             If a class for one of the field types could not be found
-	 * @throws NotActiveException
-	 *             If <code>defaultReadObject</code> is called from the wrong
-	 *             context.
-	 * 
-	 * @see #defaultReadObject
-	 * @see #readObject()
-	 */
-	private void readHierarchy(Object object, ObjectStreamClass classDesc)
-			throws IOException, ClassNotFoundException, NotActiveException {
-		// We can't be called from just anywhere. There are rules.
-		if (object == null && mustResolve)
-			throw new NotActiveException();
-
-		ArrayList<ObjectStreamClass> streamClassList = new ArrayList<ObjectStreamClass>(32);
-		ObjectStreamClass nextStreamClass = classDesc;
-		while (nextStreamClass != null) {
-			streamClassList.add(0, nextStreamClass);
-			nextStreamClass = nextStreamClass.getSuperclass();
-		}
-		if (object == null) {
-			Iterator streamIt = streamClassList.iterator();
-			while (streamIt.hasNext()) {
-				ObjectStreamClass streamClass = (ObjectStreamClass) streamIt
-						.next();
-				readObjectForClass(object, streamClass);
-			}
-		} else {
-			ArrayList<Class> classList = new ArrayList<Class>(32);
-			Class nextClass = object.getClass();
-			while (nextClass != null) {
-				Class testClass = nextClass.getSuperclass();
-				if (testClass != null) {
-					classList.add(0, nextClass);
-				}
-				nextClass = testClass;
-			}
-			int lastIndex = 0;
-			for (int i = 0; i < classList.size(); i++) {
-				Class superclass = (Class) classList.get(i);
-				int index = findStreamSuperclass(superclass, streamClassList,
-						lastIndex);
-				if (index == -1) {
-					readObjectNoData(object, superclass);
-				} else {
-					for (int j = lastIndex; j <= index; j++) {
-						readObjectForClass(object,
-								(ObjectStreamClass) streamClassList.get(j));
-					}
-					lastIndex = index + 1;
-				}
-			}
-		}
-	}
-
-	private int findStreamSuperclass(Class cl, ArrayList classList,
-			int lastIndex) {
-		for (int i = lastIndex; i < classList.size(); i++) {
-			if (cl.getName().equals(
-					((ObjectStreamClass) classList.get(i)).getName())) {
-				return i;
-			}
-		}
-		return -1;
-	}
-
-	private void readObjectNoData(Object object, Class cl)
-			throws ObjectStreamException {
-		if (!ObjectStreamClass.isSerializable(cl)) {
-			return;
-		}
-
-		final Method readMethod = ObjectStreamClass
-				.getPrivateReadObjectNoDataMethod(cl);
-		if (readMethod != null) {
-			AccessController.doPrivileged(new PriviAction(readMethod));
-			try {
-				readMethod.invoke(object, new Object[0]);
-			} catch (InvocationTargetException e) {
-				Throwable ex = e.getTargetException();
-				if (ex instanceof RuntimeException)
-					throw (RuntimeException) ex;
-				else if (ex instanceof Error)
-					throw (Error) ex;
-				throw (ObjectStreamException) ex;
-			} catch (IllegalAccessException e) {
-				throw new RuntimeException(e.toString());
-			}
-		}
-	}
-
-	private void readObjectForClass(Object object, ObjectStreamClass classDesc)
-			throws IOException, ClassNotFoundException, NotActiveException {
-		// Have to do this before calling defaultreadObject or anything that
-		// calls defaultReadObject
-		currentObject = object;
-		currentClass = classDesc;
-
-		boolean hadWriteMethod = (classDesc.getFlags() & SC_WRITE_METHOD) > 0;
-		Class targetClass = classDesc.forClass();
-		final Method readMethod;
-		if (targetClass == null || !mustResolve)
-			readMethod = null;
-		else
-			readMethod = ObjectStreamClass
-					.getPrivateReadObjectMethod(targetClass);
-		try {
-			if (readMethod != null) {
-				// We have to be able to fetch its value, even if it is private
-				AccessController.doPrivileged(new PriviAction(readMethod));
-				try {
-					readMethod.invoke(object, new Object[] { this });
-				} catch (InvocationTargetException e) {
-					Throwable ex = e.getTargetException();
-					if (ex instanceof ClassNotFoundException)
-						throw (ClassNotFoundException) ex;
-					else if (ex instanceof RuntimeException)
-						throw (RuntimeException) ex;
-					else if (ex instanceof Error)
-						throw (Error) ex;
-					throw (IOException) ex;
-				} catch (IllegalAccessException e) {
-					throw new RuntimeException(e.toString());
-				}
-			} else {
-				defaultReadObject();
-			}
-			if (hadWriteMethod) {
-				discardData();
-			}
-		} finally {
-			// Cleanup, needs to run always so that we can later detect invalid
-			// calls to defaultReadObject
-			currentObject = null; // We did not set this, so we do not need to
-									// clean it
-			currentClass = null;
-		}
-	}
-
-	/**
-	 * Reads and returns primitive data of type int read from the receiver
-	 * 
-	 * @return an int saved as primitive data using
-	 *         <code>ObjectOutputStream.writeInt()</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public int readInt() throws IOException {
-		return primitiveTypes.readInt();
-	}
-
-	/**
-	 * Reads and returns the next line (primitive data of type String) read from
-	 * the receiver
-	 * 
-	 * @return a String saved as primitive data using
-	 *         <code>ObjectOutputStream.writeLine()</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 * 
-	 * @deprecated Use BufferedReader
-	 */
-	public String readLine() throws IOException {
-		return primitiveTypes.readLine();
-	}
-
-	/**
-	 * Reads and returns primitive data of type long read from the receiver
-	 * 
-	 * @return a long saved as primitive data using
-	 *         <code>ObjectOutputStream.writeLong()</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public long readLong() throws IOException {
-		return primitiveTypes.readLong();
-	}
-
-	/**
-	 * Read a new array from the receiver. It is assumed the array has not been
-	 * read yet (not a cyclic reference). Return the array read.
-	 * 
-	 * @param unshared
-	 *            read the object unshared
-	 * @return the array read
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the array.
-	 * @throws ClassNotFoundException
-	 *             If a class for one of the objects could not be found
-	 * @throws OptionalDataException
-	 *             If optional data could not be found when reading the array.
-	 */
-	private Object readNewArray(boolean unshared) throws OptionalDataException,
-			ClassNotFoundException, IOException {
-		ObjectStreamClass classDesc = readClassDesc();
-
-		if (classDesc == null)
-			throw new InvalidClassException(org.apache.harmony.luni.util.Msg
-					.getString("K00d1")); //$NON-NLS-1$
-
-		Integer newHandle = new Integer(nextHandle());
-
-		// Array size
-		int size = input.readInt();
-		Class arrayClass = classDesc.forClass();
-		Class componentType = arrayClass.getComponentType();
-		Object result = java.lang.reflect.Array
-				.newInstance(componentType, size);
-		if (!unshared) {
-			registerObjectRead(result, newHandle);
-		}
-
-		// Now we have code duplication just because Java is typed. We have to
-		// read N elements
-		// and assign to array positions, but we must typecast the array first,
-		// and also
-		// call different methods depending on the elements.
-
-		if (componentType.isPrimitive()) {
-			if (componentType == Integer.TYPE) {
-				int[] intArray = (int[]) result;
-				for (int i = 0; i < size; i++)
-					intArray[i] = input.readInt();
-			} else if (componentType == Byte.TYPE) {
-				byte[] byteArray = (byte[]) result;
-				input.readFully(byteArray, 0, size);
-			} else if (componentType == Character.TYPE) {
-				char[] charArray = (char[]) result;
-				for (int i = 0; i < size; i++)
-					charArray[i] = input.readChar();
-			} else if (componentType == Short.TYPE) {
-				short[] shortArray = (short[]) result;
-				for (int i = 0; i < size; i++)
-					shortArray[i] = input.readShort();
-			} else if (componentType == Boolean.TYPE) {
-				boolean[] booleanArray = (boolean[]) result;
-				for (int i = 0; i < size; i++)
-					booleanArray[i] = input.readBoolean();
-			} else if (componentType == Long.TYPE) {
-				long[] longArray = (long[]) result;
-				for (int i = 0; i < size; i++)
-					longArray[i] = input.readLong();
-			} else if (componentType == Float.TYPE) {
-				float[] floatArray = (float[]) result;
-				for (int i = 0; i < size; i++)
-					floatArray[i] = input.readFloat();
-			} else if (componentType == Double.TYPE) {
-				double[] doubleArray = (double[]) result;
-				for (int i = 0; i < size; i++)
-					doubleArray[i] = input.readDouble();
-			} else
-				throw new ClassNotFoundException(org.apache.harmony.luni.util.Msg
-						.getString("K00d7", classDesc.getName())); //$NON-NLS-1$
-		} else {
-			// Array of Objects
-			Object[] objectArray = (Object[]) result;
-			for (int i = 0; i < size; i++)
-				objectArray[i] = readObject();
-		}
-		if (enableResolve) {
-			result = resolveObject(result);
-			registerObjectRead(result, newHandle);
-		}
-		return result;
-	}
-
-	/**
-	 * Reads a new class from the receiver. It is assumed the class has not been
-	 * read yet (not a cyclic reference). Return the class read.
-	 * 
-	 * @param unshared
-	 *            read the object unshared
-	 * @return The <code>java.lang.Class</code> read from the stream.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the class.
-	 * @throws ClassNotFoundException
-	 *             If a class for one of the objects could not be found
-	 */
-	private Class readNewClass(boolean unshared) throws ClassNotFoundException,
-			IOException {
-		ObjectStreamClass classDesc = readClassDesc();
-
-		if (classDesc != null) {
-			Integer newHandle = new Integer(nextHandle());
-			Class localClass = classDesc.forClass();
-			if (localClass != null && !unshared)
-				registerObjectRead(localClass, newHandle);
-			return localClass;
-		}
-		throw new InvalidClassException(org.apache.harmony.luni.util.Msg.getString("K00d1")); //$NON-NLS-1$
-	}
-
-	/**
-	 * Reads a new class descriptor from the receiver. It is assumed the class
-	 * descriptor has not been read yet (not a cyclic reference). Return the
-	 * class descriptor read.
-	 * 
-	 * @param unshared
-	 *            read the object unshared
-	 * @return The <code>ObjectStreamClass</code> read from the stream.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the class
-	 *             descriptor.
-	 * @throws ClassNotFoundException
-	 *             If a class for one of the objects could not be found
-	 */
-	private ObjectStreamClass readNewClassDesc(boolean unshared)
-			throws ClassNotFoundException, IOException {
-		// So read...() methods can be used by
-		// subclasses during readClassDescriptor()
-		primitiveData = input;
-		Integer oldHandle = descriptorHandle;
-		descriptorHandle = new Integer(nextHandle());
-		ObjectStreamClass newClassDesc = readClassDescriptor();
-		if (descriptorHandle != null && !unshared) {
-			registerObjectRead(newClassDesc, descriptorHandle);
-		}
-		descriptorHandle = oldHandle;
-		primitiveData = emptyStream;
-
-		// We need to map classDesc to class.
-		try {
-			newClassDesc.setClass(resolveClass(newClassDesc));
-			// Check SUIDs
-			verifySUID(newClassDesc);
-		} catch (ClassNotFoundException e) {
-			if (mustResolve)
-				throw e;
-			// Just continue, the class may not be required
-		}
-
-		// Resolve the field signatures using the class loader of the
-		// resolved class
-		ObjectStreamField[] fields = newClassDesc.getLoadFields();
-		ClassLoader loader = newClassDesc.forClass() == null ? callerClassLoader
-				: newClassDesc.forClass().getClassLoader();
-		for (int i = 0; i < fields.length; i++)
-			fields[i].resolve(loader);
-
-		// Consume unread class annotation data and TC_ENDBLOCKDATA
-		discardData();
-		newClassDesc.setSuperclass(readClassDesc());
-
-		return newClassDesc;
-	}
-
-	/**
-	 * Reads a new proxy class descriptor from the receiver. It is assumed the
-	 * proxy class descriptor has not been read yet (not a cyclic reference).
-	 * Return the proxy class descriptor read.
-	 * 
-	 * @return The <code>Class</code> read from the stream.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the class
-	 *             descriptor.
-	 * @throws ClassNotFoundException
-	 *             If a class for one of the objects could not be found
-	 */
-	private Class readNewProxyClassDesc() throws ClassNotFoundException,
-			IOException {
-		int count = input.readInt();
-		String[] interfaceNames = new String[count];
-		for (int i = 0; i < count; i++)
-			interfaceNames[i] = input.readUTF();
-		Class proxy = resolveProxyClass(interfaceNames);
-		// Consume unread class annotation data and TC_ENDBLOCKDATA
-		discardData();
-		return proxy;
-	}
-
-	/**
-	 * Reads a new class descriptor from the receiver. Return the class
-	 * descriptor read.
-	 * 
-	 * @return The <code>ObjectStreamClass</code> read from the stream.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the class
-	 *             descriptor.
-	 * @throws ClassNotFoundException
-	 *             If a class for one of the objects could not be found
-	 */
-	protected ObjectStreamClass readClassDescriptor() throws IOException,
-			ClassNotFoundException {
-		if (descriptorHandle == null)
-			throw new NotActiveException();
-
-		ObjectStreamClass newClassDesc = new ObjectStreamClass();
-		newClassDesc.setName(input.readUTF());
-		newClassDesc.setSerialVersionUID(input.readLong());
-		newClassDesc.setFlags(input.readByte());
-
-		// We must register the class descriptor before reading field
-		// descriptors.
-		registerObjectRead(newClassDesc, descriptorHandle);
-		descriptorHandle = null;
-
-		readFieldDescriptors(newClassDesc);
-		return newClassDesc;
-	}
-
-	/**
-	 * Retrieves the proxy class corresponding to the interface names.
-	 * 
-	 * @param interfaceNames
-	 *            The interfaces used to create the proxy class
-	 * @return A proxy class
-	 * 
-	 * @throws IOException
-	 *             If any IO problem occurred when trying to load the class.
-	 * @throws ClassNotFoundException
-	 *             If the proxy class cannot be created
-	 */
-	protected Class<?> resolveProxyClass(String[] interfaceNames)
-			throws IOException, ClassNotFoundException {
-		ClassLoader loader = org.apache.harmony.kernel.vm.VM.getNonBootstrapClassLoader();
-		Class[] interfaces = new Class[interfaceNames.length];
-		for (int i = 0; i < interfaceNames.length; i++) {
-			interfaces[i] = Class.forName(interfaceNames[i], false, loader);
-		}
-		try {
-			return Proxy.getProxyClass(loader, interfaces);
-		} catch (IllegalArgumentException e) {
-			throw new ClassNotFoundException(e.toString(), e);
-		}
-	}
-
-	/**
-	 * Write a new handfle describing a cyclic reference from the stream.
-	 * 
-	 * @return the handle read
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the handle
-	 */
-	private Integer readNewHandle() throws IOException {
-		return new Integer(input.readInt());
-	}
-
-	/**
-	 * Read a new object from the stream. It is assumed the object has not been
-	 * loade yet (not a cyclic reference). Return the object read.
-	 * 
-	 * If the object implements <code>Externalizable</code> its
-	 * <code>readExternal</code> is called. Otherwise, all fields described by
-	 * the class hierarchy are loaded. Each class can define how its declared
-	 * instance fields are laoded by defining a private method
-	 * <code>readObject</code>
-	 * 
-	 * @param unshared
-	 *            read the object unshared
-	 * @return the object read
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the object.
-	 * @throws OptionalDataException
-	 *             If optional data could not be found when reading the object
-	 *             graph
-	 * @throws ClassNotFoundException
-	 *             If a class for one of the objects could not be found
-	 */
-	private Object readNewObject(boolean unshared)
-			throws OptionalDataException, ClassNotFoundException, IOException {
-		ObjectStreamClass classDesc = readClassDesc();
-
-		if (classDesc == null)
-			throw new InvalidClassException(org.apache.harmony.luni.util.Msg
-					.getString("K00d1")); //$NON-NLS-1$
-
-		Integer newHandle = new Integer(nextHandle());
-
-		// Note that these values come from the Stream, and in fact it could be
-		// that the
-		// classes have been changed so that the info below now conflicts with
-		// the newer class
-		boolean wasExternalizable = (classDesc.getFlags() & SC_EXTERNALIZABLE) > 0;
-		boolean wasSerializable = (classDesc.getFlags() & SC_SERIALIZABLE) > 0;
-
-		// Maybe we should cache the values above in classDesc ? It may be the
-		// case that when reading classDesc
-		// we may need to read more stuff depending on the values above
-
-		Class objectClass = classDesc.forClass();
-
-		Object result, registeredResult = null;
-		if (objectClass != null) {
-			// The class of the instance may not be the same as the class of the
-			// constructor to run
-			Class constructorClass = objectClass; // This is the constructor
-													// to run if Externalizable
-
-			// WARNING - What if the object is serializable and externalizable ?
-			// Is that possible ?
-			if (wasSerializable) {
-				// Now we must run the constructor of the class just above the
-				// one that implements Serializable
-				// so that slots that were not dumped can be initialized
-				// properly
-				while (constructorClass != null
-						& ObjectStreamClass.isSerializable(constructorClass)) {
-					constructorClass = constructorClass.getSuperclass();
-				}
-			}
-
-			// Fetch the empty constructor
-			Constructor constructor;
-			try {
-				constructor = constructorClass
-						.getDeclaredConstructor(ObjectStreamClass.EMPTY_CONSTRUCTOR_PARAM_TYPES);
-			} catch (NoSuchMethodException nsmEx) {
-				constructor = null;
-			}
-
-			// Has to have an empty constructor
-			if (constructor == null)
-				throw new InvalidClassException(constructorClass.getName(),
-						org.apache.harmony.luni.util.Msg.getString("K00dc")); //$NON-NLS-1$
-
-			int constructorModifiers = constructor.getModifiers();
-
-			// Now we must check if the empty constructor is visible to the
-			// instantiation class
-			if (Modifier.isPrivate(constructorModifiers)
-					|| (wasExternalizable && !Modifier
-							.isPublic(constructorModifiers)))
-				throw new InvalidClassException(constructorClass.getName(),
-						org.apache.harmony.luni.util.Msg.getString("K00dc")); //$NON-NLS-1$
-
-			// We know we are testing from a subclass, so the only other case
-			// where the visibility
-			// is not allowed is when the constructor has default visibility and
-			// the instantiation class
-			// is in a different package than the constructor class
-			if (!Modifier.isPublic(constructorModifiers)
-					&& !Modifier.isProtected(constructorModifiers)) {
-				// Not public, not private and not protected...means default
-				// visibility. Check if same package
-				if (!inSamePackage(constructorClass, objectClass))
-					throw new InvalidClassException(constructorClass.getName(),
-							org.apache.harmony.luni.util.Msg.getString("K00dc")); //$NON-NLS-1$
-			}
-
-			// Now we know which class to instantiate and which constructor to
-			// run. We are allowed to run the constructor.
-			result = newInstance(objectClass, constructorClass);
-			if (!unshared) {
-				registerObjectRead(result, newHandle);
-			}
-			registeredResult = result;
-		} else {
-			result = null;
-		}
-
-		try {
-			// This is how we know what to do in defaultReadObject. And it is
-			// also
-			// used by defaultReadObject to check if it was called from an
-			// invalid place.
-			// It also allows readExternal to call defaultReadObject and have it
-			// work.
-			currentObject = result;
-			currentClass = classDesc;
-
-			// If Externalizable, just let the object read itself
-			if (wasExternalizable) {
-				boolean blockData = (classDesc.getFlags() & SC_BLOCK_DATA) > 0;
-				if (!blockData)
-					primitiveData = input;
-				if (mustResolve) {
-					Externalizable extern = (Externalizable) result;
-					extern.readExternal(this);
-				}
-				if (blockData) {
-					// Similar to readHierarchy. Anything not read by
-					// readExternal has to be consumed here
-					discardData();
-				} else {
-					primitiveData = emptyStream;
-				}
-			} else {
-				// If we got here, it is Serializable but not Externalizable.
-				// Walk the hierarchy reading each class' slots
-				readHierarchy(result, classDesc);
-			}
-		} finally {
-			// Cleanup, needs to run always so that we can later detect invalid
-			// calls to defaultReadObject
-			currentObject = null;
-			currentClass = null;
-		}
-
-		if (objectClass != null) {
-			Object readResolveMethod = readResolveCache.get(objectClass);
-			if (readResolveMethod != this) {
-				if (readResolveMethod == null) {
-					final Method readResolve = ObjectStreamClass
-							.methodReadResolve(objectClass);
-					if (readResolve == null) {
-						readResolveCache.put(objectClass, this);
-						readResolveMethod = null;
-					} else {
-						// Has replacement method
-						AccessController.doPrivileged(new PriviAction(
-								readResolve));
-						readResolveCache.put(objectClass, readResolve);
-						readResolveMethod = readResolve;
-					}
-				}
-				if (readResolveMethod != null) {
-					try {
-						result = ((Method) readResolveMethod).invoke(result,
-								null);
-					} catch (IllegalAccessException iae) {
-					} catch (InvocationTargetException ite) {
-						Throwable target = ite.getTargetException();
-						if (target instanceof ObjectStreamException)
-							throw (ObjectStreamException) target;
-						else if (target instanceof Error)
-							throw (Error) target;
-						else
-							throw (RuntimeException) target;
-					}
-				}
-			}
-		}
-		// We get here either if class-based replacement was not needed or if it
-		// was needed
-		// but produced the same object or if it could not be computed.
-
-		// The object to return is the one we instantiated or a replacement for
-		// it
-		if (result != null && enableResolve)
-			result = resolveObject(result);
-		if (registeredResult != result && !unshared) {
-			registerObjectRead(result, newHandle);
-		}
-		return result;
-	}
-
-	/**
-	 * Read a new String in UTF format from the receiver. Return the string
-	 * read.
-	 * 
-	 * @param unshared
-	 *            read the object unshared
-	 * @return the string just read.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the String.
-	 */
-	private Object readNewString(boolean unshared) throws IOException {
-		Object result = input.readUTF();
-		if (enableResolve)
-			result = resolveObject(result);
-		int newHandle = nextHandle();
-		if (!unshared) {
-			registerObjectRead(result, new Integer(newHandle));
-		}
-		return result;
-	}
-
-	/**
-	 * Read a new String in UTF format from the receiver. Return the string
-	 * read.
-	 * 
-	 * @param unshared
-	 *            read the object unshared
-	 * @return the string just read.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the String.
-	 */
-	private Object readNewLongString(boolean unshared) throws IOException {
-		long length = input.readLong();
-		Object result = input.decodeUTF((int) length);
-		if (enableResolve)
-			result = resolveObject(result);
-		int newHandle = nextHandle();
-		if (!unshared) {
-			registerObjectRead(result, new Integer(newHandle));
-		}
-		return result;
-	}
-
-	/**
-	 * Read the next object from the receiver's underlying stream.
-	 * 
-	 * @return the new object read.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the object
-	 * @throws ClassNotFoundException
-	 *             If the class of one of the objects in the object graph could
-	 *             not be found
-	 * @throws OptionalDataException
-	 *             If primitive data types were found instead of an object.
-	 * 
-	 * @see ObjectOutputStream#writeObject(Object)
-	 */
-	public final Object readObject() throws OptionalDataException,
-			ClassNotFoundException, IOException {
-		return readObject(false);
-	}
-
-	/**
-	 * Read the next unshared object from the receiver's underlying stream.
-	 * 
-	 * @return the new object read.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the object
-	 * @throws ClassNotFoundException
-	 *             If the class of one of the objects in the object graph could
-	 *             not be found
-	 * 
-	 * @see ObjectOutputStream#writeUnshared
-	 */
-	public Object readUnshared() throws IOException, ClassNotFoundException {
-		return readObject(true);
-	}
-
-	private Object readObject(boolean unshared) throws OptionalDataException,
-			ClassNotFoundException, IOException {
-		boolean restoreInput = (primitiveData == input);
-		if (restoreInput) {
-			primitiveData = emptyStream;
-		}
-
-		// This is the spec'ed behavior in JDK 1.2. Very bizarre way to allow
-		// behavior overriding.
-		if (subclassOverridingImplementation && !unshared)
-			return readObjectOverride();
-
-		// If we still had primitive types to read, should we discard them
-		// (reset the primitiveTypes stream)
-		// or leave as is, so that attempts to read primitive types won't read
-		// 'past data' ???
-		Object result;
-		try {
-			// We need this so we can tell when we are returning to the
-			// original/outside caller
-			if (++nestedLevels == 1) {
-				// Remember the caller's class loader
-				callerClassLoader = org.apache.harmony.kernel.vm.VM
-						.getNonBootstrapClassLoader();
-			}
-
-			result = readNonPrimitiveContent(unshared);
-			if (restoreInput) {
-				primitiveData = input;
-			}
-		} finally {
-			// We need this so we can tell when we are returning to the
-			// original/outside caller
-			if (--nestedLevels == 0) {
-				// We are going to return to the original caller, perform
-				// cleanups.
-				callerClassLoader = null; // No more need to remember the
-											// caller's class loader
-			}
-		}
-
-		// Done reading this object. Is it time to return to the original caller
-		// ? If so
-		// we need to perform validations first.
-
-		if (nestedLevels == 0 && validations != null) {
-			// We are going to return to the original caller. If validation is
-			// enabled we
-			// need to run them now and then cleanup the validation collection
-			try {
-				for (int i = 0; i < validations.length; i++)
-					validations[i].validator.validateObject();
-			} finally {
-				validations = null;
-			} // validations have to be renewed, since they are only called
-				// from readObject
-		}
-		return result;
-	}
-
-	/**
-	 * Method to be overriden by subclasses to read the next object from the
-	 * receiver's underlying stream.
-	 * 
-	 * @return the new object read.
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the object
-	 * @throws ClassNotFoundException
-	 *             If the class of one of the objects in the object graph could
-	 *             not be found
-	 * @throws OptionalDataException
-	 *             If primitive data types were found instead of an object.
-	 * 
-	 * @see ObjectOutputStream#writeObjectOverride
-	 */
-	protected Object readObjectOverride() throws OptionalDataException,
-			ClassNotFoundException, IOException {
-		// Subclasses must override.
-		throw new IOException();
-	}
-
-	/**
-	 * Reads and returns primitive data of type short from the receiver
-	 * 
-	 * @return a short saved as primitive data using
-	 *         <code>ObjectOutputStream.writeShort()</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public short readShort() throws IOException {
-		return primitiveTypes.readShort();
-	}
-
-	/**
-	 * Reads and validates the ObjectInputStream header from the receiver
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the stream header.
-	 * @throws StreamCorruptedException
-	 *             If the underlying stream does not contain serialized objects
-	 *             that can be read.
-	 */
-	protected void readStreamHeader() throws IOException,
-			StreamCorruptedException {
-		if (input.readShort() == STREAM_MAGIC
-				&& input.readShort() == STREAM_VERSION)
-			return;
-		throw new StreamCorruptedException();
-	}
-
-	/**
-	 * Reads and returns primitive data of type byte (unsigned) from the
-	 * receiver
-	 * 
-	 * @return a byte saved as primitive data using
-	 *         <code>ObjectOutputStream.writeUnsignedByte()</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public int readUnsignedByte() throws IOException {
-		return primitiveTypes.readUnsignedByte();
-	}
-
-	/**
-	 * Reads and returns primitive data of type short (unsigned) from the
-	 * receiver
-	 * 
-	 * @return a short saved as primitive data using
-	 *         <code>ObjectOutputStream.writeUnsignedShort()</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public int readUnsignedShort() throws IOException {
-		return primitiveTypes.readUnsignedShort();
-	}
-
-	/**
-	 * Reads and returns primitive data of type String read in UTF format from
-	 * the receiver
-	 * 
-	 * @return a String saved as primitive data using
-	 *         <code>ObjectOutputStream.writeUTF()</code>
-	 * 
-	 * @throws IOException
-	 *             If an IO exception happened when reading the primitive data.
-	 */
-	public String readUTF() throws IOException {
-		return primitiveTypes.readUTF();
-	}
-
-	/**
-	 * Return the object previously read tagged with handle <code>handle</code>.
-	 * 
-	 * @param handle
-	 *            The handle that this object was assigned when it was read.
-	 * @return the object previusly read.
-	 * 
-	 * @throws InvalidObjectException
-	 *             If there is no previously read object with this handle
-	 */
-	private Object registeredObjectRead(Integer handle)
-			throws InvalidObjectException {
-		return objectsRead.get(handle);
-	}
-
-	/**
-	 * Assume object <code>obj</code> has been read, and assign a handle to
-	 * it, <code>handle</code>.
-	 * 
-	 * @param obj
-	 *            Non-null object being loaded.
-	 * @param handle
-	 *            An Integer, the handle to this object
-	 * 
-	 * @see #nextHandle
-	 */
-	private void registerObjectRead(Object obj, Integer handle) {
-		objectsRead.put(handle, obj);
-	}
-
-	/**
-	 * Register object validator <code>object</code> to be executed to perform
-	 * validation of objects loaded from the receiver. Validations will be run
-	 * in order of decreasing priority, defined by <code>priority</code>.
-	 * 
-	 * @param object
-	 *            An ObjectInputValidation to validate objects loaded.
-	 * @param priority
-	 *            validator priority
-	 * 
-	 * @throws NotActiveException
-	 *             If this method is not called from <code>readObject()</code>
-	 * @throws InvalidObjectException
-	 *             If <code>object</code> is null.
-	 */
-	public synchronized void registerValidation(ObjectInputValidation object,
-			int priority) throws NotActiveException, InvalidObjectException {
-		if (object != null) {
-			// Validation can only be registered when inside readObject calls
-			Object instanceBeingRead = this.currentObject;
-			// We can't be called from just anywhere. There are rules.
-			if (instanceBeingRead != null) {
-				// From now on it is just insertion in a SortedCollection. Since
-				// the Java class
-				// libraries don't provide that, we have to implement it from
-				// scratch here.
-
-				InputValidationDesc desc = new InputValidationDesc();
-				desc.validator = object;
-				desc.priority = priority;
-				// No need for this, validateObject does not take a parameter
-				// desc.toValidate = instanceBeingRead;
-				if (validations == null) {
-					validations = new InputValidationDesc[1];
-					validations[0] = desc;
-				} else {
-					int i = 0;
-					for (; i < validations.length; i++) {
-						InputValidationDesc validation = validations[i];
-						// Sorted, higher priority first.
-						if (priority >= validation.priority)
-							break; // Found the index where to insert
-					}
-					InputValidationDesc[] oldValidations = validations;
-					int currentSize = oldValidations.length;
-					validations = new InputValidationDesc[currentSize + 1];
-					System.arraycopy(oldValidations, 0, validations, 0, i);
-					System.arraycopy(oldValidations, i, validations, i + 1,
-							currentSize - i);
-					validations[i] = desc;
-				}
-			} else
-				throw new NotActiveException();
-		} else
-			throw new InvalidObjectException(org.apache.harmony.luni.util.Msg
-					.getString("K00d9")); //$NON-NLS-1$
-	}
-
-	/**
-	 * Reset the collection of objects already loaded by the receiver.
-	 */
-	private void resetSeenObjects() {
-		objectsRead = new Hashtable<Integer,Object>();
-		currentHandle = baseWireHandle;
-		primitiveData = emptyStream;
-	}
-
-	/**
-	 * Reset the receiver. The collection of objects already read by the
-	 * receiver is reset, and internal structures are also reset so that the
-	 * receiver knows it is in a fresh clean state.
-	 */
-	private void resetState() {
-		resetSeenObjects();
-		hasPushbackTC = false;
-		pushbackTC = 0;
-		// nestedLevels = 0;
-	}
-
-	/**
-	 * Loads the Java class corresponding to the class descriptor
-	 * <code>osClass</code>(ObjectStreamClass) just read from the receiver.
-	 * 
-	 * @param osClass
-	 *            An ObjectStreamClass read from the receiver.
-	 * @return a Class corresponding to the descriptor loaded.
-	 * 
-	 * @throws IOException
-	 *             If any IO problem occurred when trying to load the class.
-	 * @throws ClassNotFoundException
-	 *             If the corresponding class cannot be found.
-	 */
-	protected Class<?> resolveClass(ObjectStreamClass osClass) throws IOException,
-			ClassNotFoundException {
-		// Use the first non-null ClassLoader on the stack. If null, use the
-		// system class loader
-		return Class.forName(osClass.getName(), true, callerClassLoader);
-	}
-
-	/**
-	 * If <code>enableResolveObject()</code> was activated, computes the
-	 * replacement object for the original object <code>object</code> and
-	 * returns the replacement. Otherwise returns <code>object</code>.
-	 * 
-	 * @param object
-	 *            Original object for which a replacement may be defined
-	 * @return a possibly new, replacement object for <code>object</code>
-	 * 
-	 * @throws IOException
-	 *             If any IO problem occurred when trying to resolve the object.
-	 * 
-	 * @see #enableResolveObject
-	 * @see ObjectOutputStream#enableReplaceObject
-	 * @see ObjectOutputStream#replaceObject
-	 */
-	protected Object resolveObject(Object object) throws IOException {
-		// By default no object replacement. Subclasses can override
-		return object;
-	}
-
-	/**
-	 * Set a given declared field named <code>fieldName</code> of
-	 * <code>instance</code> to the new <code>byte</code> value
-	 * <code>value</code>.
-	 * 
-	 * This method could be implemented non-natively on top of java.lang.reflect
-	 * implementations that support the <code>setAccessible</code> API, at the
-	 * expense of extra object creation (java.lang.reflect.Field). Otherwise
-	 * Serialization could not set private fields, except by the use of a native
-	 * method like this one.
-	 * 
-	 * 
-	 * @param instance
-	 *            Object whose field to set
-	 * @param declaringClass
-	 *            <code>instance</code>'s declaring class
-	 * @param fieldName
-	 *            Name of the field to set
-	 * @param value
-	 *            New value for the field
-	 * 
-	 * @throws NoSuchFieldError
-	 *             If the field does not exist.
-	 */
-	private static native void setField(Object instance, Class declaringClass,
-			String fieldName, byte value) throws NoSuchFieldError;
-
-	/**
-	 * Set a given declared field named <code>fieldName</code> of
-	 * <code>instance</code> to the new <code>char</code> value
-	 * <code>value</code>.
-	 * 
-	 * This method could be implemented non-natively on top of java.lang.reflect
-	 * implementations that support the <code>setAccessible</code> API, at the
-	 * expense of extra object creation (java.lang.reflect.Field). Otherwise
-	 * Serialization could not set private fields, except by the use of a native
-	 * method like this one.
-	 * 
-	 * @param instance
-	 *            Object whose field to set
-	 * @param declaringClass
-	 *            <code>instance</code>'s declaring class
-	 * @param fieldName
-	 *            Name of the field to set
-	 * @param value
-	 *            New value for the field
-	 * 
-	 * @throws NoSuchFieldError
-	 *             If the field does not exist.
-	 */
-	private static native void setField(Object instance, Class declaringClass,
-			String fieldName, char value) throws NoSuchFieldError;
-
-	/**
-	 * Set a given declared field named <code>fieldName</code> of
-	 * <code>instance</code> to the new <code>double</code> value
-	 * <code>value</code>.
-	 * 
-	 * This method could be implemented non-natively on top of java.lang.reflect
-	 * implementations that support the <code>setAccessible</code> API, at the
-	 * expense of extra object creation (java.lang.reflect.Field). Otherwise
-	 * Serialization could not set private fields, except by the use of a native
-	 * method like this one.
-	 * 
-	 * @param instance
-	 *            Object whose field to set
-	 * @param declaringClass
-	 *            <code>instance</code>'s declaring class
-	 * @param fieldName
-	 *            Name of the field to set
-	 * @param value
-	 *            New value for the field
-	 * 
-	 * @throws NoSuchFieldError
-	 *             If the field does not exist.
-	 */
-	private static native void setField(Object instance, Class declaringClass,
-			String fieldName, double value) throws NoSuchFieldError;
-
-	/**
-	 * Set a given declared field named <code>fieldName</code> of
-	 * <code>instance</code> to the new <code>float</code> value
-	 * <code>value</code>.
-	 * 
-	 * This method could be implemented non-natively on top of java.lang.reflect
-	 * implementations that support the <code>setAccessible</code> API, at the
-	 * expense of extra object creation (java.lang.reflect.Field). Otherwise
-	 * Serialization could not set private fields, except by the use of a native
-	 * method like this one.
-	 * 
-	 * @param instance
-	 *            Object whose field to set
-	 * @param declaringClass
-	 *            <code>instance</code>'s declaring class
-	 * @param fieldName
-	 *            Name of the field to set
-	 * @param value
-	 *            New value for the field
-	 * 
-	 * @throws NoSuchFieldError
-	 *             If the field does not exist.
-	 */
-	private static native void setField(Object instance, Class declaringClass,
-			String fieldName, float value) throws NoSuchFieldError;
-
-	/**
-	 * Set a given declared field named <code>fieldName</code> of
-	 * <code>instance</code> to the new <code>int</code> value
-	 * <code>value</code>.
-	 * 
-	 * This method could be implemented non-natively on top of java.lang.reflect
-	 * implementations that support the <code>setAccessible</code> API, at the
-	 * expense of extra object creation (java.lang.reflect.Field). Otherwise
-	 * Serialization could not set private fields, except by the use of a native
-	 * method like this one.
-	 * 
-	 * @param instance
-	 *            Object whose field to set
-	 * @param declaringClass
-	 *            <code>instance</code>'s declaring class
-	 * @param fieldName
-	 *            Name of the field to set
-	 * @param value
-	 *            New value for the field
-	 * 
-	 * @throws NoSuchFieldError
-	 *             If the field does not exist.
-	 */
-	private static native void setField(Object instance, Class declaringClass,
-			String fieldName, int value) throws NoSuchFieldError;
-
-	/**
-	 * Set a given declared field named <code>fieldName</code> of
-	 * <code>instance</code> to the new <code>long</code> value
-	 * <code>value</code>.
-	 * 
-	 * This method could be implemented non-natively on top of java.lang.reflect
-	 * implementations that support the <code>setAccessible</code> API, at the
-	 * expense of extra object creation (java.lang.reflect.Field). Otherwise
-	 * Serialization could not set private fields, except by the use of a native
-	 * method like this one.
-	 * 
-	 * @param instance
-	 *            Object whose field to set
-	 * @param declaringClass
-	 *            <code>instance</code>'s declaring class
-	 * @param fieldName
-	 *            Name of the field to set
-	 * @param value
-	 *            New value for the field
-	 * 
-	 * @throws NoSuchFieldError
-	 *             If the field does not exist.
-	 */
-	private static native void setField(Object instance, Class declaringClass,
-			String fieldName, long value) throws NoSuchFieldError;
-
-	/**
-	 * Set a given declared field named <code>fieldName</code> of
-	 * <code>instance</code> to the new value <code>value</code>.
-	 * 
-	 * This method could be implemented non-natively on top of java.lang.reflect
-	 * implementations that support the <code>setAccessible</code> API, at the
-	 * expense of extra object creation (java.lang.reflect.Field). Otherwise
-	 * Serialization could not set private fields, except by the use of a native
-	 * method like this one.
-	 * 
-	 * @param instance
-	 *            Object whose field to set
-	 * @param declaringClass
-	 *            Class which delares the field
-	 * @param fieldName
-	 *            Name of the field to set
-	 * @param fieldTypeName
-	 *            Name of the class defining the type of the field
-	 * @param value
-	 *            New value for the field
-	 * 
-	 * @throws NoSuchFieldError
-	 *             If the field does not exist.
-	 */
-	private static native void objSetField(Object instance,
-			Class declaringClass, String fieldName, String fieldTypeName,
-			Object value) throws NoSuchFieldError;
-
-	/**
-	 * Set a given declared field named <code>fieldName</code> of
-	 * <code>instance</code> to the new <code>short</code> value
-	 * <code>value</code>.
-	 * 
-	 * This method could be implemented non-natively on top of java.lang.reflect
-	 * implementations that support the <code>setAccessible</code> API, at the
-	 * expense of extra object creation (java.lang.reflect.Field). Otherwise
-	 * Serialization could not set private fields, except by the use of a native
-	 * method like this one.
-	 * 
-	 * @param instance
-	 *            Object whose field to set
-	 * @param declaringClass
-	 *            <code>instance</code>'s declaring class
-	 * @param fieldName
-	 *            Name of the field to set
-	 * @param value
-	 *            New value for the field
-	 * 
-	 * @throws NoSuchFieldError
-	 *             If the field does not exist.
-	 */
-	private static native void setField(Object instance, Class declaringClass,
-			String fieldName, short value) throws NoSuchFieldError;
-
-	/**
-	 * Set a given declared field named <code>fieldName</code> of
-	 * <code>instance</code> to the new <code>boolean</code> value
-	 * <code>value</code>.
-	 * 
-	 * This method could be implemented non-natively on top of java.lang.reflect
-	 * implementations that support the <code>setAccessible</code> API, at the
-	 * expense of extra object creation (java.lang.reflect.Field). Otherwise
-	 * Serialization could not set private fields, except by the use of a native
-	 * method like this one.
-	 * 
-	 * @param instance
-	 *            Object whose field to set
-	 * @param declaringClass
-	 *            <code>instance</code>'s declaring class
-	 * @param fieldName
-	 *            Name of the field to set
-	 * @param value
-	 *            New value for the field
-	 * 
-	 * @throws NoSuchFieldError
-	 *             If the field does not exist.
-	 */
-	private static native void setField(Object instance, Class declaringClass,
-			String fieldName, boolean value) throws NoSuchFieldError;
-
-	/**
-	 * Skips <code>length</code> bytes of primitive data from the receiver. It
-	 * should not be used to skip bytes at any arbitrary position; just when
-	 * reading primitive data types (ints, chars, etc).
-	 * 
-	 * 
-	 * @param length
-	 *            How many bytes to skip
-	 * @return number of bytes skipped
-	 * 
-	 * @throws IOException
-	 *             If any IO problem occurred when trying to skip the bytes.
-	 */
-	public int skipBytes(int length) throws IOException {
-		// To be used with available. Ok to call if reading primitive buffer
-		int offset = 0;
-		while (offset < length) {
-			checkReadPrimitiveTypes();
-			long skipped = primitiveData.skip(length - offset);
-			if (skipped == 0)
-				return offset;
-			offset += (int) skipped;
-		}
-		return length;
-	}
-
-	/**
-	 * Verify if the SUID for descriptor <code>loadedStreamClass</code>matches
-	 * the SUID of the corresponding loaded class.
-	 * 
-	 * 
-	 * @param loadedStreamClass
-	 *            An ObjectStreamClass that was loaded from the stream.
-	 * 
-	 * @throws InvalidClassException
-	 *             If teh SUID of the stream class does not match the VM class
-	 * 
-	 */
-	private void verifySUID(ObjectStreamClass loadedStreamClass)
-			throws InvalidClassException {
-		Class localClass = loadedStreamClass.forClass();
-		// Instances of java.lang.Class
-		// are always Serializable, even if their instances aren't (e.g.
-		// java.lang.Object.class).
-		// We cannot call lookup because it returns null if the parameter
-		// represents instances
-		// that cannot be serialized, and that is not what we want. If we are
-		// loading an instance
-		// of java.lang.Class, we better have the corresponding
-		// ObjectStreamClass.
-
-		ObjectStreamClass localStreamClass = ObjectStreamClass
-				.lookupStreamClass(localClass);
-		if (loadedStreamClass.getSerialVersionUID() != localStreamClass
-				.getSerialVersionUID())
-			throw new InvalidClassException(loadedStreamClass.getName(),
-					org.apache.harmony.luni.util.Msg.getString("K00da", loadedStreamClass, //$NON-NLS-1$
-							localStreamClass));
-	}
+        ObjectStreamConstants {
+
+    private static InputStream emptyStream = new ByteArrayInputStream(
+            new byte[0]);
+
+    // If the receiver has already read & not consumed a TC code
+    private boolean hasPushbackTC;
+
+    // Pushback TC code if teh variable above is true
+    private byte pushbackTC;
+
+    // How many nested levels to readObject. When we reach 0 we have to validate
+    // the graph then reset it
+    private int nestedLevels;
+
+    // All objects are assigned an ID (integer handle)
+    private int currentHandle;
+
+    // Where we read from
+    private DataInputStream input;
+
+    // Where we read primitive types from
+    private DataInputStream primitiveTypes;
+
+    // Where we keep primitive type data
+    private InputStream primitiveData = emptyStream;
+
+    // Resolve object is a mechanism for replacement
+    private boolean enableResolve;
+
+    // Table mapping Integer (handle) -> Object
+    private Hashtable<Integer, Object> objectsRead;
+
+    // Used by defaultReadObject
+    private Object currentObject;
+
+    // Used by defaultReadObject

[... 2426 lines stripped ...]


Mime
View raw message