?? variantsupport.java
字號:
/* ==================================================================== Copyright 2002-2004 Apache Software Foundation Licensed 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,v 1.15 2005/04/29 16:58:55 klute Exp $ */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>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 to write 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.getUShort(src, o1)); break; } case Variant.VT_I4: { /* * Read a word. In Java it is represented as a * Long object. */ value = new Long(LittleEndian.getUInt(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, (int) first, l, codepageToEncoding(codepage)) : new String(src, (int) 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:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -