/[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.66 by tromey, Tue Sep 13 22:19:15 2005 UTC revision 1.67 by gnu_andrew, Wed Sep 14 14:47:47 2005 UTC
# Line 120  public class ObjectInputStream extends I Line 120  public class ObjectInputStream extends I
120     * @exception IOException Exception from underlying     * @exception IOException Exception from underlying
121     * <code>InputStream</code>.     * <code>InputStream</code>.
122     */     */
123    public final Object readObject() throws ClassNotFoundException, IOException    public final Object readObject()
124        throws ClassNotFoundException, IOException
125    {    {
126      if (this.useSubclassMethod)      if (this.useSubclassMethod)
127        return readObjectOverride();        return readObjectOverride();
# Line 130  public class ObjectInputStream extends I Line 131  public class ObjectInputStream extends I
131      Object ret_val;      Object ret_val;
132      was_deserializing = this.isDeserializing;      was_deserializing = this.isDeserializing;
133    
     boolean is_consumed = false;  
134      boolean old_mode = setBlockDataMode(false);      boolean old_mode = setBlockDataMode(false);
135    
136      this.isDeserializing = true;      this.isDeserializing = true;
# Line 143  public class ObjectInputStream extends I Line 143  public class ObjectInputStream extends I
143    
144      try      try
145        {        {
146          switch (marker)          ret_val = parseContent(marker);
147           }
148         finally
149           {
150            setBlockDataMode(old_mode);
151            
152            this.isDeserializing = was_deserializing;
153            
154            depth -= 2;
155            
156            if (! was_deserializing)
157            {            {
158            case TC_ENDBLOCKDATA:              if (validators.size() > 0)
159                  invokeValidators();
160              }
161           }
162        
163         return ret_val;
164       }
165    
166       /**
167        * Handles a content block within the stream, which begins with a marker
168        * byte indicating its type.
169        *
170        * @param byte the byte marker.
171        * @return an object which represents the parsed content.
172        * @throws ClassNotFoundException if the class of an object being
173        *                                read in cannot be found.
174        * @throws IOException if invalid data occurs or one is thrown by the
175        *                     underlying <code>InputStream</code>.
176        */
177       private Object parseContent(byte marker)
178         throws ClassNotFoundException, IOException
179       {
180         Object ret_val;
181         boolean is_consumed = false;
182    
183         switch (marker)
184           {
185           case TC_ENDBLOCKDATA:
186            {
187              ret_val = null;
188              is_consumed = true;
189              break;
190            }
191            
192           case TC_BLOCKDATA:
193           case TC_BLOCKDATALONG:
194            {
195              if (marker == TC_BLOCKDATALONG)
196                { if(dump) dumpElementln("BLOCKDATALONG"); }
197              else
198                { if(dump) dumpElementln("BLOCKDATA"); }
199              readNextBlock(marker);
200              throw new StreamCorruptedException("Unexpected blockData");
201            }
202            
203           case TC_NULL:
204            {
205              if(dump) dumpElementln("NULL");
206              ret_val = null;
207              break;
208            }
209            
210           case TC_REFERENCE:
211            {
212              if(dump) dumpElement("REFERENCE ");
213              Integer oid = new Integer(this.realInputStream.readInt());
214              if(dump) dumpElementln(Integer.toHexString(oid.intValue()));
215              ret_val = ((ObjectIdentityWrapper)
216                         this.objectLookupTable.get(oid)).object;
217              break;
218            }
219            
220           case TC_CLASS:
221            {
222              if(dump) dumpElementln("CLASS");
223              ObjectStreamClass osc = (ObjectStreamClass)readObject();
224              Class clazz = osc.forClass();
225              assignNewHandle(clazz);
226              ret_val = clazz;
227              break;
228            }
229            
230           case TC_PROXYCLASSDESC:
231            {
232              if(dump) dumpElementln("PROXYCLASS");
233              int n_intf = this.realInputStream.readInt();
234              String[] intfs = new String[n_intf];
235              for (int i = 0; i < n_intf; i++)
236                {
237                  intfs[i] = this.realInputStream.readUTF();
238                  System.out.println(intfs[i]);
239                }
240              
241              boolean oldmode = setBlockDataMode(true);
242              Class cl = resolveProxyClass(intfs);
243              setBlockDataMode(oldmode);
244              
245              ObjectStreamClass osc = lookupClass(cl);
246              assignNewHandle(osc);
247              
248              if (!is_consumed)
249                {
250                  byte b = this.realInputStream.readByte();
251                  if (b != TC_ENDBLOCKDATA)
252                    throw new IOException("Data annotated to class was not consumed." + b);
253                }
254              else
255                is_consumed = false;
256              ObjectStreamClass superosc = (ObjectStreamClass)readObject();
257              osc.setSuperclass(superosc);
258              ret_val = osc;
259              break;
260            }
261            
262           case TC_CLASSDESC:
263            {
264              ObjectStreamClass osc = readClassDescriptor();
265              
266              if (!is_consumed)
267                {
268                  byte b = this.realInputStream.readByte();
269                  if (b != TC_ENDBLOCKDATA)
270                    throw new IOException("Data annotated to class was not consumed." + b);
271                }
272              else
273                is_consumed = false;
274              
275              osc.setSuperclass ((ObjectStreamClass)readObject());
276              ret_val = osc;
277              break;
278            }
279            
280           case TC_STRING:
281           case TC_LONGSTRING:
282            {
283              if(dump) dumpElement("STRING=");
284              String s = this.realInputStream.readUTF();
285              if(dump) dumpElementln(s);
286              ret_val = processResolution(null, s, assignNewHandle(s));
287              break;
288            }
289    
290           case TC_ARRAY:
291            {
292              if(dump) dumpElementln("ARRAY");
293              ObjectStreamClass osc = (ObjectStreamClass)readObject();
294              Class componentType = osc.forClass().getComponentType();
295              if(dump) dumpElement("ARRAY LENGTH=");
296              int length = this.realInputStream.readInt();
297              if(dump) dumpElementln (length + "; COMPONENT TYPE=" + componentType);
298              Object array = Array.newInstance(componentType, length);
299              int handle = assignNewHandle(array);
300              readArrayElements(array, componentType);
301              if(dump)
302                for (int i = 0, len = Array.getLength(array); i < len; i++)
303                  dumpElementln("  ELEMENT[" + i + "]=" + Array.get(array, i));
304              ret_val = processResolution(null, array, handle);
305              break;
306            }
307            
308           case TC_OBJECT:
309            {
310              if(dump) dumpElementln("OBJECT");
311              ObjectStreamClass osc = (ObjectStreamClass)readObject();
312              Class clazz = osc.forClass();
313              
314              if (!osc.realClassIsSerializable)
315                throw new NotSerializableException
316                  (clazz + " is not Serializable, and thus cannot be deserialized.");
317              
318              if (osc.realClassIsExternalizable)
319              {              {
320                ret_val = null;                Externalizable obj = osc.newInstance();
               is_consumed = true;  
               break;  
             }  
   
           case TC_BLOCKDATA:  
           case TC_BLOCKDATALONG:  
             {  
               if (marker == TC_BLOCKDATALONG)  
                 { if(dump) dumpElementln("BLOCKDATALONG"); }  
               else  
                 { if(dump) dumpElementln("BLOCKDATA"); }  
               readNextBlock(marker);  
               throw new StreamCorruptedException("Unexpected blockData");  
             }  
   
           case TC_NULL:  
             {  
               if(dump) dumpElementln("NULL");  
               ret_val = null;  
               break;  
             }  
   
           case TC_REFERENCE:  
             {  
               if(dump) dumpElement("REFERENCE ");  
               Integer oid = new Integer(this.realInputStream.readInt());  
               if(dump) dumpElementln(Integer.toHexString(oid.intValue()));  
               ret_val = ((ObjectIdentityWrapper)  
                          this.objectLookupTable.get(oid)).object;  
               break;  
             }  
   
           case TC_CLASS:  
             {  
               if(dump) dumpElementln("CLASS");  
               ObjectStreamClass osc = (ObjectStreamClass)readObject();  
               Class clazz = osc.forClass();  
               assignNewHandle(clazz);  
               ret_val = clazz;  
               break;  
             }  
   
           case TC_PROXYCLASSDESC:  
             {  
               if(dump) dumpElementln("PROXYCLASS");  
               int n_intf = this.realInputStream.readInt();  
               String[] intfs = new String[n_intf];  
               for (int i = 0; i < n_intf; i++)  
                 {  
                   intfs[i] = this.realInputStream.readUTF();  
                 }  
321                                
322                boolean oldmode = setBlockDataMode(true);                int handle = assignNewHandle(obj);
               Class cl = resolveProxyClass(intfs);  
               setBlockDataMode(oldmode);  
323                                
324                ObjectStreamClass osc = lookupClass(cl);                boolean read_from_blocks = ((osc.getFlags() & SC_BLOCK_DATA) != 0);
               assignNewHandle(osc);  
325                                
326                if (!is_consumed)                boolean oldmode = this.readDataFromBlock;
327                  {                if (read_from_blocks)
328                    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);  
               osc.firstNonSerializableParentConstructor =  
                 superosc.firstNonSerializableParentConstructor;  
               osc.fieldMapping = new ObjectStreamField[0];  
               osc.realClassIsSerializable = true;  
               ret_val = osc;  
               break;  
             }  
   
           case TC_CLASSDESC:  
             {  
               ObjectStreamClass osc = readClassDescriptor();  
329                                
330                if (!is_consumed)                obj.readExternal(this);
331                  {                
332                    byte b = this.realInputStream.readByte();                if (read_from_blocks)
333                    if (b != TC_ENDBLOCKDATA)                  {
334                      throw new IOException("Data annotated to class was not consumed." + b);                    setBlockDataMode(oldmode);
335                      if (!oldmode)
336                        if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
337                          throw new IOException("No end of block data seen for class with readExternal (ObjectInputStream) method.");
338                  }                  }
               else  
                 is_consumed = false;  
                 
               osc.setSuperclass ((ObjectStreamClass)readObject());  
               ret_val = osc;  
               break;  
             }  
339    
340            case TC_STRING:                ret_val = processResolution(osc, obj, handle);
341            case TC_LONGSTRING:                break;
             {  
               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.");  
342                                
343                if (osc.realClassIsExternalizable)              } // end if (osc.realClassIsExternalizable)
344                  {            
345                    Externalizable obj = osc.newInstance();            Object obj = newObject(clazz, osc.firstNonSerializableParentConstructor);
346                                
347                    int handle = assignNewHandle(obj);            int handle = assignNewHandle(obj);
348                                Object prevObject = this.currentObject;
349                    boolean read_from_blocks = ((osc.getFlags() & SC_BLOCK_DATA) != 0);            ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
350                                
351                    boolean oldmode = this.readDataFromBlock;            this.currentObject = obj;
352                    if (read_from_blocks)            ObjectStreamClass[] hierarchy =
353                      setBlockDataMode(true);              inputGetObjectStreamClasses(clazz);
354                                
355                    obj.readExternal(this);            for (int i = 0; i < hierarchy.length; i++)      
356                                {
357                    if (read_from_blocks)                this.currentObjectStreamClass = hierarchy[i];
358                      {                if(dump) dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ());
359                        setBlockDataMode(oldmode);                
360                        if (!oldmode)                // XXX: should initialize fields in classes in the hierarchy
361                          if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)                // that aren't in the stream
362                              throw new IOException("No end of block data seen for class with readExternal (ObjectInputStream) method.");                // should skip over classes in the stream that aren't in the
363                      }                // real classes hierarchy
364                                    
365                    ret_val = processResolution(osc, obj, handle);                Method readObjectMethod = this.currentObjectStreamClass.readObjectMethod;
366                    break;                if (readObjectMethod != null)
367                  } // end if (osc.realClassIsExternalizable)                  {
368                      fieldsAlreadyRead = false;
369                Object obj = newObject(clazz, osc.firstNonSerializableParentConstructor);                    boolean oldmode = setBlockDataMode(true);
370                                    callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);
371                int handle = assignNewHandle(obj);                    setBlockDataMode(oldmode);
372                Object prevObject = this.currentObject;                  }
373                ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;                else
374                                  {
375                this.currentObject = obj;                    readFields(obj, currentObjectStreamClass);
376                ObjectStreamClass[] hierarchy =                  }
377                  inputGetObjectStreamClasses(clazz);                
378                                if (this.currentObjectStreamClass.hasWriteMethod())
379                for (int i = 0; i < hierarchy.length; i++)                  {
380                  {                    if(dump) dumpElement("ENDBLOCKDATA? ");
381                    this.currentObjectStreamClass = hierarchy[i];                    try
382                                          {
383                    if(dump) dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ());                        /* Read blocks until an end marker */
384                          byte writeMarker = this.realInputStream.readByte();
385                    // XXX: should initialize fields in classes in the hierarchy                        while (writeMarker != TC_ENDBLOCKDATA)
386                    // that aren't in the stream                          {      
387                    // should skip over classes in the stream that aren't in the                            parseContent(writeMarker);
388                    // real classes hierarchy                            writeMarker = this.realInputStream.readByte();
                     
                   Method readObjectMethod = this.currentObjectStreamClass.readObjectMethod;  
                   if (readObjectMethod != null)  
                     {  
                       fieldsAlreadyRead = false;  
                       boolean oldmode = setBlockDataMode(true);  
                       callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);  
                       setBlockDataMode(oldmode);  
                     }  
                   else  
                     {  
                       readFields(obj, currentObjectStreamClass);  
                     }  
   
                   if (this.currentObjectStreamClass.hasWriteMethod())  
                     {  
                       if(dump) dumpElement("ENDBLOCKDATA? ");  
                       try  
                         {  
                           // FIXME: XXX: This try block is to  
                           // catch EOF which is thrown for some  
                           // objects.  That indicates a bug in  
                           // the logic.  
   
                           if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)  
                             throw new IOException  
                               ("No end of block data seen for class with readObject (ObjectInputStream) method.");  
                           if(dump) dumpElementln("yes");  
                         }  
 //                    catch (EOFException e)  
 //                      {  
 //                        if(dump) dumpElementln("no, got EOFException");  
 //                      }  
                       catch (IOException e)  
                         {  
                           if(dump) dumpElementln("no, got IOException");  
389                          }                          }
390                          if(dump) dumpElementln("yes");
391                        }
392                      catch (EOFException e)
393                        {
394                          throw (IOException) new IOException
395                            ("No end of block data seen for class with readObject (ObjectInputStream) method.").initCause(e);
396                      }                      }
397                  }                  }
   
               this.currentObject = prevObject;  
               this.currentObjectStreamClass = prevObjectStreamClass;  
               ret_val = processResolution(osc, obj, handle);  
                     
               break;  
398              }              }
399              
400            case TC_RESET:            this.currentObject = prevObject;
401              if(dump) dumpElementln("RESET");            this.currentObjectStreamClass = prevObjectStreamClass;
402              clearHandles();            ret_val = processResolution(osc, obj, handle);
403              ret_val = readObject();            
404              break;            break;
405            }
           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);  
406                    
407          this.isDeserializing = was_deserializing;         case TC_RESET:
408            if(dump) dumpElementln("RESET");
409            clearHandles();
410            ret_val = readObject();
411            break;
412                    
413          depth -= 2;         case TC_EXCEPTION:
414            {
415              if(dump) dumpElement("EXCEPTION=");
416              Exception e = (Exception)readObject();
417              if(dump) dumpElementln(e.toString());
418              clearHandles();
419              throw new WriteAbortedException("Exception thrown during writing of stream", e);
420            }
421                    
422          if (! was_deserializing)         default:
423            {          throw new IOException("Unknown marker on stream: " + marker);
             if (validators.size() > 0)  
               invokeValidators();  
           }  
424        }        }
       
425      return ret_val;      return ret_val;
426    }    }
427    

Legend:
Removed from v.1.66  
changed lines
  Added in v.1.67

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