Merged revisions 703100,703197,703302,703596,703620,703645,703651,706540 via svnmerge from
https://svn.apache.org/repos/asf/poi/trunk ........ r703100 | josh | 2008-10-09 01:33:54 -0700 (Thu, 09 Oct 2008) | 1 line Removed last occurrences of storing Ptg arrays in Stacks. Some related clean-up. ........ r703197 | josh | 2008-10-09 09:10:39 -0700 (Thu, 09 Oct 2008) | 1 line Should have been submitted with r703100 (changes to Ptg) ........ r703302 | josh | 2008-10-09 17:40:58 -0700 (Thu, 09 Oct 2008) | 1 line Fix for bug 45964 - support for link formulas in Text Objects ........ r703596 | josh | 2008-10-10 15:59:14 -0700 (Fri, 10 Oct 2008) | 1 line Made RecordInputStream final (major clean-up in test cases and BiffViewer) ........ r703620 | josh | 2008-10-10 18:11:05 -0700 (Fri, 10 Oct 2008) | 2 lines fix for bug 45866 - allowed for change of unicode compression across Continue records ........ r703645 | yegor | 2008-10-11 03:31:24 -0700 (Sat, 11 Oct 2008) | 1 line fixed error in eval.xml: use < instead of '<' ........ r703651 | yegor | 2008-10-11 05:01:42 -0700 (Sat, 11 Oct 2008) | 1 line set trunk version.id=3.3-alpha1 ........ r706540 | yegor | 2008-10-20 23:47:35 -0700 (Mon, 20 Oct 2008) | 1 line updated release version on the index page, started a new section in the change log ........ git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@707807 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
dfb6d9f84f
commit
18e5d2d0db
@ -66,7 +66,12 @@
|
||||
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling PowerPoint files, irrespective of if they are .ppt or .pptx</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
|
||||
</release>
|
||||
<release version="3.2-alpha1" date="2008-??-??">
|
||||
<release version="3.5-beta4" date="2008-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="fix">YK: remove me. required to keep Forrest DTD compiler quiet</action>
|
||||
</release>
|
||||
<release version="3.2-FINAL" date="2008-10-19">
|
||||
<action dev="POI-DEVELOPERS" type="fix">45866 - allowed for change of unicode compression across Continue records</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45964 - support for link formulas in Text Objects</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">43354 - support for evalating formulas with missing args</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45912 - fixed ArrayIndexOutOfBoundsException in EmbeddedObjectRefSubRecord</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45889 - fixed ArrayIndexOutOfBoundsException when constructing HSLF Table with a single row </action>
|
||||
|
@ -44,10 +44,10 @@
|
||||
People interested should also follow the
|
||||
<link href="mailinglists.html">dev list</link> to track progress.</p>
|
||||
</section>
|
||||
<section><title>POI 3.1-FINAL Released (2008-06-29)</title>
|
||||
<section><title>POI 3.2-FINAL Released (2008-10-19)</title>
|
||||
<p>
|
||||
The POI team is pleased to announce the release of 3.1 FINAL, the latest release of Apache POI.
|
||||
There have been many important bug fixes since the 3.0.2 release and a lot of new features.
|
||||
The POI team is pleased to announce the release of 3.2 FINAL, the latest release of Apache POI.
|
||||
There have been many important bug fixes since the 3.1 release and a lot of new features.
|
||||
</p><p> A full list of changes is available in
|
||||
<link href="./changes.html">the changelog</link>, and
|
||||
<link href="http://www.apache.org/dyn/closer.cgi/poi/release/">download</link>
|
||||
@ -56,7 +56,7 @@
|
||||
</p>
|
||||
<p>
|
||||
The release is also available from the central Maven repository
|
||||
under Group ID "org.apache.poi" and Version "3.1-FINAL".
|
||||
under Group ID "org.apache.poi" and Version "3.2-FINAL".
|
||||
</p>
|
||||
</section>
|
||||
|
||||
|
@ -63,7 +63,12 @@
|
||||
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling PowerPoint files, irrespective of if they are .ppt or .pptx</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
|
||||
</release>
|
||||
<release version="3.2-alpha1" date="2008-??-??">
|
||||
<release version="3.5-beta4" date="2008-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="fix">YK: remove me. required to keep Forrest DTD compiler quiet</action>
|
||||
</release>
|
||||
<release version="3.2-FINAL" date="2008-10-19">
|
||||
<action dev="POI-DEVELOPERS" type="fix">45866 - allowed for change of unicode compression across Continue records</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45964 - support for link formulas in Text Objects</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">43354 - support for evalating formulas with missing args</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45912 - fixed ArrayIndexOutOfBoundsException in EmbeddedObjectRefSubRecord</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45889 - fixed ArrayIndexOutOfBoundsException when constructing HSLF Table with a single row </action>
|
||||
|
@ -17,17 +17,23 @@
|
||||
|
||||
package org.apache.poi.hssf.dev;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintStream;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.hssf.record.*;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* Utillity for reading in BIFF8 records and displaying data from them.
|
||||
@ -37,70 +43,46 @@ import org.apache.poi.util.HexDump;
|
||||
*@see #main
|
||||
*/
|
||||
public final class BiffViewer {
|
||||
private final File _inputFile;
|
||||
private boolean dump;
|
||||
private final PrintStream _ps;
|
||||
static final char[] NEW_LINE_CHARS = System.getProperty("line.separator").toCharArray();
|
||||
|
||||
|
||||
public BiffViewer(File inFile, PrintStream ps) {
|
||||
_inputFile = inFile;
|
||||
_ps = ps;
|
||||
private BiffViewer() {
|
||||
// no instances of this class
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method run starts up BiffViewer...
|
||||
*/
|
||||
public void run() {
|
||||
try {
|
||||
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(_inputFile));
|
||||
InputStream stream = fs.createDocumentInputStream("Workbook");
|
||||
createRecords(stream, dump, _ps);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an array of records from an input stream
|
||||
*
|
||||
*@param in the InputStream from which the records
|
||||
* will be obtained
|
||||
*@param dump
|
||||
*@return an array of Records created from the
|
||||
* InputStream
|
||||
*@param in the InputStream from which the records will be obtained
|
||||
*@return an array of Records created from the InputStream
|
||||
*@exception RecordFormatException on error processing the InputStream
|
||||
*/
|
||||
public static Record[] createRecords(InputStream in, boolean dump, PrintStream ps)
|
||||
public static Record[] createRecords(InputStream is, PrintStream ps, BiffRecordListener recListener, boolean dumpInterpretedRecords)
|
||||
throws RecordFormatException {
|
||||
ArrayList records = new ArrayList();
|
||||
RecordDetails activeRecord = null;
|
||||
ArrayList temp = new ArrayList();
|
||||
|
||||
BiffviewRecordInputStream recStream = new BiffviewRecordInputStream(in);
|
||||
RecordInputStream recStream = new RecordInputStream(is);
|
||||
while (recStream.hasNextRecord()) {
|
||||
recStream.nextRecord();
|
||||
if (recStream.getSid() != 0) {
|
||||
if (recStream.getSid() == 0) {
|
||||
continue;
|
||||
}
|
||||
Record record = createRecord (recStream);
|
||||
if (record.getSid() != ContinueRecord.sid)
|
||||
{
|
||||
records.add(record);
|
||||
if (activeRecord != null)
|
||||
activeRecord.dump(ps);
|
||||
int startPos = (int)(recStream.getPos()-recStream.getLength() - 4);
|
||||
activeRecord = new RecordDetails(recStream.getSid(), recStream.getLength(), startPos, record);
|
||||
if (record.getSid() == ContinueRecord.sid) {
|
||||
continue;
|
||||
}
|
||||
if (dump) {
|
||||
recStream.dumpBytes(ps);
|
||||
temp.add(record);
|
||||
if (dumpInterpretedRecords) {
|
||||
String[] headers = recListener.getRecentHeaders();
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
ps.println(headers[i]);
|
||||
}
|
||||
ps.print(record.toString());
|
||||
}
|
||||
ps.println();
|
||||
}
|
||||
if (activeRecord != null) {
|
||||
activeRecord.dump(ps);
|
||||
}
|
||||
Record[] retval = new Record[records.size()];
|
||||
records.toArray(retval);
|
||||
return retval;
|
||||
Record[] result = new Record[temp.size()];
|
||||
temp.toArray(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -109,12 +91,11 @@ public final class BiffViewer {
|
||||
* up non-debug operations.
|
||||
*
|
||||
*/
|
||||
private static Record createRecord( RecordInputStream in )
|
||||
{
|
||||
switch ( in.getSid() )
|
||||
{
|
||||
private static Record createRecord(RecordInputStream in) {
|
||||
switch (in.getSid()) {
|
||||
case AreaFormatRecord.sid: return new AreaFormatRecord(in);
|
||||
case AreaRecord.sid: return new AreaRecord(in);
|
||||
case ArrayRecord.sid: return new ArrayRecord(in);
|
||||
case AxisLineFormatRecord.sid: return new AxisLineFormatRecord(in);
|
||||
case AxisOptionsRecord.sid: return new AxisOptionsRecord(in);
|
||||
case AxisParentRecord.sid: return new AxisParentRecord(in);
|
||||
@ -249,15 +230,6 @@ public final class BiffViewer {
|
||||
return new UnknownRecord(in);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method setDump - hex dump out data or not.
|
||||
*/
|
||||
public void setDump(boolean dump) {
|
||||
this.dump = dump;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method main with 1 argument just run straight biffview against given
|
||||
* file<P>
|
||||
@ -295,11 +267,7 @@ public final class BiffViewer {
|
||||
} else {
|
||||
ps = System.out;
|
||||
}
|
||||
BiffViewer viewer = new BiffViewer(inputFile, ps);
|
||||
|
||||
if (args.length > 1 && args[1].equals("on")) {
|
||||
viewer.setDump(true);
|
||||
}
|
||||
if (args.length > 1 && args[1].equals("bfd")) {
|
||||
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(inputFile));
|
||||
InputStream stream = fs.createDocumentInputStream("Workbook");
|
||||
@ -309,7 +277,14 @@ public final class BiffViewer {
|
||||
stream.read(data);
|
||||
HexDump.dump(data, 0, System.out, 0);
|
||||
} else {
|
||||
viewer.run();
|
||||
boolean dumpInterpretedRecords = true;
|
||||
boolean dumpHex = args.length > 1 && args[1].equals("on");
|
||||
|
||||
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(inputFile));
|
||||
InputStream is = fs.createDocumentInputStream("Workbook");
|
||||
BiffRecordListener recListener = new BiffRecordListener(dumpHex ? new OutputStreamWriter(ps) : null);
|
||||
is = new BiffDumpingStream(is, recListener);
|
||||
createRecords(is, ps, recListener, dumpInterpretedRecords);
|
||||
}
|
||||
ps.close();
|
||||
} catch (Exception e) {
|
||||
@ -317,53 +292,239 @@ public final class BiffViewer {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class BiffRecordListener implements IBiffRecordListener {
|
||||
private final Writer _hexDumpWriter;
|
||||
private final List _headers;
|
||||
public BiffRecordListener(Writer hexDumpWriter) {
|
||||
_hexDumpWriter = hexDumpWriter;
|
||||
_headers = new ArrayList();
|
||||
}
|
||||
|
||||
public void processRecord(int globalOffset, int recordCounter, int sid, int dataSize,
|
||||
byte[] data) {
|
||||
String header = formatRecordDetails(globalOffset, sid, dataSize, recordCounter);
|
||||
_headers.add(header);
|
||||
Writer w = _hexDumpWriter;
|
||||
if (w != null) {
|
||||
try {
|
||||
w.write(header);
|
||||
w.write(NEW_LINE_CHARS);
|
||||
hexDumpAligned(w, data, 0, dataSize+4, globalOffset);
|
||||
w.flush();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
public String[] getRecentHeaders() {
|
||||
String[] result = new String[_headers.size()];
|
||||
_headers.toArray(result);
|
||||
_headers.clear();
|
||||
return result;
|
||||
}
|
||||
private static String formatRecordDetails(int globalOffset, int sid, int size, int recordCounter) {
|
||||
StringBuffer sb = new StringBuffer(64);
|
||||
sb.append("Offset=").append(HexDump.intToHex(globalOffset)).append("(").append(globalOffset).append(")");
|
||||
sb.append(" recno=").append(recordCounter);
|
||||
sb.append( " sid=").append(HexDump.shortToHex(sid));
|
||||
sb.append( " size=").append(HexDump.shortToHex(size)).append("(").append(size).append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static interface IBiffRecordListener {
|
||||
|
||||
void processRecord(int globalOffset, int recordCounter, int sid, int dataSize, byte[] data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This record supports dumping of completed continue records.
|
||||
* Wraps a plain {@link InputStream} and allows BIFF record information to be tapped off
|
||||
*
|
||||
*/
|
||||
private static final class RecordDetails
|
||||
{
|
||||
short rectype, recsize;
|
||||
int startloc;
|
||||
Record record;
|
||||
private static final class BiffDumpingStream extends InputStream {
|
||||
private final DataInputStream _is;
|
||||
private final IBiffRecordListener _listener;
|
||||
private final byte[] _data;
|
||||
private int _recordCounter;
|
||||
private int _overallStreamPos;
|
||||
private int _currentPos;
|
||||
private int _currentSize;
|
||||
private boolean _innerHasReachedEOF;
|
||||
|
||||
public RecordDetails( short rectype, short recsize, int startloc, Record record )
|
||||
{
|
||||
this.rectype = rectype;
|
||||
this.recsize = recsize;
|
||||
this.startloc = startloc;
|
||||
this.record = record;
|
||||
public BiffDumpingStream(InputStream is, IBiffRecordListener listener) {
|
||||
_is = new DataInputStream(is);
|
||||
_listener = listener;
|
||||
_data = new byte[RecordInputStream.MAX_RECORD_DATA_SIZE + 4];
|
||||
_recordCounter = 0;
|
||||
_overallStreamPos = 0;
|
||||
_currentSize = 0;
|
||||
_currentPos = 0;
|
||||
}
|
||||
|
||||
public short getRectype()
|
||||
{
|
||||
return rectype;
|
||||
public int read() throws IOException {
|
||||
if (_currentPos >= _currentSize) {
|
||||
fillNextBuffer();
|
||||
}
|
||||
if (_currentPos >= _currentSize) {
|
||||
return -1;
|
||||
}
|
||||
int result = _data[_currentPos] & 0x00FF;
|
||||
_currentPos ++;
|
||||
_overallStreamPos ++;
|
||||
formatBufferIfAtEndOfRec();
|
||||
return result;
|
||||
}
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (_currentPos >= _currentSize) {
|
||||
fillNextBuffer();
|
||||
}
|
||||
if (_currentPos >= _currentSize) {
|
||||
return -1;
|
||||
}
|
||||
int availSize = _currentSize - _currentPos;
|
||||
int result;
|
||||
if (len > availSize) {
|
||||
System.err.println("Unexpected request to read past end of current biff record");
|
||||
result = availSize;
|
||||
} else {
|
||||
result = len;
|
||||
}
|
||||
System.arraycopy(_data, _currentPos, b, off, result);
|
||||
_currentPos += result;
|
||||
_overallStreamPos += result;
|
||||
formatBufferIfAtEndOfRec();
|
||||
return result;
|
||||
}
|
||||
|
||||
public short getRecsize()
|
||||
{
|
||||
return recsize;
|
||||
public int available() throws IOException {
|
||||
return _currentSize - _currentPos + _is.available();
|
||||
}
|
||||
|
||||
public Record getRecord()
|
||||
{
|
||||
return record;
|
||||
private void fillNextBuffer() throws IOException {
|
||||
if (_innerHasReachedEOF) {
|
||||
return;
|
||||
}
|
||||
|
||||
public void dump(PrintStream ps) {
|
||||
ps.println("Offset 0x" + Integer.toHexString(startloc) + " (" + startloc + ")");
|
||||
ps.println( "recordid = 0x" + Integer.toHexString( rectype ) + ", size = " + recsize );
|
||||
ps.println( record.toString() );
|
||||
int b0 = _is.read();
|
||||
if (b0 == -1) {
|
||||
_innerHasReachedEOF = true;
|
||||
return;
|
||||
}
|
||||
_data[0] = (byte) b0;
|
||||
_is.readFully(_data, 1, 3);
|
||||
int len = LittleEndian.getShort(_data, 2);
|
||||
_is.readFully(_data, 4, len);
|
||||
_currentPos = 0;
|
||||
_currentSize = len + 4;
|
||||
_recordCounter++;
|
||||
}
|
||||
private void formatBufferIfAtEndOfRec() {
|
||||
if (_currentPos != _currentSize) {
|
||||
return;
|
||||
}
|
||||
int dataSize = _currentSize-4;
|
||||
int sid = LittleEndian.getShort(_data, 0);
|
||||
int globalOffset = _overallStreamPos-_currentSize;
|
||||
_listener.processRecord(globalOffset, _recordCounter, sid, dataSize, _data);
|
||||
}
|
||||
public void close() throws IOException {
|
||||
_is.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class BiffviewRecordInputStream extends RecordInputStream {
|
||||
public BiffviewRecordInputStream(InputStream in) {
|
||||
super(in);
|
||||
private static final int DUMP_LINE_LEN = 16;
|
||||
private static final char[] COLUMN_SEPARATOR = " | ".toCharArray();
|
||||
/**
|
||||
* Hex-dumps a portion of a byte array in typical format, also preserving dump-line alignment
|
||||
* @param globalOffset (somewhat arbitrary) used to calculate the addresses printed at the
|
||||
* start of each line
|
||||
*/
|
||||
static void hexDumpAligned(Writer w, byte[] data, int baseDataOffset, int dumpLen, int globalOffset) {
|
||||
// perhaps this code should be moved to HexDump
|
||||
int globalStart = globalOffset + baseDataOffset;
|
||||
int globalEnd = globalOffset + baseDataOffset + dumpLen;
|
||||
int startDelta = globalStart % DUMP_LINE_LEN;
|
||||
int endDelta = globalEnd % DUMP_LINE_LEN;
|
||||
int startLineAddr = globalStart - startDelta;
|
||||
int endLineAddr = globalEnd - endDelta;
|
||||
|
||||
int lineDataOffset = baseDataOffset - startDelta;
|
||||
int lineAddr = startLineAddr;
|
||||
|
||||
// output (possibly incomplete) first line
|
||||
if (startLineAddr == endLineAddr) {
|
||||
hexDumpLine(w, data, lineAddr, lineDataOffset, startDelta, endDelta);
|
||||
return;
|
||||
}
|
||||
public void dumpBytes(PrintStream ps) {
|
||||
ps.println(HexDump.dump(this.data, 0, this.currentLength));
|
||||
hexDumpLine(w, data, lineAddr, lineDataOffset, startDelta, DUMP_LINE_LEN);
|
||||
|
||||
// output all full lines in the middle
|
||||
while (true) {
|
||||
lineAddr += DUMP_LINE_LEN;
|
||||
lineDataOffset += DUMP_LINE_LEN;
|
||||
if (lineAddr >= endLineAddr) {
|
||||
break;
|
||||
}
|
||||
hexDumpLine(w, data, lineAddr, lineDataOffset, 0, DUMP_LINE_LEN);
|
||||
}
|
||||
|
||||
|
||||
// output (possibly incomplete) last line
|
||||
if (endDelta != 0) {
|
||||
hexDumpLine(w, data, lineAddr, lineDataOffset, 0, endDelta);
|
||||
}
|
||||
}
|
||||
|
||||
private static void hexDumpLine(Writer w, byte[] data, int lineStartAddress, int lineDataOffset, int startDelta, int endDelta) {
|
||||
if (startDelta >= endDelta) {
|
||||
throw new IllegalArgumentException("Bad start/end delta");
|
||||
}
|
||||
try {
|
||||
writeHex(w, lineStartAddress, 8);
|
||||
w.write(COLUMN_SEPARATOR);
|
||||
// raw hex data
|
||||
for (int i=0; i< DUMP_LINE_LEN; i++) {
|
||||
if (i>0) {
|
||||
w.write(" ");
|
||||
}
|
||||
if (i >= startDelta && i < endDelta) {
|
||||
writeHex(w, data[lineDataOffset+i], 2);
|
||||
} else {
|
||||
w.write(" ");
|
||||
}
|
||||
}
|
||||
w.write(COLUMN_SEPARATOR);
|
||||
|
||||
// interpreted ascii
|
||||
for (int i=0; i< DUMP_LINE_LEN; i++) {
|
||||
if (i >= startDelta && i < endDelta) {
|
||||
w.write(getPrintableChar(data[lineDataOffset+i]));
|
||||
} else {
|
||||
w.write(" ");
|
||||
}
|
||||
}
|
||||
w.write(NEW_LINE_CHARS);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static char getPrintableChar(byte b) {
|
||||
char ib = (char) (b & 0x00FF);
|
||||
if (ib < 32 || ib > 126) {
|
||||
return '.';
|
||||
}
|
||||
return ib;
|
||||
}
|
||||
|
||||
private static void writeHex(Writer w, int value, int nDigits) throws IOException {
|
||||
char[] buf = new char[nDigits];
|
||||
int acc = value;
|
||||
for(int i=nDigits-1; i>=0; i--) {
|
||||
int digit = acc & 0x0F;
|
||||
buf[i] = (char) (digit < 10 ? ('0' + digit) : ('A' + digit - 10));
|
||||
acc >>= 4;
|
||||
}
|
||||
w.write(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,11 +142,7 @@ public class TextboxShape
|
||||
obj.setVerticalTextAlignment(hssfShape.getVerticalAlignment());
|
||||
obj.setTextLocked(true);
|
||||
obj.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_NONE);
|
||||
int frLength = ( shape.getString().numFormattingRuns() + 1 ) * 8;
|
||||
obj.setFormattingRunLength( (short) frLength );
|
||||
obj.setTextLength( (short) shape.getString().length() );
|
||||
obj.setStr(shape.getString());
|
||||
obj.setReserved7( 0 );
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
@ -22,76 +22,44 @@ package org.apache.poi.hssf.record;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* Title: Continue Record - Helper class used primarily for SST Records <P>
|
||||
* Title: Continue Record(0x003C) - Helper class used primarily for SST Records <P>
|
||||
* Description: handles overflow for prior record in the input
|
||||
* stream; content is tailored to that prior record<P>
|
||||
* @author Marc Johnson (mjohnson at apache dot org)
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Csaba Nagy (ncsaba at yahoo dot com)
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
|
||||
public class ContinueRecord
|
||||
extends Record
|
||||
{
|
||||
public final class ContinueRecord extends Record {
|
||||
public final static short sid = 0x003C;
|
||||
private byte[] field_1_data;
|
||||
private byte[] _data;
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
|
||||
public ContinueRecord()
|
||||
{
|
||||
public ContinueRecord(byte[] data) {
|
||||
_data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* USE ONLY within "processContinue"
|
||||
*/
|
||||
|
||||
public byte [] serialize()
|
||||
{
|
||||
byte[] retval = new byte[ field_1_data.length + 4 ];
|
||||
byte[] retval = new byte[ _data.length + 4 ];
|
||||
serialize(0, retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
public int serialize(int offset, byte [] data)
|
||||
{
|
||||
|
||||
LittleEndian.putShort(data, offset, sid);
|
||||
LittleEndian.putShort(data, offset + 2, ( short ) field_1_data.length);
|
||||
System.arraycopy(field_1_data, 0, data, offset + 4, field_1_data.length);
|
||||
return field_1_data.length + 4;
|
||||
// throw new RecordFormatException(
|
||||
// "You're not supposed to serialize Continue records like this directly");
|
||||
}
|
||||
|
||||
/*
|
||||
* @param data raw data
|
||||
*/
|
||||
|
||||
public void setData(byte [] data)
|
||||
{
|
||||
field_1_data = data;
|
||||
public int serialize(int offset, byte[] data) {
|
||||
return write(data, offset, null, _data);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the data for continuation
|
||||
* @return byte array containing all of the continued data
|
||||
*/
|
||||
|
||||
public byte [] getData()
|
||||
{
|
||||
return field_1_data;
|
||||
return _data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Debugging toString
|
||||
*
|
||||
* @return string representation
|
||||
*/
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
@ -113,19 +81,36 @@ public class ContinueRecord
|
||||
*
|
||||
* @param in the RecordInputstream to read the record from
|
||||
*/
|
||||
|
||||
public ContinueRecord(RecordInputStream in)
|
||||
{
|
||||
field_1_data = in.readRemainder();
|
||||
_data = in.readRemainder();
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return new ContinueRecord(_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone this record.
|
||||
* Writes the full encoding of a Continue record without making an instance
|
||||
*/
|
||||
public Object clone() {
|
||||
ContinueRecord clone = new ContinueRecord();
|
||||
clone.setData(field_1_data);
|
||||
return clone;
|
||||
public static int write(byte[] destBuf, int destOffset, Byte initialDataByte, byte[] srcData) {
|
||||
return write(destBuf, destOffset, initialDataByte, srcData, 0, srcData.length);
|
||||
}
|
||||
/**
|
||||
* @param initialDataByte (optional - often used for unicode flag).
|
||||
* If supplied, this will be written before srcData
|
||||
* @return the total number of bytes written
|
||||
*/
|
||||
public static int write(byte[] destBuf, int destOffset, Byte initialDataByte, byte[] srcData, int srcOffset, int len) {
|
||||
int totalLen = len + (initialDataByte == null ? 0 : 1);
|
||||
LittleEndian.putUShort(destBuf, destOffset, sid);
|
||||
LittleEndian.putUShort(destBuf, destOffset + 2, totalLen);
|
||||
int pos = destOffset + 4;
|
||||
if (initialDataByte != null) {
|
||||
LittleEndian.putByte(destBuf, pos, initialDataByte.byteValue());
|
||||
pos += 1;
|
||||
}
|
||||
System.arraycopy(srcData, srcOffset, destBuf, pos, len);
|
||||
return 4 + totalLen;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,52 +0,0 @@
|
||||
/* ====================================================================
|
||||
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.hssf.record;
|
||||
|
||||
public interface CustomField
|
||||
extends Cloneable
|
||||
{
|
||||
/**
|
||||
* @return The size of this field in bytes. This operation is not valid
|
||||
* until after the call to <code>fillField()</code>
|
||||
*/
|
||||
int getSize();
|
||||
|
||||
/**
|
||||
* Populates this fields data from the byte array passed in.
|
||||
* @param in the RecordInputstream to read the record from
|
||||
*/
|
||||
int fillField(RecordInputStream in);
|
||||
|
||||
/**
|
||||
* Appends the string representation of this field to the supplied
|
||||
* StringBuffer.
|
||||
*
|
||||
* @param str The string buffer to append to.
|
||||
*/
|
||||
void toString(StringBuffer str);
|
||||
|
||||
/**
|
||||
* Converts this field to it's byte array form.
|
||||
* @param offset The offset into the byte array to start writing to.
|
||||
* @param data The data array to write to.
|
||||
* @return The number of bytes written.
|
||||
*/
|
||||
int serializeField(int offset, byte[] data);
|
||||
|
||||
|
||||
}
|
@ -17,8 +17,6 @@
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
@ -124,11 +122,7 @@ public final class ExternalNameRecord extends Record {
|
||||
}
|
||||
|
||||
private int getNameDefinitionSize() {
|
||||
int result = 0;
|
||||
for (int i = 0; i < field_5_name_definition.length; i++) {
|
||||
result += field_5_name_definition[i].getSize();
|
||||
}
|
||||
return result;
|
||||
return Ptg.getEncodedSize(field_5_name_definition);
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,47 +20,38 @@ package org.apache.poi.hssf.record;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
import java.util.Stack;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Not implemented yet. May commit it anyway just so people can see
|
||||
* where I'm heading.
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public final class LinkedDataFormulaField implements CustomField {
|
||||
Stack formulaTokens = new Stack();
|
||||
public final class LinkedDataFormulaField {
|
||||
private Ptg[] formulaTokens;
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
int size = 0;
|
||||
for ( Iterator iterator = formulaTokens.iterator(); iterator.hasNext(); )
|
||||
{
|
||||
Ptg token = (Ptg) iterator.next();
|
||||
size += token.getSize();
|
||||
}
|
||||
return size + 2;
|
||||
return 2 + Ptg.getEncodedSize(formulaTokens);
|
||||
}
|
||||
|
||||
public int fillField( RecordInputStream in )
|
||||
{
|
||||
short tokenSize = in.readShort();
|
||||
formulaTokens = Ptg.createParsedExpressionTokens(tokenSize, in);
|
||||
|
||||
int tokenSize = in.readUShort();
|
||||
formulaTokens = Ptg.readTokens(tokenSize, in);
|
||||
return tokenSize + 2;
|
||||
}
|
||||
|
||||
public void toString( StringBuffer buffer )
|
||||
{
|
||||
for ( int k = 0; k < formulaTokens.size(); k++ )
|
||||
for ( int k = 0; k < formulaTokens.length; k++ )
|
||||
{
|
||||
Ptg ptg = formulaTokens[k];
|
||||
buffer.append( "Formula " )
|
||||
.append( k )
|
||||
.append( "=" )
|
||||
.append( formulaTokens.get( k ).toString() )
|
||||
.append(ptg.toString() )
|
||||
.append( "\n" )
|
||||
.append( ( (Ptg) formulaTokens.get( k ) ).toDebugString() )
|
||||
.append(ptg.toDebugString() )
|
||||
.append( "\n" );
|
||||
}
|
||||
}
|
||||
@ -75,34 +66,26 @@ public final class LinkedDataFormulaField implements CustomField {
|
||||
public int serializeField( int offset, byte[] data )
|
||||
{
|
||||
int size = getSize();
|
||||
LittleEndian.putShort(data, offset, (short)(size - 2));
|
||||
LittleEndian.putUShort(data, offset, size - 2);
|
||||
int pos = offset + 2;
|
||||
pos += Ptg.serializePtgStack(formulaTokens, data, pos);
|
||||
pos += Ptg.serializePtgs(formulaTokens, data, pos);
|
||||
return size;
|
||||
}
|
||||
|
||||
public Object clone()
|
||||
public void setFormulaTokens(Ptg[] ptgs)
|
||||
{
|
||||
try
|
||||
{
|
||||
// todo: clone tokens? or are they immutable?
|
||||
return super.clone();
|
||||
}
|
||||
catch ( CloneNotSupportedException e )
|
||||
{
|
||||
// should not happen
|
||||
return null;
|
||||
}
|
||||
this.formulaTokens = (Ptg[])ptgs.clone();
|
||||
}
|
||||
|
||||
public void setFormulaTokens( Stack formulaTokens )
|
||||
public Ptg[] getFormulaTokens()
|
||||
{
|
||||
this.formulaTokens = (Stack) formulaTokens.clone();
|
||||
return (Ptg[])this.formulaTokens.clone();
|
||||
}
|
||||
|
||||
public Stack getFormulaTokens()
|
||||
{
|
||||
return (Stack)this.formulaTokens.clone();
|
||||
}
|
||||
public LinkedDataFormulaField copy() {
|
||||
LinkedDataFormulaField result = new LinkedDataFormulaField();
|
||||
|
||||
result.formulaTokens = getFormulaTokens();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ public final class LinkedDataRecord extends Record {
|
||||
rec.field_2_referenceType = field_2_referenceType;
|
||||
rec.field_3_options = field_3_options;
|
||||
rec.field_4_indexNumberFmtRecord = field_4_indexNumberFmtRecord;
|
||||
rec.field_5_formulaOfLink = ((LinkedDataFormulaField)field_5_formulaOfLink.clone());
|
||||
rec.field_5_formulaOfLink = field_5_formulaOfLink.copy();
|
||||
return rec;
|
||||
}
|
||||
|
||||
|
@ -321,42 +321,48 @@ public final class RecordFactory {
|
||||
Record lastRecord = null;
|
||||
while (recStream.hasNextRecord()) {
|
||||
recStream.nextRecord();
|
||||
if (recStream.getSid() != 0) {
|
||||
if (recStream.getSid() == 0) {
|
||||
// After EOF, Excel seems to pad block with zeros
|
||||
continue;
|
||||
}
|
||||
Record[] recs = createRecord(recStream); // handle MulRK records
|
||||
|
||||
if (recs.length > 1) {
|
||||
for (int k = 0; k < recs.length; k++) {
|
||||
records.add(recs[ k ]); // these will be number records
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
Record record = recs[ 0 ];
|
||||
|
||||
if (record != null) {
|
||||
if (record == null) {
|
||||
continue;
|
||||
}
|
||||
if (record.getSid() == DrawingGroupRecord.sid
|
||||
&& lastRecord instanceof DrawingGroupRecord) {
|
||||
DrawingGroupRecord lastDGRecord = (DrawingGroupRecord) lastRecord;
|
||||
lastDGRecord.join((AbstractEscherHolderRecord) record);
|
||||
} else if (record.getSid() == ContinueRecord.sid &&
|
||||
((lastRecord instanceof ObjRecord) || (lastRecord instanceof TextObjectRecord))) {
|
||||
} else if (record.getSid() == ContinueRecord.sid) {
|
||||
ContinueRecord contRec = (ContinueRecord)record;
|
||||
|
||||
if (lastRecord instanceof ObjRecord || lastRecord instanceof TextObjectRecord) {
|
||||
// Drawing records have a very strange continue behaviour.
|
||||
//There can actually be OBJ records mixed between the continues.
|
||||
lastDrawingRecord.processContinueRecord( ((ContinueRecord)record).getData() );
|
||||
lastDrawingRecord.processContinueRecord(contRec.getData() );
|
||||
//we must remember the position of the continue record.
|
||||
//in the serialization procedure the original structure of records must be preserved
|
||||
records.add(record);
|
||||
} else if (record.getSid() == ContinueRecord.sid &&
|
||||
(lastRecord instanceof DrawingGroupRecord)) {
|
||||
((DrawingGroupRecord)lastRecord).processContinueRecord(((ContinueRecord)record).getData());
|
||||
} else if (record.getSid() == ContinueRecord.sid &&
|
||||
(lastRecord instanceof StringRecord)) {
|
||||
((StringRecord)lastRecord).processContinueRecord(((ContinueRecord)record).getData());
|
||||
} else if (record.getSid() == ContinueRecord.sid) {
|
||||
if (lastRecord instanceof UnknownRecord) {
|
||||
//Gracefully handle records that we dont know about,
|
||||
} else if (lastRecord instanceof DrawingGroupRecord) {
|
||||
((DrawingGroupRecord)lastRecord).processContinueRecord(contRec.getData());
|
||||
} else if (lastRecord instanceof StringRecord) {
|
||||
((StringRecord)lastRecord).processContinueRecord(contRec.getData());
|
||||
} else if (lastRecord instanceof UnknownRecord) {
|
||||
//Gracefully handle records that we don't know about,
|
||||
//that happen to be continued
|
||||
records.add(record);
|
||||
} else
|
||||
} else {
|
||||
throw new RecordFormatException("Unhandled Continue Record");
|
||||
}
|
||||
} else {
|
||||
lastRecord = record;
|
||||
if (record instanceof DrawingRecord) {
|
||||
@ -365,9 +371,6 @@ public final class RecordFactory {
|
||||
records.add(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return records;
|
||||
}
|
||||
}
|
||||
|
@ -29,19 +29,19 @@ import java.io.ByteArrayOutputStream;
|
||||
*
|
||||
* @author Jason Height (jheight @ apache dot org)
|
||||
*/
|
||||
public class RecordInputStream extends InputStream {
|
||||
public final class RecordInputStream extends InputStream {
|
||||
/** Maximum size of a single record (minus the 4 byte header) without a continue*/
|
||||
public final static short MAX_RECORD_DATA_SIZE = 8224;
|
||||
private static final int INVALID_SID_VALUE = -1;
|
||||
|
||||
private InputStream in;
|
||||
protected short currentSid;
|
||||
protected short currentLength = -1;
|
||||
protected short nextSid;
|
||||
private short currentSid;
|
||||
private short currentLength = -1;
|
||||
private short nextSid;
|
||||
|
||||
protected byte[] data = new byte[MAX_RECORD_DATA_SIZE];
|
||||
protected short recordOffset;
|
||||
protected long pos;
|
||||
private final byte[] data = new byte[MAX_RECORD_DATA_SIZE];
|
||||
private short recordOffset;
|
||||
private long pos;
|
||||
|
||||
private boolean autoContinue = true;
|
||||
|
||||
@ -218,53 +218,80 @@ public class RecordInputStream extends InputStream {
|
||||
return result;
|
||||
}
|
||||
|
||||
public String readString() {
|
||||
int requestedLength = readUShort();
|
||||
byte compressFlag = readByte();
|
||||
return readStringCommon(requestedLength, compressFlag == 0);
|
||||
}
|
||||
/**
|
||||
* given a byte array of 16-bit unicode characters, compress to 8-bit and
|
||||
* return a string
|
||||
*
|
||||
* { 0x16, 0x00 } -0x16
|
||||
*
|
||||
* @param length the length of the final string
|
||||
* @param requestedLength the length of the final string
|
||||
* @return the converted string
|
||||
* @exception IllegalArgumentException if len is too large (i.e.,
|
||||
* there is not enough data in string to create a String of that
|
||||
* length)
|
||||
*/
|
||||
public String readUnicodeLEString(int length) {
|
||||
if ((length < 0) || (((remaining() / 2) < length) && !isContinueNext())) {
|
||||
throw new IllegalArgumentException("Illegal length - asked for " + length + " but only " + (remaining()/2) + " left!");
|
||||
public String readUnicodeLEString(int requestedLength) {
|
||||
return readStringCommon(requestedLength, false);
|
||||
}
|
||||
|
||||
StringBuffer buf = new StringBuffer(length);
|
||||
for (int i=0;i<length;i++) {
|
||||
if ((remaining() == 0) && (isContinueNext())){
|
||||
public String readCompressedUnicode(int requestedLength) {
|
||||
return readStringCommon(requestedLength, true);
|
||||
}
|
||||
|
||||
private String readStringCommon(int requestedLength, boolean pIsCompressedEncoding) {
|
||||
// Sanity check to detect garbage string lengths
|
||||
if (requestedLength < 0 || requestedLength > 0x100000) { // 16 million chars?
|
||||
throw new IllegalArgumentException("Bad requested string length (" + requestedLength + ")");
|
||||
}
|
||||
char[] buf = new char[requestedLength];
|
||||
boolean isCompressedEncoding = pIsCompressedEncoding;
|
||||
int curLen = 0;
|
||||
while(true) {
|
||||
int availableChars =isCompressedEncoding ? remaining() : remaining() / LittleEndian.SHORT_SIZE;
|
||||
if (requestedLength - curLen <= availableChars) {
|
||||
// enough space in current record, so just read it out
|
||||
while(curLen < requestedLength) {
|
||||
char ch;
|
||||
if (isCompressedEncoding) {
|
||||
ch = (char)readUByte();
|
||||
} else {
|
||||
ch = (char)readShort();
|
||||
}
|
||||
buf[curLen] = ch;
|
||||
curLen++;
|
||||
}
|
||||
return new String(buf);
|
||||
}
|
||||
// else string has been spilled into next continue record
|
||||
// so read what's left of the current record
|
||||
while(availableChars > 0) {
|
||||
char ch;
|
||||
if (isCompressedEncoding) {
|
||||
ch = (char)readUByte();
|
||||
} else {
|
||||
ch = (char)readShort();
|
||||
}
|
||||
buf[curLen] = ch;
|
||||
curLen++;
|
||||
availableChars--;
|
||||
}
|
||||
if (!isContinueNext()) {
|
||||
throw new RecordFormatException("Expected to find a ContinueRecord in order to read remaining "
|
||||
+ (requestedLength-curLen) + " of " + requestedLength + " chars");
|
||||
}
|
||||
if(remaining() != 0) {
|
||||
throw new RecordFormatException("Odd number of bytes(" + remaining() + ") left behind");
|
||||
}
|
||||
nextRecord();
|
||||
int compressByte = readByte();
|
||||
if(compressByte != 1) throw new IllegalArgumentException("compressByte in continue records must be 1 while reading unicode LE string");
|
||||
// note - the compressed flag may change on the fly
|
||||
byte compressFlag = readByte();
|
||||
isCompressedEncoding = (compressFlag == 0);
|
||||
}
|
||||
char ch = (char)readShort();
|
||||
buf.append(ch);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String readCompressedUnicode(int length) {
|
||||
if ((length < 0) || ((remaining() < length) && !isContinueNext())) {
|
||||
throw new IllegalArgumentException("Illegal length " + length);
|
||||
}
|
||||
|
||||
StringBuffer buf = new StringBuffer(length);
|
||||
for (int i=0;i<length;i++) {
|
||||
if ((remaining() == 0) && (isContinueNext())) {
|
||||
nextRecord();
|
||||
int compressByte = readByte();
|
||||
if(compressByte != 0) throw new IllegalArgumentException("compressByte in continue records must be 0 while reading compressed unicode");
|
||||
}
|
||||
byte b = readByte();
|
||||
char ch = (char)(0x00FF & b); // avoid sex
|
||||
buf.append(ch);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** Returns an excel style unicode string from the bytes reminaing in the record.
|
||||
|
@ -1,427 +0,0 @@
|
||||
|
||||
/* ====================================================================
|
||||
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.hssf.record;
|
||||
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* The TXO record is used to define the properties of a text box. It is followed
|
||||
* by two continue records unless there is no actual text. The first continue record contains
|
||||
* the text data and the next continue record contains the formatting runs.<p/>
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public class TextObjectBaseRecord extends Record {
|
||||
// TODO - don't instantiate superclass
|
||||
public final static short sid = 0x01B6;
|
||||
|
||||
private static final BitField reserved1 = BitFieldFactory.getInstance(0x0001);
|
||||
private static final BitField HorizontalTextAlignment = BitFieldFactory.getInstance(0x000E);
|
||||
private static final BitField VerticalTextAlignment = BitFieldFactory.getInstance(0x0070);
|
||||
private static final BitField reserved2 = BitFieldFactory.getInstance(0x0180);
|
||||
private static final BitField textLocked = BitFieldFactory.getInstance(0x0200);
|
||||
private static final BitField reserved3 = BitFieldFactory.getInstance(0xFC00);
|
||||
|
||||
private short field_1_options;
|
||||
public final static short HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED = 1;
|
||||
public final static short HORIZONTAL_TEXT_ALIGNMENT_CENTERED = 2;
|
||||
public final static short HORIZONTAL_TEXT_ALIGNMENT_RIGHT_ALIGNED = 3;
|
||||
public final static short HORIZONTAL_TEXT_ALIGNMENT_JUSTIFIED = 4;
|
||||
public final static short VERTICAL_TEXT_ALIGNMENT_TOP = 1;
|
||||
public final static short VERTICAL_TEXT_ALIGNMENT_CENTER = 2;
|
||||
public final static short VERTICAL_TEXT_ALIGNMENT_BOTTOM = 3;
|
||||
public final static short VERTICAL_TEXT_ALIGNMENT_JUSTIFY = 4;
|
||||
private short field_2_textOrientation;
|
||||
public final static short TEXT_ORIENTATION_NONE = 0;
|
||||
public final static short TEXT_ORIENTATION_TOP_TO_BOTTOM = 1;
|
||||
public final static short TEXT_ORIENTATION_ROT_RIGHT = 2;
|
||||
public final static short TEXT_ORIENTATION_ROT_LEFT = 3;
|
||||
private short field_3_reserved4;
|
||||
private short field_4_reserved5;
|
||||
private short field_5_reserved6;
|
||||
private short field_6_textLength;
|
||||
private short field_7_formattingRunLength;
|
||||
private int field_8_reserved7;
|
||||
|
||||
|
||||
public TextObjectBaseRecord()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public TextObjectBaseRecord(RecordInputStream in)
|
||||
{
|
||||
field_1_options = in.readShort();
|
||||
field_2_textOrientation = in.readShort();
|
||||
field_3_reserved4 = in.readShort();
|
||||
field_4_reserved5 = in.readShort();
|
||||
field_5_reserved6 = in.readShort();
|
||||
field_6_textLength = in.readShort();
|
||||
field_7_formattingRunLength = in.readShort();
|
||||
field_8_reserved7 = in.readInt();
|
||||
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
buffer.append("[TXO]\n");
|
||||
buffer.append(" .options = ")
|
||||
.append("0x").append(HexDump.toHex( getOptions ()))
|
||||
.append(" (").append( getOptions() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .reserved1 = ").append(isReserved1()).append('\n');
|
||||
buffer.append(" .HorizontalTextAlignment = ").append(getHorizontalTextAlignment()).append('\n');
|
||||
buffer.append(" .VerticalTextAlignment = ").append(getVerticalTextAlignment()).append('\n');
|
||||
buffer.append(" .reserved2 = ").append(getReserved2()).append('\n');
|
||||
buffer.append(" .textLocked = ").append(isTextLocked()).append('\n');
|
||||
buffer.append(" .reserved3 = ").append(getReserved3()).append('\n');
|
||||
buffer.append(" .textOrientation = ")
|
||||
.append("0x").append(HexDump.toHex( getTextOrientation ()))
|
||||
.append(" (").append( getTextOrientation() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .reserved4 = ")
|
||||
.append("0x").append(HexDump.toHex( getReserved4 ()))
|
||||
.append(" (").append( getReserved4() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .reserved5 = ")
|
||||
.append("0x").append(HexDump.toHex( getReserved5 ()))
|
||||
.append(" (").append( getReserved5() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .reserved6 = ")
|
||||
.append("0x").append(HexDump.toHex( getReserved6 ()))
|
||||
.append(" (").append( getReserved6() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .textLength = ")
|
||||
.append("0x").append(HexDump.toHex( getTextLength ()))
|
||||
.append(" (").append( getTextLength() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .formattingRunLength = ")
|
||||
.append("0x").append(HexDump.toHex( getFormattingRunLength ()))
|
||||
.append(" (").append( getFormattingRunLength() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .reserved7 = ")
|
||||
.append("0x").append(HexDump.toHex( getReserved7 ()))
|
||||
.append(" (").append( getReserved7() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
|
||||
buffer.append("[/TXO]\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public int serialize(int offset, byte[] data)
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
LittleEndian.putShort(data, 0 + offset, sid);
|
||||
LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4));
|
||||
|
||||
LittleEndian.putShort(data, 4 + offset + pos, field_1_options);
|
||||
LittleEndian.putShort(data, 6 + offset + pos, field_2_textOrientation);
|
||||
LittleEndian.putShort(data, 8 + offset + pos, field_3_reserved4);
|
||||
LittleEndian.putShort(data, 10 + offset + pos, field_4_reserved5);
|
||||
LittleEndian.putShort(data, 12 + offset + pos, field_5_reserved6);
|
||||
LittleEndian.putShort(data, 14 + offset + pos, field_6_textLength);
|
||||
LittleEndian.putShort(data, 16 + offset + pos, field_7_formattingRunLength);
|
||||
LittleEndian.putInt(data, 18 + offset + pos, field_8_reserved7);
|
||||
|
||||
return getRecordSize();
|
||||
}
|
||||
|
||||
public int getRecordSize()
|
||||
{
|
||||
return 4 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 4;
|
||||
}
|
||||
|
||||
public short getSid()
|
||||
{
|
||||
return sid;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
TextObjectBaseRecord rec = new TextObjectBaseRecord();
|
||||
|
||||
rec.field_1_options = field_1_options;
|
||||
rec.field_2_textOrientation = field_2_textOrientation;
|
||||
rec.field_3_reserved4 = field_3_reserved4;
|
||||
rec.field_4_reserved5 = field_4_reserved5;
|
||||
rec.field_5_reserved6 = field_5_reserved6;
|
||||
rec.field_6_textLength = field_6_textLength;
|
||||
rec.field_7_formattingRunLength = field_7_formattingRunLength;
|
||||
rec.field_8_reserved7 = field_8_reserved7;
|
||||
return rec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the options field for the TextObjectBase record.
|
||||
*/
|
||||
public short getOptions()
|
||||
{
|
||||
return field_1_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the options field for the TextObjectBase record.
|
||||
*/
|
||||
public void setOptions(short field_1_options)
|
||||
{
|
||||
this.field_1_options = field_1_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text orientation field for the TextObjectBase record.
|
||||
*
|
||||
* @return One of
|
||||
* TEXT_ORIENTATION_NONE
|
||||
* TEXT_ORIENTATION_TOP_TO_BOTTOM
|
||||
* TEXT_ORIENTATION_ROT_RIGHT
|
||||
* TEXT_ORIENTATION_ROT_LEFT
|
||||
*/
|
||||
public short getTextOrientation()
|
||||
{
|
||||
return field_2_textOrientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text orientation field for the TextObjectBase record.
|
||||
*
|
||||
* @param field_2_textOrientation
|
||||
* One of
|
||||
* TEXT_ORIENTATION_NONE
|
||||
* TEXT_ORIENTATION_TOP_TO_BOTTOM
|
||||
* TEXT_ORIENTATION_ROT_RIGHT
|
||||
* TEXT_ORIENTATION_ROT_LEFT
|
||||
*/
|
||||
public void setTextOrientation(short field_2_textOrientation)
|
||||
{
|
||||
this.field_2_textOrientation = field_2_textOrientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reserved4 field for the TextObjectBase record.
|
||||
*/
|
||||
public short getReserved4()
|
||||
{
|
||||
return field_3_reserved4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reserved4 field for the TextObjectBase record.
|
||||
*/
|
||||
public void setReserved4(short field_3_reserved4)
|
||||
{
|
||||
this.field_3_reserved4 = field_3_reserved4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reserved5 field for the TextObjectBase record.
|
||||
*/
|
||||
public short getReserved5()
|
||||
{
|
||||
return field_4_reserved5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reserved5 field for the TextObjectBase record.
|
||||
*/
|
||||
public void setReserved5(short field_4_reserved5)
|
||||
{
|
||||
this.field_4_reserved5 = field_4_reserved5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reserved6 field for the TextObjectBase record.
|
||||
*/
|
||||
public short getReserved6()
|
||||
{
|
||||
return field_5_reserved6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reserved6 field for the TextObjectBase record.
|
||||
*/
|
||||
public void setReserved6(short field_5_reserved6)
|
||||
{
|
||||
this.field_5_reserved6 = field_5_reserved6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text length field for the TextObjectBase record.
|
||||
*/
|
||||
public short getTextLength()
|
||||
{
|
||||
return field_6_textLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text length field for the TextObjectBase record.
|
||||
*/
|
||||
public void setTextLength(short field_6_textLength)
|
||||
{
|
||||
this.field_6_textLength = field_6_textLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatting run length field for the TextObjectBase record.
|
||||
*/
|
||||
public short getFormattingRunLength()
|
||||
{
|
||||
return field_7_formattingRunLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the formatting run length field for the TextObjectBase record.
|
||||
*/
|
||||
public void setFormattingRunLength(short field_7_formattingRunLength)
|
||||
{
|
||||
this.field_7_formattingRunLength = field_7_formattingRunLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reserved7 field for the TextObjectBase record.
|
||||
*/
|
||||
public int getReserved7()
|
||||
{
|
||||
return field_8_reserved7;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reserved7 field for the TextObjectBase record.
|
||||
*/
|
||||
public void setReserved7(int field_8_reserved7)
|
||||
{
|
||||
this.field_8_reserved7 = field_8_reserved7;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the reserved1 field value.
|
||||
* reserved field
|
||||
*/
|
||||
public void setReserved1(boolean value)
|
||||
{
|
||||
field_1_options = reserved1.setShortBoolean(field_1_options, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* reserved field
|
||||
* @return the reserved1 field value.
|
||||
*/
|
||||
public boolean isReserved1()
|
||||
{
|
||||
return reserved1.isSet(field_1_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Horizontal text alignment field value.
|
||||
*
|
||||
*/
|
||||
public void setHorizontalTextAlignment(short value)
|
||||
{
|
||||
field_1_options = HorizontalTextAlignment.setShortValue(field_1_options, value);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the Horizontal text alignment field value.
|
||||
*/
|
||||
public short getHorizontalTextAlignment()
|
||||
{
|
||||
return HorizontalTextAlignment.getShortValue(field_1_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Vertical text alignment field value.
|
||||
*
|
||||
*/
|
||||
public void setVerticalTextAlignment(short value)
|
||||
{
|
||||
field_1_options = VerticalTextAlignment.setShortValue(field_1_options, value);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the Vertical text alignment field value.
|
||||
*/
|
||||
public short getVerticalTextAlignment()
|
||||
{
|
||||
return VerticalTextAlignment.getShortValue(field_1_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the reserved2 field value.
|
||||
*
|
||||
*/
|
||||
public void setReserved2(short value)
|
||||
{
|
||||
field_1_options = reserved2.setShortValue(field_1_options, value);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the reserved2 field value.
|
||||
*/
|
||||
public short getReserved2()
|
||||
{
|
||||
return reserved2.getShortValue(field_1_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text locked field value.
|
||||
* Text has been locked
|
||||
*/
|
||||
public void setTextLocked(boolean value)
|
||||
{
|
||||
field_1_options = textLocked.setShortBoolean(field_1_options, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Text has been locked
|
||||
* @return the text locked field value.
|
||||
*/
|
||||
public boolean isTextLocked()
|
||||
{
|
||||
return textLocked.isSet(field_1_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the reserved3 field value.
|
||||
*
|
||||
*/
|
||||
public void setReserved3(short value)
|
||||
{
|
||||
field_1_options = reserved3.setShortValue(field_1_options, value);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the reserved3 field value.
|
||||
*/
|
||||
public short getReserved3()
|
||||
{
|
||||
return reserved3.getShortValue(field_1_options);
|
||||
}
|
||||
}
|
@ -19,253 +19,427 @@ package org.apache.poi.hssf.record;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
public class TextObjectRecord
|
||||
extends TextObjectBaseRecord
|
||||
{
|
||||
HSSFRichTextString str;
|
||||
/**
|
||||
* The TXO record (0x01B6) is used to define the properties of a text box. It is
|
||||
* followed by two or more continue records unless there is no actual text. The
|
||||
* first continue records contain the text data and the last continue record
|
||||
* contains the formatting runs.<p/>
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public final class TextObjectRecord extends Record {
|
||||
public final static short sid = 0x01B6;
|
||||
|
||||
public TextObjectRecord()
|
||||
{
|
||||
private static final int FORMAT_RUN_ENCODED_SIZE = 8; // 2 shorts and 4 bytes reserved
|
||||
|
||||
private static final BitField HorizontalTextAlignment = BitFieldFactory.getInstance(0x000E);
|
||||
private static final BitField VerticalTextAlignment = BitFieldFactory.getInstance(0x0070);
|
||||
private static final BitField textLocked = BitFieldFactory.getInstance(0x0200);
|
||||
|
||||
public final static short HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED = 1;
|
||||
public final static short HORIZONTAL_TEXT_ALIGNMENT_CENTERED = 2;
|
||||
public final static short HORIZONTAL_TEXT_ALIGNMENT_RIGHT_ALIGNED = 3;
|
||||
public final static short HORIZONTAL_TEXT_ALIGNMENT_JUSTIFIED = 4;
|
||||
public final static short VERTICAL_TEXT_ALIGNMENT_TOP = 1;
|
||||
public final static short VERTICAL_TEXT_ALIGNMENT_CENTER = 2;
|
||||
public final static short VERTICAL_TEXT_ALIGNMENT_BOTTOM = 3;
|
||||
public final static short VERTICAL_TEXT_ALIGNMENT_JUSTIFY = 4;
|
||||
|
||||
public final static short TEXT_ORIENTATION_NONE = 0;
|
||||
public final static short TEXT_ORIENTATION_TOP_TO_BOTTOM = 1;
|
||||
public final static short TEXT_ORIENTATION_ROT_RIGHT = 2;
|
||||
public final static short TEXT_ORIENTATION_ROT_LEFT = 3;
|
||||
|
||||
private int field_1_options;
|
||||
private int field_2_textOrientation;
|
||||
private int field_3_reserved4;
|
||||
private int field_4_reserved5;
|
||||
private int field_5_reserved6;
|
||||
private int field_8_reserved7;
|
||||
|
||||
private HSSFRichTextString _text;
|
||||
|
||||
/*
|
||||
* Note - the next three fields are very similar to those on
|
||||
* EmbededObjectRefSubRecord(ftPictFmla 0x0009)
|
||||
*
|
||||
* some observed values for the 4 bytes preceding the formula: C0 5E 86 03
|
||||
* C0 11 AC 02 80 F1 8A 03 D4 F0 8A 03
|
||||
*/
|
||||
private int _unknownPreFormulaInt;
|
||||
/** expect tRef, tRef3D, tArea, tArea3D or tName */
|
||||
private Ptg _linkRefPtg;
|
||||
/**
|
||||
* Not clear if needed . Excel seems to be OK if this byte is not present.
|
||||
* Value is often the same as the earlier firstColumn byte. */
|
||||
private Byte _unknownPostFormulaByte;
|
||||
|
||||
public TextObjectRecord() {
|
||||
}
|
||||
|
||||
public TextObjectRecord( RecordInputStream in )
|
||||
{
|
||||
super( in );
|
||||
public TextObjectRecord(RecordInputStream in) {
|
||||
field_1_options = in.readUShort();
|
||||
field_2_textOrientation = in.readUShort();
|
||||
field_3_reserved4 = in.readUShort();
|
||||
field_4_reserved5 = in.readUShort();
|
||||
field_5_reserved6 = in.readUShort();
|
||||
int field_6_textLength = in.readUShort();
|
||||
int field_7_formattingDataLength = in.readUShort();
|
||||
field_8_reserved7 = in.readInt();
|
||||
|
||||
if (getTextLength() > 0) {
|
||||
if (in.isContinueNext() && in.remaining() == 0) {
|
||||
//1st Continue
|
||||
in.nextRecord();
|
||||
processRawString(in);
|
||||
} else
|
||||
throw new RecordFormatException("Expected Continue record to hold string data for TextObjectRecord");
|
||||
if (in.remaining() > 0) {
|
||||
// Text Objects can have simple reference formulas
|
||||
// (This bit not mentioned in the MS document)
|
||||
if (in.remaining() < 11) {
|
||||
throw new RecordFormatException("Not enough remaining data for a link formula");
|
||||
}
|
||||
if (getFormattingRunLength() > 0) {
|
||||
int formulaSize = in.readUShort();
|
||||
_unknownPreFormulaInt = in.readInt();
|
||||
Ptg[] ptgs = Ptg.readTokens(formulaSize, in);
|
||||
if (ptgs.length != 1) {
|
||||
throw new RecordFormatException("Read " + ptgs.length
|
||||
+ " tokens but expected exactly 1");
|
||||
}
|
||||
_linkRefPtg = ptgs[0];
|
||||
if (in.remaining() > 0) {
|
||||
_unknownPostFormulaByte = new Byte(in.readByte());
|
||||
} else {
|
||||
_unknownPostFormulaByte = null;
|
||||
}
|
||||
} else {
|
||||
_linkRefPtg = null;
|
||||
}
|
||||
if (in.remaining() > 0) {
|
||||
throw new RecordFormatException("Unused " + in.remaining() + " bytes at end of record");
|
||||
}
|
||||
|
||||
String text;
|
||||
if (field_6_textLength > 0) {
|
||||
text = readRawString(in, field_6_textLength);
|
||||
} else {
|
||||
text = "";
|
||||
}
|
||||
_text = new HSSFRichTextString(text);
|
||||
|
||||
if (field_7_formattingDataLength > 0) {
|
||||
if (in.isContinueNext() && in.remaining() == 0) {
|
||||
in.nextRecord();
|
||||
processFontRuns(in);
|
||||
} else throw new RecordFormatException("Expected Continue Record to hold font runs for TextObjectRecord");
|
||||
processFontRuns(in, _text, field_7_formattingDataLength);
|
||||
} else {
|
||||
throw new RecordFormatException(
|
||||
"Expected Continue Record to hold font runs for TextObjectRecord");
|
||||
}
|
||||
}
|
||||
if (str == null)
|
||||
str = new HSSFRichTextString("");
|
||||
}
|
||||
|
||||
|
||||
public int getRecordSize()
|
||||
{
|
||||
int continue1Size = 0;
|
||||
int continue2Size = 0;
|
||||
if (str.length() != 0)
|
||||
{
|
||||
int length = str.length() * 2;
|
||||
while(length > 0){
|
||||
int chunkSize = Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE-2, length);
|
||||
length -= chunkSize;
|
||||
|
||||
continue1Size += chunkSize;
|
||||
continue1Size += 1 + 4;
|
||||
private static String readRawString(RecordInputStream in, int textLength) {
|
||||
byte compressByte = in.readByte();
|
||||
boolean isCompressed = (compressByte & 0x01) == 0;
|
||||
if (isCompressed) {
|
||||
return in.readCompressedUnicode(textLength);
|
||||
}
|
||||
return in.readUnicodeLEString(textLength);
|
||||
}
|
||||
|
||||
continue2Size = (str.numFormattingRuns() + 1) * 8 + 4;
|
||||
private static void processFontRuns(RecordInputStream in, HSSFRichTextString str,
|
||||
int formattingRunDataLength) {
|
||||
if (formattingRunDataLength % FORMAT_RUN_ENCODED_SIZE != 0) {
|
||||
throw new RecordFormatException("Bad format run data length " + formattingRunDataLength
|
||||
+ ")");
|
||||
}
|
||||
return super.getRecordSize() + continue1Size + continue2Size;
|
||||
if (in.remaining() != formattingRunDataLength) {
|
||||
throw new RecordFormatException("Expected " + formattingRunDataLength
|
||||
+ " bytes but got " + in.remaining());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int serialize( int offset, byte[] data )
|
||||
{
|
||||
// Temporarily blank out str so that record size is calculated without the continue records.
|
||||
HSSFRichTextString temp = str;
|
||||
str = new HSSFRichTextString("");
|
||||
int bytesWritten1 = super.serialize( offset, data );
|
||||
str = temp;
|
||||
|
||||
int pos = offset + bytesWritten1;
|
||||
if ( str.getString().equals( "" ) == false )
|
||||
{
|
||||
ContinueRecord c2 = createContinue2();
|
||||
int bytesWritten2 = 0;
|
||||
|
||||
try
|
||||
{
|
||||
byte[] c1Data = str.getString().getBytes( "UTF-16LE" );
|
||||
int length = c1Data.length;
|
||||
|
||||
int charsWritten = 0;
|
||||
int spos = pos;
|
||||
while(length > 0){
|
||||
int chunkSize = Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE-2 , length);
|
||||
length -= chunkSize;
|
||||
|
||||
//continue header
|
||||
LittleEndian.putShort(data, spos, ContinueRecord.sid);
|
||||
spos += LittleEndian.SHORT_SIZE;
|
||||
LittleEndian.putShort(data, spos, (short)(chunkSize+1));
|
||||
spos += LittleEndian.SHORT_SIZE;
|
||||
|
||||
//The first byte specifies if the text is compressed unicode or unicode.
|
||||
//(regardless what was read, we always serialize double-byte unicode characters (UTF-16LE).
|
||||
data[spos] = 1;
|
||||
spos += LittleEndian.BYTE_SIZE;
|
||||
|
||||
//copy characters data
|
||||
System.arraycopy(c1Data, charsWritten, data, spos, chunkSize);
|
||||
spos += chunkSize;
|
||||
charsWritten += chunkSize;
|
||||
}
|
||||
|
||||
bytesWritten2 = (spos-pos);
|
||||
}
|
||||
catch ( UnsupportedEncodingException e )
|
||||
{
|
||||
throw new RuntimeException( e.getMessage(), e );
|
||||
}
|
||||
|
||||
pos += bytesWritten2;
|
||||
int bytesWritten3 = c2.serialize( pos, data );
|
||||
pos += bytesWritten3;
|
||||
|
||||
int size = bytesWritten1 + bytesWritten2 + bytesWritten3;
|
||||
if ( size != getRecordSize() )
|
||||
throw new RecordFormatException(size + " bytes written but getRecordSize() reports " + getRecordSize());
|
||||
return size;
|
||||
}
|
||||
if ( bytesWritten1 != getRecordSize() )
|
||||
throw new RecordFormatException(bytesWritten1 + " bytes written but getRecordSize() reports " + getRecordSize());
|
||||
return bytesWritten1;
|
||||
}
|
||||
|
||||
private ContinueRecord createContinue2()
|
||||
{
|
||||
ContinueRecord c2 = new ContinueRecord();
|
||||
byte[] c2Data = new byte[str.numFormattingRuns() * 8 + 8];
|
||||
int pos = 0;
|
||||
for ( int i = 0; i < str.numFormattingRuns(); i++ )
|
||||
{
|
||||
LittleEndian.putShort( c2Data, pos, (short) str.getIndexOfFormattingRun( i ) );
|
||||
pos += 2;
|
||||
LittleEndian.putShort( c2Data, pos, str.getFontOfFormattingRun( i ) == str.NO_FONT ? 0 : str.getFontOfFormattingRun( i ) );
|
||||
pos += 2;
|
||||
pos += 4; // skip reserved
|
||||
}
|
||||
LittleEndian.putShort( c2Data, pos, (short) str.length() );
|
||||
pos += 2;
|
||||
LittleEndian.putShort( c2Data, pos, (short) 0 );
|
||||
pos += 2;
|
||||
pos += 4; // skip reserved
|
||||
|
||||
c2.setData( c2Data );
|
||||
|
||||
return c2;
|
||||
}
|
||||
|
||||
private void processFontRuns( RecordInputStream in )
|
||||
{
|
||||
while (in.remaining() > 0)
|
||||
{
|
||||
int nRuns = formattingRunDataLength / FORMAT_RUN_ENCODED_SIZE;
|
||||
for (int i = 0; i < nRuns; i++) {
|
||||
short index = in.readShort();
|
||||
short iFont = in.readShort();
|
||||
in.readInt(); // skip reserved.
|
||||
|
||||
str.applyFont(index, str.length(), iFont);
|
||||
}
|
||||
}
|
||||
|
||||
private void processRawString( RecordInputStream in )
|
||||
{
|
||||
String s;
|
||||
byte compressByte = in.readByte();
|
||||
boolean isCompressed = compressByte == 0;
|
||||
if ( isCompressed )
|
||||
{
|
||||
s = in.readCompressedUnicode(getTextLength());
|
||||
}
|
||||
else
|
||||
{
|
||||
s = in.readUnicodeLEString(getTextLength());
|
||||
}
|
||||
str = new HSSFRichTextString( s );
|
||||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
public HSSFRichTextString getStr()
|
||||
{
|
||||
return str;
|
||||
/**
|
||||
* Only for the current record. does not include any subsequent Continue
|
||||
* records
|
||||
*/
|
||||
private int getDataSize() {
|
||||
int result = 2 + 2 + 2 + 2 + 2 + 2 + 2 + 4;
|
||||
if (_linkRefPtg != null) {
|
||||
result += 2 // formula size
|
||||
+ 4 // unknownInt
|
||||
+_linkRefPtg.getSize();
|
||||
if (_unknownPostFormulaByte != null) {
|
||||
result += 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setStr( HSSFRichTextString str )
|
||||
{
|
||||
this.str = str;
|
||||
private int serializeTXORecord(int offset, byte[] data) {
|
||||
int dataSize = getDataSize();
|
||||
|
||||
LittleEndian.putUShort(data, 0 + offset, TextObjectRecord.sid);
|
||||
LittleEndian.putUShort(data, 2 + offset, dataSize);
|
||||
|
||||
|
||||
LittleEndian.putUShort(data, 4 + offset, field_1_options);
|
||||
LittleEndian.putUShort(data, 6 + offset, field_2_textOrientation);
|
||||
LittleEndian.putUShort(data, 8 + offset, field_3_reserved4);
|
||||
LittleEndian.putUShort(data, 10 + offset, field_4_reserved5);
|
||||
LittleEndian.putUShort(data, 12 + offset, field_5_reserved6);
|
||||
LittleEndian.putUShort(data, 14 + offset, _text.length());
|
||||
LittleEndian.putUShort(data, 16 + offset, getFormattingDataLength());
|
||||
LittleEndian.putInt(data, 18 + offset, field_8_reserved7);
|
||||
|
||||
if (_linkRefPtg != null) {
|
||||
int pos = offset+22;
|
||||
int formulaSize = _linkRefPtg.getSize();
|
||||
LittleEndian.putUShort(data, pos, formulaSize);
|
||||
pos += LittleEndian.SHORT_SIZE;
|
||||
LittleEndian.putInt(data, pos, _unknownPreFormulaInt);
|
||||
pos += LittleEndian.INT_SIZE;
|
||||
_linkRefPtg.writeBytes(data, pos);
|
||||
pos += formulaSize;
|
||||
if (_unknownPostFormulaByte != null) {
|
||||
LittleEndian.putByte(data, pos, _unknownPostFormulaByte.byteValue());
|
||||
pos += LittleEndian.BYTE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
return 4 + dataSize;
|
||||
}
|
||||
|
||||
buffer.append( "[TXO]\n" );
|
||||
buffer.append( " .options = " )
|
||||
.append( "0x" ).append( HexDump.toHex( getOptions() ) )
|
||||
.append( " (" ).append( getOptions() ).append( " )" );
|
||||
buffer.append( System.getProperty( "line.separator" ) );
|
||||
buffer.append( " .reserved1 = " ).append( isReserved1() ).append( '\n' );
|
||||
buffer.append( " .HorizontalTextAlignment = " ).append( getHorizontalTextAlignment() ).append( '\n' );
|
||||
buffer.append( " .VerticalTextAlignment = " ).append( getVerticalTextAlignment() ).append( '\n' );
|
||||
buffer.append( " .reserved2 = " ).append( getReserved2() ).append( '\n' );
|
||||
buffer.append( " .textLocked = " ).append( isTextLocked() ).append( '\n' );
|
||||
buffer.append( " .reserved3 = " ).append( getReserved3() ).append( '\n' );
|
||||
buffer.append( " .textOrientation = " )
|
||||
.append( "0x" ).append( HexDump.toHex( getTextOrientation() ) )
|
||||
.append( " (" ).append( getTextOrientation() ).append( " )" );
|
||||
buffer.append( System.getProperty( "line.separator" ) );
|
||||
buffer.append( " .reserved4 = " )
|
||||
.append( "0x" ).append( HexDump.toHex( getReserved4() ) )
|
||||
.append( " (" ).append( getReserved4() ).append( " )" );
|
||||
buffer.append( System.getProperty( "line.separator" ) );
|
||||
buffer.append( " .reserved5 = " )
|
||||
.append( "0x" ).append( HexDump.toHex( getReserved5() ) )
|
||||
.append( " (" ).append( getReserved5() ).append( " )" );
|
||||
buffer.append( System.getProperty( "line.separator" ) );
|
||||
buffer.append( " .reserved6 = " )
|
||||
.append( "0x" ).append( HexDump.toHex( getReserved6() ) )
|
||||
.append( " (" ).append( getReserved6() ).append( " )" );
|
||||
buffer.append( System.getProperty( "line.separator" ) );
|
||||
buffer.append( " .textLength = " )
|
||||
.append( "0x" ).append( HexDump.toHex( getTextLength() ) )
|
||||
.append( " (" ).append( getTextLength() ).append( " )" );
|
||||
buffer.append( System.getProperty( "line.separator" ) );
|
||||
buffer.append( " .reserved7 = " )
|
||||
.append( "0x" ).append( HexDump.toHex( getReserved7() ) )
|
||||
.append( " (" ).append( getReserved7() ).append( " )" );
|
||||
buffer.append( System.getProperty( "line.separator" ) );
|
||||
private int serializeTrailingRecords(int offset, byte[] data) {
|
||||
byte[] textBytes;
|
||||
try {
|
||||
textBytes = _text.getString().getBytes("UTF-16LE");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
int remainingLength = textBytes.length;
|
||||
|
||||
buffer.append( " .string = " ).append(str).append('\n');
|
||||
int countTextBytesWritten = 0;
|
||||
int pos = offset;
|
||||
// (regardless what was read, we always serialize double-byte
|
||||
// unicode characters (UTF-16LE).
|
||||
Byte unicodeFlag = new Byte((byte)1);
|
||||
while (remainingLength > 0) {
|
||||
int chunkSize = Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE - 2, remainingLength);
|
||||
remainingLength -= chunkSize;
|
||||
pos += ContinueRecord.write(data, pos, unicodeFlag, textBytes, countTextBytesWritten, chunkSize);
|
||||
countTextBytesWritten += chunkSize;
|
||||
}
|
||||
|
||||
for (int i = 0; i < str.numFormattingRuns(); i++) {
|
||||
buffer.append( " .textrun = " ).append(str.getFontOfFormattingRun(i)).append('\n');
|
||||
byte[] formatData = createFormatData(_text);
|
||||
pos += ContinueRecord.write(data, pos, null, formatData);
|
||||
return pos - offset;
|
||||
}
|
||||
|
||||
private int getTrailingRecordsSize() {
|
||||
if (_text.length() < 1) {
|
||||
return 0;
|
||||
}
|
||||
int encodedTextSize = 0;
|
||||
int textBytesLength = _text.length() * LittleEndian.SHORT_SIZE;
|
||||
while (textBytesLength > 0) {
|
||||
int chunkSize = Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE - 2, textBytesLength);
|
||||
textBytesLength -= chunkSize;
|
||||
|
||||
encodedTextSize += 4; // +4 for ContinueRecord sid+size
|
||||
encodedTextSize += 1+chunkSize; // +1 for compressed unicode flag,
|
||||
}
|
||||
|
||||
int encodedFormatSize = (_text.numFormattingRuns() + 1) * FORMAT_RUN_ENCODED_SIZE
|
||||
+ 4; // +4 for ContinueRecord sid+size
|
||||
return encodedTextSize + encodedFormatSize;
|
||||
}
|
||||
|
||||
|
||||
public int serialize(int offset, byte[] data) {
|
||||
|
||||
int expectedTotalSize = getRecordSize();
|
||||
int totalSize = serializeTXORecord(offset, data);
|
||||
|
||||
if (_text.getString().length() > 0) {
|
||||
totalSize += serializeTrailingRecords(offset+totalSize, data);
|
||||
}
|
||||
|
||||
if (totalSize != expectedTotalSize)
|
||||
throw new RecordFormatException(totalSize
|
||||
+ " bytes written but getRecordSize() reports " + expectedTotalSize);
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note - this total size includes all potential {@link ContinueRecord}s written
|
||||
*/
|
||||
public int getRecordSize() {
|
||||
int baseSize = 4 + getDataSize();
|
||||
return baseSize + getTrailingRecordsSize();
|
||||
}
|
||||
|
||||
|
||||
private int getFormattingDataLength() {
|
||||
if (_text.length() < 1) {
|
||||
// important - no formatting data if text is empty
|
||||
return 0;
|
||||
}
|
||||
return (_text.numFormattingRuns() + 1) * FORMAT_RUN_ENCODED_SIZE;
|
||||
}
|
||||
|
||||
private static byte[] createFormatData(HSSFRichTextString str) {
|
||||
int nRuns = str.numFormattingRuns();
|
||||
byte[] result = new byte[(nRuns + 1) * FORMAT_RUN_ENCODED_SIZE];
|
||||
int pos = 0;
|
||||
for (int i = 0; i < nRuns; i++) {
|
||||
LittleEndian.putUShort(result, pos, str.getIndexOfFormattingRun(i));
|
||||
pos += 2;
|
||||
int fontIndex = str.getFontOfFormattingRun(i);
|
||||
LittleEndian.putUShort(result, pos, fontIndex == str.NO_FONT ? 0 : fontIndex);
|
||||
pos += 2;
|
||||
pos += 4; // skip reserved
|
||||
}
|
||||
LittleEndian.putUShort(result, pos, str.length());
|
||||
pos += 2;
|
||||
LittleEndian.putUShort(result, pos, 0);
|
||||
pos += 2;
|
||||
pos += 4; // skip reserved
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Horizontal text alignment field value.
|
||||
*/
|
||||
public void setHorizontalTextAlignment(int value) {
|
||||
field_1_options = HorizontalTextAlignment.setValue(field_1_options, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Horizontal text alignment field value.
|
||||
*/
|
||||
public int getHorizontalTextAlignment() {
|
||||
return HorizontalTextAlignment.getValue(field_1_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Vertical text alignment field value.
|
||||
*/
|
||||
public void setVerticalTextAlignment(int value) {
|
||||
field_1_options = VerticalTextAlignment.setValue(field_1_options, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Vertical text alignment field value.
|
||||
*/
|
||||
public int getVerticalTextAlignment() {
|
||||
return VerticalTextAlignment.getValue(field_1_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text locked field value.
|
||||
*/
|
||||
public void setTextLocked(boolean value) {
|
||||
field_1_options = textLocked.setBoolean(field_1_options, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the text locked field value.
|
||||
*/
|
||||
public boolean isTextLocked() {
|
||||
return textLocked.isSet(field_1_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text orientation field for the TextObjectBase record.
|
||||
*
|
||||
* @return One of TEXT_ORIENTATION_NONE TEXT_ORIENTATION_TOP_TO_BOTTOM
|
||||
* TEXT_ORIENTATION_ROT_RIGHT TEXT_ORIENTATION_ROT_LEFT
|
||||
*/
|
||||
public int getTextOrientation() {
|
||||
return field_2_textOrientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text orientation field for the TextObjectBase record.
|
||||
*
|
||||
* @param textOrientation
|
||||
* One of TEXT_ORIENTATION_NONE TEXT_ORIENTATION_TOP_TO_BOTTOM
|
||||
* TEXT_ORIENTATION_ROT_RIGHT TEXT_ORIENTATION_ROT_LEFT
|
||||
*/
|
||||
public void setTextOrientation(int textOrientation) {
|
||||
this.field_2_textOrientation = textOrientation;
|
||||
}
|
||||
|
||||
public HSSFRichTextString getStr() {
|
||||
return _text;
|
||||
}
|
||||
|
||||
public void setStr(HSSFRichTextString str) {
|
||||
_text = str;
|
||||
}
|
||||
|
||||
public Ptg getLinkRefPtg() {
|
||||
return _linkRefPtg;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
sb.append("[TXO]\n");
|
||||
sb.append(" .options = ").append(HexDump.shortToHex(field_1_options)).append("\n");
|
||||
sb.append(" .isHorizontal = ").append(getHorizontalTextAlignment()).append('\n');
|
||||
sb.append(" .isVertical = ").append(getVerticalTextAlignment()).append('\n');
|
||||
sb.append(" .textLocked = ").append(isTextLocked()).append('\n');
|
||||
sb.append(" .textOrientation= ").append(HexDump.shortToHex(getTextOrientation())).append("\n");
|
||||
sb.append(" .reserved4 = ").append(HexDump.shortToHex(field_3_reserved4)).append("\n");
|
||||
sb.append(" .reserved5 = ").append(HexDump.shortToHex(field_4_reserved5)).append("\n");
|
||||
sb.append(" .reserved6 = ").append(HexDump.shortToHex(field_5_reserved6)).append("\n");
|
||||
sb.append(" .textLength = ").append(HexDump.shortToHex(_text.length())).append("\n");
|
||||
sb.append(" .reserved7 = ").append(HexDump.intToHex(field_8_reserved7)).append("\n");
|
||||
|
||||
sb.append(" .string = ").append(_text).append('\n');
|
||||
|
||||
for (int i = 0; i < _text.numFormattingRuns(); i++) {
|
||||
sb.append(" .textrun = ").append(_text.getFontOfFormattingRun(i)).append('\n');
|
||||
|
||||
}
|
||||
buffer.append( "[/TXO]\n" );
|
||||
return buffer.toString();
|
||||
sb.append("[/TXO]\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
|
||||
TextObjectRecord rec = new TextObjectRecord();
|
||||
rec.str = str;
|
||||
rec._text = _text;
|
||||
|
||||
rec.setOptions(getOptions());
|
||||
rec.setTextOrientation(getTextOrientation());
|
||||
rec.setReserved4(getReserved4());
|
||||
rec.setReserved5(getReserved5());
|
||||
rec.setReserved6(getReserved6());
|
||||
rec.setTextLength(getTextLength());
|
||||
rec.setFormattingRunLength(getFormattingRunLength());
|
||||
rec.setReserved7(getReserved7());
|
||||
rec.field_1_options = field_1_options;
|
||||
rec.field_2_textOrientation = field_2_textOrientation;
|
||||
rec.field_3_reserved4 = field_3_reserved4;
|
||||
rec.field_4_reserved5 = field_4_reserved5;
|
||||
rec.field_5_reserved6 = field_5_reserved6;
|
||||
rec.field_8_reserved7 = field_8_reserved7;
|
||||
|
||||
rec._text = _text; // clone needed?
|
||||
|
||||
if (_linkRefPtg != null) {
|
||||
rec._unknownPreFormulaInt = _unknownPreFormulaInt;
|
||||
rec._linkRefPtg = _linkRefPtg.copy();
|
||||
rec._unknownPostFormulaByte = rec._unknownPostFormulaByte;
|
||||
}
|
||||
return rec;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,10 +19,8 @@ package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
/**
|
||||
* <tt>Ptg</tt> represents a syntactic token in a formula. 'PTG' is an acronym for
|
||||
@ -49,15 +47,7 @@ public abstract class Ptg implements Cloneable {
|
||||
* Extra data (beyond <tt>size</tt>) may be read if and <tt>ArrayPtg</tt>s are present.
|
||||
*/
|
||||
public static Ptg[] readTokens(int size, RecordInputStream in) {
|
||||
Stack temp = createParsedExpressionTokens((short)size, in);
|
||||
return toPtgArray(temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated - use readTokens()
|
||||
*/
|
||||
public static Stack createParsedExpressionTokens(short size, RecordInputStream in) {
|
||||
Stack stack = new Stack();
|
||||
List temp = new ArrayList(4 + size / 2);
|
||||
int pos = 0;
|
||||
List arrayPtgs = null;
|
||||
while (pos < size) {
|
||||
@ -71,7 +61,7 @@ public abstract class Ptg implements Cloneable {
|
||||
} else {
|
||||
pos += ptg.getSize();
|
||||
}
|
||||
stack.push( ptg );
|
||||
temp.add( ptg );
|
||||
}
|
||||
if(pos != size) {
|
||||
throw new RuntimeException("Ptg array size mismatch");
|
||||
@ -82,7 +72,7 @@ public abstract class Ptg implements Cloneable {
|
||||
p.readTokenValues(in);
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
return toPtgArray(temp);
|
||||
}
|
||||
|
||||
public static Ptg createPtg(RecordInputStream in) {
|
||||
@ -200,19 +190,11 @@ public abstract class Ptg implements Cloneable {
|
||||
l.toArray(result);
|
||||
return result;
|
||||
}
|
||||
private static Stack createStack(Ptg[] formulaTokens) {
|
||||
Stack result = new Stack();
|
||||
for (int i = 0; i < formulaTokens.length; i++) {
|
||||
result.add(formulaTokens[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* This method will return the same result as {@link #getEncodedSizeWithoutArrayData(Ptg[])}
|
||||
* if there are no array tokens present.
|
||||
* @return the full size taken to encode the specified <tt>Ptg</tt>s
|
||||
*/
|
||||
// TODO - several duplicates of this code should be refactored here
|
||||
public static int getEncodedSize(Ptg[] ptgs) {
|
||||
int result = 0;
|
||||
for (int i = 0; i < ptgs.length; i++) {
|
||||
@ -243,23 +225,14 @@ public abstract class Ptg implements Cloneable {
|
||||
* The 2 byte encode length field is <b>not</b> written by this method.
|
||||
* @return number of bytes written
|
||||
*/
|
||||
public static int serializePtgs(Ptg[] ptgs, byte[] data, int offset) {
|
||||
return serializePtgStack(createStack(ptgs), data, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use serializePtgs()
|
||||
*/
|
||||
public static int serializePtgStack(Stack expression, byte[] array, int offset) {
|
||||
public static int serializePtgs(Ptg[] ptgs, byte[] array, int offset) {
|
||||
int pos = 0;
|
||||
int size = 0;
|
||||
if (expression != null)
|
||||
size = expression.size();
|
||||
int size = ptgs.length;
|
||||
|
||||
List arrayPtgs = null;
|
||||
|
||||
for (int k = 0; k < size; k++) {
|
||||
Ptg ptg = ( Ptg ) expression.get(k);
|
||||
Ptg ptg = ptgs[k];
|
||||
|
||||
ptg.writeBytes(array, pos + offset);
|
||||
if (ptg instanceof ArrayPtg) {
|
||||
|
@ -149,9 +149,6 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
||||
if (hstring.numFormattingRuns() == 0) hstring.applyFont((short)0);
|
||||
|
||||
if (txo != null) {
|
||||
int frLength = ( hstring.numFormattingRuns() + 1 ) * 8;
|
||||
txo.setFormattingRunLength( (short) frLength );
|
||||
txo.setTextLength( (short) hstring.length() );
|
||||
txo.setStr(hstring);
|
||||
}
|
||||
super.setString(string);
|
||||
|
@ -196,7 +196,7 @@ public class HSSFRichTextString
|
||||
|
||||
|
||||
/**
|
||||
* @return the number of characters in the font.
|
||||
* @return the number of characters in the text.
|
||||
*/
|
||||
public int length()
|
||||
{
|
||||
|
@ -20,7 +20,6 @@ package org.apache.poi.hssf.usermodel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.apache.poi.hssf.record.AreaFormatRecord;
|
||||
import org.apache.poi.hssf.record.AxisLineFormatRecord;
|
||||
@ -68,6 +67,7 @@ import org.apache.poi.hssf.record.UnknownRecord;
|
||||
import org.apache.poi.hssf.record.VCenterRecord;
|
||||
import org.apache.poi.hssf.record.ValueRangeRecord;
|
||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
|
||||
/**
|
||||
* Has methods for construction of a chart object.
|
||||
@ -759,11 +759,9 @@ public final class HSSFChart {
|
||||
r.setCustomNumberFormat( false );
|
||||
r.setIndexNumberFmtRecord( (short) 0 );
|
||||
LinkedDataFormulaField formula = new LinkedDataFormulaField();
|
||||
Stack tokens = new Stack();
|
||||
Area3DPtg p = new Area3DPtg(0, 31, 1, 1,
|
||||
false, false, false, false, 0);
|
||||
tokens.add( p );
|
||||
formula.setFormulaTokens( tokens );
|
||||
formula.setFormulaTokens(new Ptg[] { p, });
|
||||
r.setFormulaOfLink( formula );
|
||||
return r;
|
||||
}
|
||||
@ -776,11 +774,9 @@ public final class HSSFChart {
|
||||
r.setCustomNumberFormat( false );
|
||||
r.setIndexNumberFmtRecord( (short) 0 );
|
||||
LinkedDataFormulaField formula = new LinkedDataFormulaField();
|
||||
Stack tokens = new Stack();
|
||||
Area3DPtg p = new Area3DPtg(0, 31, 0, 0,
|
||||
false, false, false, false, 0);
|
||||
tokens.add( p );
|
||||
formula.setFormulaTokens( tokens );
|
||||
formula.setFormulaTokens(new Ptg[] { p, });
|
||||
r.setFormulaOfLink( formula );
|
||||
return r;
|
||||
}
|
||||
|
@ -87,10 +87,8 @@ public final class TestEventRecordFactory extends TestCase {
|
||||
bof.setHistoryBitMask(BOFRecord.HISTORY_MASK);
|
||||
|
||||
byte[] bytes = bof.serialize();
|
||||
byte[] nbytes = new byte[bytes.length - 4];
|
||||
System.arraycopy(bytes,4,nbytes,0,nbytes.length);
|
||||
|
||||
Record[] records = RecordFactory.createRecord(new TestcaseRecordInputStream(bof.getSid(),(short)nbytes.length,nbytes));
|
||||
Record[] records = RecordFactory.createRecord(TestcaseRecordInputStream.create(bytes));
|
||||
|
||||
assertTrue("record.length must be 1, was ="+records.length,records.length == 1);
|
||||
assertTrue("record is the same", compareRec(bof,records[0]));
|
||||
|
@ -84,6 +84,7 @@ public final class AllRecordTests {
|
||||
result.addTestSuite(TestPaneRecord.class);
|
||||
result.addTestSuite(TestPlotAreaRecord.class);
|
||||
result.addTestSuite(TestPlotGrowthRecord.class);
|
||||
result.addTestSuite(TestRecordInputStream.class);
|
||||
result.addTestSuite(TestRecordFactory.class);
|
||||
result.addTestSuite(TestSCLRecord.class);
|
||||
result.addTestSuite(TestSSTDeserializer.class);
|
||||
|
@ -41,7 +41,7 @@ public final class TestAreaFormatRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
AreaFormatRecord record = new AreaFormatRecord(new TestcaseRecordInputStream((short)0x100a, (short)data.length, data));
|
||||
AreaFormatRecord record = new AreaFormatRecord(TestcaseRecordInputStream.create(0x100a, data));
|
||||
assertEquals( 0xFFFFFF, record.getForegroundColor());
|
||||
assertEquals( 0x000000, record.getBackgroundColor());
|
||||
assertEquals( 1, record.getPattern());
|
||||
|
@ -35,7 +35,7 @@ public final class TestAreaRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
AreaRecord record = new AreaRecord(new TestcaseRecordInputStream((short)0x101A, (short)data.length, data));
|
||||
AreaRecord record = new AreaRecord(TestcaseRecordInputStream.create(0x101A, data));
|
||||
assertEquals( 2, record.getFormatFlags());
|
||||
assertEquals( false, record.isStacked() );
|
||||
assertEquals( true, record.isDisplayAsPercentage() );
|
||||
|
@ -34,7 +34,7 @@ public final class TestAxisLineFormatRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
AxisLineFormatRecord record = new AxisLineFormatRecord(new TestcaseRecordInputStream((short)0x1021, (short)data.length, data));
|
||||
AxisLineFormatRecord record = new AxisLineFormatRecord(TestcaseRecordInputStream.create(0x1021, data));
|
||||
assertEquals( AxisLineFormatRecord.AXIS_TYPE_MAJOR_GRID_LINE, record.getAxisType());
|
||||
|
||||
assertEquals( 6, record.getRecordSize() );
|
||||
|
@ -37,7 +37,7 @@ public final class TestAxisOptionsRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
AxisOptionsRecord record = new AxisOptionsRecord(new TestcaseRecordInputStream((short)0x1062, (short)data.length, data));
|
||||
AxisOptionsRecord record = new AxisOptionsRecord(TestcaseRecordInputStream.create(0x1062, data));
|
||||
assertEquals( 0, record.getMinimumCategory());
|
||||
assertEquals( 0, record.getMaximumCategory());
|
||||
assertEquals( 1, record.getMajorUnitValue());
|
||||
|
@ -37,7 +37,7 @@ public final class TestAxisParentRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
AxisParentRecord record = new AxisParentRecord(new TestcaseRecordInputStream((short)0x1041, (short)data.length, data));
|
||||
AxisParentRecord record = new AxisParentRecord(TestcaseRecordInputStream.create(0x1041, data));
|
||||
assertEquals( AxisParentRecord.AXIS_TYPE_MAIN, record.getAxisType());
|
||||
assertEquals( 0x021d, record.getX());
|
||||
assertEquals( 0xdd, record.getY());
|
||||
|
@ -39,7 +39,7 @@ public final class TestAxisRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
AxisRecord record = new AxisRecord(new TestcaseRecordInputStream((short)0x101d, (short)data.length, data));
|
||||
AxisRecord record = new AxisRecord(TestcaseRecordInputStream.create(0x101d, data));
|
||||
assertEquals( AxisRecord.AXIS_TYPE_CATEGORY_OR_X_AXIS, record.getAxisType());
|
||||
assertEquals( 0, record.getReserved1());
|
||||
assertEquals( 0, record.getReserved2());
|
||||
|
@ -34,7 +34,7 @@ public final class TestAxisUsedRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
AxisUsedRecord record = new AxisUsedRecord(new TestcaseRecordInputStream((short)0x1046, (short)data.length, data));
|
||||
AxisUsedRecord record = new AxisUsedRecord(TestcaseRecordInputStream.create(0x1046, data));
|
||||
assertEquals( 1, record.getNumAxis());
|
||||
|
||||
assertEquals( 6, record.getRecordSize() );
|
||||
|
@ -37,7 +37,7 @@ public final class TestBarRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
BarRecord record = new BarRecord(new TestcaseRecordInputStream((short)0x1017, (short)data.length, data));
|
||||
BarRecord record = new BarRecord(TestcaseRecordInputStream.create(0x1017, data));
|
||||
assertEquals( 0, record.getBarSpace());
|
||||
assertEquals( 0x96, record.getCategorySpace());
|
||||
assertEquals( 0, record.getFormatFlags());
|
||||
|
@ -69,7 +69,7 @@ public final class TestBoundSheetRecord extends TestCase {
|
||||
// </str>
|
||||
};
|
||||
|
||||
RecordInputStream in = new TestcaseRecordInputStream(BoundSheetRecord.sid, data);
|
||||
RecordInputStream in = TestcaseRecordInputStream.create(BoundSheetRecord.sid, data);
|
||||
BoundSheetRecord bsr = new BoundSheetRecord(in);
|
||||
// sheet name is unicode Russian for 'minor page'
|
||||
assertEquals("\u0421\u0442\u0440\u0430\u043D\u0438\u0447\u043A\u0430", bsr.getSheetname());
|
||||
|
@ -90,7 +90,7 @@ public final class TestCFHeaderRecord extends TestCase
|
||||
(byte)0x03, (byte)0x00,
|
||||
};
|
||||
|
||||
CFHeaderRecord record = new CFHeaderRecord(new TestcaseRecordInputStream(CFHeaderRecord.sid, (short)recordData.length, recordData));
|
||||
CFHeaderRecord record = new CFHeaderRecord(TestcaseRecordInputStream.create(CFHeaderRecord.sid, recordData));
|
||||
|
||||
assertEquals("#CFRULES", 3, record.getNumberOfConditionalFormats());
|
||||
assertTrue(record.getNeedRecalculation());
|
||||
@ -143,7 +143,7 @@ public final class TestCFHeaderRecord extends TestCase
|
||||
|
||||
CFHeaderRecord record;
|
||||
try {
|
||||
record = new CFHeaderRecord(new TestcaseRecordInputStream(CFHeaderRecord.sid, (short)recordData.length, recordData));
|
||||
record = new CFHeaderRecord(TestcaseRecordInputStream.create(CFHeaderRecord.sid, recordData));
|
||||
} catch (IllegalArgumentException e) {
|
||||
if(e.getMessage().equals("invalid cell range (-25536, 2, -15536, 2)")) {
|
||||
throw new AssertionFailedError("Identified bug 44739b");
|
||||
|
@ -54,7 +54,7 @@ public final class TestCFRuleRecord extends TestCase
|
||||
System.arraycopy(serializedRecord, 4, recordData, 0, recordData.length);
|
||||
|
||||
// Deserialize
|
||||
record = new CFRuleRecord(new TestcaseRecordInputStream(CFRuleRecord.sid, (short)recordData.length, recordData));
|
||||
record = new CFRuleRecord(TestcaseRecordInputStream.create(CFRuleRecord.sid, recordData));
|
||||
|
||||
// Serialize again
|
||||
byte[] output = record.serialize();
|
||||
@ -317,7 +317,7 @@ public final class TestCFRuleRecord extends TestCase
|
||||
*/
|
||||
public void testReserializeRefNTokens() {
|
||||
|
||||
RecordInputStream is = new TestcaseRecordInputStream(CFRuleRecord.sid, DATA_REFN);
|
||||
RecordInputStream is = TestcaseRecordInputStream.create(CFRuleRecord.sid, DATA_REFN);
|
||||
CFRuleRecord rr = new CFRuleRecord(is);
|
||||
Ptg[] ptgs = rr.getParsedExpression1();
|
||||
assertEquals(3, ptgs.length);
|
||||
|
@ -38,7 +38,7 @@ public final class TestCategorySeriesAxisRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
CategorySeriesAxisRecord record = new CategorySeriesAxisRecord(new TestcaseRecordInputStream((short)0x1020, (short)data.length, data));
|
||||
CategorySeriesAxisRecord record = new CategorySeriesAxisRecord(TestcaseRecordInputStream.create(0x1020, data));
|
||||
assertEquals( 1, record.getCrossingPoint());
|
||||
assertEquals( 1, record.getLabelFrequency());
|
||||
assertEquals( 1, record.getTickMarkFrequency());
|
||||
|
@ -38,7 +38,7 @@ public final class TestChartRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
ChartRecord record = new ChartRecord(new TestcaseRecordInputStream((short)0x1002, (short)data.length, data));
|
||||
ChartRecord record = new ChartRecord(TestcaseRecordInputStream.create(0x1002, data));
|
||||
assertEquals( 0, record.getX());
|
||||
assertEquals( 0, record.getY());
|
||||
assertEquals( 30474216, record.getWidth());
|
||||
|
@ -38,7 +38,7 @@ public final class TestCommonObjectDataSubRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
CommonObjectDataSubRecord record = new CommonObjectDataSubRecord(new TestcaseRecordInputStream((short)0x15, (short)data.length, data));
|
||||
CommonObjectDataSubRecord record = new CommonObjectDataSubRecord(TestcaseRecordInputStream.create(0x15, data));
|
||||
|
||||
assertEquals( CommonObjectDataSubRecord.OBJECT_TYPE_LIST_BOX, record.getObjectType());
|
||||
assertEquals( (short)1, record.getObjectId());
|
||||
|
@ -35,7 +35,7 @@ public final class TestDatRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
DatRecord record = new DatRecord(new TestcaseRecordInputStream((short)0x1063, (short)data.length, data));
|
||||
DatRecord record = new DatRecord(TestcaseRecordInputStream.create(0x1063, data));
|
||||
assertEquals( 0xD, record.getOptions());
|
||||
assertEquals( true, record.isHorizontalBorder() );
|
||||
assertEquals( false, record.isVerticalBorder() );
|
||||
|
@ -38,7 +38,7 @@ public final class TestDataFormatRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
DataFormatRecord record = new DataFormatRecord(new TestcaseRecordInputStream((short)0x1006, (short)data.length, data));
|
||||
DataFormatRecord record = new DataFormatRecord(TestcaseRecordInputStream.create(0x1006, data));
|
||||
assertEquals( (short)0xFFFF, record.getPointNumber());
|
||||
assertEquals( 0, record.getSeriesIndex());
|
||||
assertEquals( 0, record.getSeriesNumber());
|
||||
|
@ -35,7 +35,7 @@ public final class TestDefaultDataLabelTextPropertiesRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
DefaultDataLabelTextPropertiesRecord record = new DefaultDataLabelTextPropertiesRecord(new TestcaseRecordInputStream((short)0x1024, (short)data.length, data));
|
||||
DefaultDataLabelTextPropertiesRecord record = new DefaultDataLabelTextPropertiesRecord(TestcaseRecordInputStream.create(0x1024, data));
|
||||
assertEquals( 2, record.getCategoryDataType());
|
||||
|
||||
assertEquals( 6, record.getRecordSize() );
|
||||
|
@ -127,7 +127,7 @@ public final class TestEmbeddedObjectRefSubRecord extends TestCase {
|
||||
}
|
||||
|
||||
private static void confirmRead(byte[] data, int i) {
|
||||
RecordInputStream in = new TestcaseRecordInputStream(EmbeddedObjectRefSubRecord.sid, (short)data.length, data);
|
||||
RecordInputStream in = TestcaseRecordInputStream.create(EmbeddedObjectRefSubRecord.sid, data);
|
||||
|
||||
EmbeddedObjectRefSubRecord rec = new EmbeddedObjectRefSubRecord(in);
|
||||
byte[] ser2 = rec.serialize();
|
||||
|
@ -33,7 +33,7 @@ public final class TestEndSubRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
EndSubRecord record = new EndSubRecord(new TestcaseRecordInputStream((short)0x00, (short)data.length, data));
|
||||
EndSubRecord record = new EndSubRecord(TestcaseRecordInputStream.create(0x00, data));
|
||||
|
||||
assertEquals( 4, record.getRecordSize() );
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public final class TestExtendedFormatRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
ExtendedFormatRecord record = new ExtendedFormatRecord(new TestcaseRecordInputStream((short)0xe0, (short)data.length, data));
|
||||
ExtendedFormatRecord record = new ExtendedFormatRecord(TestcaseRecordInputStream.create(0xe0, data));
|
||||
assertEquals(0, record.getFontIndex());
|
||||
assertEquals(0, record.getFormatIndex());
|
||||
assertEquals(0xF5-256, record.getCellOptions());
|
||||
@ -117,7 +117,7 @@ public final class TestExtendedFormatRecord extends TestCase {
|
||||
}
|
||||
|
||||
public void testCloneOnto() throws Exception {
|
||||
ExtendedFormatRecord base = new ExtendedFormatRecord(new TestcaseRecordInputStream((short)0xe0, (short)data.length, data));
|
||||
ExtendedFormatRecord base = new ExtendedFormatRecord(TestcaseRecordInputStream.create(0xe0, data));
|
||||
|
||||
ExtendedFormatRecord other = new ExtendedFormatRecord();
|
||||
other.cloneStyleFrom(base);
|
||||
|
@ -43,7 +43,7 @@ public final class TestExternalNameRecord extends TestCase {
|
||||
};
|
||||
|
||||
private static ExternalNameRecord createSimpleENR(byte[] data) {
|
||||
return new ExternalNameRecord(new TestcaseRecordInputStream((short)0x0023, data));
|
||||
return new ExternalNameRecord(TestcaseRecordInputStream.create(0x0023, data));
|
||||
}
|
||||
public void testBasicDeserializeReserialize() {
|
||||
|
||||
|
@ -39,7 +39,7 @@ public final class TestFontBasisRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
FontBasisRecord record = new FontBasisRecord(new TestcaseRecordInputStream((short)0x1060, (short)data.length, data));
|
||||
FontBasisRecord record = new FontBasisRecord(TestcaseRecordInputStream.create(0x1060, data));
|
||||
assertEquals( 0x1a28, record.getXBasis());
|
||||
assertEquals( 0x0f9c, record.getYBasis());
|
||||
assertEquals( 0xc8, record.getHeightBasis());
|
||||
|
@ -35,7 +35,7 @@ public final class TestFontIndexRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
FontIndexRecord record = new FontIndexRecord(new TestcaseRecordInputStream((short)0x1026, (short)data.length, data));
|
||||
FontIndexRecord record = new FontIndexRecord(TestcaseRecordInputStream.create(0x1026, data));
|
||||
assertEquals( 5, record.getFontIndex());
|
||||
|
||||
assertEquals( 6, record.getRecordSize() );
|
||||
|
@ -44,7 +44,7 @@ public final class TestFontRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
FontRecord record = new FontRecord(new TestcaseRecordInputStream((short)0x31, (short)data.length, data));
|
||||
FontRecord record = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
|
||||
assertEquals( 0xc8, record.getFontHeight());
|
||||
assertEquals( 0x00, record.getAttributes());
|
||||
assertFalse( record.isItalic());
|
||||
@ -100,7 +100,7 @@ public final class TestFontRecord extends TestCase {
|
||||
}
|
||||
|
||||
public void testCloneOnto() throws Exception {
|
||||
FontRecord base = new FontRecord(new TestcaseRecordInputStream((short)0x31, (short)data.length, data));
|
||||
FontRecord base = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
|
||||
|
||||
FontRecord other = new FontRecord();
|
||||
other.cloneStyleFrom(base);
|
||||
@ -112,8 +112,8 @@ public final class TestFontRecord extends TestCase {
|
||||
}
|
||||
|
||||
public void testSameProperties() throws Exception {
|
||||
FontRecord f1 = new FontRecord(new TestcaseRecordInputStream((short)0x31, (short)data.length, data));
|
||||
FontRecord f2 = new FontRecord(new TestcaseRecordInputStream((short)0x31, (short)data.length, data));
|
||||
FontRecord f1 = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
|
||||
FontRecord f2 = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
|
||||
|
||||
assertTrue(f1.sameProperties(f2));
|
||||
|
||||
|
@ -82,7 +82,7 @@ public final class TestFormulaRecord extends TestCase {
|
||||
|
||||
};
|
||||
|
||||
FormulaRecord record = new FormulaRecord(new TestcaseRecordInputStream(FormulaRecord.sid, (short)29, formulaByte));
|
||||
FormulaRecord record = new FormulaRecord(TestcaseRecordInputStream.create(FormulaRecord.sid, formulaByte));
|
||||
assertEquals("Row", 0, record.getRow());
|
||||
assertEquals("Column", 0, record.getColumn());
|
||||
assertEquals(HSSFCell.CELL_TYPE_ERROR, record.getCachedResultType());
|
||||
@ -108,7 +108,7 @@ public final class TestFormulaRecord extends TestCase {
|
||||
formulaByte[19]=(byte)0xFD;
|
||||
formulaByte[20]=(byte)0x05;
|
||||
formulaByte[22]=(byte)0x01;
|
||||
FormulaRecord record = new FormulaRecord(new TestcaseRecordInputStream(FormulaRecord.sid, (short)27, formulaByte));
|
||||
FormulaRecord record = new FormulaRecord(TestcaseRecordInputStream.create(FormulaRecord.sid, formulaByte));
|
||||
assertEquals("Row", 0, record.getRow());
|
||||
assertEquals("Column", 0, record.getColumn());
|
||||
byte[] output = record.serialize();
|
||||
|
@ -36,7 +36,7 @@ public final class TestFrameRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
FrameRecord record = new FrameRecord(new TestcaseRecordInputStream((short)0x1032, (short)data.length, data));
|
||||
FrameRecord record = new FrameRecord(TestcaseRecordInputStream.create(0x1032, data));
|
||||
assertEquals( FrameRecord.BORDER_TYPE_REGULAR, record.getBorderType());
|
||||
assertEquals( 2, record.getOptions());
|
||||
assertEquals( false, record.isAutoSize() );
|
||||
|
@ -17,7 +17,6 @@
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
@ -28,7 +27,7 @@ import junit.framework.TestCase;
|
||||
* @author Nick Burch
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class TestHyperlinkRecord extends TestCase {
|
||||
public final class TestHyperlinkRecord extends TestCase {
|
||||
|
||||
//link to http://www.lakings.com/
|
||||
byte[] data1 = { 0x02, 0x00, //First row of the hyperlink
|
||||
@ -165,7 +164,7 @@ public class TestHyperlinkRecord extends TestCase {
|
||||
0x00, 0x41, 0x00, 0x31, 0x00, 0x00, 0x00};
|
||||
|
||||
public void testReadURLLink(){
|
||||
RecordInputStream is = new TestcaseRecordInputStream((short)HyperlinkRecord.sid, (short)data1.length, data1);
|
||||
RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data1);
|
||||
HyperlinkRecord link = new HyperlinkRecord(is);
|
||||
assertEquals(2, link.getFirstRow());
|
||||
assertEquals(2, link.getLastRow());
|
||||
@ -184,7 +183,7 @@ public class TestHyperlinkRecord extends TestCase {
|
||||
}
|
||||
|
||||
public void testReadFileLink(){
|
||||
RecordInputStream is = new TestcaseRecordInputStream((short)HyperlinkRecord.sid, (short)data2.length, data2);
|
||||
RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data2);
|
||||
HyperlinkRecord link = new HyperlinkRecord(is);
|
||||
assertEquals(0, link.getFirstRow());
|
||||
assertEquals(0, link.getLastRow());
|
||||
@ -202,7 +201,7 @@ public class TestHyperlinkRecord extends TestCase {
|
||||
}
|
||||
|
||||
public void testReadEmailLink(){
|
||||
RecordInputStream is = new TestcaseRecordInputStream((short)HyperlinkRecord.sid, (short)data3.length, data3);
|
||||
RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data3);
|
||||
HyperlinkRecord link = new HyperlinkRecord(is);
|
||||
assertEquals(1, link.getFirstRow());
|
||||
assertEquals(1, link.getLastRow());
|
||||
@ -220,7 +219,7 @@ public class TestHyperlinkRecord extends TestCase {
|
||||
}
|
||||
|
||||
public void testReadDocumentLink(){
|
||||
RecordInputStream is = new TestcaseRecordInputStream((short)HyperlinkRecord.sid, (short)data4.length, data4);
|
||||
RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data4);
|
||||
HyperlinkRecord link = new HyperlinkRecord(is);
|
||||
assertEquals(3, link.getFirstRow());
|
||||
assertEquals(3, link.getLastRow());
|
||||
@ -237,7 +236,7 @@ public class TestHyperlinkRecord extends TestCase {
|
||||
}
|
||||
|
||||
private void serialize(byte[] data){
|
||||
RecordInputStream is = new TestcaseRecordInputStream((short)HyperlinkRecord.sid, (short)data.length, data);
|
||||
RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data);
|
||||
HyperlinkRecord link = new HyperlinkRecord(is);
|
||||
byte[] bytes1 = link.serialize();
|
||||
is = new RecordInputStream(new ByteArrayInputStream(bytes1));
|
||||
@ -318,7 +317,7 @@ public class TestHyperlinkRecord extends TestCase {
|
||||
public void testClone() throws Exception {
|
||||
byte[][] data = {data1, data2, data3, data4};
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
RecordInputStream is = new TestcaseRecordInputStream((short)HyperlinkRecord.sid, (short)data[i].length, data[i]);
|
||||
RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data[i]);
|
||||
HyperlinkRecord link = new HyperlinkRecord(is);
|
||||
HyperlinkRecord clone = (HyperlinkRecord)link.clone();
|
||||
assertTrue(Arrays.equals(link.serialize(), clone.serialize()));
|
||||
|
@ -17,33 +17,31 @@
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests the serialization and deserialization of the LegendRecord
|
||||
* class works correctly. Test data taken directly from a real
|
||||
* Excel file.
|
||||
* Tests the serialization and deserialization of the LegendRecord class works
|
||||
* correctly. Test data taken directly from a real Excel file.
|
||||
*
|
||||
*
|
||||
|
||||
* @author Andrew C. Oliver (acoliver at apache.org)
|
||||
*/
|
||||
public class TestLegendRecord extends TestCase {
|
||||
byte[] data = new byte[] {
|
||||
(byte)0x76,(byte)0x0E,(byte)0x00,(byte)0x00,(byte)0x86,(byte)0x07,(byte)0x00,(byte)0x00,(byte)0x19,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x8B,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x03,(byte)0x01,(byte)0x1F,(byte)0x00
|
||||
};
|
||||
public final class TestLegendRecord extends TestCase {
|
||||
byte[] data = new byte[] { (byte) 0x76, (byte) 0x0E, (byte) 0x00, (byte) 0x00, (byte) 0x86,
|
||||
(byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0x19, (byte) 0x01, (byte) 0x00,
|
||||
(byte) 0x00, (byte) 0x8B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03,
|
||||
(byte) 0x01, (byte) 0x1F, (byte) 0x00 };
|
||||
|
||||
public void testLoad() {
|
||||
LegendRecord record = new LegendRecord(new TestcaseRecordInputStream((short)0x1015, (short)data.length, data));
|
||||
LegendRecord record = new LegendRecord(TestcaseRecordInputStream.create(0x1015, data));
|
||||
|
||||
assertEquals(0xe76, record.getXAxisUpperLeft());
|
||||
|
||||
assertEquals( (int)0xe76, record.getXAxisUpperLeft());
|
||||
assertEquals(0x786, record.getYAxisUpperLeft());
|
||||
|
||||
assertEquals( (int)0x786, record.getYAxisUpperLeft());
|
||||
assertEquals(0x119, record.getXSize());
|
||||
|
||||
assertEquals( (int)0x119, record.getXSize());
|
||||
|
||||
assertEquals( (int)0x8b, record.getYSize());
|
||||
assertEquals(0x8b, record.getYSize());
|
||||
|
||||
assertEquals((byte) 0x3, record.getType());
|
||||
|
||||
@ -57,23 +55,19 @@ public class TestLegendRecord extends TestCase {
|
||||
assertEquals(true, record.isVertical());
|
||||
assertEquals(false, record.isDataTable());
|
||||
|
||||
|
||||
assertEquals(24, record.getRecordSize());
|
||||
}
|
||||
|
||||
public void testStore()
|
||||
{
|
||||
public void testStore() {
|
||||
LegendRecord record = new LegendRecord();
|
||||
|
||||
record.setXAxisUpperLeft(0xe76);
|
||||
|
||||
record.setYAxisUpperLeft(0x786);
|
||||
|
||||
record.setXAxisUpperLeft( (int)0xe76 );
|
||||
record.setXSize(0x119);
|
||||
|
||||
record.setYAxisUpperLeft( (int)0x786 );
|
||||
|
||||
record.setXSize( (int)0x119 );
|
||||
|
||||
record.setYSize( (int)0x8b );
|
||||
record.setYSize(0x8b);
|
||||
|
||||
record.setType((byte) 0x3);
|
||||
|
||||
@ -87,7 +81,6 @@ public class TestLegendRecord extends TestCase {
|
||||
record.setVertical(true);
|
||||
record.setDataTable(false);
|
||||
|
||||
|
||||
byte[] recordBytes = record.serialize();
|
||||
assertEquals(recordBytes.length - 4, data.length);
|
||||
for (int i = 0; i < data.length; i++)
|
||||
|
@ -28,7 +28,7 @@ import junit.framework.TestCase;
|
||||
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public class TestLineFormatRecord extends TestCase {
|
||||
public final class TestLineFormatRecord extends TestCase {
|
||||
byte[] data = new byte[] {
|
||||
(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, // colour
|
||||
(byte)0x00,(byte)0x00, // pattern
|
||||
@ -38,7 +38,7 @@ public class TestLineFormatRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
LineFormatRecord record = new LineFormatRecord(new TestcaseRecordInputStream((short)0x1007, (short)data.length, data));
|
||||
LineFormatRecord record = new LineFormatRecord(TestcaseRecordInputStream.create(0x1007, data));
|
||||
assertEquals( 0, record.getLineColor());
|
||||
assertEquals( 0, record.getLinePattern());
|
||||
assertEquals( 0, record.getWeight());
|
||||
|
@ -19,9 +19,9 @@ package org.apache.poi.hssf.record;
|
||||
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
||||
|
||||
import java.util.Stack;
|
||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
|
||||
/**
|
||||
* Tests the serialization and deserialization of the LinkedDataRecord
|
||||
@ -157,7 +157,7 @@ recordid = 0x1051, size =8
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
LinkedDataRecord record = new LinkedDataRecord(new TestcaseRecordInputStream((short)0x1051, (short)data.length, data));
|
||||
LinkedDataRecord record = new LinkedDataRecord(TestcaseRecordInputStream.create(0x1051, data));
|
||||
assertEquals( LinkedDataRecord.LINK_TYPE_VALUES, record.getLinkType());
|
||||
assertEquals( LinkedDataRecord.REFERENCE_TYPE_WORKSHEET, record.getReferenceType());
|
||||
assertEquals( 0, record.getOptions());
|
||||
@ -167,7 +167,7 @@ recordid = 0x1051, size =8
|
||||
Area3DPtg ptgExpected = new Area3DPtg(0, 7936, 0, 0,
|
||||
false, false, false, false, 0);
|
||||
|
||||
Object ptgActual = record.getFormulaOfLink().getFormulaTokens().get(0);
|
||||
Object ptgActual = record.getFormulaOfLink().getFormulaTokens()[0];
|
||||
assertEquals(ptgExpected.toString(), ptgActual.toString());
|
||||
|
||||
assertEquals( data.length + 4, record.getRecordSize() );
|
||||
@ -182,10 +182,8 @@ recordid = 0x1051, size =8
|
||||
record.setIndexNumberFmtRecord( (short)0 );
|
||||
Area3DPtg ptg = new Area3DPtg(0, 7936, 0, 0,
|
||||
false, false, false, false, 0);
|
||||
Stack s = new Stack();
|
||||
s.push(ptg);
|
||||
LinkedDataFormulaField formulaOfLink = new LinkedDataFormulaField();
|
||||
formulaOfLink.setFormulaTokens(s);
|
||||
formulaOfLink.setFormulaTokens(new Ptg[] { ptg, });
|
||||
record.setFormulaOfLink(formulaOfLink );
|
||||
|
||||
byte [] recordBytes = record.serialize();
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
@ -25,9 +24,7 @@ import junit.framework.TestCase;
|
||||
*
|
||||
* @author Danny Mui (dmui at apache dot org)
|
||||
*/
|
||||
public class TestNameRecord
|
||||
extends TestCase
|
||||
{
|
||||
public final class TestNameRecord extends TestCase {
|
||||
|
||||
/**
|
||||
* Makes sure that additional name information is parsed properly such as menu/description
|
||||
@ -55,13 +52,11 @@ public class TestNameRecord
|
||||
};
|
||||
|
||||
|
||||
NameRecord name = new NameRecord(new TestcaseRecordInputStream(NameRecord.sid, (short) examples.length, examples));
|
||||
NameRecord name = new NameRecord(TestcaseRecordInputStream.create(NameRecord.sid, examples));
|
||||
String description = name.getDescriptionText();
|
||||
assertNotNull( description );
|
||||
assertTrue( "text contains ALLWOR", description.indexOf( "ALLWOR" ) > 0 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,9 +29,7 @@ import java.util.Arrays;
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class TestNoteRecord
|
||||
extends TestCase
|
||||
{
|
||||
public final class TestNoteRecord extends TestCase {
|
||||
private byte[] data = new byte[] {
|
||||
0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x04, 0x1A, 0x00,
|
||||
0x00, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x20, 0x53, 0x6F,
|
||||
@ -41,7 +39,7 @@ public class TestNoteRecord
|
||||
|
||||
public void testRead() {
|
||||
|
||||
NoteRecord record = new NoteRecord(new TestcaseRecordInputStream(NoteRecord.sid, (short)data.length, data));
|
||||
NoteRecord record = new NoteRecord(TestcaseRecordInputStream.create(NoteRecord.sid, data));
|
||||
|
||||
assertEquals(NoteRecord.sid, record.getSid());
|
||||
assertEquals(6, record.getRow());
|
||||
|
@ -38,7 +38,7 @@ public final class TestNoteStructureSubRecord extends TestCase {
|
||||
|
||||
public void testRead() {
|
||||
|
||||
NoteStructureSubRecord record = new NoteStructureSubRecord(new TestcaseRecordInputStream(NoteStructureSubRecord.sid, (short)data.length, data));
|
||||
NoteStructureSubRecord record = new NoteStructureSubRecord(TestcaseRecordInputStream.create(NoteStructureSubRecord.sid, data));
|
||||
|
||||
assertEquals(NoteStructureSubRecord.sid, record.getSid());
|
||||
assertEquals(data.length + 4, record.getRecordSize());
|
||||
|
@ -35,7 +35,7 @@ public final class TestNumberFormatIndexRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
NumberFormatIndexRecord record = new NumberFormatIndexRecord(new TestcaseRecordInputStream((short)0x104e, (short)data.length, data));
|
||||
NumberFormatIndexRecord record = new NumberFormatIndexRecord(TestcaseRecordInputStream.create(0x104e, data));
|
||||
assertEquals( 5, record.getFormatIndex());
|
||||
|
||||
assertEquals( 6, record.getRecordSize() );
|
||||
|
@ -51,7 +51,7 @@ public final class TestObjRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
ObjRecord record = new ObjRecord(new TestcaseRecordInputStream(ObjRecord.sid, (short)recdata.length, recdata));
|
||||
ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdata));
|
||||
|
||||
assertEquals(28, record.getRecordSize() - 4);
|
||||
|
||||
@ -63,7 +63,7 @@ public final class TestObjRecord extends TestCase {
|
||||
}
|
||||
|
||||
public void testStore() {
|
||||
ObjRecord record = new ObjRecord(new TestcaseRecordInputStream(ObjRecord.sid, (short)recdata.length, recdata));
|
||||
ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdata));
|
||||
|
||||
byte [] recordBytes = record.serialize();
|
||||
assertEquals(28, recordBytes.length - 4);
|
||||
@ -91,7 +91,7 @@ public final class TestObjRecord extends TestCase {
|
||||
byte [] bytes = new byte[recordBytes.length-4];
|
||||
System.arraycopy(recordBytes, 4, bytes, 0, bytes.length);
|
||||
|
||||
record = new ObjRecord(new TestcaseRecordInputStream(ObjRecord.sid, (short)bytes.length, bytes));
|
||||
record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, bytes));
|
||||
List subrecords = record.getSubRecords();
|
||||
assertEquals( 2, subrecords.size() );
|
||||
assertTrue( subrecords.get(0) instanceof CommonObjectDataSubRecord);
|
||||
@ -99,7 +99,7 @@ public final class TestObjRecord extends TestCase {
|
||||
}
|
||||
|
||||
public void testReadWriteWithPadding_bug45133() {
|
||||
ObjRecord record = new ObjRecord(new TestcaseRecordInputStream(ObjRecord.sid, (short)recdataNeedingPadding.length, recdataNeedingPadding));
|
||||
ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdataNeedingPadding));
|
||||
|
||||
if (record.getRecordSize() == 34) {
|
||||
throw new AssertionFailedError("Identified bug 45133");
|
||||
|
@ -34,7 +34,7 @@ public final class TestObjectLinkRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
ObjectLinkRecord record = new ObjectLinkRecord(new TestcaseRecordInputStream((short)0x1027, (short)data.length, data));
|
||||
ObjectLinkRecord record = new ObjectLinkRecord(TestcaseRecordInputStream.create(0x1027, data));
|
||||
|
||||
assertEquals( (short)3, record.getAnchorId());
|
||||
assertEquals( (short)0x00, record.getLink1());
|
||||
|
@ -37,7 +37,7 @@ public final class TestPaneRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
PaneRecord record = new PaneRecord(new TestcaseRecordInputStream((short)0x41, (short)data.length, data));
|
||||
PaneRecord record = new PaneRecord(TestcaseRecordInputStream.create(0x41, data));
|
||||
|
||||
assertEquals( (short)1, record.getX());
|
||||
assertEquals( (short)2, record.getY());
|
||||
|
@ -34,7 +34,7 @@ public final class TestPlotAreaRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
PlotAreaRecord record = new PlotAreaRecord(new TestcaseRecordInputStream((short)0x1035, (short)data.length, data));
|
||||
PlotAreaRecord record = new PlotAreaRecord(TestcaseRecordInputStream.create(0x1035, data));
|
||||
|
||||
assertEquals( 4, record.getRecordSize() );
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public final class TestPlotGrowthRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
PlotGrowthRecord record = new PlotGrowthRecord(new TestcaseRecordInputStream((short)0x1064, (short)data.length, data));
|
||||
PlotGrowthRecord record = new PlotGrowthRecord(TestcaseRecordInputStream.create(0x1064, data));
|
||||
assertEquals( 65536, record.getHorizontalScale());
|
||||
assertEquals( 65536, record.getVerticalScale());
|
||||
|
||||
|
@ -49,7 +49,7 @@ public final class TestRecordFactory extends TestCase {
|
||||
0, 6, 5, 0, -2, 28, -51, 7, -55, 64, 0, 0, 6, 1, 0, 0
|
||||
};
|
||||
short size = 16;
|
||||
Record[] record = RecordFactory.createRecord(new TestcaseRecordInputStream(recType, size, data));
|
||||
Record[] record = RecordFactory.createRecord(TestcaseRecordInputStream.create(recType, data));
|
||||
|
||||
assertEquals(BOFRecord.class.getName(),
|
||||
record[ 0 ].getClass().getName());
|
||||
@ -69,7 +69,7 @@ public final class TestRecordFactory extends TestCase {
|
||||
{
|
||||
0, 0
|
||||
};
|
||||
record = RecordFactory.createRecord(new TestcaseRecordInputStream(recType, size, data));
|
||||
record = RecordFactory.createRecord(TestcaseRecordInputStream.create(recType, data));
|
||||
assertEquals(MMSRecord.class.getName(),
|
||||
record[ 0 ].getClass().getName());
|
||||
MMSRecord mmsRecord = ( MMSRecord ) record[ 0 ];
|
||||
@ -94,7 +94,7 @@ public final class TestRecordFactory extends TestCase {
|
||||
0, 0, 0, 0, 21, 0, 0, 0, 0, 0
|
||||
};
|
||||
short size = 10;
|
||||
Record[] record = RecordFactory.createRecord(new TestcaseRecordInputStream(recType, size, data));
|
||||
Record[] record = RecordFactory.createRecord(TestcaseRecordInputStream.create(recType, data));
|
||||
|
||||
assertEquals(NumberRecord.class.getName(),
|
||||
record[ 0 ].getClass().getName());
|
||||
|
@ -0,0 +1,97 @@
|
||||
/* ====================================================================
|
||||
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.hssf.record;
|
||||
|
||||
import org.apache.poi.util.HexRead;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for {@link RecordInputStream}
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public final class TestRecordInputStream extends TestCase {
|
||||
|
||||
/**
|
||||
* Data inspired by attachment 22626 of bug 45866<br/>
|
||||
* A unicode string of 18 chars, with a continue record where the compression flag changes
|
||||
*/
|
||||
private static final String HED_DUMP1 = ""
|
||||
+ "1A 59 00 8A 9E 8A " // 3 uncompressed unicode chars
|
||||
+ "3C 00 " // Continue sid
|
||||
+ "10 00 " // rec size 16 (1+15)
|
||||
+ "00" // next chunk is compressed
|
||||
+ "20 2D 20 4D 75 6C 74 69 6C 69 6E 67 75 61 6C " // 15 chars
|
||||
;
|
||||
/**
|
||||
* same string re-arranged
|
||||
*/
|
||||
private static final String HED_DUMP2 = ""
|
||||
// 15 chars at end of current record
|
||||
+ "4D 75 6C 74 69 6C 69 6E 67 75 61 6C 20 2D 20"
|
||||
+ "3C 00 " // Continue sid
|
||||
+ "07 00 " // rec size 7 (1+6)
|
||||
+ "01" // this bit uncompressed
|
||||
+ "1A 59 00 8A 9E 8A " // 3 uncompressed unicode chars
|
||||
;
|
||||
public void testChangeOfCompressionFlag_bug25866() {
|
||||
byte[] changingFlagSimpleData = HexRead.readFromString(""
|
||||
+ "AA AA " // fake SID
|
||||
+ "06 00 " // first rec len 6
|
||||
+ HED_DUMP1
|
||||
);
|
||||
RecordInputStream in = TestcaseRecordInputStream.create(changingFlagSimpleData);
|
||||
String actual;
|
||||
try {
|
||||
actual = in.readUnicodeLEString(18);
|
||||
} catch (IllegalArgumentException e) {
|
||||
if ("compressByte in continue records must be 1 while reading unicode LE string".equals(e.getMessage())) {
|
||||
throw new AssertionFailedError("Identified bug 45866");
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
assertEquals("\u591A\u8A00\u8A9E - Multilingual", actual);
|
||||
}
|
||||
|
||||
public void testChangeFromUnCompressedToCompressed() {
|
||||
byte[] changingFlagSimpleData = HexRead.readFromString(""
|
||||
+ "AA AA " // fake SID
|
||||
+ "0F 00 " // first rec len 15
|
||||
+ HED_DUMP2
|
||||
);
|
||||
RecordInputStream in = TestcaseRecordInputStream.create(changingFlagSimpleData);
|
||||
String actual = in.readCompressedUnicode(18);
|
||||
assertEquals("Multilingual - \u591A\u8A00\u8A9E", actual);
|
||||
}
|
||||
|
||||
public void testReadString() {
|
||||
byte[] changingFlagFullData = HexRead.readFromString(""
|
||||
+ "AA AA " // fake SID
|
||||
+ "12 00 " // first rec len 18 (15 + next 3 bytes)
|
||||
+ "12 00 " // total chars 18
|
||||
+ "00 " // this bit compressed
|
||||
+ HED_DUMP2
|
||||
);
|
||||
RecordInputStream in = TestcaseRecordInputStream.create(changingFlagFullData);
|
||||
String actual = in.readString();
|
||||
assertEquals("Multilingual - \u591A\u8A00\u8A9E", actual);
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@ public final class TestSCLRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
SCLRecord record = new SCLRecord(new TestcaseRecordInputStream((short)0xa0, (short)data.length, data));
|
||||
SCLRecord record = new SCLRecord(TestcaseRecordInputStream.create(0xa0, data));
|
||||
assertEquals( 3, record.getNumerator());
|
||||
assertEquals( 4, record.getDenominator());
|
||||
|
||||
|
@ -32,31 +32,30 @@ import org.apache.poi.util.IntMapper;
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public final class TestSSTDeserializer extends TestCase {
|
||||
private static final int FAKE_SID = -5555;
|
||||
|
||||
|
||||
private byte[] joinArray(byte[] array1, byte[] array2) {
|
||||
byte[] bigArray = new byte[array1.length + array2.length];
|
||||
System.arraycopy(array1, 0, bigArray, 0, array1.length);
|
||||
System.arraycopy(array2, 0, bigArray, array1.length, array2.length);
|
||||
return bigArray;
|
||||
private static byte[] concat(byte[] a, byte[] b) {
|
||||
byte[] result = new byte[a.length + b.length];
|
||||
System.arraycopy(a, 0, result, 0, a.length);
|
||||
System.arraycopy(b, 0, result, a.length, b.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] readSampleHexData(String sampleFileName, String sectionName) {
|
||||
private static byte[] readSampleHexData(String sampleFileName, String sectionName, int recSid) {
|
||||
InputStream is = HSSFTestDataSamples.openSampleFileStream(sampleFileName);
|
||||
byte[] data;
|
||||
try {
|
||||
return HexRead.readData(is, sectionName);
|
||||
data = HexRead.readData(is, sectionName);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return TestcaseRecordInputStream.mergeDataAndSid(recSid, data.length, data);
|
||||
}
|
||||
|
||||
public void testSpanRichTextToPlainText()
|
||||
throws Exception
|
||||
{
|
||||
byte[] header = readSampleHexData("richtextdata.txt", "header" );
|
||||
byte[] continueBytes = readSampleHexData("richtextdata.txt", "continue1" );
|
||||
continueBytes = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continueBytes.length, continueBytes);
|
||||
TestcaseRecordInputStream in = new TestcaseRecordInputStream((short)0, (short)header.length, joinArray(header, continueBytes));
|
||||
public void testSpanRichTextToPlainText() {
|
||||
byte[] header = readSampleHexData("richtextdata.txt", "header", FAKE_SID);
|
||||
byte[] continueBytes = readSampleHexData("richtextdata.txt", "continue1", ContinueRecord.sid);
|
||||
RecordInputStream in = TestcaseRecordInputStream.create(concat(header, continueBytes));
|
||||
|
||||
|
||||
IntMapper strings = new IntMapper();
|
||||
@ -66,13 +65,10 @@ public final class TestSSTDeserializer extends TestCase {
|
||||
assertEquals( "At a dinner party orAt At At ", strings.get( 0 ) + "" );
|
||||
}
|
||||
|
||||
public void testContinuationWithNoOverlap()
|
||||
throws Exception
|
||||
{
|
||||
byte[] header = readSampleHexData("evencontinuation.txt", "header" );
|
||||
byte[] continueBytes = readSampleHexData("evencontinuation.txt", "continue1" );
|
||||
continueBytes = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continueBytes.length, continueBytes);
|
||||
TestcaseRecordInputStream in = new TestcaseRecordInputStream((short)0, (short)header.length, joinArray(header, continueBytes));
|
||||
public void testContinuationWithNoOverlap() {
|
||||
byte[] header = readSampleHexData("evencontinuation.txt", "header", FAKE_SID);
|
||||
byte[] continueBytes = readSampleHexData("evencontinuation.txt", "continue1", ContinueRecord.sid);
|
||||
RecordInputStream in = TestcaseRecordInputStream.create(concat(header, continueBytes));
|
||||
|
||||
IntMapper strings = new IntMapper();
|
||||
SSTDeserializer deserializer = new SSTDeserializer( strings );
|
||||
@ -85,18 +81,12 @@ public final class TestSSTDeserializer extends TestCase {
|
||||
/**
|
||||
* Strings can actually span across more than one continuation.
|
||||
*/
|
||||
public void testStringAcross2Continuations()
|
||||
throws Exception
|
||||
{
|
||||
byte[] header = readSampleHexData("stringacross2continuations.txt", "header" );
|
||||
byte[] continue1 = readSampleHexData("stringacross2continuations.txt", "continue1" );
|
||||
continue1 = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continue1.length, continue1);
|
||||
byte[] continue2 = readSampleHexData("stringacross2continuations.txt", "continue2" );
|
||||
continue2 = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continue2.length, continue2);
|
||||
public void testStringAcross2Continuations() {
|
||||
byte[] header = readSampleHexData("stringacross2continuations.txt", "header", FAKE_SID);
|
||||
byte[] continue1 = readSampleHexData("stringacross2continuations.txt", "continue1", ContinueRecord.sid);
|
||||
byte[] continue2 = readSampleHexData("stringacross2continuations.txt", "continue2", ContinueRecord.sid);
|
||||
|
||||
byte[] bytes = joinArray(header, continue1);
|
||||
bytes = joinArray(bytes, continue2);
|
||||
TestcaseRecordInputStream in = new TestcaseRecordInputStream((short)0, (short)header.length, bytes);
|
||||
RecordInputStream in = TestcaseRecordInputStream.create(concat(header, concat(continue1, continue2)));
|
||||
|
||||
IntMapper strings = new IntMapper();
|
||||
SSTDeserializer deserializer = new SSTDeserializer( strings );
|
||||
@ -107,10 +97,9 @@ public final class TestSSTDeserializer extends TestCase {
|
||||
}
|
||||
|
||||
public void testExtendedStrings() {
|
||||
byte[] header = readSampleHexData("extendedtextstrings.txt", "rich-header" );
|
||||
byte[] continueBytes = readSampleHexData("extendedtextstrings.txt", "rich-continue1" );
|
||||
continueBytes = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continueBytes.length, continueBytes);
|
||||
TestcaseRecordInputStream in = new TestcaseRecordInputStream((short)0, (short)header.length, joinArray(header, continueBytes));
|
||||
byte[] header = readSampleHexData("extendedtextstrings.txt", "rich-header", FAKE_SID);
|
||||
byte[] continueBytes = readSampleHexData("extendedtextstrings.txt", "rich-continue1", ContinueRecord.sid);
|
||||
RecordInputStream in = TestcaseRecordInputStream.create(concat(header, continueBytes));
|
||||
|
||||
IntMapper strings = new IntMapper();
|
||||
SSTDeserializer deserializer = new SSTDeserializer( strings );
|
||||
@ -119,10 +108,9 @@ public final class TestSSTDeserializer extends TestCase {
|
||||
assertEquals( "At a dinner party orAt At At ", strings.get( 0 ) + "" );
|
||||
|
||||
|
||||
header = readSampleHexData("extendedtextstrings.txt", "norich-header" );
|
||||
continueBytes = readSampleHexData("extendedtextstrings.txt", "norich-continue1" );
|
||||
continueBytes = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continueBytes.length, continueBytes);
|
||||
in = new TestcaseRecordInputStream((short)0, (short)header.length, joinArray(header, continueBytes));
|
||||
header = readSampleHexData("extendedtextstrings.txt", "norich-header", FAKE_SID);
|
||||
continueBytes = readSampleHexData("extendedtextstrings.txt", "norich-continue1", ContinueRecord.sid);
|
||||
in = TestcaseRecordInputStream.create(concat(header, continueBytes));
|
||||
|
||||
strings = new IntMapper();
|
||||
deserializer = new SSTDeserializer( strings );
|
||||
|
@ -33,7 +33,7 @@ public final class TestSeriesChartGroupIndexRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
SeriesChartGroupIndexRecord record = new SeriesChartGroupIndexRecord(new TestcaseRecordInputStream((short)0x1045, (short)data.length, data));
|
||||
SeriesChartGroupIndexRecord record = new SeriesChartGroupIndexRecord(TestcaseRecordInputStream.create(0x1045, data));
|
||||
assertEquals( 0, record.getChartGroupIndex());
|
||||
|
||||
assertEquals( 6, record.getRecordSize() );
|
||||
|
@ -34,7 +34,7 @@ public final class TestSeriesIndexRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
SeriesIndexRecord record = new SeriesIndexRecord(new TestcaseRecordInputStream((short)0x1065, (short)data.length, data));
|
||||
SeriesIndexRecord record = new SeriesIndexRecord(TestcaseRecordInputStream.create(0x1065, data));
|
||||
|
||||
assertEquals( (short)3, record.getIndex());
|
||||
assertEquals( 6, record.getRecordSize() );
|
||||
|
@ -34,7 +34,7 @@ public final class TestSeriesLabelsRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
SeriesLabelsRecord record = new SeriesLabelsRecord(new TestcaseRecordInputStream((short)0x100c, (short)data.length, data));
|
||||
SeriesLabelsRecord record = new SeriesLabelsRecord(TestcaseRecordInputStream.create(0x100c, data));
|
||||
assertEquals( 3, record.getFormatFlags());
|
||||
assertEquals( true, record.isShowActual() );
|
||||
assertEquals( true, record.isShowPercent() );
|
||||
|
@ -35,7 +35,7 @@ public final class TestSeriesListRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
SeriesListRecord record = new SeriesListRecord(new TestcaseRecordInputStream((short)0x1016, (short)data.length, data));
|
||||
SeriesListRecord record = new SeriesListRecord(TestcaseRecordInputStream.create(0x1016, data));
|
||||
assertEquals( (short)0x2001, record.getSeriesNumbers()[0]);
|
||||
assertEquals( (short)0xf0ff, record.getSeriesNumbers()[1]);
|
||||
assertEquals( 2, record.getSeriesNumbers().length);
|
||||
|
@ -39,7 +39,7 @@ public final class TestSeriesRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
SeriesRecord record = new SeriesRecord(new TestcaseRecordInputStream((short)0x1003, (short)data.length, data));
|
||||
SeriesRecord record = new SeriesRecord(TestcaseRecordInputStream.create(0x1003, data));
|
||||
assertEquals( SeriesRecord.CATEGORY_DATA_TYPE_NUMERIC, record.getCategoryDataType());
|
||||
assertEquals( SeriesRecord.VALUES_DATA_TYPE_NUMERIC, record.getValuesDataType());
|
||||
assertEquals( 27, record.getNumCategories());
|
||||
|
@ -34,7 +34,7 @@ public final class TestSeriesTextRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
SeriesTextRecord record = new SeriesTextRecord(new TestcaseRecordInputStream((short)0x100d, (short)data.length, data));
|
||||
SeriesTextRecord record = new SeriesTextRecord(TestcaseRecordInputStream.create(0x100d, data));
|
||||
|
||||
assertEquals( (short)0, record.getId());
|
||||
assertEquals( (byte)0x0C, record.getTextLength());
|
||||
|
@ -34,7 +34,7 @@ public final class TestSeriesToChartGroupRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
SeriesToChartGroupRecord record = new SeriesToChartGroupRecord(new TestcaseRecordInputStream((short)0x1045, (short)data.length, data));
|
||||
SeriesToChartGroupRecord record = new SeriesToChartGroupRecord(TestcaseRecordInputStream.create(0x1045, data));
|
||||
assertEquals( 0x0, record.getChartGroupIndex());
|
||||
|
||||
assertEquals( 0x6, record.getRecordSize() );
|
||||
|
@ -59,7 +59,7 @@ public final class TestSharedFormulaRecord extends TestCase {
|
||||
*/
|
||||
public void testConvertSharedFormulasOperandClasses_bug45123() {
|
||||
|
||||
TestcaseRecordInputStream in = new TestcaseRecordInputStream(0, SHARED_FORMULA_WITH_REF_ARRAYS_DATA);
|
||||
RecordInputStream in = TestcaseRecordInputStream.createWithFakeSid(SHARED_FORMULA_WITH_REF_ARRAYS_DATA);
|
||||
int encodedLen = in.readUShort();
|
||||
Ptg[] sharedFormula = Ptg.readTokens(encodedLen, in);
|
||||
|
||||
|
@ -36,7 +36,7 @@ public final class TestSheetPropertiesRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
SheetPropertiesRecord record = new SheetPropertiesRecord(new TestcaseRecordInputStream((short)0x1044, (short)data.length, data));
|
||||
SheetPropertiesRecord record = new SheetPropertiesRecord(TestcaseRecordInputStream.create(0x1044, data));
|
||||
assertEquals( 10, record.getFlags());
|
||||
assertEquals( false, record.isChartTypeManuallyFormatted() );
|
||||
assertEquals( true, record.isPlotVisibleOnly() );
|
||||
|
@ -27,7 +27,7 @@ import junit.framework.TestCase;
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public class TestStringRecord extends TestCase {
|
||||
public final class TestStringRecord extends TestCase {
|
||||
byte[] data = new byte[] {
|
||||
(byte)0x0B,(byte)0x00, // length
|
||||
(byte)0x00, // option
|
||||
@ -37,7 +37,7 @@ public class TestStringRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
StringRecord record = new StringRecord(new TestcaseRecordInputStream((short)0x207, (short)data.length, data));
|
||||
StringRecord record = new StringRecord(TestcaseRecordInputStream.create(0x207, data));
|
||||
assertEquals( "Fahrzeugtyp", record.getString());
|
||||
|
||||
assertEquals( 18, record.getRecordSize() );
|
||||
|
@ -51,7 +51,7 @@ public final class TestSupBookRecord extends TestCase {
|
||||
*/
|
||||
public void testLoadIR() {
|
||||
|
||||
SupBookRecord record = new SupBookRecord(new TestcaseRecordInputStream((short)0x01AE, dataIR));
|
||||
SupBookRecord record = new SupBookRecord(TestcaseRecordInputStream.create(0x01AE, dataIR));
|
||||
assertTrue( record.isInternalReferences() ); //expected flag
|
||||
assertEquals( 0x4, record.getNumberOfSheets() ); //expected # of sheets
|
||||
|
||||
@ -62,7 +62,7 @@ public final class TestSupBookRecord extends TestCase {
|
||||
*/
|
||||
public void testLoadER() {
|
||||
|
||||
SupBookRecord record = new SupBookRecord(new TestcaseRecordInputStream((short)0x01AE, dataER));
|
||||
SupBookRecord record = new SupBookRecord(TestcaseRecordInputStream.create(0x01AE, dataER));
|
||||
assertTrue( record.isExternalReferences() ); //expected flag
|
||||
assertEquals( 0x2, record.getNumberOfSheets() ); //expected # of sheets
|
||||
|
||||
@ -80,7 +80,7 @@ public final class TestSupBookRecord extends TestCase {
|
||||
*/
|
||||
public void testLoadAIF() {
|
||||
|
||||
SupBookRecord record = new SupBookRecord(new TestcaseRecordInputStream((short)0x01AE, dataAIF));
|
||||
SupBookRecord record = new SupBookRecord(TestcaseRecordInputStream.create(0x01AE, dataAIF));
|
||||
assertTrue( record.isAddInFunctions() ); //expected flag
|
||||
assertEquals( 0x1, record.getNumberOfSheets() ); //expected # of sheets
|
||||
assertEquals( 8, record.getRecordSize() ); //sid+size+data
|
||||
|
@ -44,7 +44,7 @@ public final class TestTableRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
TableRecord record = new TableRecord(new TestcaseRecordInputStream((short)0x236, (short)data.length, data));
|
||||
TableRecord record = new TableRecord(TestcaseRecordInputStream.create(0x236, data));
|
||||
|
||||
CellRangeAddress8Bit range = record.getRange();
|
||||
assertEquals(3, range.getFirstRow());
|
||||
|
@ -18,6 +18,11 @@
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
|
||||
import org.apache.poi.util.HexRead;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
@ -25,63 +30,62 @@ import junit.framework.TestCase;
|
||||
* class works correctly. Test data taken directly from a real
|
||||
* Excel file.
|
||||
*
|
||||
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public class TestTextObjectBaseRecord extends TestCase {
|
||||
byte[] data = new byte[] {
|
||||
0x44, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
};
|
||||
public final class TestTextObjectBaseRecord extends TestCase {
|
||||
/** data for one TXO rec and two continue recs */
|
||||
private static final byte[] data = HexRead.readFromString(
|
||||
"B6 01 " + // TextObjectRecord.sid
|
||||
"12 00 " + // size 18
|
||||
"44 02 02 00 00 00 00 00" +
|
||||
"00 00 " +
|
||||
"02 00 " + // strLen 2
|
||||
"10 00 " + // 16 bytes for 2 format runs
|
||||
"00 00" +
|
||||
"00 00 " +
|
||||
"3C 00 " + // ContinueRecord.sid
|
||||
"05 00 " + // size 5
|
||||
"01 " + // unicode uncompressed
|
||||
"41 00 42 00 " + // 'AB'
|
||||
"3C 00 " + // ContinueRecord.sid
|
||||
"10 00 " + // size 16
|
||||
"00 00 18 00 00 00 00 00 " +
|
||||
"02 00 00 00 00 00 00 00 "
|
||||
);
|
||||
|
||||
|
||||
public void testLoad() {
|
||||
TextObjectBaseRecord record = new TextObjectBaseRecord(new TestcaseRecordInputStream((short)0x1B6, (short)data.length, data));
|
||||
RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(data));
|
||||
in.nextRecord();
|
||||
TextObjectRecord record = new TextObjectRecord(in);
|
||||
|
||||
|
||||
// assertEquals( (short), record.getOptions());
|
||||
assertEquals( false, record.isReserved1() );
|
||||
assertEquals( TextObjectBaseRecord.HORIZONTAL_TEXT_ALIGNMENT_CENTERED, record.getHorizontalTextAlignment() );
|
||||
assertEquals( TextObjectBaseRecord.VERTICAL_TEXT_ALIGNMENT_JUSTIFY, record.getVerticalTextAlignment() );
|
||||
assertEquals( 0, record.getReserved2() );
|
||||
assertEquals(TextObjectRecord.HORIZONTAL_TEXT_ALIGNMENT_CENTERED, record.getHorizontalTextAlignment());
|
||||
assertEquals(TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_JUSTIFY, record.getVerticalTextAlignment());
|
||||
assertEquals(true, record.isTextLocked());
|
||||
assertEquals( 0, record.getReserved3() );
|
||||
assertEquals( TextObjectBaseRecord.TEXT_ORIENTATION_ROT_RIGHT, record.getTextOrientation());
|
||||
assertEquals( 0, record.getReserved4());
|
||||
assertEquals( 0, record.getReserved5());
|
||||
assertEquals( 0, record.getReserved6());
|
||||
assertEquals( 2, record.getTextLength());
|
||||
assertEquals( 2, record.getFormattingRunLength());
|
||||
assertEquals( 0, record.getReserved7());
|
||||
assertEquals(TextObjectRecord.TEXT_ORIENTATION_ROT_RIGHT, record.getTextOrientation());
|
||||
|
||||
|
||||
assertEquals( 22, record.getRecordSize() );
|
||||
assertEquals(51, record.getRecordSize() );
|
||||
}
|
||||
|
||||
public void testStore()
|
||||
{
|
||||
TextObjectBaseRecord record = new TextObjectBaseRecord();
|
||||
TextObjectRecord record = new TextObjectRecord();
|
||||
|
||||
|
||||
HSSFRichTextString str = new HSSFRichTextString("AB");
|
||||
str.applyFont(0, 2, (short)0x0018);
|
||||
str.applyFont(2, 2, (short)0x0320);
|
||||
|
||||
// record.setOptions( (short) 0x0000);
|
||||
record.setReserved1( false );
|
||||
record.setHorizontalTextAlignment( TextObjectBaseRecord.HORIZONTAL_TEXT_ALIGNMENT_CENTERED );
|
||||
record.setVerticalTextAlignment( TextObjectBaseRecord.VERTICAL_TEXT_ALIGNMENT_JUSTIFY );
|
||||
record.setReserved2( (short)0 );
|
||||
record.setHorizontalTextAlignment(TextObjectRecord.HORIZONTAL_TEXT_ALIGNMENT_CENTERED);
|
||||
record.setVerticalTextAlignment(TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_JUSTIFY);
|
||||
record.setTextLocked(true);
|
||||
record.setReserved3( (short)0 );
|
||||
record.setTextOrientation( TextObjectBaseRecord.TEXT_ORIENTATION_ROT_RIGHT );
|
||||
record.setReserved4( (short)0 );
|
||||
record.setReserved5( (short)0 );
|
||||
record.setReserved6( (short)0 );
|
||||
record.setTextLength( (short)2 );
|
||||
record.setFormattingRunLength( (short)2 );
|
||||
record.setReserved7( 0 );
|
||||
record.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_ROT_RIGHT);
|
||||
record.setStr(str);
|
||||
|
||||
byte [] recordBytes = record.serialize();
|
||||
assertEquals(recordBytes.length - 4, data.length);
|
||||
assertEquals(recordBytes.length, data.length);
|
||||
for (int i = 0; i < data.length; i++)
|
||||
assertEquals("At offset " + i, data[i], recordBytes[i+4]);
|
||||
assertEquals("At offset " + i, data[i], recordBytes[i]);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,11 @@ import java.util.Arrays;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.record.formula.RefPtg;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
|
||||
import org.apache.poi.util.HexRead;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* Tests that serialization and deserialization of the TextObjectRecord .
|
||||
@ -32,17 +36,23 @@ import org.apache.poi.hssf.usermodel.HSSFRichTextString;
|
||||
*/
|
||||
public final class TestTextObjectRecord extends TestCase {
|
||||
|
||||
byte[] data = {(byte)0xB6, 0x01, 0x12, 0x00, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3C, 0x00, 0x1B, 0x00, 0x01, 0x48, 0x00, 0x65, 0x00, 0x6C,
|
||||
0x00, 0x6C, 0x00, 0x6F, 0x00, 0x2C, 0x00, 0x20, 0x00, 0x57, 0x00,
|
||||
0x6F, 0x00, 0x72, 0x00, 0x6C, 0x00, 0x64, 0x00, 0x21, 0x00, 0x3C,
|
||||
0x00, 0x08, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
private static final byte[] simpleData = HexRead.readFromString(
|
||||
"B6 01 12 00 " +
|
||||
"12 02 00 00 00 00 00 00" +
|
||||
"00 00 0D 00 08 00 00 00" +
|
||||
"00 00 " +
|
||||
"3C 00 1B 00 " +
|
||||
"01 48 00 65 00 6C 00 6C 00 6F 00 " +
|
||||
"2C 00 20 00 57 00 6F 00 72 00 6C " +
|
||||
"00 64 00 21 00 " +
|
||||
"3C 00 08 " +
|
||||
"00 0D 00 00 00 00 00 00 00"
|
||||
);
|
||||
|
||||
|
||||
public void testRead() {
|
||||
|
||||
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(data));
|
||||
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(simpleData));
|
||||
is.nextRecord();
|
||||
TextObjectRecord record = new TextObjectRecord(is);
|
||||
|
||||
@ -50,36 +60,51 @@ public final class TestTextObjectRecord extends TestCase {
|
||||
assertEquals(TextObjectRecord.HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED, record.getHorizontalTextAlignment());
|
||||
assertEquals(TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_TOP, record.getVerticalTextAlignment());
|
||||
assertEquals(TextObjectRecord.TEXT_ORIENTATION_NONE, record.getTextOrientation());
|
||||
assertEquals(0, record.getReserved7());
|
||||
assertEquals("Hello, World!", record.getStr().getString());
|
||||
|
||||
}
|
||||
|
||||
public void testWrite()
|
||||
{
|
||||
public void testWrite() {
|
||||
HSSFRichTextString str = new HSSFRichTextString("Hello, World!");
|
||||
|
||||
TextObjectRecord record = new TextObjectRecord();
|
||||
int frLength = ( str.numFormattingRuns() + 1 ) * 8;
|
||||
record.setFormattingRunLength( (short) frLength );
|
||||
record.setTextLength( (short) str.length() );
|
||||
record.setStr(str);
|
||||
record.setHorizontalTextAlignment( TextObjectRecord.HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED );
|
||||
record.setVerticalTextAlignment( TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_TOP );
|
||||
record.setTextLocked( true );
|
||||
record.setTextOrientation( TextObjectRecord.TEXT_ORIENTATION_NONE );
|
||||
record.setReserved7( 0 );
|
||||
|
||||
byte [] ser = record.serialize();
|
||||
//assertEquals(ser.length , data.length);
|
||||
assertEquals(ser.length , simpleData.length);
|
||||
|
||||
//assertTrue(Arrays.equals(data, ser));
|
||||
assertTrue(Arrays.equals(simpleData, ser));
|
||||
|
||||
//read again
|
||||
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(data));
|
||||
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(simpleData));
|
||||
is.nextRecord();
|
||||
record = new TextObjectRecord(is);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero {@link ContinueRecord}s follow a {@link TextObjectRecord} if the text is empty
|
||||
*/
|
||||
public void testWriteEmpty() {
|
||||
HSSFRichTextString str = new HSSFRichTextString("");
|
||||
|
||||
TextObjectRecord record = new TextObjectRecord();
|
||||
record.setStr(str);
|
||||
|
||||
byte [] ser = record.serialize();
|
||||
|
||||
int formatDataLen = LittleEndian.getUShort(ser, 16);
|
||||
assertEquals("formatDataLength", 0, formatDataLen);
|
||||
|
||||
assertEquals(22, ser.length); // just the TXO record
|
||||
|
||||
//read again
|
||||
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(ser));
|
||||
is.nextRecord();
|
||||
record = new TextObjectRecord(is);
|
||||
assertEquals(0, record.getStr().length());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,9 +120,6 @@ public final class TestTextObjectRecord extends TestCase {
|
||||
HSSFRichTextString str = new HSSFRichTextString(buff.toString());
|
||||
|
||||
TextObjectRecord obj = new TextObjectRecord();
|
||||
int frLength = ( str.numFormattingRuns() + 1 ) * 8;
|
||||
obj.setFormattingRunLength( (short) frLength );
|
||||
obj.setTextLength( (short) str.length() );
|
||||
obj.setStr(str);
|
||||
|
||||
byte [] data = obj.serialize();
|
||||
@ -120,30 +142,12 @@ public final class TestTextObjectRecord extends TestCase {
|
||||
HSSFRichTextString str = new HSSFRichTextString(text);
|
||||
|
||||
TextObjectRecord obj = new TextObjectRecord();
|
||||
int frLength = ( str.numFormattingRuns() + 1 ) * 8;
|
||||
obj.setFormattingRunLength( (short) frLength );
|
||||
obj.setTextLength( (short) str.length() );
|
||||
obj.setReserved1(true);
|
||||
obj.setReserved2((short)2);
|
||||
obj.setReserved3((short)3);
|
||||
obj.setReserved4((short)4);
|
||||
obj.setReserved5((short)5);
|
||||
obj.setReserved6((short)6);
|
||||
obj.setReserved7((short)7);
|
||||
obj.setStr( str );
|
||||
|
||||
|
||||
TextObjectRecord cloned = (TextObjectRecord)obj.clone();
|
||||
assertEquals(obj.getReserved2(), cloned.getReserved2());
|
||||
assertEquals(obj.getReserved3(), cloned.getReserved3());
|
||||
assertEquals(obj.getReserved4(), cloned.getReserved4());
|
||||
assertEquals(obj.getReserved5(), cloned.getReserved5());
|
||||
assertEquals(obj.getReserved6(), cloned.getReserved6());
|
||||
assertEquals(obj.getReserved7(), cloned.getReserved7());
|
||||
assertEquals(obj.getRecordSize(), cloned.getRecordSize());
|
||||
assertEquals(obj.getOptions(), cloned.getOptions());
|
||||
assertEquals(obj.getHorizontalTextAlignment(), cloned.getHorizontalTextAlignment());
|
||||
assertEquals(obj.getFormattingRunLength(), cloned.getFormattingRunLength());
|
||||
assertEquals(obj.getStr().getString(), cloned.getStr().getString());
|
||||
|
||||
//finally check that the serialized data is the same
|
||||
@ -151,4 +155,47 @@ public final class TestTextObjectRecord extends TestCase {
|
||||
byte[] cln = cloned.serialize();
|
||||
assertTrue(Arrays.equals(src, cln));
|
||||
}
|
||||
|
||||
/** similar to {@link #simpleData} but with link formula at end of TXO rec*/
|
||||
private static final byte[] linkData = HexRead.readFromString(
|
||||
"B6 01 " + // TextObjectRecord.sid
|
||||
"1E 00 " + // size 18
|
||||
"44 02 02 00 00 00 00 00" +
|
||||
"00 00 " +
|
||||
"02 00 " + // strLen 2
|
||||
"10 00 " + // 16 bytes for 2 format runs
|
||||
"00 00 00 00 " +
|
||||
|
||||
"05 00 " + // formula size
|
||||
"D4 F0 8A 03 " + // unknownInt
|
||||
"24 01 00 13 C0 " + //tRef(T2)
|
||||
"13 " + // ??
|
||||
|
||||
"3C 00 " + // ContinueRecord.sid
|
||||
"05 00 " + // size 5
|
||||
"01 " + // unicode uncompressed
|
||||
"41 00 42 00 " + // 'AB'
|
||||
"3C 00 " + // ContinueRecord.sid
|
||||
"10 00 " + // size 16
|
||||
"00 00 18 00 00 00 00 00 " +
|
||||
"02 00 00 00 00 00 00 00 "
|
||||
);
|
||||
|
||||
|
||||
public void testLinkFormula() {
|
||||
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(linkData));
|
||||
is.nextRecord();
|
||||
TextObjectRecord rec = new TextObjectRecord(is);
|
||||
|
||||
Ptg ptg = rec.getLinkRefPtg();
|
||||
assertNotNull(ptg);
|
||||
assertEquals(RefPtg.class, ptg.getClass());
|
||||
RefPtg rptg = (RefPtg) ptg;
|
||||
assertEquals("T2", rptg.toFormulaString());
|
||||
|
||||
byte [] data2 = rec.serialize();
|
||||
assertEquals(linkData.length, data2.length);
|
||||
assertTrue(Arrays.equals(linkData, data2));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ import junit.framework.TestCase;
|
||||
*
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
*/
|
||||
public class TestTextRecord extends TestCase {
|
||||
public final class TestTextRecord extends TestCase {
|
||||
byte[] data = new byte[] {
|
||||
(byte)0x02, // horiz align
|
||||
(byte)0x02, // vert align
|
||||
@ -45,7 +45,7 @@ public class TestTextRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
TextRecord record = new TextRecord(new TestcaseRecordInputStream((short)0x1025, (short)data.length, data));
|
||||
TextRecord record = new TextRecord(TestcaseRecordInputStream.create(0x1025, data));
|
||||
assertEquals( TextRecord.HORIZONTAL_ALIGNMENT_CENTER, record.getHorizontalAlignment());
|
||||
assertEquals( TextRecord.VERTICAL_ALIGNMENT_CENTER, record.getVerticalAlignment());
|
||||
assertEquals( TextRecord.DISPLAY_MODE_TRANSPARENT, record.getDisplayMode());
|
||||
|
@ -40,7 +40,7 @@ public final class TestTickRecord extends TestCase {
|
||||
};
|
||||
|
||||
public void testLoad() {
|
||||
TickRecord record = new TickRecord(new TestcaseRecordInputStream((short)0x101e, (short)data.length, data));
|
||||
TickRecord record = new TickRecord(TestcaseRecordInputStream.create(0x101e, data));
|
||||
assertEquals( (byte)2, record.getMajorTickType());
|
||||
assertEquals( (byte)0, record.getMinorTickType());
|
||||
assertEquals( (byte)3, record.getLabelPosition());
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
@ -19,6 +18,8 @@
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.HexRead;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
@ -26,18 +27,10 @@ import junit.framework.TestCase;
|
||||
*
|
||||
* @author Jason Height (jheight at apache.org)
|
||||
*/
|
||||
public class TestUnicodeString
|
||||
extends TestCase
|
||||
{
|
||||
public final class TestUnicodeString extends TestCase {
|
||||
|
||||
public TestUnicodeString( String s )
|
||||
{
|
||||
super( s );
|
||||
}
|
||||
|
||||
public void testSmallStringSize()
|
||||
throws Exception
|
||||
{
|
||||
public void testSmallStringSize() {
|
||||
//Test a basic string
|
||||
UnicodeString s = makeUnicodeString("Test");
|
||||
UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
|
||||
@ -80,9 +73,7 @@ public class TestUnicodeString
|
||||
assertEquals(30, stats.recordSize);
|
||||
}
|
||||
|
||||
public void testPerfectStringSize()
|
||||
throws Exception
|
||||
{
|
||||
public void testPerfectStringSize() {
|
||||
//Test a basic string
|
||||
UnicodeString s = makeUnicodeString(SSTRecord.MAX_RECORD_SIZE-2-1);
|
||||
UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
|
||||
@ -99,9 +90,7 @@ public class TestUnicodeString
|
||||
assertEquals(SSTRecord.MAX_RECORD_SIZE-1, stats.recordSize);
|
||||
}
|
||||
|
||||
public void testPerfectRichStringSize()
|
||||
throws Exception
|
||||
{
|
||||
public void testPerfectRichStringSize() {
|
||||
//Test a rich text string
|
||||
UnicodeString s = makeUnicodeString(SSTRecord.MAX_RECORD_SIZE-2-1-8-2);
|
||||
s.addFormatRun(new UnicodeString.FormatRun((short)1,(short)0));
|
||||
@ -123,7 +112,7 @@ public class TestUnicodeString
|
||||
assertEquals(SSTRecord.MAX_RECORD_SIZE-1, stats.recordSize);
|
||||
}
|
||||
|
||||
public void testContinuedStringSize() throws Exception {
|
||||
public void testContinuedStringSize() {
|
||||
//Test a basic string
|
||||
UnicodeString s = makeUnicodeString(SSTRecord.MAX_RECORD_SIZE-2-1+20);
|
||||
UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
|
||||
@ -132,7 +121,7 @@ public class TestUnicodeString
|
||||
}
|
||||
|
||||
/** Tests that a string size calculation that fits neatly in two records, the second being a continue*/
|
||||
public void testPerfectContinuedStringSize() throws Exception {
|
||||
public void testPerfectContinuedStringSize() {
|
||||
//Test a basic string
|
||||
int strSize = SSTRecord.MAX_RECORD_SIZE*2;
|
||||
//String overhead
|
||||
@ -150,19 +139,18 @@ public class TestUnicodeString
|
||||
|
||||
|
||||
|
||||
private UnicodeString makeUnicodeString( String s )
|
||||
private static UnicodeString makeUnicodeString( String s )
|
||||
{
|
||||
UnicodeString st = new UnicodeString(s);
|
||||
st.setOptionFlags((byte)0);
|
||||
return st;
|
||||
}
|
||||
|
||||
private UnicodeString makeUnicodeString( int numChars) {
|
||||
private static UnicodeString makeUnicodeString( int numChars) {
|
||||
StringBuffer b = new StringBuffer(numChars);
|
||||
for (int i=0;i<numChars;i++) {
|
||||
b.append(i%10);
|
||||
}
|
||||
return makeUnicodeString(b.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public final class TestUnitsRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
UnitsRecord record = new UnitsRecord(new TestcaseRecordInputStream((short)0x1001, (short)data.length, data));
|
||||
UnitsRecord record = new UnitsRecord(TestcaseRecordInputStream.create(0x1001, data));
|
||||
assertEquals( 0, record.getUnits());
|
||||
|
||||
assertEquals( 6, record.getRecordSize() );
|
||||
|
@ -40,7 +40,7 @@ public final class TestValueRangeRecord extends TestCase {
|
||||
|
||||
public void testLoad() {
|
||||
|
||||
ValueRangeRecord record = new ValueRangeRecord(new TestcaseRecordInputStream((short)0x101f, (short)data.length, data));
|
||||
ValueRangeRecord record = new ValueRangeRecord(TestcaseRecordInputStream.create(0x101f, data));
|
||||
assertEquals( 0.0, record.getMinimumAxisValue(), 0.001);
|
||||
assertEquals( 0.0, record.getMaximumAxisValue(), 0.001);
|
||||
assertEquals( 0.0, record.getMajorIncrement(), 0.001);
|
||||
|
@ -18,6 +18,7 @@
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
@ -30,27 +31,51 @@ import org.apache.poi.util.LittleEndian;
|
||||
*
|
||||
* @author Jason Height (jheight at apache.org)
|
||||
*/
|
||||
public class TestcaseRecordInputStream
|
||||
extends RecordInputStream
|
||||
{
|
||||
public final class TestcaseRecordInputStream {
|
||||
|
||||
private TestcaseRecordInputStream() {
|
||||
// no instances of this class
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepends a mock record identifier to the supplied data and opens a record input stream
|
||||
*/
|
||||
public static RecordInputStream createWithFakeSid(byte[] data) {
|
||||
return create(-5555, data);
|
||||
|
||||
}
|
||||
public static RecordInputStream create(int sid, byte[] data) {
|
||||
return create(mergeDataAndSid(sid, data.length, data));
|
||||
}
|
||||
/**
|
||||
* First 4 bytes of <tt>data</tt> are assumed to be record identifier and length. The supplied
|
||||
* <tt>data</tt> can contain multiple records (sequentially encoded in the same way)
|
||||
*/
|
||||
public static RecordInputStream create(byte[] data) {
|
||||
InputStream is = new ByteArrayInputStream(data);
|
||||
RecordInputStream result = new RecordInputStream(is);
|
||||
result.nextRecord();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor
|
||||
*/
|
||||
public TestcaseRecordInputStream(int sid, byte[] data)
|
||||
{
|
||||
super(new ByteArrayInputStream(mergeDataAndSid((short)sid, (short)data.length, data)));
|
||||
nextRecord();
|
||||
}
|
||||
public TestcaseRecordInputStream(short sid, short length, byte[] data)
|
||||
{
|
||||
super(new ByteArrayInputStream(mergeDataAndSid(sid, length, data)));
|
||||
nextRecord();
|
||||
}
|
||||
// public TestcaseRecordInputStream(int sid, byte[] data)
|
||||
// {
|
||||
// super(new ByteArrayInputStream(mergeDataAndSid(sid, data.length, data)));
|
||||
// nextRecord();
|
||||
// }
|
||||
// public TestcaseRecordInputStream(short sid, short length, byte[] data)
|
||||
// {
|
||||
// super(new ByteArrayInputStream(mergeDataAndSid(sid, length, data)));
|
||||
// nextRecord();
|
||||
// }
|
||||
|
||||
public static byte[] mergeDataAndSid(short sid, short length, byte[] data) {
|
||||
public static byte[] mergeDataAndSid(int sid, int length, byte[] data) {
|
||||
byte[] result = new byte[data.length + 4];
|
||||
LittleEndian.putShort(result, 0, sid);
|
||||
LittleEndian.putShort(result, 2, length);
|
||||
LittleEndian.putUShort(result, 0, sid);
|
||||
LittleEndian.putUShort(result, 2, length);
|
||||
System.arraycopy(data, 0, result, 4, data.length);
|
||||
return result;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.record.TestcaseRecordInputStream;
|
||||
import org.apache.poi.hssf.record.UnicodeString;
|
||||
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
|
||||
import org.apache.poi.util.HexRead;
|
||||
/**
|
||||
*
|
||||
* @author Josh Micich
|
||||
@ -37,13 +38,12 @@ public final class TestConstantValueParser extends TestCase {
|
||||
new UnicodeString("Sample text"),
|
||||
ErrorConstant.valueOf(HSSFErrorConstants.ERROR_DIV_0),
|
||||
};
|
||||
private static final byte[] SAMPLE_ENCODING = {
|
||||
4, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, -102, -103, -103, -103, -103, -103, -15, 63,
|
||||
2, 11, 0, 0, 83, 97, 109, 112, 108, 101, 32, 116, 101, 120, 116,
|
||||
16, 7, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
private static final byte[] SAMPLE_ENCODING = HexRead.readFromString(
|
||||
"04 01 00 00 00 00 00 00 00 " +
|
||||
"00 00 00 00 00 00 00 00 00 " +
|
||||
"01 9A 99 99 99 99 99 F1 3F " +
|
||||
"02 0B 00 00 53 61 6D 70 6C 65 20 74 65 78 74 " +
|
||||
"10 07 00 00 00 00 00 00 00");
|
||||
|
||||
public void testGetEncodedSize() {
|
||||
int actual = ConstantValueParser.getEncodedSize(SAMPLE_VALUES);
|
||||
@ -59,7 +59,7 @@ public final class TestConstantValueParser extends TestCase {
|
||||
}
|
||||
}
|
||||
public void testDecode() {
|
||||
RecordInputStream in = new TestcaseRecordInputStream(0x0001, SAMPLE_ENCODING);
|
||||
RecordInputStream in = TestcaseRecordInputStream.createWithFakeSid(SAMPLE_ENCODING);
|
||||
|
||||
Object[] values = ConstantValueParser.parse(in, 4);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
|
@ -54,9 +54,9 @@ public final class TestArrayPtg extends TestCase {
|
||||
*/
|
||||
public void testReadWriteTokenValueBytes() {
|
||||
|
||||
ArrayPtg ptg = new ArrayPtg(new TestcaseRecordInputStream(ArrayPtg.sid, ENCODED_PTG_DATA));
|
||||
ArrayPtg ptg = new ArrayPtg(TestcaseRecordInputStream.createWithFakeSid(ENCODED_PTG_DATA));
|
||||
|
||||
ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
|
||||
ptg.readTokenValues(TestcaseRecordInputStream.createWithFakeSid(ENCODED_CONSTANT_DATA));
|
||||
assertEquals(3, ptg.getColumnCount());
|
||||
assertEquals(2, ptg.getRowCount());
|
||||
Object[][] values = ptg.getTokenArrayValues();
|
||||
@ -82,8 +82,8 @@ public final class TestArrayPtg extends TestCase {
|
||||
* Excel stores array elements column by column. This test makes sure POI does the same.
|
||||
*/
|
||||
public void testElementOrdering() {
|
||||
ArrayPtg ptg = new ArrayPtg(new TestcaseRecordInputStream(ArrayPtg.sid, ENCODED_PTG_DATA));
|
||||
ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
|
||||
ArrayPtg ptg = new ArrayPtg(TestcaseRecordInputStream.createWithFakeSid(ENCODED_PTG_DATA));
|
||||
ptg.readTokenValues(TestcaseRecordInputStream.createWithFakeSid(ENCODED_CONSTANT_DATA));
|
||||
assertEquals(3, ptg.getColumnCount());
|
||||
assertEquals(2, ptg.getRowCount());
|
||||
|
||||
@ -113,9 +113,9 @@ public final class TestArrayPtg extends TestCase {
|
||||
}
|
||||
|
||||
public void testToFormulaString() {
|
||||
ArrayPtg ptg = new ArrayPtg(new TestcaseRecordInputStream(ArrayPtg.sid, ENCODED_PTG_DATA));
|
||||
ArrayPtg ptg = new ArrayPtg(TestcaseRecordInputStream.createWithFakeSid(ENCODED_PTG_DATA));
|
||||
|
||||
ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
|
||||
ptg.readTokenValues(TestcaseRecordInputStream.createWithFakeSid(ENCODED_CONSTANT_DATA));
|
||||
|
||||
String actualFormula;
|
||||
try {
|
||||
@ -146,7 +146,7 @@ public final class TestArrayPtg extends TestCase {
|
||||
// Force encoded operand class for tArray
|
||||
fullData[0] = (byte) (ArrayPtg.sid + operandClass);
|
||||
|
||||
RecordInputStream in = new TestcaseRecordInputStream(ArrayPtg.sid, fullData);
|
||||
RecordInputStream in = TestcaseRecordInputStream.createWithFakeSid(fullData);
|
||||
|
||||
Ptg[] ptgs = Ptg.readTokens(ENCODED_PTG_DATA.length, in);
|
||||
assertEquals(1, ptgs.length);
|
||||
|
@ -34,7 +34,7 @@ public final class TestFuncPtg extends TestCase {
|
||||
0,
|
||||
};
|
||||
|
||||
FuncPtg ptg = new FuncPtg( new TestcaseRecordInputStream((short)0, (short)fakeData.length, fakeData) );
|
||||
FuncPtg ptg = new FuncPtg(TestcaseRecordInputStream.createWithFakeSid(fakeData) );
|
||||
assertEquals( "Len formula index is not 32(20H)", 0x20, ptg.getFunctionIndex() );
|
||||
assertEquals( "Number of operands in the len formula", 1, ptg.getNumberOfOperands() );
|
||||
assertEquals( "Function Name", "LEN", ptg.getName() );
|
||||
|
@ -18,12 +18,12 @@
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Stack;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.record.TestcaseRecordInputStream;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
@ -94,10 +94,10 @@ public final class TestReferencePtg extends TestCase {
|
||||
0x2C, 33, 44, 55, 66,
|
||||
};
|
||||
public void testReadWrite_tRefN_bug45091() {
|
||||
TestcaseRecordInputStream in = new TestcaseRecordInputStream(-1, tRefN_data);
|
||||
Stack ptgs = Ptg.createParsedExpressionTokens((short)tRefN_data.length, in);
|
||||
RecordInputStream in = TestcaseRecordInputStream.createWithFakeSid(tRefN_data);
|
||||
Ptg[] ptgs = Ptg.readTokens(tRefN_data.length, in);
|
||||
byte[] outData = new byte[5];
|
||||
Ptg.serializePtgStack(ptgs, outData, 0);
|
||||
Ptg.serializePtgs(ptgs, outData, 0);
|
||||
if (outData[0] == 0x24) {
|
||||
throw new AssertionFailedError("Identified bug 45091");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user