variantsupport.java
来自「EXCEL read and write」· Java 代码 · 共 589 行 · 第 1/2 页
JAVA
589 行
/* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.==================================================================== */package org.apache.poi.hpsf;import java.io.IOException;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import java.util.Date;import java.util.LinkedList;import java.util.List;import org.apache.poi.util.LittleEndian;import org.apache.poi.util.LittleEndianConsts;/** * <p>Supports reading and writing of variant data.</p> * * <p><strong>FIXME (3):</strong> Reading and writing should be made more * uniform than it is now. The following items should be resolved: * * <ul> * * <li><p>Reading requires a length parameter that is 4 byte greater than the * actual data, because the variant type field is included. </p></li> * * <li><p>Reading reads from a byte array while writing writes to an byte array * output stream.</p></li> * * </ul> * * @author Rainer Klute <a * href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a> * @since 2003-08-08 * @version $Id: VariantSupport.java 619848 2008-02-08 11:55:43Z klute $ */public class VariantSupport extends Variant{ private static boolean logUnsupportedTypes = false; /** * <p>Specifies whether warnings about unsupported variant types are to be * written to <code>System.err</code> or not.</p> * * @param logUnsupportedTypes If <code>true</code> warnings will be written, * if <code>false</code> they won't. */ public static void setLogUnsupportedTypes(final boolean logUnsupportedTypes) { VariantSupport.logUnsupportedTypes = logUnsupportedTypes; } /** * <p>Checks whether logging of unsupported variant types warning is turned * on or off.</p> * * @return <code>true</code> if logging is turned on, else * <code>false</code>. */ public static boolean isLogUnsupportedTypes() { return logUnsupportedTypes; } /** * <p>Keeps a list of the variant types an "unsupported" message has already * been issued for.</p> */ protected static List unsupportedMessage; /** * <p>Writes a warning to <code>System.err</code> that a variant type is * unsupported by HPSF. Such a warning is written only once for each variant * type. Log messages can be turned on or off by </p> * * @param ex The exception to log */ protected static void writeUnsupportedTypeMessage (final UnsupportedVariantTypeException ex) { if (isLogUnsupportedTypes()) { if (unsupportedMessage == null) unsupportedMessage = new LinkedList(); Long vt = new Long(ex.getVariantType()); if (!unsupportedMessage.contains(vt)) { System.err.println(ex.getMessage()); unsupportedMessage.add(vt); } } } /** * <p>HPSF is able to read these {@link Variant} types.</p> */ final static public int[] SUPPORTED_TYPES = { Variant.VT_EMPTY, Variant.VT_I2, Variant.VT_I4, Variant.VT_I8, Variant.VT_R8, Variant.VT_FILETIME, Variant.VT_LPSTR, Variant.VT_LPWSTR, Variant.VT_CF, Variant.VT_BOOL }; /** * <p>Checks whether HPSF supports the specified variant type. Unsupported * types should be implemented included in the {@link #SUPPORTED_TYPES} * array.</p> * * @see Variant * @param variantType the variant type to check * @return <code>true</code> if HPFS supports this type, else * <code>false</code> */ public boolean isSupportedType(final int variantType) { for (int i = 0; i < SUPPORTED_TYPES.length; i++) if (variantType == SUPPORTED_TYPES[i]) return true; return false; } /** * <p>Reads a variant type from a byte array.</p> * * @param src The byte array * @param offset The offset in the byte array where the variant starts * @param length The length of the variant including the variant type field * @param type The variant type to read * @param codepage The codepage to use for non-wide strings * @return A Java object that corresponds best to the variant field. For * example, a VT_I4 is returned as a {@link Long}, a VT_LPSTR as a * {@link String}. * @exception ReadingNotSupportedException if a property is to be written * who's variant type HPSF does not yet support * @exception UnsupportedEncodingException if the specified codepage is not * supported. * @see Variant */ public static Object read(final byte[] src, final int offset, final int length, final long type, final int codepage) throws ReadingNotSupportedException, UnsupportedEncodingException { Object value; int o1 = offset; int l1 = length - LittleEndian.INT_SIZE; long lType = type; /* Instead of trying to read 8-bit characters from a Unicode string, * read 16-bit characters. */ if (codepage == Constants.CP_UNICODE && type == Variant.VT_LPSTR) lType = Variant.VT_LPWSTR; switch ((int) lType) { case Variant.VT_EMPTY: { value = null; break; } case Variant.VT_I2: { /* * Read a short. In Java it is represented as an * Integer object. */ value = new Integer(LittleEndian.getShort(src, o1)); break; } case Variant.VT_I4: { /* * Read a word. In Java it is represented as an * Integer object. */ value = new Integer(LittleEndian.getInt(src, o1)); break; } case Variant.VT_I8: { /* * Read a double word. In Java it is represented as a * Long object. */ value = new Long(LittleEndian.getLong(src, o1)); break; } case Variant.VT_R8: { /* * Read an eight-byte double value. In Java it is represented as * a Double object. */ value = new Double(LittleEndian.getDouble(src, o1)); break; } case Variant.VT_FILETIME: { /* * Read a FILETIME object. In Java it is represented * as a Date object. */ final long low = LittleEndian.getUInt(src, o1); o1 += LittleEndian.INT_SIZE; final long high = LittleEndian.getUInt(src, o1); value = Util.filetimeToDate((int) high, (int) low); break; } case Variant.VT_LPSTR: { /* * Read a byte string. In Java it is represented as a * String object. The 0x00 bytes at the end must be * stripped. */ final int first = o1 + LittleEndian.INT_SIZE; long last = first + LittleEndian.getUInt(src, o1) - 1; o1 += LittleEndian.INT_SIZE; while (src[(int) last] == 0 && first <= last) last--; final int l = (int) (last - first + 1); value = codepage != -1 ? new String(src, first, l, codepageToEncoding(codepage)) : new String(src, first, l); break; } case Variant.VT_LPWSTR: { /* * Read a Unicode string. In Java it is represented as * a String object. The 0x00 bytes at the end must be * stripped. */ final int first = o1 + LittleEndian.INT_SIZE; long last = first + LittleEndian.getUInt(src, o1) - 1; long l = last - first; o1 += LittleEndian.INT_SIZE; StringBuffer b = new StringBuffer((int) (last - first)); for (int i = 0; i <= l; i++) { final int i1 = o1 + (i * 2); final int i2 = i1 + 1; final int high = src[i2] << 8; final int low = src[i1] & 0x00ff; final char c = (char) (high | low); b.append(c); } /* Strip 0x00 characters from the end of the string: */ while (b.length() > 0 && b.charAt(b.length() - 1) == 0x00) b.setLength(b.length() - 1); value = b.toString(); break; } case Variant.VT_CF: { final byte[] v = new byte[l1]; for (int i = 0; i < l1; i++) v[i] = src[(o1 + i)]; value = v; break; } case Variant.VT_BOOL: { /* * The first four bytes in src, from src[offset] to * src[offset + 3] contain the DWord for VT_BOOL, so * skip it, we don't need it. */ // final int first = offset + LittleEndian.INT_SIZE; long bool = LittleEndian.getUInt(src, o1); if (bool != 0) value = Boolean.TRUE; else value = Boolean.FALSE;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?