⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 variant.java

📁 java 调用windows的api
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
				leos.writeDouble(var.date);
				break;
			// other simple types
			case VarTypes.VT_BOOL:
				leos.writeBoolean(var.boolVal);
				break;
			case VarTypes.VT_BSTR:
				leos.writeStringUnicode(var.bstrVal);
				break;
			// dispatch references
			case VarTypes.VT_DISPATCH:
				leos.writeInt(DispatchPtr.IID_TOKEN);
				leos.writeInt(var.pdispVal.getPeer());
				leos.writeInt(var.pdispVal.getUnknown());
				break;
			case VarTypes.VT_UNKNOWN:
				leos.writeInt(UnknownPtr.IID_TOKEN);
				leos.writeInt(var.punkVal.getPeer());
				leos.writeInt(var.punkVal.getUnknown());
				break;
			case VarTypes.VT_ERROR:
				leos.writeInt(var.scode);
				break;
			case VarTypes.VT_NULL:
				// do nothing
				break;
			default:
				throw new COMException("Unable to serialize variant: " + var);
		}
	}

	/**
	 * Marshall a Java-array onto the leos-output stream
	 * <br><br>
	 * The marshalling code is the "inverse" of the native code in the method
	 * deserializeVariantSafeArray() in Transform.cpp.
	 */
	private static void writeArray(Object array, int appendVt, LittleEndianOutputStream leos) throws COMException, IOException {
		Class cls = array.getClass().getComponentType();
		if (cls == Byte.TYPE) {
			byte[] values = (byte[]) array;
			leos.writeShort(VarTypes.VT_ARRAY | VarTypes.VT_UI1 | appendVt);
			leos.writeInt(values.length);
			for (int i = 0, n = values.length; i < n; i++) {
				leos.writeByte(values[i]);
			}
		} else if (cls == Short.TYPE) {
			short[] values = (short[]) array;
			leos.writeShort(VarTypes.VT_ARRAY | VarTypes.VT_I2 | appendVt);
			leos.writeInt(values.length);
			for (int i = 0, n = values.length; i < n; i++) {
				leos.writeShort(values[i]);
			}
		} else if (cls == Integer.TYPE) {
			int[] values = (int[])array;
			leos.writeShort(VarTypes.VT_ARRAY | VarTypes.VT_I4 | appendVt);
			leos.writeInt(values.length);
			for (int i = 0, n = values.length; i < n; i++) {
				leos.writeInt(values[i]);
			}
		} else if (cls == Long.TYPE) {
			long[] values = (long[])array;
			leos.writeShort(VarTypes.VT_ARRAY | VarTypes.VT_I8 | appendVt);
			leos.writeInt(values.length);
			for (int i = 0, n = values.length; i < n; i++) {
				leos.writeLong(values[i]);
			}
		} else if (cls == Float.TYPE) {
			float[] values = (float[]) array;
			leos.writeShort(VarTypes.VT_ARRAY | VarTypes.VT_R4 | appendVt);
			leos.writeInt(values.length);
			for (int i = 0, n = values.length; i < n; i++) {
				leos.writeFloat(values[i]);
			}
		} else if (cls == Double.TYPE) {
			double[] values = (double[]) array;
			leos.writeShort(VarTypes.VT_ARRAY | VarTypes.VT_R8 | appendVt);
			leos.writeInt(values.length);
			for (int i = 0, n = values.length; i < n; i++) {
				leos.writeDouble(values[i]);
			}
		} else if (Date.class.isAssignableFrom(cls)) {
			Date[] values = (Date[]) array;
			leos.writeShort(VarTypes.VT_ARRAY | VarTypes.VT_DATE | appendVt);
			leos.writeInt(values.length);
			for (int i = 0, n = values.length; i < n; i++) {
				leos.writeDouble(DateUtil.getWin32Date(values[i]));
			}
		} else if (cls == Boolean.TYPE) {
			boolean[] values = (boolean[]) array;
			leos.writeShort(VarTypes.VT_ARRAY | VarTypes.VT_BOOL | appendVt);
			leos.writeInt(values.length);
			for (int i = 0, n = values.length; i < n; i++) {
				leos.writeBoolean(values[i]);
			}
		} else if (cls == String.class) {
			String[] values = (String[]) array;
			leos.writeShort(VarTypes.VT_ARRAY | VarTypes.VT_BSTR | appendVt);
			leos.writeInt(values.length);
			for (int i = 0, n = values.length; i < n; i++) {
				leos.writeStringUnicode(values[i]);
			}
		} else if (Object.class.isAssignableFrom(cls)) { 
			short subTypeVt = VarTypes.VT_VARIANT;
			if (DispatchPtr.class.isAssignableFrom(cls)) {
				subTypeVt = VarTypes.VT_DISPATCH;
			} else if (UnknownPtr.class.isAssignableFrom(cls)) {
				subTypeVt = VarTypes.VT_UNKNOWN;
			}

			Object[] values = (Object[]) array;
			leos.writeShort(VarTypes.VT_ARRAY | subTypeVt | appendVt);
			leos.writeInt(values.length);
			for (int i = 0, n = values.length; i < n; i++) {
				writeObject(values[i], leos);
			}
		} else {
			throw new COMException("Type cannot be marshalled to variant-array: " + cls);
		}
	}

	/**
	 * Unmarshall from the leis-input stream, into a Java-array.
	 * <br><br>
	 * The unmarshalling code is the "inverse" of the native code in the method
	 * serializeVariantSafeArray() in Transform.cpp.
	 */
	private static Object readArray(short vt, LittleEndianInputStream leis) throws COMException, IOException {
		int length = leis.readInt();
		switch (vt) {
			case VarTypes.VT_I1:
			case VarTypes.VT_UI1:
				byte[] bytes = new byte[length];
				for (int n = 0; n < length; n++) {
					bytes[n] = leis.readByte();
				}
				return bytes;
			case VarTypes.VT_I2:
			case VarTypes.VT_UI2:
				short[] shorts = new short[length];
				for (int n = 0; n < length; n++) {
					shorts[n] = leis.readShort();
				}
				return shorts;
			case VarTypes.VT_I4:
			case VarTypes.VT_UI4:
			case VarTypes.VT_INT:
			case VarTypes.VT_UINT:
			case VarTypes.VT_ERROR:
				int[] ints = new int[length];
				for (int n = 0; n < length; n++) {
					ints[n] = leis.readInt();
				}
				return ints;
			case VarTypes.VT_I8:
			case VarTypes.VT_UI8:
			case VarTypes.VT_CY:
				long[] longs = new long[length];
				for (int n = 0; n < length; n++) {
					longs[n] = leis.readLong();
				}
				return longs;
			case VarTypes.VT_R4:
				float[] floats = new float[length];
				for (int n = 0; n < length; n++) {
					floats[n] = leis.readFloat();
				}
				return floats;
			case VarTypes.VT_R8:
				double[] doubles = new double[length];
				for (int n = 0; n < length; n++) {
					doubles[n] = leis.readDouble();
				}
				return doubles;
			case VarTypes.VT_DATE:
				Date[] dates = new Date[length];
				for (int n = 0; n < length; n++) {
					dates[n] = new Date(DateUtil.getJavaDate(leis.readDouble()));
				}
				return dates;
			case VarTypes.VT_BOOL:
				boolean[] booleans = new boolean[length];
				for (int n = 0; n < length; n++) {
					booleans[n] = leis.readBoolean();
				}
				return booleans;
			case VarTypes.VT_BSTR:
				String[] strings = new String[length];
				for (int n = 0; n < length; n++) {
					strings[n] = leis.readStringUnicode();
				}
				return strings;
			case VarTypes.VT_DISPATCH:
				DispatchPtr[] dispatches = new DispatchPtr[length];
				for (int n = 0; n < length; n++) {
					dispatches[n] = (DispatchPtr)IdentityManager.getCOMPtr(leis, WellKnownGUIDs.IID_IDispatch);
				}
				return dispatches;
			case VarTypes.VT_UNKNOWN:
				UnknownPtr[] unknowns = new UnknownPtr[length];
				for (int n = 0; n < length; n++) {
					unknowns[n] = (UnknownPtr)IdentityManager.getCOMPtr(leis, WellKnownGUIDs.IID_IUnknown);
				}
				return unknowns;
			case VarTypes.VT_VARIANT:
				Object[] objects = new Object[length];
				for (int n = 0; n < length; n++) {
					objects[n] = readObject(leis);
				}
				return objects;
		}
		throw new COMException("Bad vartype in array: " + vt);
	}

	/**
	 * the method that does the actual work for {@link #readObject(LittleEndianInputStream)
	 */
	private static Object readObject(short vt, LittleEndianInputStream leis) throws COMException, IOException {
		if (0 != (vt & VarTypes.VT_ARRAY)) {
			return readArray((short) (vt & VarTypes.VT_TYPEMASK), leis);
		}

		if (0 != (vt & VarTypes.VT_BYREF)) {
			return readObject((short) (vt & VarTypes.VT_TYPEMASK), leis);
		}
		
		int temp = 0;
		switch (vt) {
			case VarTypes.VT_EMPTY:
			case VarTypes.VT_NULL:
				return null;
			case VarTypes.VT_I1:
			case VarTypes.VT_UI1:
				return new Byte(leis.readByte());
			case VarTypes.VT_I2:
			case VarTypes.VT_UI2:
				return new Short(leis.readShort());
			case VarTypes.VT_I4:
			case VarTypes.VT_UI4:
			case VarTypes.VT_INT:
			case VarTypes.VT_UINT:
			case VarTypes.VT_ERROR:
				return new Integer(leis.readInt());
			case VarTypes.VT_I8:
			case VarTypes.VT_UI8:
			case VarTypes.VT_CY:
				return new Long(leis.readLong());
			case VarTypes.VT_R4:
				return new Float(leis.readFloat());
			case VarTypes.VT_R8:
				return new Double(leis.readDouble());
			case VarTypes.VT_DATE:
				return new Date(DateUtil.getJavaDate(leis.readDouble()));
			case VarTypes.VT_BOOL:
				return (leis.readBoolean() ? Boolean.TRUE: Boolean.FALSE);
			case VarTypes.VT_BSTR:
				return leis.readStringUnicode();
			case VarTypes.VT_VARIANT:
				return readObject(leis);
			case VarTypes.VT_DISPATCH:
				return IdentityManager.getCOMPtr(leis, WellKnownGUIDs.IID_IDispatch);
			case VarTypes.VT_UNKNOWN:
				return (IdentityManager.getCOMPtr(leis, WellKnownGUIDs.IID_IUnknown));
			default:
				throw new COMException("Unable to deserialize variant type: " + vt);
		}
	}

	/**
	 * unmarshall an object from an input stream. The object will be unmarshalled
	 * following these rules:
	 * <ul>
	 * 	<li><b><code>VT_EMPTY</code> and <code>VT_NULL</code>:</b> will be unmarshalled as <code>null</code>.</li>
	 * 	<li><b><code>*|VT_BYREF</code>:</b> will be unmarshalled as the base <code>VT_TYPE</code>,
	 * 			ie. the returned object will NOT be wrapped in a {@link Variant.ByrefHolder}.</li>
	 * 	<li><b><code>*|VT_ARRAY</code>:</b> will be unmarshalled as an array of the base type.</li>
	 * 	<li><b><code>VT_I1</code> and <code>VT_UI1</code>:</b> will be unmarshalled as <code>Byte</code>.</li>
	 * 	<li><b><code>VT_I2</code> and <code>VT_UI2</code>:</b> will be unmarshalled as <code>Short</code>.</li>
	 * 	<li><b><code>VT_I4</code>, <code>VT_UI4</code>, <code>VT_INT</code>, <code>VT_UINT</code> and <code>VT_ERROR</code>:</b>
	 * 			will be unmarshalled as <code>Integer</code>.</li>
	 * 	<li><b><code>VT_I8</code>, <code>VT_UI8</code> and <code>VT_CY</code>:</b>
	 * 			will be unmarshalled as <code>Long</code>.</li>
	 * 	<li><b><code>VT_R4</code>:</b> will be unmarshalled as <code>Float</code>.</li>    
	 * 	<li><b><code>VT_R8</code>:</b> will be unmarshalled as <code>Double</code>.</li>
	 * 	<li><b><code>VT_DATE</code>:</b> will be unmarshalled as <code>Date</code> using
	 * 			the {@link DateUtil#getJavaDate(double)}-method.</li>
	 * 	<li><b><code>VT_BOOL</code>:</b> will be unmarshalled as <code>Boolean</code>.</li>
	 * 	<li><b><code>VT_BSTR</code>:</b> will be unmarshalled as <code>String</code>.</li>
	 * 	<li><b><code>VT_VARIANT</code>:</b> will be unmarshalled as the wrapped base object,
	 * 			ie. will NOT be returned as a {@link Variant}-object.</li>
	 * 	<li><b><code>VT_DISPATCH</code>:</b> will be unmarshalled as a {@link DispatchPtr}-object.</li>
	 * 	<li><b><code>VT_UNKNOWN</code>:</b> will be unmarshalled as a {@link UnknownPtr}-object.</li>
	 * </ul>
	 * If none of the rules match, a COMException will be thrown.
	 * <br><br>
	 * <b>Arrays:</b> If the next object on the input stream is an object, this call 
	 * will unmarshall the entire array. If it is an array of primitive types it will be
	 * returned as such (and NOT as an array of the wrapper class). Eg. if the next object
	 * on the stream is an int-array:
	 * <pre>	int[] result = (int[])Variant.readObject(leis);</pre>
	 * <br><br>
	 * The unmarshalling code is the "inverse" of the native code in the method
	 * serializeVariant() in Transform.cpp
	 * 
	 * @param leis the stream the object should be read from.
	 * @return the next object on the stream.
	 * @throws COMException if the object can not be unmarshalled due to an 
	 * 			unknown <code>VT_TYPE</code> or due to IOExceptions on the stream.
	 */
	public static Object readObject(LittleEndianInputStream leis) throws COMException {
		try {
			short vt = leis.readShort();
			return readObject(vt, leis);
		} catch (IOException ioe) {
			throw new COMException(ioe);
		}
	}
}

⌨️ 快捷键说明

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