objectinputstream.java

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

JAVA
1,847
字号
   * deserialization.  This constructor should be called by subclasses   * that wish to override <code>readObject (Object)</code>.  This   * method does a security check <i>NOTE: currently not   * implemented</i>, then sets a flag that informs   * <code>readObject (Object)</code> to call the subclasses   * <code>readObjectOverride (Object)</code> method.   *   * @see #readObjectOverride()   */  protected ObjectInputStream()    throws IOException, SecurityException  {    SecurityManager sec_man = System.getSecurityManager();    if (sec_man != null)      sec_man.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);    this.useSubclassMethod = true;  }  /**   * This method allows subclasses to override the default   * de serialization mechanism provided by   * <code>ObjectInputStream</code>.  To make this method be used for   * writing objects, subclasses must invoke the 0-argument   * constructor on this class from their constructor.   *   * @see #ObjectInputStream()   */  protected Object readObjectOverride()    throws ClassNotFoundException, IOException, OptionalDataException  {    throw new IOException("Subclass of ObjectInputStream must implement readObjectOverride");  }  /**   * Assigns the next available handle to <code>obj</code>.   *   * @param obj The object for which we want a new handle.   * @return A valid handle for the specified object.   */  private int assignNewHandle(Object obj)  {    this.objectLookupTable.put(new Integer(this.nextOID),			       new ObjectIdentityWrapper(obj));    return this.nextOID++;  }  private Object processResolution(ObjectStreamClass osc, Object obj, int handle)    throws IOException  {    if (osc != null && obj instanceof Serializable)      {	try	  {	    Method m = osc.readResolveMethod; 	    if(m != null)	    {		obj = m.invoke(obj, new Object[] {});	    }	  }	catch (IllegalAccessException ignore)	  {	  }	catch (InvocationTargetException ignore)	  {	  }      }    if (this.resolveEnabled)      obj = resolveObject(obj);    this.objectLookupTable.put(new Integer(handle),			       new ObjectIdentityWrapper(obj));    return obj;  }  private void clearHandles()  {    this.objectLookupTable.clear();    this.nextOID = baseWireHandle;  }  private void readNextBlock() throws IOException  {    readNextBlock(this.realInputStream.readByte());  }  private void readNextBlock(byte marker) throws IOException  {    if (marker == TC_BLOCKDATA)      {	if(dump) dumpElement("BLOCK DATA SIZE=");	this.blockDataBytes = this.realInputStream.readUnsignedByte();	if(dump) dumpElementln (Integer.toString(this.blockDataBytes));      }    else if (marker == TC_BLOCKDATALONG)      {	if(dump) dumpElement("BLOCK DATA LONG SIZE=");	this.blockDataBytes = this.realInputStream.readInt();	if(dump) dumpElementln (Integer.toString(this.blockDataBytes));      }    else      {	throw new EOFException("Attempt to read primitive data, but no data block is active.");      }    if (this.blockData.length < this.blockDataBytes)      this.blockData = new byte[this.blockDataBytes];    this.realInputStream.readFully (this.blockData, 0, this.blockDataBytes);    this.blockDataPosition = 0;  }  private void readArrayElements (Object array, Class clazz)    throws ClassNotFoundException, IOException  {    if (clazz.isPrimitive())      {	if (clazz == Boolean.TYPE)	  {	    boolean[] cast_array = (boolean[])array;	    for (int i=0; i < cast_array.length; i++)	      cast_array[i] = this.realInputStream.readBoolean();	    return;	  }	if (clazz == Byte.TYPE)	  {	    byte[] cast_array = (byte[])array;	    for (int i=0; i < cast_array.length; i++)	      cast_array[i] = this.realInputStream.readByte();	    return;	  }	if (clazz == Character.TYPE)	  {	    char[] cast_array = (char[])array;	    for (int i=0; i < cast_array.length; i++)	      cast_array[i] = this.realInputStream.readChar();	    return;	  }	if (clazz == Double.TYPE)	  {	    double[] cast_array = (double[])array;	    for (int i=0; i < cast_array.length; i++)	      cast_array[i] = this.realInputStream.readDouble();	    return;	  }	if (clazz == Float.TYPE)	  {	    float[] cast_array = (float[])array;	    for (int i=0; i < cast_array.length; i++)	      cast_array[i] = this.realInputStream.readFloat();	    return;	  }	if (clazz == Integer.TYPE)	  {	    int[] cast_array = (int[])array;	    for (int i=0; i < cast_array.length; i++)	      cast_array[i] = this.realInputStream.readInt();	    return;	  }	if (clazz == Long.TYPE)	  {	    long[] cast_array = (long[])array;	    for (int i=0; i < cast_array.length; i++)	      cast_array[i] = this.realInputStream.readLong();	    return;	  }	if (clazz == Short.TYPE)	  {	    short[] cast_array = (short[])array;	    for (int i=0; i < cast_array.length; i++)	      cast_array[i] = this.realInputStream.readShort();	    return;	  }      }    else      {	Object[] cast_array = (Object[])array;	for (int i=0; i < cast_array.length; i++) 	  cast_array[i] = readObject();      }  }  private void readFields (Object obj, ObjectStreamClass stream_osc)    throws ClassNotFoundException, IOException  {    ObjectStreamField[] fields = stream_osc.fieldMapping;    for (int i = 0; i < fields.length; i += 2)      {	ObjectStreamField stream_field = fields[i];	ObjectStreamField real_field = fields[i + 1];	if(stream_field != null || real_field != null)	  {	    boolean read_value = stream_field != null;	    boolean set_value = real_field != null;	    String field_name;	    char type;	    if (stream_field != null)	      {		field_name = stream_field.getName();		type = stream_field.getTypeCode();	      }	    else	      {		field_name = real_field.getName();		type = real_field.getTypeCode();	      }	    switch(type)	      {		case 'Z':		  {		    boolean value =			read_value ? this.realInputStream.readBoolean() : false;		    if (dump && read_value && set_value)		    dumpElementln("  " + field_name + ": " + value);		    if (set_value)			real_field.setBooleanField(obj, value);		    break;		  }		case 'B':		  {		    byte value =			read_value ? this.realInputStream.readByte() : 0;		    if (dump && read_value && set_value)		    dumpElementln("  " + field_name + ": " + value);		    if (set_value)			real_field.setByteField(obj, value);		    break;		  }		case 'C':		  {		    char value =			read_value ? this.realInputStream.readChar(): 0;		    if (dump && read_value && set_value)		    dumpElementln("  " + field_name + ": " + value);		    if (set_value)			real_field.setCharField(obj, value);		    break;		  }		case 'D':		  {		    double value =			read_value ? this.realInputStream.readDouble() : 0;		    if (dump && read_value && set_value)		    dumpElementln("  " + field_name + ": " + value);		    if (set_value)			real_field.setDoubleField(obj, value);		    break;		  }		case 'F':		  {		    float value =			read_value ? this.realInputStream.readFloat() : 0;		    if (dump && read_value && set_value)		    dumpElementln("  " + field_name + ": " + value);		    if (set_value)			real_field.setFloatField(obj, value);		    break;		  }		case 'I':		  {		    int value =			read_value ? this.realInputStream.readInt() : 0;		    if (dump && read_value && set_value)		    dumpElementln("  " + field_name + ": " + value);		    if (set_value)			real_field.setIntField(obj, value);		    break;		  }		case 'J':		  {		    long value =			read_value ? this.realInputStream.readLong() : 0;		    if (dump && read_value && set_value)		    dumpElementln("  " + field_name + ": " + value);		    if (set_value)			real_field.setLongField(obj, value);		    break;		  }		case 'S':		  {		    short value =			read_value ? this.realInputStream.readShort() : 0;		    if (dump && read_value && set_value)		    dumpElementln("  " + field_name + ": " + value);		    if (set_value)			real_field.setShortField(obj, value);		    break;		  }		case 'L':		case '[':		  {		    Object value =			read_value ? readObject() : null;		    if (set_value)			real_field.setObjectField(obj, value);		    break;		  }		default:		    throw new InternalError("Invalid type code: " + type);	      }	  }      }  }  // Toggles writing primitive data to block-data buffer.  private boolean setBlockDataMode (boolean on)  {    boolean oldmode = this.readDataFromBlock;    this.readDataFromBlock = on;    if (on)      this.dataInputStream = this.blockDataInput;    else      this.dataInputStream = this.realInputStream;    return oldmode;  }  // returns a new instance of REAL_CLASS that has been constructed  // only to the level of CONSTRUCTOR_CLASS (a super class of REAL_CLASS)  private Object newObject (Class real_class, Class constructor_class)    throws ClassNotFoundException  {    try      {	Object obj = allocateObject (real_class);	callConstructor (constructor_class, obj);	return obj;      }    catch (InstantiationException e)      {        throw new ClassNotFoundException		("Instance of " + real_class + " could not be created");      }  }  // runs all registered ObjectInputValidations in prioritized order  // on OBJ  private void invokeValidators() throws InvalidObjectException  {    Object[] validators = new Object[this.validators.size()];    this.validators.copyInto (validators);    Arrays.sort (validators);    try      {	for (int i=0; i < validators.length; i++)	  ((ObjectInputValidation)validators[i]).validateObject();      }    finally      {	this.validators.removeAllElements();      }  }  /**   * This native method is used to get access to the protected method   * of the same name in SecurityManger.   *   * @param sm SecurityManager instance which should be called.   * @return The current class loader in the calling stack.   */  private static native ClassLoader currentClassLoader (SecurityManager sm);  private void callReadMethod (Method readObject, Class klass, Object obj) throws IOException  {    try      {	readObject.invoke(obj, new Object[] { this });      }    catch (InvocationTargetException x)      {        /* Rethrow if possible. */	Throwable exception = x.getTargetException();	if (exception instanceof RuntimeException)	  throw (RuntimeException) exception;	if (exception instanceof IOException)	  throw (IOException) exception;	throw new IOException("Exception thrown from readObject() on " +			       klass + ": " + exception.getClass().getName());      }    catch (Exception x)      {	throw new IOException("Failure invoking readObject() on " +			       klass + ": " + x.getClass().getName());      }    // Invalidate fields which has been read through readFields.    prereadFields = null;  }      private native Object allocateObject (Class clazz)    throws InstantiationException;  private native void callConstructor (Class clazz, Object obj);  private static final int BUFFER_SIZE = 1024;  private DataInputStream realInputStream;  private DataInputStream dataInputStream;  private DataInputStream blockDataInput;  private int blockDataPosition;  private int blockDataBytes;  private byte[] blockData;  private boolean useSubclassMethod;  private int nextOID;  private boolean resolveEnabled;  private Hashtable objectLookupTable;  private Object currentObject;  private ObjectStreamClass currentObjectStreamClass;  private boolean readDataFromBlock;  private boolean isDeserializing;  private boolean fieldsAlreadyRead;  private Vector validators;  private Hashtable classLookupTable;  private GetField prereadFields;  private static boolean dump = false && Configuration.DEBUG;  private void dumpElement (String msg)  {    System.out.print(msg);  }    private void dumpElementln (String msg)  {    System.out.println(msg);  }  static  {    if (Configuration.INIT_LOAD_LIBRARY)      {	System.loadLibrary ("io");      }  }}// used to keep a prioritized list of object validatorsclass ValidatorAndPriority implements Comparable{  int priority;  ObjectInputValidation validator;  ValidatorAndPriority (ObjectInputValidation validator, int priority)  {    this.priority = priority;    this.validator = validator;  }  public int compareTo (Object o)  {    ValidatorAndPriority vap = (ValidatorAndPriority)o;    return this.priority - vap.priority;  }}

⌨️ 快捷键说明

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