jxl.write.biff.SharedStrings Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jxl Show documentation
Show all versions of jxl Show documentation
JExcelApi is a java library which provides the ability to read, write, and modify Microsoft Excel spreadsheets.
The newest version!
/*********************************************************************
*
* Copyright (C) 2002 Andrew Khan
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************/
package jxl.write.biff;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
/**
* The list of available shared strings. This class contains
* the labels used for the entire spreadsheet
*/
class SharedStrings
{
/**
* All the strings in the spreadsheet, keyed on the string itself
*/
private HashMap strings;
/**
* Contains the same strings, held in a list
*/
private ArrayList stringList;
/**
* The total occurrence of strings in the workbook
*/
private int totalOccurrences;
/**
* Constructor
*/
public SharedStrings()
{
strings = new HashMap(100);
stringList = new ArrayList(100);
totalOccurrences = 0;
}
/**
* Gets the index for the string passed in. If the string is already
* present, then returns the index of that string, otherwise
* creates a new key-index mapping
*
* @param s the string whose index we want
* @return the index of the string
*/
public int getIndex(String s)
{
Integer i = (Integer) strings.get(s);
if (i == null)
{
i = new Integer(strings.size());
strings.put(s, i);
stringList.add(s);
}
totalOccurrences++;
return i.intValue();
}
/**
* Gets the string at the specified index
*
* @param i the index of the string
* @return the string at the specified index
*/
public String get(int i)
{
return (String) stringList.get(i);
}
/**
* Writes out the shared string table
*
* @param outputFile the binary output file
* @exception IOException
*/
public void write(File outputFile) throws IOException
{
// Thanks to Guenther for contributing the ExtSST implementation portion
// of this method
int charsLeft = 0;
String curString = null;
SSTRecord sst = new SSTRecord(totalOccurrences, stringList.size());
ExtendedSSTRecord extsst = new ExtendedSSTRecord(stringList.size());
int bucketSize = extsst.getNumberOfStringsPerBucket();
Iterator i = stringList.iterator();
int stringIndex = 0;
while (i.hasNext() && charsLeft == 0)
{
curString = (String) i.next();
// offset + header bytes
int relativePosition = sst.getOffset() + 4;
charsLeft = sst.add(curString);
if ((stringIndex % bucketSize) == 0) {
extsst.addString(outputFile.getPos(), relativePosition);
}
stringIndex++;
}
outputFile.write(sst);
if (charsLeft != 0 || i.hasNext())
{
// Add the remainder of the string to the continue record
SSTContinueRecord cont = createContinueRecord(curString,
charsLeft,
outputFile);
// Carry on looping through the array until all the strings are done
while (i.hasNext())
{
curString = (String) i.next();
int relativePosition = cont.getOffset() + 4;
charsLeft = cont.add(curString);
if ((stringIndex % bucketSize) == 0) {
extsst.addString(outputFile.getPos(), relativePosition);
}
stringIndex++;
if (charsLeft != 0)
{
outputFile.write(cont);
cont = createContinueRecord(curString, charsLeft, outputFile);
}
}
outputFile.write(cont);
}
outputFile.write(extsst);
}
/**
* Creates and returns a continue record using the left over bits and
* pieces
*/
private SSTContinueRecord createContinueRecord
(String curString, int charsLeft, File outputFile) throws IOException
{
// Set up the remainder of the string in the continue record
SSTContinueRecord cont = null;
while (charsLeft != 0)
{
cont = new SSTContinueRecord();
if (charsLeft == curString.length() || curString.length() == 0)
{
charsLeft = cont.setFirstString(curString, true);
}
else
{
charsLeft = cont.setFirstString
(curString.substring(curString.length() - charsLeft), false);
}
if (charsLeft != 0)
{
outputFile.write(cont);
cont = new SSTContinueRecord();
}
}
return cont;
}
}