objectoutputstream.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 1,258 行 · 第 1/3 页

JAVA
1,258
字号
				ObjectStreamField field =
					currentObjectStreamClass.getField(name);
				checkType(field, 'I');
				int off = field.getOffset();
				prim_field_data[off++] = (byte) (value >>> 24);
				prim_field_data[off++] = (byte) (value >>> 16);
				prim_field_data[off++] = (byte) (value >>> 8);
				prim_field_data[off] = (byte) value;
			}

			public void put(String name, long value)
				throws IOException, IllegalArgumentException {
				ObjectStreamField field =
					currentObjectStreamClass.getField(name);
				checkType(field, 'J');
				int off = field.getOffset();
				prim_field_data[off++] = (byte) (value >>> 52);
				prim_field_data[off++] = (byte) (value >>> 48);
				prim_field_data[off++] = (byte) (value >>> 40);
				prim_field_data[off++] = (byte) (value >>> 32);
				prim_field_data[off++] = (byte) (value >>> 24);
				prim_field_data[off++] = (byte) (value >>> 16);
				prim_field_data[off++] = (byte) (value >>> 8);
				prim_field_data[off] = (byte) value;
			}

			public void put(String name, short value)
				throws IOException, IllegalArgumentException {
				ObjectStreamField field =
					currentObjectStreamClass.getField(name);
				checkType(field, 'S');
				int off = field.getOffset();
				prim_field_data[off++] = (byte) (value >>> 8);
				prim_field_data[off] = (byte) value;
			}

			public void put(String name, Object value)
				throws IOException, IllegalArgumentException {
				ObjectStreamField field =
					currentObjectStreamClass.getField(name);
				if (field == null)
					throw new IllegalArgumentException();
				if (value != null
					&& !field.getType().isAssignableFrom(value.getClass()))
					throw new IllegalArgumentException();
				objs[field.getOffset()] = value;
			}

			public void write(ObjectOutput out) throws IOException {
				// Apparently Block data is not used with PutField as per
				// empirical evidence against JDK 1.2.  Also see Mauve test
				// java.io.ObjectInputOutput.Test.GetPutField.
				boolean oldmode = setBlockDataMode(false);
				out.write(prim_field_data);
				for (int i = 0; i < objs.length; ++i)
					out.writeObject(objs[i]);
				setBlockDataMode(oldmode);
			}

			private void checkType(ObjectStreamField field, char type)
				throws IllegalArgumentException {
				if (TypeSignature.getEncodingOfClass(field.getType()).charAt(0)
					!= type)
					throw new IllegalArgumentException();
			}
		};
		// end PutFieldImpl

		return currentPutField;
	}

	public void writeFields() throws IOException {
		if (currentPutField == null)
			throw new NotActiveException("writeFields can only be called after putFields has been called");

		currentPutField.write(this);
	}

	// write out the block-data buffer, picking the correct header
	// depending on the size of the buffer
	private void writeBlockDataHeader(int size) throws IOException {
		if (size < 256) {
			realOutput.writeByte(TC_BLOCKDATA);
			realOutput.write(size);
		} else {
			realOutput.writeByte(TC_BLOCKDATALONG);
			realOutput.writeInt(size);
		}
	}

	// lookup the handle for OBJ, return null if OBJ doesn't have a
	// handle yet
	private Integer findHandle(Object obj) {
		return (Integer) OIDLookupTable.get(new ObjectIdentityWrapper(obj));
	}

	// assigns the next availible handle to OBJ
	private int assignNewHandle(Object obj) {
		OIDLookupTable.put(
			new ObjectIdentityWrapper(obj),
			new Integer(nextOID));
		return nextOID++;
	}

	// resets mapping from objects to handles
	private void clearHandles() {
		nextOID = baseWireHandle;
		OIDLookupTable.clear();
	}

	// write out array size followed by each element of the array
	private void writeArraySizeAndElements(Object array, Class clazz)
		throws IOException {
		int length = Array.getLength(array);

		if (clazz.isPrimitive()) {
			if (clazz == Boolean.TYPE) {
				boolean[] cast_array = (boolean[]) array;
				realOutput.writeInt(length);
				for (int i = 0; i < length; i++)
					realOutput.writeBoolean(cast_array[i]);
				return;
			}
			if (clazz == Byte.TYPE) {
				byte[] cast_array = (byte[]) array;
				realOutput.writeInt(length);
				realOutput.write(cast_array, 0, length);
				return;
			}
			if (clazz == Character.TYPE) {
				char[] cast_array = (char[]) array;
				realOutput.writeInt(length);
				for (int i = 0; i < length; i++)
					realOutput.writeChar(cast_array[i]);
				return;
			}
			if (clazz == Double.TYPE) {
				double[] cast_array = (double[]) array;
				realOutput.writeInt(length);
				for (int i = 0; i < length; i++)
					realOutput.writeDouble(cast_array[i]);
				return;
			}
			if (clazz == Float.TYPE) {
				float[] cast_array = (float[]) array;
				realOutput.writeInt(length);
				for (int i = 0; i < length; i++)
					realOutput.writeFloat(cast_array[i]);
				return;
			}
			if (clazz == Integer.TYPE) {
				int[] cast_array = (int[]) array;
				realOutput.writeInt(length);
				for (int i = 0; i < length; i++)
					realOutput.writeInt(cast_array[i]);
				return;
			}
			if (clazz == Long.TYPE) {
				long[] cast_array = (long[]) array;
				realOutput.writeInt(length);
				for (int i = 0; i < length; i++)
					realOutput.writeLong(cast_array[i]);
				return;
			}
			if (clazz == Short.TYPE) {
				short[] cast_array = (short[]) array;
				realOutput.writeInt(length);
				for (int i = 0; i < length; i++)
					realOutput.writeShort(cast_array[i]);
				return;
			}
		} else {
			Object[] cast_array = (Object[]) array;
			realOutput.writeInt(length);
			for (int i = 0; i < length; i++)
				writeObject(cast_array[i]);
		}
	}

	// writes out FIELDS of OBJECT.  If CALL_WRITE_METHOD is true, use
	// object's writeObject (ObjectOutputStream), otherwise use default
	// serialization.  FIELDS are already in canonical order.
	private void writeFields(
		Object obj,
		ObjectStreamField[] fields,
		boolean call_write_method)
		throws IOException {
		if (call_write_method) {
			setBlockDataMode(true);
			callWriteMethod(obj);
			setBlockDataMode(false);
			realOutput.writeByte(TC_ENDBLOCKDATA);
			return;
		}

		boolean oldmode = setBlockDataMode(false); //??
		String field_name;
		Class type;
		for (int i = 0; i < fields.length; i++) {
			field_name = fields[i].getName();
			type = fields[i].getType();

			if (type == Boolean.TYPE)
				realOutput.writeBoolean(getBooleanField(obj, field_name));
			else if (type == Byte.TYPE)
				realOutput.writeByte(getByteField(obj, field_name));
			else if (type == Character.TYPE)
				realOutput.writeChar(getCharField(obj, field_name));
			else if (type == Double.TYPE)
				realOutput.writeDouble(getDoubleField(obj, field_name));
			else if (type == Float.TYPE)
				realOutput.writeFloat(getFloatField(obj, field_name));
			else if (type == Integer.TYPE)
				realOutput.writeInt(getIntField(obj, field_name));
			else if (type == Long.TYPE)
				realOutput.writeLong(getLongField(obj, field_name));
			else if (type == Short.TYPE)
				realOutput.writeShort(getShortField(obj, field_name));
			else
				writeObject(
					getObjectField(obj, field_name, fields[i].getTypeString()));
		}
		setBlockDataMode(oldmode); // ??
	}

	// Toggles writing primitive data to block-data buffer.
	private boolean setBlockDataMode(boolean on) throws IOException {
		if (on == writeDataAsBlocks)
			return on;

		drain();
		boolean oldmode = writeDataAsBlocks;
		writeDataAsBlocks = on;

		if (on)
			dataOutput = blockDataOutput;
		else
			dataOutput = realOutput;

		return oldmode;
	}

	private void callWriteMethod(Object obj) throws IOException {
		Class klass = obj.getClass();
		try {
			Class classArgs[] = { ObjectOutputStream.class };
			Method m = getMethod(klass, "writeObject", classArgs);
			if (m == null)
				return;
			Object args[] = { this };
			m.invoke(obj, args);
		} 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 writeObject() on "
					+ klass
					+ ": "
					+ exception.getClass().getName());
		} catch (Exception x) {
			throw new IOException(
				"Failure invoking writeObject() on "
					+ klass
					+ ": "
					+ x.getClass().getName());
		}
	}

	private boolean getBooleanField(Object obj, String field_name)
		throws IOException {
		try {
			Class klass = obj.getClass();
			Field f = getField(klass, field_name);
			boolean b = f.getBoolean(obj);
			return b;
		} catch (Exception _) {
			throw new IOException();
		}
	}

	private byte getByteField(Object obj, String field_name)
		throws IOException {
		try {
			Class klass = obj.getClass();
			Field f = getField(klass, field_name);
			byte b = f.getByte(obj);
			return b;
		} catch (Exception _) {
			throw new IOException();
		}
	}

	private char getCharField(Object obj, String field_name)
		throws IOException {
		try {
			Class klass = obj.getClass();
			Field f = getField(klass, field_name);
			char b = f.getChar(obj);
			return b;
		} catch (Exception _) {
			throw new IOException();
		}
	}

	private double getDoubleField(Object obj, String field_name)
		throws IOException {
		try {
			Class klass = obj.getClass();
			Field f = getField(klass, field_name);
			double b = f.getDouble(obj);
			return b;
		} catch (Exception _) {
			throw new IOException();
		}
	}

	private float getFloatField(Object obj, String field_name)
		throws IOException {
		try {
			Class klass = obj.getClass();
			Field f = getField(klass, field_name);
			float b = f.getFloat(obj);
			return b;
		} catch (Exception _) {
			throw new IOException();
		}
	}

	private int getIntField(Object obj, String field_name) throws IOException {
		try {
			Class klass = obj.getClass();
			Field f = getField(klass, field_name);
			int b = f.getInt(obj);
			return b;
		} catch (Exception _) {
			throw new IOException();
		}
	}

	private long getLongField(Object obj, String field_name)
		throws IOException {
		try {
			Class klass = obj.getClass();
			Field f = getField(klass, field_name);
			long b = f.getLong(obj);
			return b;
		} catch (Exception _) {
			throw new IOException();
		}
	}

	private short getShortField(Object obj, String field_name)
		throws IOException {
		try {
			Class klass = obj.getClass();
			Field f = getField(klass, field_name);
			short b = f.getShort(obj);
			return b;
		} catch (Exception _) {
			throw new IOException();
		}
	}

	private Object getObjectField(
		Object obj,
		String field_name,
		String type_code)
		throws IOException {
		try {
			Class klass = obj.getClass();
			Field f = getField(klass, field_name);
			Object o = f.get(obj);
			// FIXME: We should check the type_code here
			return o;
		} catch (Exception _) {
			throw new IOException();
		}
	}

	private static Field getField(Class klass, String name)
		throws java.lang.NoSuchFieldException {
		return klass.getDeclaredField(name);
	}

	private static Method getMethod(Class klass, String name, Class[] args)
		throws java.lang.NoSuchMethodException {
		return klass.getDeclaredMethod(name, args);
	}

	// this value comes from 1.2 spec, but is used in 1.1 as well
	private final static int BUFFER_SIZE = 1024;

	private static int defaultProtocolVersion = PROTOCOL_VERSION_1;

	private DataOutputStream dataOutput;
	private boolean writeDataAsBlocks;
	private DataOutputStream realOutput;
	private DataOutputStream blockDataOutput;
	private byte[] blockData;
	private int blockDataCount;
	private Object currentObject;
	private ObjectStreamClass currentObjectStreamClass;
	private PutField currentPutField;
	private boolean fieldsAlreadyWritten;
	private boolean replacementEnabled;
	private boolean isSerializing;
	private int nextOID;
	private Hashtable OIDLookupTable;
	private int protocolVersion;
	private boolean useSubclassMethod;

}

⌨️ 快捷键说明

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