objectinputstream.java

来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· Java 代码 · 共 1,847 行 · 第 1/4 页

JAVA
1,847
字号
	  class_name = (String)readObject();	else	  class_name = String.valueOf(type_code);		  	fields[i] =	  new ObjectStreamField(field_name, class_name, currentLoader);      }	          /* Now that fields have been read we may resolve the class     * (and read annotation if needed). */    Class clazz = resolveClass(osc);    boolean oldmode = setBlockDataMode(true);    osc.setClass(clazz, lookupClass(clazz.getSuperclass()));    classLookupTable.put(clazz, osc);    setBlockDataMode(oldmode);    // find the first non-serializable, non-abstract    // class in clazz's inheritance hierarchy    Class first_nonserial = clazz.getSuperclass();    while (Serializable.class.isAssignableFrom(first_nonserial)	|| Modifier.isAbstract(first_nonserial.getModifiers()))	first_nonserial = first_nonserial.getSuperclass();    osc.firstNonSerializableParent = first_nonserial;    osc.realClassIsSerializable = Serializable.class.isAssignableFrom(clazz);    osc.realClassIsExternalizable = Externalizable.class.isAssignableFrom(clazz);    ObjectStreamField[] stream_fields = osc.fields;    ObjectStreamField[] real_fields = ObjectStreamClass.lookup(clazz).fields;    ObjectStreamField[] fieldmapping = new ObjectStreamField[2 * Math.max(stream_fields.length, real_fields.length)];    int stream_idx = 0;    int real_idx = 0;    int map_idx = 0;    while (stream_idx < stream_fields.length	   || real_idx < real_fields.length)      {	ObjectStreamField stream_field = null;	ObjectStreamField real_field = null;	if (stream_idx == stream_fields.length)	  {	    real_field = real_fields[real_idx++];	  }	else if (real_idx == real_fields.length)	  {	    stream_field = stream_fields[stream_idx++];	  }	else	  {	    int comp_val =		real_fields[real_idx].compareTo (stream_fields[stream_idx]);	    if (comp_val < 0)	      {		real_field = real_fields[real_idx++];	      }	    else if (comp_val > 0)	      {		stream_field = stream_fields[stream_idx++];	      }	    else	      {		stream_field = stream_fields[stream_idx++];		real_field = real_fields[real_idx++];		if(stream_field.getType() != real_field.getType())		    throw new InvalidClassException			("invalid field type for " + real_field.getName() +			" in class " + name);	      }	  }	if (stream_field != null)	  {	    if (stream_field.getOffset() < 0)		stream_field = null;	    else if (!stream_field.isToSet())		real_field = null;	  }	if (real_field != null && !real_field.isToSet())	    real_field = null;	/* If some of stream_fields does not correspond to any of real_fields,	 * or the opposite, then fieldmapping will go short.	 */	if (map_idx == fieldmapping.length)	  {	    ObjectStreamField[] newfieldmapping =	      new ObjectStreamField[fieldmapping.length + 2];	    System.arraycopy(fieldmapping, 0,	      newfieldmapping, 0, fieldmapping.length);	    fieldmapping = newfieldmapping;	  }	fieldmapping[map_idx++] = stream_field;	fieldmapping[map_idx++] = real_field;      }    osc.fieldMapping = fieldmapping;    return osc;  }  /**   * Reads the current objects non-transient, non-static fields from   * the current class from the underlying output stream.   *   * This method is intended to be called from within a object's   * <code>private void readObject (ObjectInputStream)</code>   * method.   *   * @exception ClassNotFoundException The class that an object being   * read in belongs to cannot be found.   *   * @exception NotActiveException This method was called from a   * context other than from the current object's and current class's   * <code>private void readObject (ObjectInputStream)</code>   * method.   *   * @exception IOException Exception from underlying   * <code>OutputStream</code>.   */  public void defaultReadObject()    throws ClassNotFoundException, IOException, NotActiveException  {    if (this.currentObject == null || this.currentObjectStreamClass == null)      throw new NotActiveException("defaultReadObject called by non-active"				   + " class and/or object");    if (fieldsAlreadyRead)      throw new NotActiveException("defaultReadObject called but fields "				   + "already read from stream (by "				   + "defaultReadObject or readFields)");    boolean oldmode = setBlockDataMode(false);    readFields(this.currentObject, this.currentObjectStreamClass);    setBlockDataMode(oldmode);    fieldsAlreadyRead = true;  }  /**   * Registers a <code>ObjectInputValidation</code> to be carried out   * on the object graph currently being deserialized before it is   * returned to the original caller of <code>readObject ()</code>.   * The order of validation for multiple   * <code>ObjectInputValidation</code>s can be controled using   * <code>priority</code>.  Validators with higher priorities are   * called first.   *   * @see java.io.ObjectInputValidation   *   * @exception InvalidObjectException <code>validator</code> is   * <code>null</code>   *   * @exception NotActiveException an attempt was made to add a   * validator outside of the <code>readObject</code> method of the   * object currently being deserialized   */  public void registerValidation(ObjectInputValidation validator,				 int priority)    throws InvalidObjectException, NotActiveException  {    if (this.currentObject == null || this.currentObjectStreamClass == null)      throw new NotActiveException("registerValidation called by non-active "				   + "class and/or object");    if (validator == null)      throw new InvalidObjectException("attempt to add a null "				       + "ObjectInputValidation object");    this.validators.addElement(new ValidatorAndPriority (validator,							 priority));  }  /**   * Called when a class is being deserialized.  This is a hook to   * allow subclasses to read in information written by the   * <code>annotateClass (Class)</code> method of an   * <code>ObjectOutputStream</code>.   *   * This implementation looks up the active call stack for a   * <code>ClassLoader</code>; if a <code>ClassLoader</code> is found,   * it is used to load the class associated with <code>osc</code>,   * otherwise, the default system <code>ClassLoader</code> is used.   *   * @exception IOException Exception from underlying   * <code>OutputStream</code>.   *   * @see java.io.ObjectOutputStream#annotateClass (java.lang.Class)   */  protected Class resolveClass(ObjectStreamClass osc)    throws ClassNotFoundException, IOException  {    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();    if (sm == null)      sm = new SecurityManager () {};        return currentClassLoader(sm);  }  /**   * Lookup a class stored in the local hashtable. If it is not   * use the global lookup function in ObjectStreamClass to build   * the ObjectStreamClass. This method is requested according to   * the behaviour detected in the JDK by Kaffe's team.   *   * @param clazz Class to lookup in the hash table or for which   * we must build a descriptor.   * @return A valid instance of ObjectStreamClass corresponding   * to the specified class.   */  private ObjectStreamClass lookupClass(Class clazz)  {    ObjectStreamClass oclazz;    oclazz = (ObjectStreamClass)classLookupTable.get(clazz);    if (oclazz == null)      return ObjectStreamClass.lookup(clazz);    else      return oclazz;  }  /**   * Reconstruct class hierarchy the same way   * {@link java.io.ObjectStreamClass.getObjectStreamClasses(java.lang.Class)} does   * but using lookupClass instead of ObjectStreamClass.lookup. This   * dup is necessary localize the lookup table. Hopefully some future   * rewritings will be able to prevent this.   *   * @param clazz This is the class for which we want the hierarchy.   *   * @return An array of valid {@link java.io.ObjectStreamClass} instances which   * represent the class hierarchy for clazz.   */  private ObjectStreamClass[] inputGetObjectStreamClasses(Class clazz)  {    ObjectStreamClass osc = lookupClass(clazz);    if (osc == null)      return new ObjectStreamClass[0];    else      {        Vector oscs = new Vector();        while (osc != null)          {            oscs.addElement(osc);            osc = osc.getSuper();	  }        int count = oscs.size();	ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[count];        for (int i = count - 1; i >= 0; i--)          sorted_oscs[count - i - 1] = (ObjectStreamClass) oscs.elementAt(i);        return sorted_oscs;      }  }  /**   * Allows subclasses to resolve objects that are read from the   * stream with other objects to be returned in their place.  This   * method is called the first time each object is encountered.   *   * This method must be enabled before it will be called in the   * serialization process.   *   * @exception IOException Exception from underlying   * <code>OutputStream</code>.   *   * @see #enableResolveObject(boolean)   */  protected Object resolveObject(Object obj) throws IOException  {    return obj;  }  protected Class resolveProxyClass(String[] intfs)    throws IOException, ClassNotFoundException  {    SecurityManager sm = System.getSecurityManager();        if (sm == null)      sm = new SecurityManager() {};        ClassLoader cl = currentClassLoader(sm);        Class[] clss = new Class[intfs.length];    if(cl == null)      {	for (int i = 0; i < intfs.length; i++)	  clss[i] = Class.forName(intfs[i]);	cl = ClassLoader.getSystemClassLoader();      }    else      for (int i = 0; i < intfs.length; i++)	clss[i] = cl.loadClass(intfs[i]);    try       {	return Proxy.getProxyClass(cl, clss);      }     catch (IllegalArgumentException e)       {	throw new ClassNotFoundException(null, e);      }  }    /**   * If <code>enable</code> is <code>true</code> and this object is   * trusted, then <code>resolveObject (Object)</code> will be called   * in subsequent calls to <code>readObject (Object)</code>.   * Otherwise, <code>resolveObject (Object)</code> will not be called.   *   * @exception SecurityException This class is not trusted.   */  protected boolean enableResolveObject (boolean enable)    throws SecurityException  {    if (enable)      {	SecurityManager sm = System.getSecurityManager();	if (sm != null)	  sm.checkPermission(new SerializablePermission("enableSubstitution"));      }    boolean old_val = this.resolveEnabled;    this.resolveEnabled = enable;    return old_val;  }  /**   * Reads stream magic and stream version information from the   * underlying stream.   *   * @exception IOException Exception from underlying stream.   *   * @exception StreamCorruptedException An invalid stream magic   * number or stream version was read from the stream.   */  protected void readStreamHeader()    throws IOException, StreamCorruptedException  {    if(dump) dumpElement("STREAM MAGIC ");    if (this.realInputStream.readShort() != STREAM_MAGIC)      throw new StreamCorruptedException("Invalid stream magic number");    if(dump) dumpElementln("STREAM VERSION ");    if (this.realInputStream.readShort() != STREAM_VERSION)      throw new StreamCorruptedException("Invalid stream version number");  }  public int read() throws IOException  {    if (this.readDataFromBlock)      {	if (this.blockDataPosition >= this.blockDataBytes)	  readNextBlock();	return (this.blockData[this.blockDataPosition++] & 0xff);      }    else      return this.realInputStream.read();  }  public int read(byte[] data, int offset, int length) throws IOException  {    if (this.readDataFromBlock)      {	if (this.blockDataPosition + length > this.blockDataBytes)	  {	    int remain = this.blockDataBytes - this.blockDataPosition;	    if (remain != 0)	      {		System.arraycopy(this.blockData, this.blockDataPosition,				 data, offset, remain);		offset += remain;		length -= remain;	      }	    readNextBlock ();	  }	System.arraycopy(this.blockData, this.blockDataPosition,			 data, offset, length);	this.blockDataPosition += length;	return length;      }    else      return this.realInputStream.read(data, offset, length);  }  public int available() throws IOException  {    if (this.readDataFromBlock)      {	if (this.blockDataPosition >= this.blockDataBytes)	  readNextBlock ();	return this.blockDataBytes - this.blockDataPosition;      }    else      return this.realInputStream.available();  }  public void close() throws IOException  {    this.realInputStream.close();  }  public boolean readBoolean() throws IOException  {    boolean switchmode = true;    boolean oldmode = this.readDataFromBlock;    if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)      switchmode = false;    if (switchmode)      oldmode = setBlockDataMode (true);    boolean value = this.dataInputStream.readBoolean ();    if (switchmode)      setBlockDataMode (oldmode);    return value;  }  public byte readByte() throws IOException  {    boolean switchmode = true;    boolean oldmode = this.readDataFromBlock;    if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)      switchmode = false;    if (switchmode)      oldmode = setBlockDataMode(true);    byte value = this.dataInputStream.readByte();    if (switchmode)      setBlockDataMode(oldmode);    return value;  }  public int readUnsignedByte() throws IOException  {    boolean switchmode = true;    boolean oldmode = this.readDataFromBlock;    if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)      switchmode = false;    if (switchmode)      oldmode = setBlockDataMode(true);    int value = this.dataInputStream.readUnsignedByte();    if (switchmode)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?