You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2007/01/04 18:47:05 UTC
svn commit: r492652 [7/13] -
/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/
Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/ObjectOutputStream.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/ObjectOutputStream.java?view=diff&rev=492652&r1=492651&r2=492652
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/ObjectOutputStream.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/ObjectOutputStream.java Thu Jan 4 09:47:01 2007
@@ -17,7 +17,6 @@
package java.io;
-
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@@ -109,9 +108,9 @@
/*
* cache for writeReplace methods
*/
- private IdentityHashMap<Class<?>, Object> writeReplaceCache;
+ private IdentityHashMap<Class<?>, Object> writeReplaceCache;
- /**
+ /**
* Inner class to provide access to serializable fields
*/
public static abstract class PutField {
@@ -141,17 +140,17 @@
public abstract void write(ObjectOutput out) throws IOException;
}
- /**
- * Constructs a new <code>ObjectOutputStream</code>. The representation
- * and proper initialization is in the hands of subclasses.
- *
- * @throws IOException
- * @throws SecurityException
- * if subclassing this is not allowed
- *
- * @see SecurityManager#checkPermission(java.security.Permission)
- */
- protected ObjectOutputStream() throws IOException, SecurityException {
+ /**
+ * Constructs a new <code>ObjectOutputStream</code>. The representation
+ * and proper initialization is in the hands of subclasses.
+ *
+ * @throws IOException
+ * @throws SecurityException
+ * if subclassing this is not allowed
+ *
+ * @see SecurityManager#checkPermission(java.security.Permission)
+ */
+ protected ObjectOutputStream() throws IOException, SecurityException {
super();
SecurityManager currentManager = System.getSecurityManager();
if (currentManager != null) {
@@ -164,624 +163,622 @@
this.subclassOverridingImplementation = true;
}
- /**
- * Constructs a new ObjectOutputStream on the OutputStream
- * <code>output</code>. All writes are now filtered through this stream.
- *
- * @param output
- * The non-null OutputStream to filter writes on.
- *
- * @throws IOException
- * If an IO exception happened when writing the object stream
- * header
- */
- public ObjectOutputStream(OutputStream output) throws IOException {
- Class<?> implementationClass = getClass();
- Class<?> thisClass = ObjectOutputStream.class;
- if (implementationClass != thisClass) {
- boolean mustCheck = false;
- try {
- Method method = implementationClass.getMethod("putFields", //$NON-NLS-1$
- ObjectStreamClass.EMPTY_CONSTRUCTOR_PARAM_TYPES);
- mustCheck = method.getDeclaringClass() != thisClass;
- } catch (NoSuchMethodException e) {
- }
- if (!mustCheck) {
- try {
- Method method = implementationClass.getMethod(
- "writeUnshared", //$NON-NLS-1$
- ObjectStreamClass.UNSHARED_PARAM_TYPES);
- mustCheck = method.getDeclaringClass() != thisClass;
- } catch (NoSuchMethodException e) {
- }
- }
- if (mustCheck) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm
- .checkPermission(ObjectStreamConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
- }
- }
- }
- this.output = (output instanceof DataOutputStream) ? (DataOutputStream) output
- : new DataOutputStream(output);
- this.enableReplace = false;
- this.protocolVersion = PROTOCOL_VERSION_2;
- this.subclassOverridingImplementation = false;
- this.writeReplaceCache = new IdentityHashMap<Class<?>, Object>();
-
- resetState();
- this.nestedException = new StreamCorruptedException();
- // So write...() methods can be used by
- // subclasses during writeStreamHeader()
- primitiveTypes = this.output;
- // Has to be done here according to the specification
- writeStreamHeader();
- primitiveTypes = null;
- }
-
- /**
- * Writes optional information for class <code>aClass</code> into the
- * stream represented by the receiver. This optional data can be read when
- * deserializing the class descriptor (ObjectStreamClass) for this class
- * from the input stream. By default no extra data is saved.
- *
- * @param aClass
- * The class to annotate
- *
- * @throws IOException
- * If an IO exception happened when annotating the class.
- *
- * @see ObjectInputStream#resolveClass
- */
- protected void annotateClass(Class<?> aClass) throws IOException {
- // By default no extra info is saved. Subclasses can override
- }
-
- /**
- * Writes optional information for a proxy class into the stream represented
- * by the receiver. This optional data can be read when deserializing the
- * proxy class from the input stream. By default no extra data is saved.
- *
- * @param aClass
- * The proxy class to annotate
- *
- * @throws IOException
- * If an IO exception happened when annotating the class.
- *
- * @see ObjectInputStream#resolveProxyClass
- */
- protected void annotateProxyClass(Class<?> aClass) throws IOException {
- // By default no extra info is saved. Subclasses can override
- }
-
- /**
- * Do the necessary work to see if the receiver can be used to write
- * primitive types like int, char, etc.
- */
- private void checkWritePrimitiveTypes() {
- if (primitiveTypes == null) {
- // If we got here we have no Stream previously created
- // WARNING - if the stream does not grow, this code is wrong
- primitiveTypesBuffer = new ByteArrayOutputStream(128);
- primitiveTypes = new DataOutputStream(primitiveTypesBuffer);
- }
- }
-
- /**
- * Close this ObjectOutputStream. Any buffered data is flushed. This
- * implementation closes the target stream.
- *
- * @throws IOException
- * If an error occurs attempting to close this stream.
- */
- @Override
+ /**
+ * Constructs a new ObjectOutputStream on the OutputStream
+ * <code>output</code>. All writes are now filtered through this stream.
+ *
+ * @param output
+ * The non-null OutputStream to filter writes on.
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the object stream
+ * header
+ */
+ public ObjectOutputStream(OutputStream output) throws IOException {
+ Class<?> implementationClass = getClass();
+ Class<?> thisClass = ObjectOutputStream.class;
+ if (implementationClass != thisClass) {
+ boolean mustCheck = false;
+ try {
+ Method method = implementationClass.getMethod("putFields", //$NON-NLS-1$
+ ObjectStreamClass.EMPTY_CONSTRUCTOR_PARAM_TYPES);
+ mustCheck = method.getDeclaringClass() != thisClass;
+ } catch (NoSuchMethodException e) {
+ }
+ if (!mustCheck) {
+ try {
+ Method method = implementationClass.getMethod(
+ "writeUnshared", //$NON-NLS-1$
+ ObjectStreamClass.UNSHARED_PARAM_TYPES);
+ mustCheck = method.getDeclaringClass() != thisClass;
+ } catch (NoSuchMethodException e) {
+ }
+ }
+ if (mustCheck) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm
+ .checkPermission(ObjectStreamConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
+ }
+ }
+ }
+ this.output = (output instanceof DataOutputStream) ? (DataOutputStream) output
+ : new DataOutputStream(output);
+ this.enableReplace = false;
+ this.protocolVersion = PROTOCOL_VERSION_2;
+ this.subclassOverridingImplementation = false;
+ this.writeReplaceCache = new IdentityHashMap<Class<?>, Object>();
+
+ resetState();
+ this.nestedException = new StreamCorruptedException();
+ // So write...() methods can be used by
+ // subclasses during writeStreamHeader()
+ primitiveTypes = this.output;
+ // Has to be done here according to the specification
+ writeStreamHeader();
+ primitiveTypes = null;
+ }
+
+ /**
+ * Writes optional information for class <code>aClass</code> into the
+ * stream represented by the receiver. This optional data can be read when
+ * deserializing the class descriptor (ObjectStreamClass) for this class
+ * from the input stream. By default no extra data is saved.
+ *
+ * @param aClass
+ * The class to annotate
+ *
+ * @throws IOException
+ * If an IO exception happened when annotating the class.
+ *
+ * @see ObjectInputStream#resolveClass
+ */
+ protected void annotateClass(Class<?> aClass) throws IOException {
+ // By default no extra info is saved. Subclasses can override
+ }
+
+ /**
+ * Writes optional information for a proxy class into the stream represented
+ * by the receiver. This optional data can be read when deserializing the
+ * proxy class from the input stream. By default no extra data is saved.
+ *
+ * @param aClass
+ * The proxy class to annotate
+ *
+ * @throws IOException
+ * If an IO exception happened when annotating the class.
+ *
+ * @see ObjectInputStream#resolveProxyClass
+ */
+ protected void annotateProxyClass(Class<?> aClass) throws IOException {
+ // By default no extra info is saved. Subclasses can override
+ }
+
+ /**
+ * Do the necessary work to see if the receiver can be used to write
+ * primitive types like int, char, etc.
+ */
+ private void checkWritePrimitiveTypes() {
+ if (primitiveTypes == null) {
+ // If we got here we have no Stream previously created
+ // WARNING - if the stream does not grow, this code is wrong
+ primitiveTypesBuffer = new ByteArrayOutputStream(128);
+ primitiveTypes = new DataOutputStream(primitiveTypesBuffer);
+ }
+ }
+
+ /**
+ * Close this ObjectOutputStream. Any buffered data is flushed. This
+ * implementation closes the target stream.
+ *
+ * @throws IOException
+ * If an error occurs attempting to close this stream.
+ */
+ @Override
public void close() throws IOException {
- // First flush what is needed (primitive data, etc)
- flush();
- output.close();
- }
-
- /**
- * Computes the collection of emulated fields that users can manipulate to
- * store a representation different than the one declared by the class of
- * the object being dumped.
- *
- * @see #writeFields
- * @see #writeFieldValues(EmulatedFieldsForDumping)
- */
- private void computePutField() {
- currentPutField = new EmulatedFieldsForDumping(currentClass);
- }
-
- /**
- * Default method to write objects into the receiver. Fields defined in the
- * object's class and superclasses (which are Serializable) will be saved.
- *
- * @throws IOException
- * If an IO error occurs attempting to write the object data
- *
- * @see ObjectInputStream#defaultReadObject
- */
- public void defaultWriteObject() throws IOException {
- // We can't be called from just anywhere. There are rules.
- if (currentObject != null) {
- writeFieldValues(currentObject, currentClass);
- } else {
+ // First flush what is needed (primitive data, etc)
+ flush();
+ output.close();
+ }
+
+ /**
+ * Computes the collection of emulated fields that users can manipulate to
+ * store a representation different than the one declared by the class of
+ * the object being dumped.
+ *
+ * @see #writeFields
+ * @see #writeFieldValues(EmulatedFieldsForDumping)
+ */
+ private void computePutField() {
+ currentPutField = new EmulatedFieldsForDumping(currentClass);
+ }
+
+ /**
+ * Default method to write objects into the receiver. Fields defined in the
+ * object's class and superclasses (which are Serializable) will be saved.
+ *
+ * @throws IOException
+ * If an IO error occurs attempting to write the object data
+ *
+ * @see ObjectInputStream#defaultReadObject
+ */
+ public void defaultWriteObject() throws IOException {
+ // We can't be called from just anywhere. There are rules.
+ if (currentObject == null) {
throw new NotActiveException();
}
- }
+ writeFieldValues(currentObject, currentClass);
+ }
- /**
- * Flushes buffered primitive data into the receiver.
- *
- * @throws IOException
- * If an error occurs attempting to drain the data
- */
- protected void drain() throws IOException {
- if (primitiveTypes == null) {
+ /**
+ * Flushes buffered primitive data into the receiver.
+ *
+ * @throws IOException
+ * If an error occurs attempting to drain the data
+ */
+ protected void drain() throws IOException {
+ if (primitiveTypes == null) {
return;
}
- // If we got here we have a Stream previously created
- int offset = 0;
- byte[] written = primitiveTypesBuffer.toByteArray();
- // Normalize the primitive data
- while (offset < written.length) {
- int toWrite = written.length - offset > 1024 ? 1024
- : written.length - offset;
- if (toWrite < 256) {
- output.writeByte(TC_BLOCKDATA);
- output.writeByte((byte) toWrite);
- } else {
- output.writeByte(TC_BLOCKDATALONG);
- output.writeInt(toWrite);
- }
-
- // write primitive types we had and the marker of end-of-buffer
- output.write(written, offset, toWrite);
- offset += toWrite;
- }
-
- // and now we're clean to a state where we can write an object
- primitiveTypes = null;
- primitiveTypesBuffer = null;
- }
-
- /**
- * Dumps the parameter <code>obj</code> only if it is <code>null</code>
- * or an object that has already been dumped previously.
- *
- * @param obj
- * Object to check if an instance previously dumped by this
- * stream.
- * @return null if it is an instance which has not been dumped yet (and this
- * method does nothing). Integer, if <code>obj</code> is an
- * instance which has been dumped already. In this case this method
- * saves the cyclic reference.
- *
- * @throws IOException
- * If an error occurs attempting to save <code>null</code> or
- * a cyclic reference.
- */
- private Integer dumpCycle(Object obj) throws IOException {
- // If the object has been saved already, save its handle only
- Integer handle = registeredObjectHandleFor(obj);
- if (handle != null) {
- writeCyclicReference(handle);
- return handle;
- }
- return null;
- }
-
- /**
- * 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 boolean the previous configuration (if it was enabled or
- * disabled)
- *
- * @throws SecurityException
- * If the class of the receiver is not trusted
- *
- * @see #replaceObject
- * @see ObjectInputStream#enableResolveObject
- */
- protected boolean enableReplaceObject(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) {
+ // If we got here we have a Stream previously created
+ int offset = 0;
+ byte[] written = primitiveTypesBuffer.toByteArray();
+ // Normalize the primitive data
+ while (offset < written.length) {
+ int toWrite = written.length - offset > 1024 ? 1024
+ : written.length - offset;
+ if (toWrite < 256) {
+ output.writeByte(TC_BLOCKDATA);
+ output.writeByte((byte) toWrite);
+ } else {
+ output.writeByte(TC_BLOCKDATALONG);
+ output.writeInt(toWrite);
+ }
+
+ // write primitive types we had and the marker of end-of-buffer
+ output.write(written, offset, toWrite);
+ offset += toWrite;
+ }
+
+ // and now we're clean to a state where we can write an object
+ primitiveTypes = null;
+ primitiveTypesBuffer = null;
+ }
+
+ /**
+ * Dumps the parameter <code>obj</code> only if it is <code>null</code>
+ * or an object that has already been dumped previously.
+ *
+ * @param obj
+ * Object to check if an instance previously dumped by this
+ * stream.
+ * @return null if it is an instance which has not been dumped yet (and this
+ * method does nothing). Integer, if <code>obj</code> is an
+ * instance which has been dumped already. In this case this method
+ * saves the cyclic reference.
+ *
+ * @throws IOException
+ * If an error occurs attempting to save <code>null</code> or
+ * a cyclic reference.
+ */
+ private Integer dumpCycle(Object obj) throws IOException {
+ // If the object has been saved already, save its handle only
+ Integer handle = registeredObjectHandleFor(obj);
+ if (handle != null) {
+ writeCyclicReference(handle);
+ return handle;
+ }
+ return null;
+ }
+
+ /**
+ * 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 boolean the previous configuration (if it was enabled or
+ * disabled)
+ *
+ * @throws SecurityException
+ * If the class of the receiver is not trusted
+ *
+ * @see #replaceObject
+ * @see ObjectInputStream#enableResolveObject
+ */
+ protected boolean enableReplaceObject(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 = enableReplace;
- enableReplace = enable;
- return originalValue;
- }
-
- /**
- * Flush this ObjectOutputStream. Any pending writes to the underlying
- * stream are written out when this method is invoked.
- *
- * @throws IOException
- * If an error occurs attempting to flush this
- * ObjectOutputStream.
- */
- @Override
+ }
+ boolean originalValue = enableReplace;
+ enableReplace = enable;
+ return originalValue;
+ }
+
+ /**
+ * Flush this ObjectOutputStream. Any pending writes to the underlying
+ * stream are written out when this method is invoked.
+ *
+ * @throws IOException
+ * If an error occurs attempting to flush this
+ * ObjectOutputStream.
+ */
+ @Override
public void flush() throws IOException {
- drain();
- output.flush();
- }
-
- /**
- * Get the value of field named
- * <code>fieldName<code> of object <code>instance</code>. The
- * field is declared by class <code>declaringClass</code>. The field is supposed to be
- * a boolean.
- *
- * 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 fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
- private static native boolean getFieldBool(Object instance,
- Class<?> declaringClass, String fieldName);
-
- /**
- * Get the value of field named
- * <code>fieldName<code> of object <code>instance</code>. The
- * field is declared by class <code>declaringClass</code>. The field is supposed to be
- * a byte
- *
- * 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 fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
- private static native byte getFieldByte(Object instance,
+ drain();
+ output.flush();
+ }
+
+ /**
+ * Get the value of field named
+ * <code>fieldName<code> of object <code>instance</code>. The
+ * field is declared by class <code>declaringClass</code>. The field is supposed to be
+ * a boolean.
+ *
+ * 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 fetch private fields, except
+ * by the use of a native method like this one.
+ *
+ * @param instance Object whose field value we want to fetch
+ * @param declaringClass The class that declares the field
+ * @param fieldName Name of the field we want to fetch
+ * @return the value of the field
+ *
+ * @throws NoSuchFieldError If the field does not exist.
+ */
+ private static native boolean getFieldBool(Object instance,
+ Class<?> declaringClass, String fieldName);
+
+ /**
+ * Get the value of field named
+ * <code>fieldName<code> of object <code>instance</code>. The
+ * field is declared by class <code>declaringClass</code>. The field is supposed to be
+ * a byte
+ *
+ * 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 fetch private fields, except
+ * by the use of a native method like this one.
+ *
+ * @param instance Object whose field value we want to fetch
+ * @param declaringClass The class that declares the field
+ * @param fieldName Name of the field we want to fetch
+ * @return the value of the field
+ *
+ * @throws NoSuchFieldError If the field does not exist.
+ */
+ private static native byte getFieldByte(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * <code>fieldName<code> of object <code>instance</code>. The
- * field is declared by class <code>declaringClass</code>. The field is supposed to be
- * a char.
- *
- * 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 fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
- private static native char getFieldChar(Object instance,
+ /**
+ * Get the value of field named
+ * <code>fieldName<code> of object <code>instance</code>. The
+ * field is declared by class <code>declaringClass</code>. The field is supposed to be
+ * a char.
+ *
+ * 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 fetch private fields, except
+ * by the use of a native method like this one.
+ *
+ * @param instance Object whose field value we want to fetch
+ * @param declaringClass The class that declares the field
+ * @param fieldName Name of the field we want to fetch
+ * @return the value of the field
+ *
+ * @throws NoSuchFieldError If the field does not exist.
+ */
+ private static native char getFieldChar(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * <code>fieldName<code> of object <code>instance</code>. The
- * field is declared by class <code>declaringClass</code>. The field is supposed to be
- * a double.
- *
- * 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 fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
- private static native double getFieldDouble(Object instance,
+ /**
+ * Get the value of field named
+ * <code>fieldName<code> of object <code>instance</code>. The
+ * field is declared by class <code>declaringClass</code>. The field is supposed to be
+ * a double.
+ *
+ * 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 fetch private fields, except
+ * by the use of a native method like this one.
+ *
+ * @param instance Object whose field value we want to fetch
+ * @param declaringClass The class that declares the field
+ * @param fieldName Name of the field we want to fetch
+ * @return the value of the field
+ *
+ * @throws NoSuchFieldError If the field does not exist.
+ */
+ private static native double getFieldDouble(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * <code>fieldName<code> of object <code>instance</code>. The
- * field is declared by class <code>declaringClass</code>. The field is supposed to be
- * a float.
- *
- * 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 fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
- private static native float getFieldFloat(Object instance,
+ /**
+ * Get the value of field named
+ * <code>fieldName<code> of object <code>instance</code>. The
+ * field is declared by class <code>declaringClass</code>. The field is supposed to be
+ * a float.
+ *
+ * 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 fetch private fields, except
+ * by the use of a native method like this one.
+ *
+ * @param instance Object whose field value we want to fetch
+ * @param declaringClass The class that declares the field
+ * @param fieldName Name of the field we want to fetch
+ * @return the value of the field
+ *
+ * @throws NoSuchFieldError If the field does not exist.
+ */
+ private static native float getFieldFloat(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * <code>fieldName<code> of object <code>instance</code>. The
- * field is declared by class <code>declaringClass</code>. The field is supposed to be
- * an int.
- *
- * 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 fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
- private static native int getFieldInt(Object instance,
+ /**
+ * Get the value of field named
+ * <code>fieldName<code> of object <code>instance</code>. The
+ * field is declared by class <code>declaringClass</code>. The field is supposed to be
+ * an int.
+ *
+ * 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 fetch private fields, except
+ * by the use of a native method like this one.
+ *
+ * @param instance Object whose field value we want to fetch
+ * @param declaringClass The class that declares the field
+ * @param fieldName Name of the field we want to fetch
+ * @return the value of the field
+ *
+ * @throws NoSuchFieldError If the field does not exist.
+ */
+ private static native int getFieldInt(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * <code>fieldName<code> of object <code>instance</code>. The
- * field is declared by class <code>declaringClass</code>. The field is supposed to be
- * a long.
- *
- * 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 fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
- private static native long getFieldLong(Object instance,
+ /**
+ * Get the value of field named
+ * <code>fieldName<code> of object <code>instance</code>. The
+ * field is declared by class <code>declaringClass</code>. The field is supposed to be
+ * a long.
+ *
+ * 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 fetch private fields, except
+ * by the use of a native method like this one.
+ *
+ * @param instance Object whose field value we want to fetch
+ * @param declaringClass The class that declares the field
+ * @param fieldName Name of the field we want to fetch
+ * @return the value of the field
+ *
+ * @throws NoSuchFieldError If the field does not exist.
+ */
+ private static native long getFieldLong(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * <code>fieldName<code> of object <code>instance</code>. The
- * field is declared by class <code>declaringClass</code>. The field is supposed to be
- * an Object type whose name is <code>fieldTypeName</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 fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @param fieldTypeName Name of the class that defines the type of this field
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
- private static native Object getFieldObj(Object instance,
+ /**
+ * Get the value of field named
+ * <code>fieldName<code> of object <code>instance</code>. The
+ * field is declared by class <code>declaringClass</code>. The field is supposed to be
+ * an Object type whose name is <code>fieldTypeName</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 fetch private fields, except
+ * by the use of a native method like this one.
+ *
+ * @param instance Object whose field value we want to fetch
+ * @param declaringClass The class that declares the field
+ * @param fieldName Name of the field we want to fetch
+ * @param fieldTypeName Name of the class that defines the type of this field
+ * @return the value of the field
+ *
+ * @throws NoSuchFieldError If the field does not exist.
+ */
+ private static native Object getFieldObj(Object instance,
Class<?> declaringClass, String fieldName, String fieldTypeName);
- /**
- * Get the value of field named
- * <code>fieldName<code> of object <code>instance</code>. The
- * field is declared by class <code>declaringClass</code>. The field is supposed to be
- * a short.
- *
- * 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 fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
- private static native short getFieldShort(Object instance,
+ /**
+ * Get the value of field named
+ * <code>fieldName<code> of object <code>instance</code>. The
+ * field is declared by class <code>declaringClass</code>. The field is supposed to be
+ * a short.
+ *
+ * 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 fetch private fields, except
+ * by the use of a native method like this one.
+ *
+ * @param instance Object whose field value we want to fetch
+ * @param declaringClass The class that declares the field
+ * @param fieldName Name of the field we want to fetch
+ * @return the value of the field
+ *
+ * @throws NoSuchFieldError If the field does not exist.
+ */
+ private static native short getFieldShort(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Return the next <code>int</code> handle to be used to indicate cyclic
- * references being saved to the stream.
- *
- * @return int, the next handle to represent the next cyclic reference
- */
- private int nextHandle() {
- return this.currentHandle++;
- }
-
- /**
- * Return the <code>PutField</code> object for the receiver. This allows
- * users to transfer values from actual object fields in the object being
- * dumped to the emulated fields represented by the <code>PutField</code>
- * returned by this method.
- *
- * @return the PutFieldObject for the receiver
- *
- * @throws IOException
- * If an IO error occurs
- * @throws NotActiveException
- * If this method is not called from writeObject()
- *
- * @see ObjectInputStream#defaultReadObject
- */
-
- public PutField putFields() throws IOException {
- // We can't be called from just anywhere. There are rules.
- if (currentObject != null) {
- if (currentPutField == null) {
- computePutField();
- }
- return currentPutField;
- }
- throw new NotActiveException();
- }
-
- /**
- * Return the <code>Integer</code> handle used to tag object
- * <code>obj</code> as an instance that has been dumped already. Return
- * <code>null</code> if object <code>obj</code> has not been saved yet.
- *
- * @param obj
- * the object
- * @return null if object <code>obj</code> has not been saved yet. Integer
- * The handle that this object was assigned when it was saved.
- */
- private Integer registeredObjectHandleFor(Object obj) {
- return objectsWritten.get(obj);
- }
-
- /**
- * Assume object <code>obj</code> has not been dumped yet, and assign a
- * handle to it
- *
- * @param obj
- * Non-null object being dumped.
- * @return the handle that this object is being assigned.
- *
- * @see #nextHandle
- */
- private Integer registerObjectWritten(Object obj) {
- Integer handle = Integer.valueOf(nextHandle());
- registerObjectWritten(obj, handle);
- return handle;
- }
-
- /**
- * Remove the unshared object from the table, and restore any previous
- * handle.
- *
- * @param obj
- * Non-null object being dumped.
- * @param previousHandle
- * The handle of the previous identical object dumped
- */
- private void removeUnsharedReference(Object obj, Integer previousHandle) {
- if (previousHandle != null) {
- registerObjectWritten(obj, previousHandle);
- } else {
- objectsWritten.remove(obj);
- }
- }
-
- /**
- * Assume object <code>obj</code> has not been dumped yet, and assign a
- * handle to it, <code>handle</code>.
- *
- * @param obj
- * Non-null object being dumped.
- * @param handle
- * An Integer, the handle to this object
- *
- * @see #nextHandle
- */
- private void registerObjectWritten(Object obj, Integer handle) {
- objectsWritten.put(obj, handle);
- }
-
- /**
- * If <code>enableReplaceObject()</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 #enableReplaceObject
- * @see ObjectInputStream#enableResolveObject
- * @see ObjectInputStream#resolveObject
- */
- protected Object replaceObject(Object object) throws IOException {
- // By default no object replacement. Subclasses can override
- return object;
- }
-
- /**
- * Reset the receiver. A marker is written to the stream, so that
- * deserialization will also perform a rest at the same point. Objects
- * previously written are no longer remembered, so they will be written again
- * (instead of a cyclical reference) if found in the object graph.
- *
- * @throws IOException
- * If any IO problem occurred when trying to reset the receiver
- */
- public void reset() throws IOException {
- // First we flush what we have
- drain();
- /*
+ /**
+ * Return the next <code>int</code> handle to be used to indicate cyclic
+ * references being saved to the stream.
+ *
+ * @return int, the next handle to represent the next cyclic reference
+ */
+ private int nextHandle() {
+ return this.currentHandle++;
+ }
+
+ /**
+ * Return the <code>PutField</code> object for the receiver. This allows
+ * users to transfer values from actual object fields in the object being
+ * dumped to the emulated fields represented by the <code>PutField</code>
+ * returned by this method.
+ *
+ * @return the PutFieldObject for the receiver
+ *
+ * @throws IOException
+ * If an IO error occurs
+ * @throws NotActiveException
+ * If this method is not called from writeObject()
+ *
+ * @see ObjectInputStream#defaultReadObject
+ */
+ public PutField putFields() throws IOException {
+ // We can't be called from just anywhere. There are rules.
+ if (currentObject == null) {
+ throw new NotActiveException();
+ }
+ if (currentPutField == null) {
+ computePutField();
+ }
+ return currentPutField;
+ }
+
+ /**
+ * Return the <code>Integer</code> handle used to tag object
+ * <code>obj</code> as an instance that has been dumped already. Return
+ * <code>null</code> if object <code>obj</code> has not been saved yet.
+ *
+ * @param obj
+ * the object
+ * @return null if object <code>obj</code> has not been saved yet. Integer
+ * The handle that this object was assigned when it was saved.
+ */
+ private Integer registeredObjectHandleFor(Object obj) {
+ return objectsWritten.get(obj);
+ }
+
+ /**
+ * Assume object <code>obj</code> has not been dumped yet, and assign a
+ * handle to it
+ *
+ * @param obj
+ * Non-null object being dumped.
+ * @return the handle that this object is being assigned.
+ *
+ * @see #nextHandle
+ */
+ private Integer registerObjectWritten(Object obj) {
+ Integer handle = Integer.valueOf(nextHandle());
+ registerObjectWritten(obj, handle);
+ return handle;
+ }
+
+ /**
+ * Remove the unshared object from the table, and restore any previous
+ * handle.
+ *
+ * @param obj
+ * Non-null object being dumped.
+ * @param previousHandle
+ * The handle of the previous identical object dumped
+ */
+ private void removeUnsharedReference(Object obj, Integer previousHandle) {
+ if (previousHandle != null) {
+ registerObjectWritten(obj, previousHandle);
+ } else {
+ objectsWritten.remove(obj);
+ }
+ }
+
+ /**
+ * Assume object <code>obj</code> has not been dumped yet, and assign a
+ * handle to it, <code>handle</code>.
+ *
+ * @param obj
+ * Non-null object being dumped.
+ * @param handle
+ * An Integer, the handle to this object
+ *
+ * @see #nextHandle
+ */
+ private void registerObjectWritten(Object obj, Integer handle) {
+ objectsWritten.put(obj, handle);
+ }
+
+ /**
+ * If <code>enableReplaceObject()</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 #enableReplaceObject
+ * @see ObjectInputStream#enableResolveObject
+ * @see ObjectInputStream#resolveObject
+ */
+ protected Object replaceObject(Object object) throws IOException {
+ // By default no object replacement. Subclasses can override
+ return object;
+ }
+
+ /**
+ * Reset the receiver. A marker is written to the stream, so that
+ * deserialization will also perform a rest at the same point. Objects
+ * previously written are no longer remembered, so they will be written
+ * again (instead of a cyclical reference) if found in the object graph.
+ *
+ * @throws IOException
+ * If any IO problem occurred when trying to reset the receiver
+ */
+ public void reset() throws IOException {
+ // First we flush what we have
+ drain();
+ /*
* And dump a reset marker, so that the ObjectInputStream can reset
* itself at the same point
*/
- output.writeByte(TC_RESET);
- // Now we reset ourselves
- resetState();
- }
-
- /**
- * Reset the collection of objects already dumped by the receiver. If the
- * objects are found again in the object graph, the receiver will dump them
- * again, instead of a handle (cyclic reference).
- *
- */
- private void resetSeenObjects() {
- objectsWritten = new IdentityHashMap<Object, Integer>();
- currentHandle = baseWireHandle;
- }
-
- /**
- * Reset the receiver. The collection of objects already dumped 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();
- nestedLevels = 0;
- }
-
- /**
- * Set the receiver to use the given protocol version.
- *
- * @param version
- * protocol version to be used
- *
- * @throws IOException
- * If an IO error occurs
- */
- public void useProtocolVersion(int version) throws IOException {
+ output.writeByte(TC_RESET);
+ // Now we reset ourselves
+ resetState();
+ }
+
+ /**
+ * Reset the collection of objects already dumped by the receiver. If the
+ * objects are found again in the object graph, the receiver will dump them
+ * again, instead of a handle (cyclic reference).
+ *
+ */
+ private void resetSeenObjects() {
+ objectsWritten = new IdentityHashMap<Object, Integer>();
+ currentHandle = baseWireHandle;
+ }
+
+ /**
+ * Reset the receiver. The collection of objects already dumped 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();
+ nestedLevels = 0;
+ }
+
+ /**
+ * Set the receiver to use the given protocol version.
+ *
+ * @param version
+ * protocol version to be used
+ *
+ * @throws IOException
+ * If an IO error occurs
+ */
+ public void useProtocolVersion(int version) throws IOException {
if (version != ObjectStreamConstants.PROTOCOL_VERSION_1
&& version != ObjectStreamConstants.PROTOCOL_VERSION_2) {
throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
@@ -790,1174 +787,1166 @@
protocolVersion = version;
}
- /**
- * Writes the entire contents of the byte array <code>buffer</code> to
- * this ObjectOutputStream.
- *
- * @param buffer
- * the buffer to be written
- *
- * @throws IOException
- * If an error occurs attempting to write to this
- * ObjectOutputStream.
- */
- @Override
+ /**
+ * Writes the entire contents of the byte array <code>buffer</code> to
+ * this ObjectOutputStream.
+ *
+ * @param buffer
+ * the buffer to be written
+ *
+ * @throws IOException
+ * If an error occurs attempting to write to this
+ * ObjectOutputStream.
+ */
+ @Override
public void write(byte[] buffer) throws IOException {
- checkWritePrimitiveTypes();
- primitiveTypes.write(buffer);
- }
-
- /**
- * Writes <code>length</code> <code>bytes</code> from the byte array
- * <code>buffer</code> starting at offset <code>offset</code> to the
- * ObjectOutputStream.
- *
- * @param buffer
- * the buffer to be written
- * @param offset
- * offset in buffer to get bytes
- * @param length
- * number of bytes in buffer to write
- *
- * @throws IOException
- * If an error occurs attempting to write to this OutputStream.
- */
- @Override
+ checkWritePrimitiveTypes();
+ primitiveTypes.write(buffer);
+ }
+
+ /**
+ * Writes <code>length</code> <code>bytes</code> from the byte array
+ * <code>buffer</code> starting at offset <code>offset</code> to the
+ * ObjectOutputStream.
+ *
+ * @param buffer
+ * the buffer to be written
+ * @param offset
+ * offset in buffer to get bytes
+ * @param length
+ * number of bytes in buffer to write
+ *
+ * @throws IOException
+ * If an error occurs attempting to write to this OutputStream.
+ */
+ @Override
public void write(byte[] buffer, int offset, int length) throws IOException {
- checkWritePrimitiveTypes();
- primitiveTypes.write(buffer, offset, length);
- }
-
- /**
- * Write one byte (<code>value</code>) into the receiver's underlying
- * stream.
- *
- * @param value
- * The primitive data to write. Only the lower byte is written.
- *
- * @throws IOException
- * If an IO exception happened when writing the byte.
- */
- @Override
+ checkWritePrimitiveTypes();
+ primitiveTypes.write(buffer, offset, length);
+ }
+
+ /**
+ * Write one byte (<code>value</code>) into the receiver's underlying
+ * stream.
+ *
+ * @param value
+ * The primitive data to write. Only the lower byte is written.
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the byte.
+ */
+ @Override
public void write(int value) throws IOException {
- checkWritePrimitiveTypes();
- primitiveTypes.write(value);
- }
-
- /**
- * Write primitive data of type boolean (<code>value</code>)into the
- * receiver's underlying stream.
- *
- * @param value
- * The primitive data to write
- *
- * @throws IOException
- * If an IO exception happened when writing the primitive data.
- */
- public void writeBoolean(boolean value) throws IOException {
- checkWritePrimitiveTypes();
- primitiveTypes.writeBoolean(value);
- }
-
- /**
- * Write primitive data of type byte (<code>value</code>)into the
- * receiver's underlying stream.
- *
- * @param value
- * The primitive data to write
- *
- * @throws IOException
- * If an IO exception happened when writing the primitive data.
- */
- public void writeByte(int value) throws IOException {
- checkWritePrimitiveTypes();
- primitiveTypes.writeByte(value);
- }
-
- /**
- * Write a String as a sequence of bytes (only lower-order 8 bits of each
- * char are written), as primitive data (<code>value</code>) into the
- * receiver's underlying stream.
- *
- * @param value
- * The primitive data to write
- *
- * @throws IOException
- * If an IO exception happened when writing the primitive data.
- */
- public void writeBytes(String value) throws IOException {
- checkWritePrimitiveTypes();
- primitiveTypes.writeBytes(value);
- }
-
- /**
- * Write primitive data of type char (<code>value</code>)into the
- * receiver's underlying stream.
- *
- * @param value
- * The primitive data to write
- *
- * @throws IOException
- * If an IO exception happened when writing the primitive data.
- */
- public void writeChar(int value) throws IOException {
- checkWritePrimitiveTypes();
- primitiveTypes.writeChar(value);
- }
-
- /**
- * Write a String as a sequence of char, as primitive data (<code>value</code>)
- * into the receiver's underlying stream.
- *
- * @param value
- * The primitive data to write
- *
- * @throws IOException
- * If an IO exception happened when writing the primitive data.
- */
- public void writeChars(String value) throws IOException {
- checkWritePrimitiveTypes();
- primitiveTypes.writeChars(value);
- }
-
- /**
- * Write a class descriptor <code>classDesc</code> (an
- * <code>ObjectStreamClass</code>) to the stream.
- *
- * @param classDesc
- * The class descriptor (an <code>ObjectStreamClass</code>) to
- * be dumped
- * @param unshared
- * Write the object unshared
- * @return the handle assigned to the class descriptor
- *
- * @throws IOException
- * If an IO exception happened when writing the class
- * descriptor.
- */
- private Integer writeClassDesc(ObjectStreamClass classDesc, boolean unshared)
- throws IOException {
- if (classDesc == null) {
- writeNull();
- return null;
- }
- Integer handle = null;
- if (!unshared) {
- handle = dumpCycle(classDesc);
- }
- if (handle == null) {
- Class<?> classToWrite = classDesc.forClass();
- Integer previousHandle = objectsWritten.get(classDesc);
- // If we got here, it is a new (non-null) classDesc that will have
- // to be registered as well
- handle = registerObjectWritten(classDesc);
-
- if (Proxy.isProxyClass(classToWrite)) {
- output.writeByte(TC_PROXYCLASSDESC);
- Class<?>[] interfaces = classToWrite.getInterfaces();
- output.writeInt(interfaces.length);
- for (int i = 0; i < interfaces.length; i++) {
- output.writeUTF(interfaces[i].getName());
- }
- annotateProxyClass(classToWrite);
- output.writeByte(TC_ENDBLOCKDATA);
- writeClassDescForClass(Proxy.class);
- if (unshared) {
- // remove reference to unshared object
- removeUnsharedReference(classDesc, previousHandle);
- }
- return handle;
- }
+ checkWritePrimitiveTypes();
+ primitiveTypes.write(value);
+ }
- output.writeByte(TC_CLASSDESC);
- if (protocolVersion == PROTOCOL_VERSION_1) {
- writeNewClassDesc(classDesc);
- } else {
- // So write...() methods can be used by
- // subclasses during writeClassDescriptor()
- primitiveTypes = output;
- writeClassDescriptor(classDesc);
- primitiveTypes = null;
- }
- // Extra class info (optional)
- annotateClass(classToWrite);
- drain(); // flush primitive types in the annotation
- output.writeByte(TC_ENDBLOCKDATA);
- writeClassDesc(classDesc.getSuperclass(), unshared);
- if (unshared) {
- // remove reference to unshared object
- removeUnsharedReference(classDesc, previousHandle);
- }
- }
- return handle;
- }
-
- /**
- * Writes a class descriptor (an <code>ObjectStreamClass</code>) that
- * corresponds to the <code>java.lang.Class objClass</code> to the stream.
- *
- * @param objClass
- * The class for which a class descriptor (an
- * <code>ObjectStreamClass</code>) will be dumped.
- * @return the handle assigned to the class descriptor
- *
- * @throws IOException
- * If an IO exception happened when writing the class
- * descriptor.
- *
- */
- private Integer writeClassDescForClass(Class<?> objClass) throws IOException {
- return writeClassDesc(ObjectStreamClass.lookup(objClass), false);
- }
-
- /**
- * Writes a handle representing a cyclic reference (object previously
- * dumped).
- *
- * @param handle
- * The Integer handle that represents an object previously seen
- *
- * @throws IOException
- * If an IO exception happened when writing the cyclic
- * reference.
- */
- private void writeCyclicReference(Integer handle) throws IOException {
- output.writeByte(TC_REFERENCE);
- output.writeInt(handle.intValue());
- }
-
- /**
- * Write primitive data of type double (<code>value</code>)into the
- * receiver's underlying stream.
- *
- * @param value
- * The primitive data to write
- *
- * @throws IOException
- * If an IO exception happened when writing the primitive data.
- */
- public void writeDouble(double value) throws IOException {
- checkWritePrimitiveTypes();
- primitiveTypes.writeDouble(value);
- }
-
- /**
- * Writes a collection of field descriptors (name, type name, etc) for the
- * class descriptor <code>classDesc</code> (an
- * <code>ObjectStreamClass</code>)
- *
- * @param classDesc
- * The class descriptor (an <code>ObjectStreamClass</code>)
- * for which to write field information
- * @param externalizable
- * true if the descriptors are externalizable
- *
- * @throws IOException
- * If an IO exception happened when writing the field
- * descriptors.
- *
- * @see #writeObject(Object)
- */
- private void writeFieldDescriptors(ObjectStreamClass classDesc,
- boolean externalizable) throws IOException {
- Class<?> loadedClass = classDesc.forClass();
- ObjectStreamField[] fields = null;
- int fieldCount = 0;
+ /**
+ * Write primitive data of type boolean (<code>value</code>)into the
+ * receiver's underlying stream.
+ *
+ * @param value
+ * The primitive data to write
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the primitive data.
+ */
+ public void writeBoolean(boolean value) throws IOException {
+ checkWritePrimitiveTypes();
+ primitiveTypes.writeBoolean(value);
+ }
- // The fields of String are not needed since Strings are treated as
- // primitive types
- if (!externalizable && loadedClass != ObjectStreamClass.STRINGCLASS) {
- fields = classDesc.fields();
- fieldCount = fields.length;
- }
-
- // Field count
- output.writeShort(fieldCount);
- // Field names
- for (int i = 0; i < fieldCount; i++) {
- ObjectStreamField f = fields[i];
- output.writeByte(f.getTypeCode());
- output.writeUTF(f.getName());
- if (!f.isPrimitive()) {
- writeObject(f.getTypeString());
- }
- }
- }
-
- /**
- * Write the fields of the object being dumped. The stream will use the
- * currently active <code>PutField</code> object, allowing users to dump
- * emulated fields, for cross-loading compatibility when a class definition
- * changes.
- *
- * @throws IOException
- * If an IO error occurs
- *
- * @see #putFields
- */
- public void writeFields() throws IOException {
- // Has to have fields to write
- if (currentPutField != null) {
- writeFieldValues(currentPutField);
- } else {
- throw new NotActiveException();
- }
- }
+ /**
+ * Write primitive data of type byte (<code>value</code>)into the
+ * receiver's underlying stream.
+ *
+ * @param value
+ * The primitive data to write
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the primitive data.
+ */
+ public void writeByte(int value) throws IOException {
+ checkWritePrimitiveTypes();
+ primitiveTypes.writeByte(value);
+ }
- /**
- * Writes a collection of field values for the emulated fields
- * <code>emulatedFields</code>
- *
- * @param emulatedFields
- * an <code>EmulatedFieldsForDumping</code>, concrete subclass
- * of <code>PutField</code>
- *
- * @throws IOException
- * If an IO exception happened when writing the field values.
- *
- * @see #writeFields
- * @see #writeObject(Object)
- */
- private void writeFieldValues(EmulatedFieldsForDumping emulatedFields)
- throws IOException {
- EmulatedFields accessibleSimulatedFields = emulatedFields
- .emulatedFields(); // Access internal fields which we can
- // set/get. Users can't do this.
- EmulatedFields.ObjectSlot[] slots = accessibleSimulatedFields.slots();
- for (int i = 0; i < slots.length; i++) {
- EmulatedFields.ObjectSlot slot = slots[i];
- Object fieldValue = slot.getFieldValue();
- Class<?> type = slot.getField().getType();
- // WARNING - default values exist for each primitive type
- if (type == Integer.TYPE) {
- output.writeInt(fieldValue != null ? ((Integer) fieldValue)
- .intValue() : 0);
- } else if (type == Byte.TYPE) {
- output.writeByte(fieldValue != null ? ((Byte) fieldValue)
- .byteValue() : (byte) 0);
- } else if (type == Character.TYPE) {
- output.writeChar(fieldValue != null ? ((Character) fieldValue)
- .charValue() : (char) 0);
- } else if (type == Short.TYPE) {
- output.writeShort(fieldValue != null ? ((Short) fieldValue)
- .shortValue() : (short) 0);
- } else if (type == Boolean.TYPE) {
- output.writeBoolean(fieldValue != null ? ((Boolean) fieldValue)
- .booleanValue() : false);
- } else if (type == Long.TYPE) {
- output.writeLong(fieldValue != null ? ((Long) fieldValue)
- .longValue() : (long) 0);
- } else if (type == Float.TYPE) {
- output.writeFloat(fieldValue != null ? ((Float) fieldValue)
- .floatValue() : (float) 0);
- } else if (type == Double.TYPE) {
- output.writeDouble(fieldValue != null ? ((Double) fieldValue)
- .doubleValue() : (double) 0);
- } else {
- // Either array or Object
- writeObject(fieldValue);
- }
- }
- }
-
- /**
- * Writes a collection of field values for the fields described by class
- * descriptor <code>classDesc</code> (an <code>ObjectStreamClass</code>).
- * This is the default mechanism, when emulated fields (an
- * <code>PutField</code>) are not used. Actual values to dump are fetched
- * directly from object <code>obj</code>.
- *
- * @param obj
- * Instance from which to fetch field values to dump.
- * @param classDesc
- * A class descriptor (an <code>ObjectStreamClass</code>)
- * defining which fields should be dumped.
- *
- * @throws IOException
- * If an IO exception happened when writing the field values.
- *
- * @see #writeObject(Object)
- */
- private void writeFieldValues(Object obj, ObjectStreamClass classDesc)
- throws IOException {
- ObjectStreamField[] fields = classDesc.fields();
- Class<?> declaringClass = classDesc.forClass();
- for (int i = 0; i < fields.length; i++) {
- try {
- // Code duplication starts, just because Java is typed
- ObjectStreamField fieldDesc = fields[i];
- if (fieldDesc.isPrimitive()) {
- switch (fieldDesc.getTypeCode()) {
- case 'B':
- output.writeByte(getFieldByte(obj, declaringClass,
- fieldDesc.getName()));
- break;
- case 'C':
- output.writeChar(getFieldChar(obj, declaringClass,
- fieldDesc.getName()));
- break;
- case 'D':
- output.writeDouble(getFieldDouble(obj, declaringClass,
- fieldDesc.getName()));
- break;
- case 'F':
- output.writeFloat(getFieldFloat(obj, declaringClass,
- fieldDesc.getName()));
- break;
- case 'I':
- output.writeInt(getFieldInt(obj, declaringClass,
- fieldDesc.getName()));
- break;
- case 'J':
- output.writeLong(getFieldLong(obj, declaringClass,
- fieldDesc.getName()));
- break;
- case 'S':
- output.writeShort(getFieldShort(obj, declaringClass,
- fieldDesc.getName()));
- break;
- case 'Z':
- output.writeBoolean(getFieldBool(obj, declaringClass,
- fieldDesc.getName()));
- break;
- default:
- throw new IOException(org.apache.harmony.luni.util.Msg.getString(
- "K00d5", fieldDesc.getTypeCode())); //$NON-NLS-1$
- }
- } else {
- // Object type (array included).
- Object field = getFieldObj(obj, declaringClass, fieldDesc
- .getName(), fieldDesc.getTypeString());
- if (fieldDesc.isUnshared()) {
- writeUnshared(field);
- } else {
- writeObject(field);
- }
- }
- } catch (NoSuchFieldError nsf) {
- // The user defined serialPersistentFields but did not provide
- // the glue to transfer values,
- // (in writeObject) so we end up using the default mechanism and
- // fail to set the emulated field
- throw new InvalidClassException(classDesc.getName());
- }
- }
- }
-
- /**
- * Write primitive data of type float (<code>value</code>)into the
- * receiver's underlying stream.
- *
- * @param value
- * The primitive data to write
- *
- * @throws IOException
- * If an IO exception happened when writing the primitive data.
- */
- public void writeFloat(float value) throws IOException {
- checkWritePrimitiveTypes();
- primitiveTypes.writeFloat(value);
- }
-
- /**
- * Walks the hierarchy of classes described by class descriptor
- * <code>classDesc</code> and writes the field values corresponding to
- * fields declared by the corresponding class descriptor. The instance to
- * fetch field values from is <code>object</code>. If the class
- * (corresponding to class descriptor <code>classDesc</code>) defines
- * private instance method <code>writeObject</code> it will be used to
- * dump field values.
- *
- * @param object
- * Instance from which to fetch field values to dump.
- * @param classDesc
- * A class descriptor (an <code>ObjectStreamClass</code>)
- * defining which fields should be dumped.
- *
- * @throws IOException
- * If an IO exception happened when writing the field values in
- * the hierarchy.
- * @throws NotActiveException
- * If the given object is not active
- *
- * @see #defaultWriteObject
- * @see #writeObject(Object)
- */
- private void writeHierarchy(Object object, ObjectStreamClass classDesc)
- throws IOException, NotActiveException {
- // We can't be called from just anywhere. There are rules.
- if (object != null) {
- // Fields are written from class closest to Object to leaf class
- // (down the chain)
- if (classDesc.getSuperclass() != null) {
- // first
- writeHierarchy(object, classDesc.getSuperclass());
- }
-
- // Have to do this before calling defaultWriteObject or anything
- // that calls defaultWriteObject
- currentObject = object;
- currentClass = classDesc;
-
- // See if the object has a writeObject method. If so, run it
- boolean executed = false;
- Class<?> targetClass = classDesc.forClass();
- try {
- final Method method = ObjectStreamClass
- .getPrivateWriteObjectMethod(targetClass);
- if (method != null) {
- // We have to be able to fetch its value, even if it is
- // private
- AccessController.doPrivileged(new PriviAction<Object>(method));
- try {
- method.invoke(object, new Object[] { this });
- executed = true;
- } catch (InvocationTargetException e) {
- Throwable ex = e.getTargetException();
- 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());
- }
- }
-
- if (executed) {
- drain();
- output.writeByte(TC_ENDBLOCKDATA);
- } else {
- // If the object did not have a writeMethod, call
- // defaultWriteObject
- defaultWriteObject();
- }
- } finally {
- // Cleanup, needs to run always so that we can later detect
- // invalid calls to defaultWriteObject
- currentObject = null;
- currentClass = null;
- currentPutField = null;
- }
- } else {
- throw new NotActiveException();
- }
- }
+ /**
+ * Write a String as a sequence of bytes (only lower-order 8 bits of each
+ * char are written), as primitive data (<code>value</code>) into the
+ * receiver's underlying stream.
+ *
+ * @param value
+ * The primitive data to write
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the primitive data.
+ */
+ public void writeBytes(String value) throws IOException {
+ checkWritePrimitiveTypes();
+ primitiveTypes.writeBytes(value);
+ }
- /**
- * Write primitive data of type int (<code>value</code>)into the
- * receiver's underlying stream.
- *
- * @param value
- * The primitive data to write
- *
- * @throws IOException
- * If an IO exception happened when writing the primitive data.
- */
- public void writeInt(int value) throws IOException {
- checkWritePrimitiveTypes();
- primitiveTypes.writeInt(value);
- }
-
- /**
- * Write primitive data of type long (<code>value</code>)into the
- * receiver's underlying stream.
- *
- * @param value
- * The primitive data to write
- *
- * @throws IOException
- * If an IO exception happened when writing the primitive data.
- */
- public void writeLong(long value) throws IOException {
- checkWritePrimitiveTypes();
- primitiveTypes.writeLong(value);
- }
-
- /**
- * Write array <code>array</code> of class <code>arrayClass</code> with
- * component type <code>componentType</code> into the receiver. It is
- * assumed the array has not been dumped yet. Return an <code>Integer</code>
- * that represents the handle for this object (array) which is dumped here.
- *
- * @param array
- * The array object to dump
- * @param arrayClass
- * A <code>java.lang.Class</code> representing the class of the
- * array
- * @param componentType
- * A <code>java.lang.Class</code> representing the array
- * component type
- * @return the handle assigned to the array
- *
- * @throws IOException
- * If an IO exception happened when writing the array.
- */
- private Integer writeNewArray(Object array, Class<?> arrayClass,
- Class<?> componentType, boolean unshared) throws IOException {
- output.writeByte(TC_ARRAY);
- writeClassDescForClass(arrayClass);
+ /**
+ * Write primitive data of type char (<code>value</code>)into the
+ * receiver's underlying stream.
+ *
+ * @param value
+ * The primitive data to write
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the primitive data.
+ */
+ public void writeChar(int value) throws IOException {
+ checkWritePrimitiveTypes();
+ primitiveTypes.writeChar(value);
+ }
- Integer previousHandle = objectsWritten.get(array);
- Integer handle = registerObjectWritten(array);
- if (unshared) {
- // remove reference to unshared object
- removeUnsharedReference(array, previousHandle);
- }
-
- // Now we have code duplication just because Java is typed. We have to
- // write 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[]) array;
- output.writeInt(intArray.length);
- for (int i = 0; i < intArray.length; i++) {
- output.writeInt(intArray[i]);
- }
- } else if (componentType == Byte.TYPE) {
- byte[] byteArray = (byte[]) array;
- output.writeInt(byteArray.length);
- output.write(byteArray, 0, byteArray.length);
- } else if (componentType == Character.TYPE) {
- char[] charArray = (char[]) array;
- output.writeInt(charArray.length);
- for (int i = 0; i < charArray.length; i++) {
- output.writeChar(charArray[i]);
- }
- } else if (componentType == Short.TYPE) {
- short[] shortArray = (short[]) array;
- output.writeInt(shortArray.length);
- for (int i = 0; i < shortArray.length; i++) {
- output.writeShort(shortArray[i]);
- }
- } else if (componentType == Boolean.TYPE) {
- boolean[] booleanArray = (boolean[]) array;
- output.writeInt(booleanArray.length);
- for (int i = 0; i < booleanArray.length; i++) {
- output.writeBoolean(booleanArray[i]);
- }
- } else if (componentType == Long.TYPE) {
- long[] longArray = (long[]) array;
- output.writeInt(longArray.length);
- for (int i = 0; i < longArray.length; i++) {
- output.writeLong(longArray[i]);
- }
- } else if (componentType == Float.TYPE) {
- float[] floatArray = (float[]) array;
- output.writeInt(floatArray.length);
- for (int i = 0; i < floatArray.length; i++) {
+ /**
+ * Write a String as a sequence of char, as primitive data (<code>value</code>)
+ * into the receiver's underlying stream.
+ *
+ * @param value
+ * The primitive data to write
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the primitive data.
+ */
+ public void writeChars(String value) throws IOException {
+ checkWritePrimitiveTypes();
+ primitiveTypes.writeChars(value);
+ }
+
+ /**
+ * Write a class descriptor <code>classDesc</code> (an
+ * <code>ObjectStreamClass</code>) to the stream.
+ *
+ * @param classDesc
+ * The class descriptor (an <code>ObjectStreamClass</code>) to
+ * be dumped
+ * @param unshared
+ * Write the object unshared
+ * @return the handle assigned to the class descriptor
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the class
+ * descriptor.
+ */
+ private Integer writeClassDesc(ObjectStreamClass classDesc, boolean unshared)
+ throws IOException {
+ if (classDesc == null) {
+ writeNull();
+ return null;
+ }
+ Integer handle = null;
+ if (!unshared) {
+ handle = dumpCycle(classDesc);
+ }
+ if (handle == null) {
+ Class<?> classToWrite = classDesc.forClass();
+ Integer previousHandle = objectsWritten.get(classDesc);
+ // If we got here, it is a new (non-null) classDesc that will have
+ // to be registered as well
+ handle = registerObjectWritten(classDesc);
+
+ if (Proxy.isProxyClass(classToWrite)) {
+ output.writeByte(TC_PROXYCLASSDESC);
+ Class<?>[] interfaces = classToWrite.getInterfaces();
+ output.writeInt(interfaces.length);
+ for (int i = 0; i < interfaces.length; i++) {
+ output.writeUTF(interfaces[i].getName());
+ }
+ annotateProxyClass(classToWrite);
+ output.writeByte(TC_ENDBLOCKDATA);
+ writeClassDescForClass(Proxy.class);
+ if (unshared) {
+ // remove reference to unshared object
+ removeUnsharedReference(classDesc, previousHandle);
+ }
+ return handle;
+ }
+
+ output.writeByte(TC_CLASSDESC);
+ if (protocolVersion == PROTOCOL_VERSION_1) {
+ writeNewClassDesc(classDesc);
+ } else {
+ // So write...() methods can be used by
+ // subclasses during writeClassDescriptor()
+ primitiveTypes = output;
+ writeClassDescriptor(classDesc);
+ primitiveTypes = null;
+ }
+ // Extra class info (optional)
+ annotateClass(classToWrite);
+ drain(); // flush primitive types in the annotation
+ output.writeByte(TC_ENDBLOCKDATA);
+ writeClassDesc(classDesc.getSuperclass(), unshared);
+ if (unshared) {
+ // remove reference to unshared object
+ removeUnsharedReference(classDesc, previousHandle);
+ }
+ }
+ return handle;
+ }
+
+ /**
+ * Writes a class descriptor (an <code>ObjectStreamClass</code>) that
+ * corresponds to the <code>java.lang.Class objClass</code> to the stream.
+ *
+ * @param objClass
+ * The class for which a class descriptor (an
+ * <code>ObjectStreamClass</code>) will be dumped.
+ * @return the handle assigned to the class descriptor
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the class
+ * descriptor.
+ *
+ */
+ private Integer writeClassDescForClass(Class<?> objClass)
+ throws IOException {
+ return writeClassDesc(ObjectStreamClass.lookup(objClass), false);
+ }
+
+ /**
+ * Writes a handle representing a cyclic reference (object previously
+ * dumped).
+ *
+ * @param handle
+ * The Integer handle that represents an object previously seen
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the cyclic
+ * reference.
+ */
+ private void writeCyclicReference(Integer handle) throws IOException {
+ output.writeByte(TC_REFERENCE);
+ output.writeInt(handle.intValue());
+ }
+
+ /**
+ * Write primitive data of type double (<code>value</code>)into the
+ * receiver's underlying stream.
+ *
+ * @param value
+ * The primitive data to write
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the primitive data.
+ */
+ public void writeDouble(double value) throws IOException {
+ checkWritePrimitiveTypes();
+ primitiveTypes.writeDouble(value);
+ }
+
+ /**
+ * Writes a collection of field descriptors (name, type name, etc) for the
+ * class descriptor <code>classDesc</code> (an
+ * <code>ObjectStreamClass</code>)
+ *
+ * @param classDesc
+ * The class descriptor (an <code>ObjectStreamClass</code>)
+ * for which to write field information
+ * @param externalizable
+ * true if the descriptors are externalizable
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the field
+ * descriptors.
+ *
+ * @see #writeObject(Object)
+ */
+ private void writeFieldDescriptors(ObjectStreamClass classDesc,
+ boolean externalizable) throws IOException {
+ Class<?> loadedClass = classDesc.forClass();
+ ObjectStreamField[] fields = null;
+ int fieldCount = 0;
+
+ // The fields of String are not needed since Strings are treated as
+ // primitive types
+ if (!externalizable && loadedClass != ObjectStreamClass.STRINGCLASS) {
+ fields = classDesc.fields();
+ fieldCount = fields.length;
+ }
+
+ // Field count
+ output.writeShort(fieldCount);
+ // Field names
+ for (int i = 0; i < fieldCount; i++) {
+ ObjectStreamField f = fields[i];
+ output.writeByte(f.getTypeCode());
+ output.writeUTF(f.getName());
+ if (!f.isPrimitive()) {
+ writeObject(f.getTypeString());
+ }
+ }
+ }
+
+ /**
+ * Write the fields of the object being dumped. The stream will use the
+ * currently active <code>PutField</code> object, allowing users to dump
+ * emulated fields, for cross-loading compatibility when a class definition
+ * changes.
+ *
+ * @throws IOException
+ * If an IO error occurs
+ *
+ * @see #putFields
+ */
+ public void writeFields() throws IOException {
+ // Has to have fields to write
+ if (currentPutField == null) {
+ throw new NotActiveException();
+ }
+ writeFieldValues(currentPutField);
+ }
+
+ /**
+ * Writes a collection of field values for the emulated fields
+ * <code>emulatedFields</code>
+ *
+ * @param emulatedFields
+ * an <code>EmulatedFieldsForDumping</code>, concrete subclass
+ * of <code>PutField</code>
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the field values.
+ *
+ * @see #writeFields
+ * @see #writeObject(Object)
+ */
+ private void writeFieldValues(EmulatedFieldsForDumping emulatedFields)
+ throws IOException {
+ EmulatedFields accessibleSimulatedFields = emulatedFields
+ .emulatedFields(); // Access internal fields which we can
+ // set/get. Users can't do this.
+ EmulatedFields.ObjectSlot[] slots = accessibleSimulatedFields.slots();
+ for (int i = 0; i < slots.length; i++) {
+ EmulatedFields.ObjectSlot slot = slots[i];
+ Object fieldValue = slot.getFieldValue();
+ Class<?> type = slot.getField().getType();
+ // WARNING - default values exist for each primitive type
+ if (type == Integer.TYPE) {
+ output.writeInt(fieldValue != null ? ((Integer) fieldValue)
+ .intValue() : 0);
+ } else if (type == Byte.TYPE) {
+ output.writeByte(fieldValue != null ? ((Byte) fieldValue)
+ .byteValue() : (byte) 0);
+ } else if (type == Character.TYPE) {
+ output.writeChar(fieldValue != null ? ((Character) fieldValue)
+ .charValue() : (char) 0);
+ } else if (type == Short.TYPE) {
+ output.writeShort(fieldValue != null ? ((Short) fieldValue)
+ .shortValue() : (short) 0);
+ } else if (type == Boolean.TYPE) {
+ output.writeBoolean(fieldValue != null ? ((Boolean) fieldValue)
+ .booleanValue() : false);
+ } else if (type == Long.TYPE) {
+ output.writeLong(fieldValue != null ? ((Long) fieldValue)
+ .longValue() : (long) 0);
+ } else if (type == Float.TYPE) {
+ output.writeFloat(fieldValue != null ? ((Float) fieldValue)
+ .floatValue() : (float) 0);
+ } else if (type == Double.TYPE) {
+ output.writeDouble(fieldValue != null ? ((Double) fieldValue)
+ .doubleValue() : (double) 0);
+ } else {
+ // Either array or Object
+ writeObject(fieldValue);
+ }
+ }
+ }
+
+ /**
+ * Writes a collection of field values for the fields described by class
+ * descriptor <code>classDesc</code> (an <code>ObjectStreamClass</code>).
+ * This is the default mechanism, when emulated fields (an
+ * <code>PutField</code>) are not used. Actual values to dump are fetched
+ * directly from object <code>obj</code>.
+ *
+ * @param obj
+ * Instance from which to fetch field values to dump.
+ * @param classDesc
+ * A class descriptor (an <code>ObjectStreamClass</code>)
+ * defining which fields should be dumped.
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the field values.
+ *
+ * @see #writeObject(Object)
+ */
+ private void writeFieldValues(Object obj, ObjectStreamClass classDesc)
+ throws IOException {
+ ObjectStreamField[] fields = classDesc.fields();
+ Class<?> declaringClass = classDesc.forClass();
+ for (int i = 0; i < fields.length; i++) {
+ try {
+ // Code duplication starts, just because Java is typed
+ ObjectStreamField fieldDesc = fields[i];
+ if (fieldDesc.isPrimitive()) {
+ switch (fieldDesc.getTypeCode()) {
+ case 'B':
+ output.writeByte(getFieldByte(obj, declaringClass,
+ fieldDesc.getName()));
+ break;
+ case 'C':
+ output.writeChar(getFieldChar(obj, declaringClass,
+ fieldDesc.getName()));
+ break;
+ case 'D':
+ output.writeDouble(getFieldDouble(obj,
+ declaringClass, fieldDesc.getName()));
+ break;
+ case 'F':
+ output.writeFloat(getFieldFloat(obj,
+ declaringClass, fieldDesc.getName()));
+ break;
+ case 'I':
+ output.writeInt(getFieldInt(obj, declaringClass,
+ fieldDesc.getName()));
+ break;
+ case 'J':
+ output.writeLong(getFieldLong(obj, declaringClass,
+ fieldDesc.getName()));
+ break;
+ case 'S':
+ output.writeShort(getFieldShort(obj,
+ declaringClass, fieldDesc.getName()));
+ break;
+ case 'Z':
+ output.writeBoolean(getFieldBool(obj,
+ declaringClass, fieldDesc.getName()));
+ break;
+ default:
+ throw new IOException(
+ org.apache.harmony.luni.util.Msg.getString(
+ "K00d5", fieldDesc.getTypeCode())); //$NON-NLS-1$
+ }
+ } else {
+ // Object type (array included).
+ Object field = getFieldObj(obj, declaringClass, fieldDesc
+ .getName(), fieldDesc.getTypeString());
+ if (fieldDesc.isUnshared()) {
+ writeUnshared(field);
+ } else {
+ writeObject(field);
+ }
+ }
+ } catch (NoSuchFieldError nsf) {
+ // The user defined serialPersistentFields but did not provide
+ // the glue to transfer values,
+ // (in writeObject) so we end up using the default mechanism and
+ // fail to set the emulated field
+ throw new InvalidClassException(classDesc.getName());
+ }
+ }
+ }
+
+ /**
+ * Write primitive data of type float (<code>value</code>)into the
+ * receiver's underlying stream.
+ *
+ * @param value
+ * The primitive data to write
+ *
+ * @throws IOException
+ * If an IO exception happened when writing the primitive data.
+ */
+ public void writeFloat(float value) throws IOException {
+ checkWritePrimitiveTypes();
+ primitiveTypes.writeFloat(value);
+ }
+
+ /**
+ * Walks the hierarchy of classes described by class descriptor
+ * <code>classDesc</code> and writes the field values corresponding to
[... 1294 lines stripped ...]