Re: [PATCH] Serialization #6 (and final)

2003-12-13 Thread Dalibor Topic
Guilhem Lavaux wrote:
Hi,

Here is the last patch on serialization.
This patch fixes the behaviour of readFields() in ObjectInputStream:
* if called multiple times read fields and build field decoder only once.
* more documentation
* GetField methods should take into account the flags concerning
each serialized fields. If transient we have to make it return
a default value, if not we try to get it in the pool of read fields.
If the field doesn't exist we should throw an exception.
Looks good to me. Please check itin when Savannah comes back online.

cheers,
dalibor topic


___
Classpath mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/classpath


[PATCH] Serialization #6 (and final)

2003-12-07 Thread Guilhem Lavaux
Hi,

Here is the last patch on serialization.
This patch fixes the behaviour of readFields() in ObjectInputStream:
* if called multiple times read fields and build field decoder only once.
* more documentation
* GetField methods should take into account the flags concerning
each serialized fields. If transient we have to make it return
a default value, if not we try to get it in the pool of read fields.
If the field doesn't exist we should throw an exception.
ChangeLog entry:

2003-12-07  Guilhem Lavaux <[EMAIL PROTECTED]>

* java/io/ObjectInputStream.java:
(readFields): Changed implementation of GetField.
(readClassDescriptor): Documented.
Cheers,

Guilhem.

--- java/io/ObjectInputStream.java.orig 2003-12-04 19:36:56.0 +0100
+++ java/io/ObjectInputStream.java  2003-12-04 19:57:15.0 +0100
@@ -417,6 +417,22 @@
 return ret_val;
   }
 
+  /**
+   * This method reads a class descriptor from the real input stream
+   * and use these data to create a new instance of ObjectStreamClass.
+   * Fields are sorted and ordered for the real read which occurs for
+   * each instance of the described class. Be aware that if you call that
+   * method you must ensure that the stream is synchronized, in the other
+   * case it may be completely desynchronized.
+   *
+   * @return A new instance of ObjectStreamClass containing the freshly
+   * created descriptor.
+   * @throws ClassNotFoundException if the required class to build the
+   * descriptor has not been found in the system.
+   * @throws IOException An input/output error occured.
+   * @throws InvalidClassException If there was a compatibility problem
+   * between the class present in the system and the serialized class.
+   */
   protected ObjectStreamClass readClassDescriptor ()
 throws ClassNotFoundException, IOException
   {
@@ -585,7 +601,15 @@
   {
 return Class.forName (osc.getName(), true, currentLoader()); 
   }
-  
+
+  /**
+   * This method invokes the method currentClassLoader for the
+   * current security manager (or build an empty one if it is not
+   * present).
+   *
+   * @return The most recent non-system ClassLoader on the execution stack.
+   * @see java.lang.SecurityManager#currentClassLoader()
+   */
   private ClassLoader currentLoader ()
   {
 SecurityManager sm = System.getSecurityManager ();
@@ -1014,14 +1038,31 @@
   throws IOException, IllegalArgumentException;
   }
 
+  /**
+   * This method should be called by a method called 'readObject' in the
+   * deserializing class (if present). It cannot (and should not)be called
+   * outside of it. Its goal is to read all fields in the real input stream
+   * and keep them accessible through the [EMAIL PROTECTED] #GetField} class. Calling
+   * this method will not alterate the deserializing object.
+   *
+   * @return A valid freshly created 'GetField' instance to get access to
+   * the deserialized stream.
+   * @throws IOException An input/output exception occured. 
+   * @throws ClassNotFoundException 
+   * @throws NotActiveException
+   */
   public GetField readFields ()
 throws IOException, ClassNotFoundException, NotActiveException
   {
 if (this.currentObject == null || this.currentObjectStreamClass == null)
   throw new NotActiveException ("readFields called by non-active class and/or 
object");
 
+if (prereadFields != null)
+  return prereadFields;
+
 if (fieldsAlreadyRead)
-  throw new NotActiveException ("readFields called but fields already read from 
stream (by defaultReadObject or readFields)");
+  throw new NotActiveException ("readFields called but fields already read from"
+   + " stream (by defaultReadObject or readFields)");
 
 final ObjectStreamClass clazz = this.currentObjectStreamClass;
 final byte[] prim_field_data = new byte[clazz.primFieldSize];
@@ -1036,7 +1077,7 @@
   objs[i] = readObject ();
 setBlockDataMode (oldmode);
 
-return new GetField ()
+prereadFields = new GetField ()
   {
public ObjectStreamClass getObjectStreamClass ()
{
@@ -1046,7 +1087,31 @@
public boolean defaulted (String name)
  throws IOException, IllegalArgumentException
{
- return clazz.getField (name) == null;
+ ObjectStreamField f = clazz.getField (name);
+ 
+ /* First if we have a serialized field use the descriptor */
+ if (f != null)
+   {
+ /* It is in serialPersistentFields but setClass tells us
+  * it should not be set. This value is defaulted.
+  */
+ if (f.isPersistent() && !f.isToSet())
+   return true;
+ 
+ return false;
+   }
+
+ /* This is not a serialized field. There should be
+  * a default value only if the field really exists.
+  */
+ try
+   {
+ return (clazz.forClass().getDeclaredField (