📄 sstrecord.java
字号:
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache POI" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache POI", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */package org.apache.poi.hssf.record;import org.apache.poi.util.BinaryTree;import org.apache.poi.util.LittleEndian;import org.apache.poi.util.LittleEndianConsts;import java.util.Iterator;import java.util.List;/** * Title: Static String Table Record * <P> * Description: This holds all the strings for LabelSSTRecords. * <P> * REFERENCE: PG 389 Microsoft Excel 97 Developer's Kit (ISBN: * 1-57231-498-2) * <P> * @author Andrew C. Oliver (acoliver at apache dot org) * @author Marc Johnson (mjohnson at apache dot org) * @author Glen Stampoultzis (glens at apache.org) * * @see org.apache.poi.hssf.record.LabelSSTRecord * @see org.apache.poi.hssf.record.ContinueRecord */public class SSTRecord extends Record{ /** how big can an SST record be? As big as any record can be: 8228 bytes */ static final int MAX_RECORD_SIZE = 8228; /** standard record overhead: two shorts (record id plus data space size)*/ static final int STD_RECORD_OVERHEAD = 2 * LittleEndianConsts.SHORT_SIZE; /** SST overhead: the standard record overhead, plus the number of strings and the number of unique strings -- two ints */ static final int SST_RECORD_OVERHEAD = ( STD_RECORD_OVERHEAD + ( 2 * LittleEndianConsts.INT_SIZE ) ); /** how much data can we stuff into an SST record? That would be _max minus the standard SST record overhead */ static final int MAX_DATA_SPACE = MAX_RECORD_SIZE - SST_RECORD_OVERHEAD; /** overhead for each string includes the string's character count (a short) and the flag describing its characteristics (a byte) */ static final int STRING_MINIMAL_OVERHEAD = LittleEndianConsts.SHORT_SIZE + LittleEndianConsts.BYTE_SIZE; public static final short sid = 0xfc; /** union of strings in the SST and EXTSST */ private int field_1_num_strings; /** according to docs ONLY SST */ private int field_2_num_unique_strings; private BinaryTree field_3_strings; /** Record lengths for initial SST record and all continue records */ private List _record_lengths = null; private SSTDeserializer deserializer; /** Offsets from the beginning of the SST record (even across continuations) */ int[] bucketAbsoluteOffsets; /** Offsets relative the start of the current SST or continue record */ int[] bucketRelativeOffsets; /** * default constructor */ public SSTRecord() { field_1_num_strings = 0; field_2_num_unique_strings = 0; field_3_strings = new BinaryTree(); deserializer = new SSTDeserializer(field_3_strings); } /** * Constructs an SST record and sets its fields appropriately. * * @param id must be 0xfc or an exception will be throw upon * validation * @param size the size of the data area of the record * @param data of the record (should not contain sid/len) */ public SSTRecord( final short id, final short size, final byte[] data ) { super( id, size, data ); } /** * Constructs an SST record and sets its fields appropriately. * * @param id must be 0xfc or an exception will be throw upon * validation * @param size the size of the data area of the record * @param data of the record (should not contain sid/len) * @param offset of the record */ public SSTRecord( final short id, final short size, final byte[] data, int offset ) { super( id, size, data, offset ); } /** * Add a string. Determines whether 8-bit encoding can be used, or * whether 16-bit encoding must be used. * <p> * THIS IS THE PREFERRED METHOD OF ADDING A STRING. IF YOU USE THE * OTHER ,code>addString</code> METHOD AND FORCE 8-BIT ENCODING ON * A STRING THAT SHOULD USE 16-BIT ENCODING, YOU WILL CORRUPT THE * STRING; IF YOU USE THAT METHOD AND FORCE 16-BIT ENCODING, YOU * ARE WASTING SPACE WHEN THE WORKBOOK IS WRITTEN OUT. * * @param string string to be added * * @return the index of that string in the table */ public int addString( final String string ) { int rval; if ( string == null ) { rval = addString( "", false ); } else { // scan for characters greater than 255 ... if any are // present, we have to use 16-bit encoding. Otherwise, we // can use 8-bit encoding boolean useUTF16 = false; int strlen = string.length(); for ( int j = 0; j < strlen; j++ ) { if ( string.charAt( j ) > 255 ) { useUTF16 = true; break; } } rval = addString( string, useUTF16 ); } return rval; } /** * Add a string and assert the encoding (8-bit or 16-bit) to be * used. * <P> * USE THIS METHOD AT YOUR OWN RISK. IF YOU FORCE 8-BIT ENCODING, * YOU MAY CORRUPT YOUR STRING. IF YOU FORCE 16-BIT ENCODING AND * IT ISN'T NECESSARY, YOU WILL WASTE SPACE WHEN THIS RECORD IS * WRITTEN OUT. * * @param string string to be added * @param useUTF16 if true, forces 16-bit encoding. If false, * forces 8-bit encoding * * @return the index of that string in the table */ public int addString( final String string, final boolean useUTF16 ) { field_1_num_strings++; String str = ( string == null ) ? "" : string; int rval; UnicodeString ucs = new UnicodeString(); ucs.setString( str ); ucs.setCharCount( (short) str.length() ); ucs.setOptionFlags( (byte) ( useUTF16 ? 1 : 0 ) ); Integer integer = (Integer) field_3_strings.getKeyForValue( ucs ); if ( integer != null ) { rval = integer.intValue(); } else { // This is a new string -- we didn't see it among the // strings we've already collected rval = field_3_strings.size(); field_2_num_unique_strings++; integer = new Integer( rval ); SSTDeserializer.addToStringTable( field_3_strings, integer, ucs );// field_3_strings.put( integer, ucs ); } return rval; } /** * @return number of strings */ public int getNumStrings() { return field_1_num_strings; } /** * @return number of unique strings */ public int getNumUniqueStrings() { return field_2_num_unique_strings; } /** * USE THIS METHOD AT YOUR OWN PERIL: THE <code>addString</code> * METHODS MANIPULATE THE NUMBER OF STRINGS AS A SIDE EFFECT; YOUR * ATTEMPTS AT MANIPULATING THE STRING COUNT IS LIKELY TO BE VERY * WRONG AND WILL RESULT IN BAD BEHAVIOR WHEN THIS RECORD IS * WRITTEN OUT AND ANOTHER PROCESS ATTEMPTS TO READ THE RECORD * * @param count number of strings * */ public void setNumStrings( final int count ) { field_1_num_strings = count; } /** * USE THIS METHOD AT YOUR OWN PERIL: THE <code>addString</code> * METHODS MANIPULATE THE NUMBER OF UNIQUE STRINGS AS A SIDE * EFFECT; YOUR ATTEMPTS AT MANIPULATING THE UNIQUE STRING COUNT * IS LIKELY TO BE VERY WRONG AND WILL RESULT IN BAD BEHAVIOR WHEN * THIS RECORD IS WRITTEN OUT AND ANOTHER PROCESS ATTEMPTS TO READ * THE RECORD * * @param count number of strings */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -