/[classpath]/classpath/java/io/ObjectInputStream.java
ViewVC logotype

Diff of /classpath/java/io/ObjectInputStream.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.43.2.15 by gnu_andrew, Tue Aug 16 16:22:37 2005 UTC revision 1.43.2.16 by gnu_andrew, Tue Sep 20 18:46:27 2005 UTC
# Line 39  exception statement from your version. * Line 39  exception statement from your version. *
39    
40  package java.io;  package java.io;
41    
 import gnu.classpath.Configuration;  
42  import gnu.java.io.ObjectIdentityWrapper;  import gnu.java.io.ObjectIdentityWrapper;
43    
44  import java.lang.reflect.Array;  import java.lang.reflect.Array;
# Line 128  public class ObjectInputStream extends I Line 127  public class ObjectInputStream extends I
127     * @exception IOException Exception from underlying     * @exception IOException Exception from underlying
128     * <code>InputStream</code>.     * <code>InputStream</code>.
129     */     */
130    public final Object readObject() throws ClassNotFoundException, IOException    public final Object readObject()
131        throws ClassNotFoundException, IOException
132    {    {
133      if (this.useSubclassMethod)      if (this.useSubclassMethod)
134        return readObjectOverride();        return readObjectOverride();
# Line 138  public class ObjectInputStream extends I Line 138  public class ObjectInputStream extends I
138      Object ret_val;      Object ret_val;
139      was_deserializing = this.isDeserializing;      was_deserializing = this.isDeserializing;
140    
     boolean is_consumed = false;  
141      boolean old_mode = setBlockDataMode(false);      boolean old_mode = setBlockDataMode(false);
142    
143      this.isDeserializing = true;      this.isDeserializing = true;
# Line 151  public class ObjectInputStream extends I Line 150  public class ObjectInputStream extends I
150    
151      try      try
152        {        {
153          switch (marker)          ret_val = parseContent(marker);
154            {         }
155            case TC_ENDBLOCKDATA:       finally
156              {         {
157                ret_val = null;          setBlockDataMode(old_mode);
158                is_consumed = true;          
159                break;          this.isDeserializing = was_deserializing;
160              }          
161            depth -= 2;
162            case TC_BLOCKDATA:          
163            case TC_BLOCKDATALONG:          if (! was_deserializing)
164              {            {
165                if (marker == TC_BLOCKDATALONG)              if (validators.size() > 0)
166                  { if(dump) dumpElementln("BLOCKDATALONG"); }                invokeValidators();
167                else            }
168                  { if(dump) dumpElementln("BLOCKDATA"); }         }
169                readNextBlock(marker);      
170                throw new StreamCorruptedException("Unexpected blockData");       return ret_val;
171              }     }
172    
173            case TC_NULL:     /**
174              {      * Handles a content block within the stream, which begins with a marker
175                if(dump) dumpElementln("NULL");      * byte indicating its type.
176                ret_val = null;      *
177                break;      * @param marker the byte marker.
178              }      * @return an object which represents the parsed content.
179        * @throws ClassNotFoundException if the class of an object being
180            case TC_REFERENCE:      *                                read in cannot be found.
181              {      * @throws IOException if invalid data occurs or one is thrown by the
182                if(dump) dumpElement("REFERENCE ");      *                     underlying <code>InputStream</code>.
183                Integer oid = new Integer(this.realInputStream.readInt());      */
184                if(dump) dumpElementln(Integer.toHexString(oid.intValue()));     private Object parseContent(byte marker)
185                ret_val = ((ObjectIdentityWrapper)       throws ClassNotFoundException, IOException
186                           this.objectLookupTable.get(oid)).object;     {
187                break;       Object ret_val;
188              }       boolean is_consumed = false;
189    
190            case TC_CLASS:       switch (marker)
191           {
192           case TC_ENDBLOCKDATA:
193            {
194              ret_val = null;
195              is_consumed = true;
196              break;
197            }
198            
199           case TC_BLOCKDATA:
200           case TC_BLOCKDATALONG:
201            {
202              if (marker == TC_BLOCKDATALONG)
203                { if(dump) dumpElementln("BLOCKDATALONG"); }
204              else
205                { if(dump) dumpElementln("BLOCKDATA"); }
206              readNextBlock(marker);
207              throw new StreamCorruptedException("Unexpected blockData");
208            }
209            
210           case TC_NULL:
211            {
212              if(dump) dumpElementln("NULL");
213              ret_val = null;
214              break;
215            }
216            
217           case TC_REFERENCE:
218            {
219              if(dump) dumpElement("REFERENCE ");
220              Integer oid = new Integer(this.realInputStream.readInt());
221              if(dump) dumpElementln(Integer.toHexString(oid.intValue()));
222              ret_val = ((ObjectIdentityWrapper)
223                         this.objectLookupTable.get(oid)).object;
224              break;
225            }
226            
227           case TC_CLASS:
228            {
229              if(dump) dumpElementln("CLASS");
230              ObjectStreamClass osc = (ObjectStreamClass)readObject();
231              Class clazz = osc.forClass();
232              assignNewHandle(clazz);
233              ret_val = clazz;
234              break;
235            }
236            
237           case TC_PROXYCLASSDESC:
238            {
239              if(dump) dumpElementln("PROXYCLASS");
240              int n_intf = this.realInputStream.readInt();
241              String[] intfs = new String[n_intf];
242              for (int i = 0; i < n_intf; i++)
243                {
244                  intfs[i] = this.realInputStream.readUTF();
245                  System.out.println(intfs[i]);
246                }
247              
248              boolean oldmode = setBlockDataMode(true);
249              Class cl = resolveProxyClass(intfs);
250              setBlockDataMode(oldmode);
251              
252              ObjectStreamClass osc = lookupClass(cl);
253              assignNewHandle(osc);
254              
255              if (!is_consumed)
256                {
257                  byte b = this.realInputStream.readByte();
258                  if (b != TC_ENDBLOCKDATA)
259                    throw new IOException("Data annotated to class was not consumed." + b);
260                }
261              else
262                is_consumed = false;
263              ObjectStreamClass superosc = (ObjectStreamClass)readObject();
264              osc.setSuperclass(superosc);
265              ret_val = osc;
266              break;
267            }
268            
269           case TC_CLASSDESC:
270            {
271              ObjectStreamClass osc = readClassDescriptor();
272              
273              if (!is_consumed)
274                {
275                  byte b = this.realInputStream.readByte();
276                  if (b != TC_ENDBLOCKDATA)
277                    throw new IOException("Data annotated to class was not consumed." + b);
278                }
279              else
280                is_consumed = false;
281              
282              osc.setSuperclass ((ObjectStreamClass)readObject());
283              ret_val = osc;
284              break;
285            }
286            
287           case TC_STRING:
288           case TC_LONGSTRING:
289            {
290              if(dump) dumpElement("STRING=");
291              String s = this.realInputStream.readUTF();
292              if(dump) dumpElementln(s);
293              ret_val = processResolution(null, s, assignNewHandle(s));
294              break;
295            }
296    
297           case TC_ARRAY:
298            {
299              if(dump) dumpElementln("ARRAY");
300              ObjectStreamClass osc = (ObjectStreamClass)readObject();
301              Class componentType = osc.forClass().getComponentType();
302              if(dump) dumpElement("ARRAY LENGTH=");
303              int length = this.realInputStream.readInt();
304              if(dump) dumpElementln (length + "; COMPONENT TYPE=" + componentType);
305              Object array = Array.newInstance(componentType, length);
306              int handle = assignNewHandle(array);
307              readArrayElements(array, componentType);
308              if(dump)
309                for (int i = 0, len = Array.getLength(array); i < len; i++)
310                  dumpElementln("  ELEMENT[" + i + "]=" + Array.get(array, i));
311              ret_val = processResolution(null, array, handle);
312              break;
313            }
314            
315           case TC_OBJECT:
316            {
317              if(dump) dumpElementln("OBJECT");
318              ObjectStreamClass osc = (ObjectStreamClass)readObject();
319              Class clazz = osc.forClass();
320              
321              if (!osc.realClassIsSerializable)
322                throw new NotSerializableException
323                  (clazz + " is not Serializable, and thus cannot be deserialized.");
324              
325              if (osc.realClassIsExternalizable)
326              {              {
327                if(dump) dumpElementln("CLASS");                Externalizable obj = osc.newInstance();
               ObjectStreamClass osc = (ObjectStreamClass)readObject();  
               Class clazz = osc.forClass();  
               assignNewHandle(clazz);  
               ret_val = clazz;  
               break;  
             }  
   
           case TC_PROXYCLASSDESC:  
             {  
               if(dump) dumpElementln("PROXYCLASS");  
               int n_intf = this.realInputStream.readInt();  
               String[] intfs = new String[n_intf];  
               for (int i = 0; i < n_intf; i++)  
                 {  
                   intfs[i] = this.realInputStream.readUTF();  
                   System.out.println(intfs[i]);  
                 }  
328                                
329                boolean oldmode = setBlockDataMode(true);                int handle = assignNewHandle(obj);
               Class cl = resolveProxyClass(intfs);  
               setBlockDataMode(oldmode);  
330                                
331                ObjectStreamClass osc = lookupClass(cl);                boolean read_from_blocks = ((osc.getFlags() & SC_BLOCK_DATA) != 0);
               assignNewHandle(osc);  
332                                
333                if (!is_consumed)                boolean oldmode = this.readDataFromBlock;
334                  {                if (read_from_blocks)
335                    byte b = this.realInputStream.readByte();                  setBlockDataMode(true);
                   if (b != TC_ENDBLOCKDATA)  
                     throw new IOException("Data annotated to class was not consumed." + b);  
                 }  
               else  
                 is_consumed = false;  
               ObjectStreamClass superosc = (ObjectStreamClass)readObject();  
               osc.setSuperclass(superosc);  
               ret_val = osc;  
               break;  
             }  
   
           case TC_CLASSDESC:  
             {  
               ObjectStreamClass osc = readClassDescriptor();  
336                                
337                if (!is_consumed)                obj.readExternal(this);
338                  {                
339                    byte b = this.realInputStream.readByte();                if (read_from_blocks)
340                    if (b != TC_ENDBLOCKDATA)                  {
341                      throw new IOException("Data annotated to class was not consumed." + b);                    setBlockDataMode(oldmode);
342                      if (!oldmode)
343                        if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
344                          throw new IOException("No end of block data seen for class with readExternal (ObjectInputStream) method.");
345                  }                  }
               else  
                 is_consumed = false;  
                 
               osc.setSuperclass ((ObjectStreamClass)readObject());  
               ret_val = osc;  
               break;  
             }  
   
           case TC_STRING:  
           case TC_LONGSTRING:  
             {  
               if(dump) dumpElement("STRING=");  
               String s = this.realInputStream.readUTF();  
               if(dump) dumpElementln(s);  
               ret_val = processResolution(null, s, assignNewHandle(s));  
               break;  
             }  
   
           case TC_ARRAY:  
             {  
               if(dump) dumpElementln("ARRAY");  
               ObjectStreamClass osc = (ObjectStreamClass)readObject();  
               Class componentType = osc.forClass().getComponentType();  
               if(dump) dumpElement("ARRAY LENGTH=");  
               int length = this.realInputStream.readInt();  
               if(dump) dumpElementln (length + "; COMPONENT TYPE=" + componentType);  
               Object array = Array.newInstance(componentType, length);  
               int handle = assignNewHandle(array);  
               readArrayElements(array, componentType);  
               if(dump)  
                 for (int i = 0, len = Array.getLength(array); i < len; i++)  
                   dumpElementln("  ELEMENT[" + i + "]=" + Array.get(array, i));  
               ret_val = processResolution(null, array, handle);  
               break;  
             }  
   
           case TC_OBJECT:  
             {  
               if(dump) dumpElementln("OBJECT");  
               ObjectStreamClass osc = (ObjectStreamClass)readObject();  
               Class clazz = osc.forClass();  
                 
               if (!osc.realClassIsSerializable)  
                 throw new NotSerializableException  
                   (clazz + " is not Serializable, and thus cannot be deserialized.");  
                 
               if (osc.realClassIsExternalizable)  
                 {  
                   Externalizable obj = osc.newInstance();  
                     
                   int handle = assignNewHandle(obj);  
                     
                   boolean read_from_blocks = ((osc.getFlags() & SC_BLOCK_DATA) != 0);  
                     
                   boolean oldmode = this.readDataFromBlock;  
                   if (read_from_blocks)  
                     setBlockDataMode(true);  
                     
                   obj.readExternal(this);  
                     
                   if (read_from_blocks)  
                     {  
                       setBlockDataMode(oldmode);  
                       if (!oldmode)  
                         if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)  
                             throw new IOException("No end of block data seen for class with readExternal (ObjectInputStream) method.");  
                     }  
                     
                   ret_val = processResolution(osc, obj, handle);  
                   break;  
                 } // end if (osc.realClassIsExternalizable)  
346    
347                Object obj = newObject(clazz, osc.firstNonSerializableParentConstructor);                ret_val = processResolution(osc, obj, handle);
348                                break;
               int handle = assignNewHandle(obj);  
               Object prevObject = this.currentObject;  
               ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;  
                 
               this.currentObject = obj;  
               ObjectStreamClass[] hierarchy =  
                 inputGetObjectStreamClasses(clazz);  
349                                
350                for (int i = 0; i < hierarchy.length; i++)              } // end if (osc.realClassIsExternalizable)
351                  {            
352                    this.currentObjectStreamClass = hierarchy[i];            Object obj = newObject(clazz, osc.firstNonSerializableParentConstructor);
353                                
354                    if(dump) dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ());            int handle = assignNewHandle(obj);
355              Object prevObject = this.currentObject;
356                    // XXX: should initialize fields in classes in the hierarchy            ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
357                    // that aren't in the stream            
358                    // should skip over classes in the stream that aren't in the            this.currentObject = obj;
359                    // real classes hierarchy            ObjectStreamClass[] hierarchy =
360                                  inputGetObjectStreamClasses(clazz);
361                    Method readObjectMethod = this.currentObjectStreamClass.readObjectMethod;            
362                    if (readObjectMethod != null)            for (int i = 0; i < hierarchy.length; i++)      
363                      {            {
364                        fieldsAlreadyRead = false;                this.currentObjectStreamClass = hierarchy[i];
365                        boolean oldmode = setBlockDataMode(true);                if(dump) dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ());
366                        callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);                
367                        setBlockDataMode(oldmode);                // XXX: should initialize fields in classes in the hierarchy
368                      }                // that aren't in the stream
369                    else                // should skip over classes in the stream that aren't in the
370                      {                // real classes hierarchy
371                        readFields(obj, currentObjectStreamClass);                
372                      }                Method readObjectMethod = this.currentObjectStreamClass.readObjectMethod;
373                  if (readObjectMethod != null)
374                    if (this.currentObjectStreamClass.hasWriteMethod())                  {
375                      {                    fieldsAlreadyRead = false;
376                        if(dump) dumpElement("ENDBLOCKDATA? ");                    boolean oldmode = setBlockDataMode(true);
377                        try                    callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);
378                          {                    setBlockDataMode(oldmode);
379                            // FIXME: XXX: This try block is to                  }
380                            // catch EOF which is thrown for some                else
381                            // objects.  That indicates a bug in                  {
382                            // the logic.                    readFields(obj, currentObjectStreamClass);
383                    }
384                            if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)                
385                              throw new IOException                if (this.currentObjectStreamClass.hasWriteMethod())
386                                ("No end of block data seen for class with readObject (ObjectInputStream) method.");                  {
387                            if(dump) dumpElementln("yes");                    if(dump) dumpElement("ENDBLOCKDATA? ");
388                          }                    try
389  //                    catch (EOFException e)                      {
390  //                      {                        /* Read blocks until an end marker */
391  //                        if(dump) dumpElementln("no, got EOFException");                        byte writeMarker = this.realInputStream.readByte();
392  //                      }                        while (writeMarker != TC_ENDBLOCKDATA)
393                        catch (IOException e)                          {      
394                          {                            parseContent(writeMarker);
395                            if(dump) dumpElementln("no, got IOException");                            writeMarker = this.realInputStream.readByte();
396                          }                          }
397                          if(dump) dumpElementln("yes");
398                        }
399                      catch (EOFException e)
400                        {
401                          throw (IOException) new IOException
402                            ("No end of block data seen for class with readObject (ObjectInputStream) method.").initCause(e);
403                      }                      }
404                  }                  }
   
               this.currentObject = prevObject;  
               this.currentObjectStreamClass = prevObjectStreamClass;  
               ret_val = processResolution(osc, obj, handle);  
                     
               break;  
405              }              }
406              
407            case TC_RESET:            this.currentObject = prevObject;
408              if(dump) dumpElementln("RESET");            this.currentObjectStreamClass = prevObjectStreamClass;
409              clearHandles();            ret_val = processResolution(osc, obj, handle);
410              ret_val = readObject();            
411              break;            break;
412            }
           case TC_EXCEPTION:  
             {  
               if(dump) dumpElement("EXCEPTION=");  
               Exception e = (Exception)readObject();  
               if(dump) dumpElementln(e.toString());  
               clearHandles();  
               throw new WriteAbortedException("Exception thrown during writing of stream", e);  
             }  
   
           default:  
             throw new IOException("Unknown marker on stream: " + marker);  
           }  
       }  
     finally  
       {  
         setBlockDataMode(old_mode);  
413                    
414          this.isDeserializing = was_deserializing;         case TC_RESET:
415            if(dump) dumpElementln("RESET");
416            clearHandles();
417            ret_val = readObject();
418            break;
419                    
420          depth -= 2;         case TC_EXCEPTION:
421            {
422              if(dump) dumpElement("EXCEPTION=");
423              Exception e = (Exception)readObject();
424              if(dump) dumpElementln(e.toString());
425              clearHandles();
426              throw new WriteAbortedException("Exception thrown during writing of stream", e);
427            }
428                    
429          if (! was_deserializing)         default:
430            {          throw new IOException("Unknown marker on stream: " + marker);
             if (validators.size() > 0)  
               invokeValidators();  
           }  
431        }        }
       
432      return ret_val;      return ret_val;
433    }    }
434    
# Line 812  public class ObjectInputStream extends I Line 828  public class ObjectInputStream extends I
828    
829    /**    /**
830     * Reconstruct class hierarchy the same way     * Reconstruct class hierarchy the same way
831     * {@link java.io.ObjectStreamClass.getObjectStreamClasses(java.lang.Class)} does     * {@link java.io.ObjectStreamClass#getObjectStreamClasses(Class)} does
832     * but using lookupClass instead of ObjectStreamClass.lookup. This     * but using lookupClass instead of ObjectStreamClass.lookup. This
833     * dup is necessary localize the lookup table. Hopefully some future     * dup is necessary localize the lookup table. Hopefully some future
834     * rewritings will be able to prevent this.     * rewritings will be able to prevent this.
# Line 881  public class ObjectInputStream extends I Line 897  public class ObjectInputStream extends I
897        }        }
898      else      else
899        for (int i = 0; i < intfs.length; i++)        for (int i = 0; i < intfs.length; i++)
900          clss[i] = cl.loadClass(intfs[i]);          clss[i] = Class.forName(intfs[i], false, cl);
901      try      try
902        {        {
903          return Proxy.getProxyClass(cl, clss);          return Proxy.getProxyClass(cl, clss);
# Line 1202  public class ObjectInputStream extends I Line 1218  public class ObjectInputStream extends I
1218     * This method should be called by a method called 'readObject' in the     * This method should be called by a method called 'readObject' in the
1219     * deserializing class (if present). It cannot (and should not)be called     * deserializing class (if present). It cannot (and should not)be called
1220     * outside of it. Its goal is to read all fields in the real input stream     * outside of it. Its goal is to read all fields in the real input stream
1221     * and keep them accessible through the {@link #GetField} class. Calling     * and keep them accessible through the {@link GetField} class. Calling
1222     * this method will not alter the deserializing object.     * this method will not alter the deserializing object.
1223     *     *
1224     * @return A valid freshly created 'GetField' instance to get access to     * @return A valid freshly created 'GetField' instance to get access to
# Line 1915  public class ObjectInputStream extends I Line 1931  public class ObjectInputStream extends I
1931      System.out.print (Thread.currentThread() + ": ");      System.out.print (Thread.currentThread() + ": ");
1932    }    }
1933    
   static  
   {  
     if (Configuration.INIT_LOAD_LIBRARY)  
       {  
         System.loadLibrary ("javaio");  
       }  
   }  
   
1934    // used to keep a prioritized list of object validators    // used to keep a prioritized list of object validators
1935    private static final class ValidatorAndPriority implements Comparable    private static final class ValidatorAndPriority implements Comparable
1936    {    {

Legend:
Removed from v.1.43.2.15  
changed lines
  Added in v.1.43.2.16

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26