/[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.32 by tromey, Fri Aug 1 03:33:59 2003 UTC revision 1.33 by glavaux, Tue Dec 2 18:35:51 2003 UTC
# Line 47  import java.util.Arrays; Line 47  import java.util.Arrays;
47  import java.util.Hashtable;  import java.util.Hashtable;
48  import java.util.Vector;  import java.util.Vector;
49    
   
50  import gnu.java.io.ObjectIdentityWrapper;  import gnu.java.io.ObjectIdentityWrapper;
51  import gnu.java.lang.reflect.TypeSignature;  import gnu.java.lang.reflect.TypeSignature;
52  import java.lang.reflect.Field;  import java.lang.reflect.Field;
# Line 99  public class ObjectInputStream extends I Line 98  public class ObjectInputStream extends I
98      this.blockDataInput = new DataInputStream (this);      this.blockDataInput = new DataInputStream (this);
99      this.realInputStream = new DataInputStream (in);      this.realInputStream = new DataInputStream (in);
100      this.nextOID = baseWireHandle;      this.nextOID = baseWireHandle;
101      this.objectLookupTable = new Hashtable ();      this.objectLookupTable = new Hashtable();
102      this.validators = new Vector ();      this.validators = new Vector();
103        this.classLookupTable = new Hashtable();
104      setBlockDataMode (true);      setBlockDataMode (true);
105      readStreamHeader ();      readStreamHeader();
106    }    }
107    
108    
# Line 203  public class ObjectInputStream extends I Line 203  public class ObjectInputStream extends I
203                Class cl = resolveProxyClass(intfs);                Class cl = resolveProxyClass(intfs);
204                setBlockDataMode(oldmode);                setBlockDataMode(oldmode);
205                                
206                ObjectStreamClass osc = ObjectStreamClass.lookup(cl);                ObjectStreamClass osc = lookupClass (cl);
207                assignNewHandle (osc);                assignNewHandle (osc);
208                                
209                if (!is_consumed)                if (!is_consumed)
# Line 332  public class ObjectInputStream extends I Line 332  public class ObjectInputStream extends I
332                int handle = assignNewHandle (obj);                int handle = assignNewHandle (obj);
333                this.currentObject = obj;                this.currentObject = obj;
334                ObjectStreamClass[] hierarchy =                ObjectStreamClass[] hierarchy =
335                  ObjectStreamClass.getObjectStreamClasses (clazz);                  inputGetObjectStreamClasses (clazz);
336                                
337                for (int i=0; i < hierarchy.length; i++)                for (int i=0; i < hierarchy.length; i++)
338                  {                  {
# Line 455  public class ObjectInputStream extends I Line 455  public class ObjectInputStream extends I
455            new ObjectStreamField (field_name, class_name);            new ObjectStreamField (field_name, class_name);
456        }        }
457                                
458        Class clazz = resolveClass (osc);
459      boolean oldmode = setBlockDataMode (true);      boolean oldmode = setBlockDataMode (true);
460      osc.setClass (resolveClass (osc));      osc.setClass (clazz, lookupClass (clazz.getSuperclass()));
461        classLookupTable.put (clazz, osc);
462      setBlockDataMode (oldmode);      setBlockDataMode (oldmode);
463                                
464      return osc;      return osc;
# Line 550  public class ObjectInputStream extends I Line 552  public class ObjectInputStream extends I
552    protected Class resolveClass (ObjectStreamClass osc)    protected Class resolveClass (ObjectStreamClass osc)
553      throws ClassNotFoundException, IOException      throws ClassNotFoundException, IOException
554    {    {
555        return Class.forName (osc.getName(), true, currentLoader());
556      }
557      
558      private ClassLoader currentLoader ()
559      {
560      SecurityManager sm = System.getSecurityManager ();      SecurityManager sm = System.getSecurityManager ();
561      if (sm == null)      if (sm == null)
562        sm = new SecurityManager () {};        sm = new SecurityManager () {};
563    
564        return currentClassLoader (sm);
565      }
566    
567      ClassLoader cl = currentClassLoader (sm);    /**
568       * Lookup a class stored in the local hashtable. If it is not
569       * use the global lookup function in ObjectStreamClass to build
570       * the ObjectStreamClass. This method is requested according to
571       * the behaviour detected in the JDK by Kaffe's team.
572       *
573       * @param clazz Class to lookup in the hash table or for which
574       * we must build a descriptor.
575       * @return A valid instance of ObjectStreamClass corresponding
576       * to the specified class.
577       */
578      private ObjectStreamClass lookupClass (Class clazz)
579      {
580        ObjectStreamClass oclazz;
581        
582        oclazz = (ObjectStreamClass) classLookupTable.get(clazz);
583        if (oclazz == null)
584          return ObjectStreamClass.lookup (clazz);
585        else
586          return oclazz;
587      }
588    
589      if (cl == null)    /**
590        return Class.forName (osc.getName ());     * Reconstruct class hierarchy the same way
591       * {@link java.io.ObjectStreamClass.getObjectStreamClasses(java.lang.Class)} does
592       * but using lookupClass instead of ObjectStreamClass.lookup. This
593       * dup is necessary localize the lookup table. Hopefully some future rewritings will
594       * be able to prevent this.
595       *
596       * @param clazz This is the class for which we want the hierarchy.
597       *
598       * @return An array of valid {@link java.io.ObjectStreamClass} instances which
599       * represent the class hierarchy for clazz.
600       */
601      private ObjectStreamClass[] inputGetObjectStreamClasses (Class clazz)
602      {
603        ObjectStreamClass osc = lookupClass (clazz);
604    
605        ObjectStreamClass[] ret_val;
606    
607        if (osc == null)
608          return new ObjectStreamClass[0];
609      else      else
610        return cl.loadClass (osc.getName ());      {
611          Vector oscs = new Vector ();
612    
613          while (osc != null)
614          {
615            oscs.addElement (osc);
616            osc = osc.getSuper ();
617          }
618    
619          int count = oscs.size ();
620          ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[ count ];
621    
622          for (int i = count - 1; i >= 0; i--)
623            sorted_oscs[ count - i - 1 ] = (ObjectStreamClass)oscs.elementAt (i);
624    
625          return sorted_oscs;
626        }
627    }    }
628    
629    /**    /**
# Line 1148  public class ObjectInputStream extends I Line 1212  public class ObjectInputStream extends I
1212      throw new IOException ("Subclass of ObjectInputStream must implement readObjectOverride");      throw new IOException ("Subclass of ObjectInputStream must implement readObjectOverride");
1213    }    }
1214    
1215    // assigns the next availible handle to OBJ    /**
1216       * Assigns the next available handle to <code>obj</code>.
1217       *
1218       * @param obj The object for which we want a new handle.
1219       * @return A valid handle for the specified object.
1220       */
1221    private int assignNewHandle (Object obj)    private int assignNewHandle (Object obj)
1222    {    {
1223      this.objectLookupTable.put (new Integer (this.nextOID),      this.objectLookupTable.put (new Integer (this.nextOID),
# Line 1300  public class ObjectInputStream extends I Line 1369  public class ObjectInputStream extends I
1369    {    {
1370      ObjectStreamField[] stream_fields = stream_osc.fields;      ObjectStreamField[] stream_fields = stream_osc.fields;
1371      ObjectStreamField[] real_fields =      ObjectStreamField[] real_fields =
1372        ObjectStreamClass.lookup (stream_osc.forClass ()).fields;        lookupClass (stream_osc.forClass ()).fields;
1373    
1374      boolean default_initialize, set_value;      boolean default_initialize, set_value;
1375      String field_name = null;      String field_name = null;
# Line 1493  public class ObjectInputStream extends I Line 1562  public class ObjectInputStream extends I
1562        }        }
1563    }    }
1564    
1565    // this native method is used to get access to the protected method    /**
1566    // of the same name in SecurityManger     * This native method is used to get access to the protected method
1567       * of the same name in SecurityManger.
1568       *
1569       * @param sm SecurityManager instance which should be called.
1570       * @return The current class loader in the calling stack.
1571       */
1572    private static native ClassLoader currentClassLoader (SecurityManager sm);    private static native ClassLoader currentClassLoader (SecurityManager sm);
1573    
1574    private static Field getField (Class klass, String name)    private static Field getField (Class klass, String name)
1575      throws java.lang.NoSuchFieldException      throws java.lang.NoSuchFieldException
1576    {    {
1577      final Field f = klass.getDeclaredField(name);      final Field f = klass.getDeclaredField(name);
1578        
1579      AccessController.doPrivileged(new PrivilegedAction()      AccessController.doPrivileged(new PrivilegedAction()
1580        {        {
1581          public Object run()          public Object run()
# Line 1565  public class ObjectInputStream extends I Line 1640  public class ObjectInputStream extends I
1640    
1641    private native void callConstructor (Class clazz, Object obj);    private native void callConstructor (Class clazz, Object obj);
1642    
1643      /**
1644       * This method writes a "boolean" value <code>val</code> in the specified field
1645       * of the instance <code>obj</code> of the type <code>klass</code>.
1646       *
1647       * @param obj Instance to setup.
1648       * @param klass Class type of the specified instance.
1649       * @param field_name Name of the field in the specified class type.
1650       * @param val The boolean value to write into the field.
1651       * @throws InvalidClassException if the specified field has not the required type.
1652       * @throws IOException if there is no field of that name in the specified class.
1653       */
1654    private void setBooleanField (Object obj, Class klass, String field_name,    private void setBooleanField (Object obj, Class klass, String field_name,
1655                                  boolean val)                                  boolean val) throws IOException, InvalidClassException
1656    {    {
1657      try      try
1658        {        {
1659          Field f = getField (klass, field_name);          Field f = getField (klass, field_name);
1660          f.setBoolean (obj, val);          f.setBoolean (obj, val);
1661        }        }
1662        catch (IllegalArgumentException _)
1663          {
1664            throw new InvalidClassException("incompatible field type for " + klass.getName() + "." + field_name);
1665          }
1666      catch (Exception _)      catch (Exception _)
1667        {        {
1668        }            }    
1669    }    }
1670    
1671      /**
1672       * This method writes a "byte" value <code>val</code> in the specified field
1673       * of the instance <code>obj</code> of the type <code>klass</code>.
1674       *
1675       * @param obj Instance to setup.
1676       * @param klass Class type of the specified instance.
1677       * @param field_name Name of the field in the specified class type.
1678       * @param val The byte value to write into the field.
1679       * @throws InvalidClassException if the specified field has not the required type.
1680       * @throws IOException if there is no field of that name in the specified class.
1681       */
1682    private void setByteField (Object obj, Class klass, String field_name,    private void setByteField (Object obj, Class klass, String field_name,
1683                               byte val)                               byte val) throws IOException, InvalidClassException
1684    {    {
1685      try      try
1686        {        {
1687          Field f = getField (klass, field_name);          Field f = getField (klass, field_name);
1688          f.setByte (obj, val);          f.setByte (obj, val);
1689        }        }
1690        catch (IllegalArgumentException _)
1691          {
1692            throw new InvalidClassException("incompatible field type for " + klass.getName() + "." + field_name);
1693          }
1694      catch (Exception _)      catch (Exception _)
1695        {        {
1696        }            }    
1697    }    }
1698    
1699      /**
1700       * This method writes a "character" value <code>val</code> in the specified field
1701       * of the instance <code>obj</code> of the type <code>klass</code>.
1702       *
1703       * @param obj Instance to setup.
1704       * @param klass Class type of the specified instance.
1705       * @param field_name Name of the field in the specified class type.
1706       * @param val The character value to write into the field.
1707       * @throws InvalidClassException if the specified field has not the required type.
1708       * @throws IOException if there is no field of that name in the specified class.
1709       */
1710    private void setCharField (Object obj, Class klass, String field_name,    private void setCharField (Object obj, Class klass, String field_name,
1711                               char val)                               char val) throws IOException, InvalidClassException
1712    {    {
1713      try      try
1714        {        {
1715          Field f = getField (klass, field_name);          Field f = getField (klass, field_name);
1716          f.setChar (obj, val);          f.setChar (obj, val);
1717        }        }
1718        catch (IllegalArgumentException _)
1719          {
1720            throw new InvalidClassException("incompatible field type for " + klass.getName() + "." + field_name);
1721          }
1722      catch (Exception _)      catch (Exception _)
1723        {        {
1724        }            }    
1725    }    }
1726    
1727      /**
1728       * This method writes a "double" value <code>val</code> in the specified field
1729       * of the instance <code>obj</code> of the type <code>klass</code>.
1730       *
1731       * @param obj Instance to setup.
1732       * @param klass Class type of the specified instance.
1733       * @param field_name Name of the field in the specified class type.
1734       * @param val The double value to write into the field.
1735       * @throws InvalidClassException if the specified field has not the required type.
1736       * @throws IOException if there is no field of that name in the specified class.
1737       */
1738    private void setDoubleField (Object obj, Class klass, String field_name,    private void setDoubleField (Object obj, Class klass, String field_name,
1739                                 double val)                                 double val) throws IOException, InvalidClassException
1740    {    {
1741      try      try
1742        {        {
1743          Field f = getField (klass, field_name);          Field f = getField (klass, field_name);
1744          f.setDouble (obj, val);          f.setDouble (obj, val);
1745        }        }
1746        catch (IllegalArgumentException _)
1747          {
1748            throw new InvalidClassException("incompatible field type for " + klass.getName() + "." + field_name);
1749          }
1750      catch (Exception _)      catch (Exception _)
1751        {        {
1752        }            }    
1753    }    }
1754    
1755      /**
1756       * This method writes a "float" value <code>val</code> in the specified field
1757       * of the instance <code>obj</code> of the type <code>klass</code>.
1758       *
1759       * @param obj Instance to setup.
1760       * @param klass Class type of the specified instance.
1761       * @param field_name Name of the field in the specified class type.
1762       * @param val The float value to write into the field.
1763       * @throws InvalidClassException if the specified field has not the required type.
1764       * @throws IOException if there is no field of that name in the specified class.
1765       */
1766    private void setFloatField (Object obj, Class klass, String field_name,    private void setFloatField (Object obj, Class klass, String field_name,
1767                                float val)                                float val) throws IOException, InvalidClassException
1768    {    {
1769      try      try
1770        {        {
1771          Field f = getField (klass, field_name);          Field f = getField (klass, field_name);
1772          f.setFloat (obj, val);          f.setFloat (obj, val);
1773        }        }
1774        catch (IllegalArgumentException _)
1775          {
1776            throw new InvalidClassException("incompatible field type for " + klass.getName() + "." + field_name);
1777          }
1778      catch (Exception _)      catch (Exception _)
1779        {        {
1780        }            }    
1781    }    }
1782    
1783      /**
1784       * This method writes an "integer" value <code>val</code> in the specified field
1785       * of the instance <code>obj</code> of the type <code>klass</code>.
1786       *
1787       * @param obj Instance to setup.
1788       * @param klass Class type of the specified instance.
1789       * @param field_name Name of the field in the specified class type.
1790       * @param val The integer value to write into the field.
1791       * @throws InvalidClassException if the specified field has not the required type.
1792       * @throws IOException if there is no field of that name in the specified class.
1793       */
1794    private void setIntField (Object obj, Class klass, String field_name,    private void setIntField (Object obj, Class klass, String field_name,
1795                              int val)                              int val) throws IOException, InvalidClassException
1796    {    {
1797      try      try
1798        {        {
1799          Field f = getField (klass, field_name);          Field f = getField (klass, field_name);
1800          f.setInt (obj, val);          f.setInt (obj, val);
1801        }        }
1802        catch (IllegalArgumentException _)
1803          {
1804            throw new InvalidClassException("incompatible field type for " + klass.getName() + "." + field_name);
1805          }
1806      catch (Exception _)      catch (Exception _)
1807        {        {
1808        }            }    
1809    }    }
1810    
1811      /**
1812       * This method writes the long value <code>val</code> in the specified field
1813       * of the instance <code>obj</code> of the type <code>klass</code>.
1814       *
1815       * @param obj Instance to setup.
1816       * @param klass Class type of the specified instance.
1817       * @param field_name Name of the field in the specified class type.
1818       * @param val The long value to write into the field.
1819       * @throws InvalidClassException if the specified field has not the required type.
1820       * @throws IOException if there is no field of that name in the specified class.
1821       */
1822    private void setLongField (Object obj, Class klass, String field_name,    private void setLongField (Object obj, Class klass, String field_name,
1823                               long val)                               long val) throws IOException, InvalidClassException
1824    {    {
1825      try      try
1826        {        {
1827          Field f = getField (klass, field_name);          Field f = getField (klass, field_name);
1828          f.setLong (obj, val);          f.setLong (obj, val);
1829        }        }
1830        catch (IllegalArgumentException _)
1831          {
1832            throw new InvalidClassException("incompatible field type for " + klass.getName() + "." + field_name);
1833          }
1834      catch (Exception _)      catch (Exception _)
1835        {        {
1836        }            }    
1837    }    }
1838    
1839      /**
1840       * This method writes a "short" value <code>val</code> in the specified field
1841       * of the instance <code>obj</code> of the type <code>klass</code>.
1842       *
1843       * @param obj Instance to setup.
1844       * @param klass Class type of the specified instance.
1845       * @param field_name Name of the field in the specified class type.
1846       * @param val The short value to write into the field.
1847       * @throws InvalidClassException if the specified field has not the required type.
1848       * @throws IOException if there is no field of that name in the specified class.
1849       */
1850    private void setShortField (Object obj, Class klass, String field_name,    private void setShortField (Object obj, Class klass, String field_name,
1851                                short val)                                short val) throws IOException, InvalidClassException
1852    {    {
1853      try      try
1854        {        {
1855          Field f = getField (klass, field_name);          Field f = getField (klass, field_name);
1856          f.setShort (obj, val);          f.setShort (obj, val);
1857        }        }
1858        catch (IllegalArgumentException _)
1859          {
1860            throw new InvalidClassException("incompatible field type for " + klass.getName() + "." + field_name);
1861          }
1862      catch (Exception _)      catch (Exception _)
1863        {        {
1864        }            }    
1865    }    }
1866    
1867      /**
1868       * This method writes an "object" value <code>val</code> in the specified field
1869       * of the instance <code>obj</code> of the type <code>klass</code>.
1870       *
1871       * @param obj Instance to setup.
1872       * @param klass Class type of the specified instance.
1873       * @param field_name Name of the field in the specified class type.
1874       * @param val The "object" value to write into the field.
1875       * @throws InvalidClassException if the specified field has not the required type.
1876       * @throws IOException if there is no field of that name in the specified class.
1877       */
1878    private void setObjectField (Object obj, Class klass, String field_name,    private void setObjectField (Object obj, Class klass, String field_name,
1879                                 String type_code, Object val)                                 String type_code, Object val) throws IOException, InvalidClassException
1880    {    {
1881      try      try
1882        {        {
1883          Field f = getField (klass, field_name);          Field f = getField (klass, field_name);
1884          // FIXME: We should check the type_code here          ObjectStreamField of = new ObjectStreamField(field_name, f.getType());
1885          f.set (obj, val);          
1886            if (of.getTypeString() == null ||
1887                !of.getTypeString().equals(type_code))
1888              throw new InvalidClassException("incompatible field type for " + klass.getName() + "." + field_name);
1889            f.set (obj, val);
1890        }        }
1891      catch (Exception _)      catch (InvalidClassException e)
1892        {        {
1893        }              throw e;
1894          }
1895        catch (Exception _)
1896          {}
1897    }    }
1898    
1899    private static final int BUFFER_SIZE = 1024;    private static final int BUFFER_SIZE = 1024;
# Line 1705  public class ObjectInputStream extends I Line 1915  public class ObjectInputStream extends I
1915    private boolean isDeserializing;    private boolean isDeserializing;
1916    private boolean fieldsAlreadyRead;    private boolean fieldsAlreadyRead;
1917    private Vector validators;    private Vector validators;
1918      private Hashtable classLookupTable;
1919    
1920    private static boolean dump;    private static boolean dump;
1921    

Legend:
Removed from v.1.32  
changed lines
  Added in v.1.33

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