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 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>
|
<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>
|
||||||
<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">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">45912 - fixed ArrayIndexOutOfBoundsException in EmbeddedObjectRefSubRecord</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">45889 - fixed ArrayIndexOutOfBoundsException when constructing HSLF Table with a single row </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
|
People interested should also follow the
|
||||||
<link href="mailinglists.html">dev list</link> to track progress.</p>
|
<link href="mailinglists.html">dev list</link> to track progress.</p>
|
||||||
</section>
|
</section>
|
||||||
<section><title>POI 3.1-FINAL Released (2008-06-29)</title>
|
<section><title>POI 3.2-FINAL Released (2008-10-19)</title>
|
||||||
<p>
|
<p>
|
||||||
The POI team is pleased to announce the release of 3.1 FINAL, the latest release of Apache POI.
|
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.0.2 release and a lot of new features.
|
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
|
</p><p> A full list of changes is available in
|
||||||
<link href="./changes.html">the changelog</link>, and
|
<link href="./changes.html">the changelog</link>, and
|
||||||
<link href="http://www.apache.org/dyn/closer.cgi/poi/release/">download</link>
|
<link href="http://www.apache.org/dyn/closer.cgi/poi/release/">download</link>
|
||||||
@ -56,7 +56,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The release is also available from the central Maven repository
|
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>
|
</p>
|
||||||
</section>
|
</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 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>
|
<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>
|
||||||
<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">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">45912 - fixed ArrayIndexOutOfBoundsException in EmbeddedObjectRefSubRecord</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">45889 - fixed ArrayIndexOutOfBoundsException when constructing HSLF Table with a single row </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;
|
package org.apache.poi.hssf.dev;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.io.Writer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.*;
|
import org.apache.poi.hssf.record.*;
|
||||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
import org.apache.poi.util.HexDump;
|
import org.apache.poi.util.HexDump;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utillity for reading in BIFF8 records and displaying data from them.
|
* Utillity for reading in BIFF8 records and displaying data from them.
|
||||||
@ -37,333 +43,488 @@ import org.apache.poi.util.HexDump;
|
|||||||
*@see #main
|
*@see #main
|
||||||
*/
|
*/
|
||||||
public final class BiffViewer {
|
public final class BiffViewer {
|
||||||
private final File _inputFile;
|
static final char[] NEW_LINE_CHARS = System.getProperty("line.separator").toCharArray();
|
||||||
private boolean dump;
|
|
||||||
private final PrintStream _ps;
|
private BiffViewer() {
|
||||||
|
// no instances of this class
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an array of records from an input stream
|
||||||
|
*
|
||||||
|
*@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 is, PrintStream ps, BiffRecordListener recListener, boolean dumpInterpretedRecords)
|
||||||
|
throws RecordFormatException {
|
||||||
|
ArrayList temp = new ArrayList();
|
||||||
|
|
||||||
|
RecordInputStream recStream = new RecordInputStream(is);
|
||||||
|
while (recStream.hasNextRecord()) {
|
||||||
|
recStream.nextRecord();
|
||||||
|
if (recStream.getSid() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Record record = createRecord (recStream);
|
||||||
|
if (record.getSid() == ContinueRecord.sid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
Record[] result = new Record[temp.size()];
|
||||||
|
temp.toArray(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public BiffViewer(File inFile, PrintStream ps) {
|
/**
|
||||||
_inputFile = inFile;
|
* Essentially a duplicate of RecordFactory. Kept separate as not to screw
|
||||||
_ps = ps;
|
* up non-debug operations.
|
||||||
}
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
case AxisRecord.sid: return new AxisRecord(in);
|
||||||
|
case AxisUsedRecord.sid: return new AxisUsedRecord(in);
|
||||||
|
case BOFRecord.sid: return new BOFRecord(in);
|
||||||
|
case BackupRecord.sid: return new BackupRecord(in);
|
||||||
|
case BarRecord.sid: return new BarRecord(in);
|
||||||
|
case BeginRecord.sid: return new BeginRecord(in);
|
||||||
|
case BlankRecord.sid: return new BlankRecord(in);
|
||||||
|
case BookBoolRecord.sid: return new BookBoolRecord(in);
|
||||||
|
case BoolErrRecord.sid: return new BoolErrRecord(in);
|
||||||
|
case BottomMarginRecord.sid: return new BottomMarginRecord(in);
|
||||||
|
case BoundSheetRecord.sid: return new BoundSheetRecord(in);
|
||||||
|
case CFHeaderRecord.sid: return new CFHeaderRecord(in);
|
||||||
|
case CFRuleRecord.sid: return new CFRuleRecord(in);
|
||||||
|
case CalcCountRecord.sid: return new CalcCountRecord(in);
|
||||||
|
case CalcModeRecord.sid: return new CalcModeRecord(in);
|
||||||
|
case CategorySeriesAxisRecord.sid: return new CategorySeriesAxisRecord(in);
|
||||||
|
case ChartFormatRecord.sid: return new ChartFormatRecord(in);
|
||||||
|
case ChartRecord.sid: return new ChartRecord(in);
|
||||||
|
case CodepageRecord.sid: return new CodepageRecord(in);
|
||||||
|
case ColumnInfoRecord.sid: return new ColumnInfoRecord(in);
|
||||||
|
case ContinueRecord.sid: return new ContinueRecord(in);
|
||||||
|
case CountryRecord.sid: return new CountryRecord(in);
|
||||||
|
case DBCellRecord.sid: return new DBCellRecord(in);
|
||||||
|
case DSFRecord.sid: return new DSFRecord(in);
|
||||||
|
case DatRecord.sid: return new DatRecord(in);
|
||||||
|
case DataFormatRecord.sid: return new DataFormatRecord(in);
|
||||||
|
case DateWindow1904Record.sid: return new DateWindow1904Record(in);
|
||||||
|
case DefaultColWidthRecord.sid:return new DefaultColWidthRecord(in);
|
||||||
|
case DefaultDataLabelTextPropertiesRecord.sid: return new DefaultDataLabelTextPropertiesRecord(in);
|
||||||
|
case DefaultRowHeightRecord.sid: return new DefaultRowHeightRecord(in);
|
||||||
|
case DeltaRecord.sid: return new DeltaRecord(in);
|
||||||
|
case DimensionsRecord.sid: return new DimensionsRecord(in);
|
||||||
|
case DrawingGroupRecord.sid: return new DrawingGroupRecord(in);
|
||||||
|
case DrawingRecordForBiffViewer.sid: return new DrawingRecordForBiffViewer(in);
|
||||||
|
case DrawingSelectionRecord.sid: return new DrawingSelectionRecord(in);
|
||||||
|
case DVRecord.sid: return new DVRecord(in);
|
||||||
|
case DVALRecord.sid: return new DVALRecord(in);
|
||||||
|
case EOFRecord.sid: return new EOFRecord(in);
|
||||||
|
case EndRecord.sid: return new EndRecord(in);
|
||||||
|
case ExtSSTRecord.sid: return new ExtSSTRecord(in);
|
||||||
|
case ExtendedFormatRecord.sid: return new ExtendedFormatRecord(in);
|
||||||
|
case ExternSheetRecord.sid: return new ExternSheetRecord(in);
|
||||||
|
case FilePassRecord.sid: return new FilePassRecord(in);
|
||||||
|
case FileSharingRecord.sid: return new FileSharingRecord(in);
|
||||||
|
case FnGroupCountRecord.sid: return new FnGroupCountRecord(in);
|
||||||
|
case FontBasisRecord.sid: return new FontBasisRecord(in);
|
||||||
|
case FontIndexRecord.sid: return new FontIndexRecord(in);
|
||||||
|
case FontRecord.sid: return new FontRecord(in);
|
||||||
|
case FooterRecord.sid: return new FooterRecord(in);
|
||||||
|
case FormatRecord.sid: return new FormatRecord(in);
|
||||||
|
case FormulaRecord.sid: return new FormulaRecord(in);
|
||||||
|
case FrameRecord.sid: return new FrameRecord(in);
|
||||||
|
case GridsetRecord.sid: return new GridsetRecord(in);
|
||||||
|
case GutsRecord.sid: return new GutsRecord(in);
|
||||||
|
case HCenterRecord.sid: return new HCenterRecord(in);
|
||||||
|
case HeaderRecord.sid: return new HeaderRecord(in);
|
||||||
|
case HideObjRecord.sid: return new HideObjRecord(in);
|
||||||
|
case HorizontalPageBreakRecord.sid: return new HorizontalPageBreakRecord(in);
|
||||||
|
case HyperlinkRecord.sid: return new HyperlinkRecord(in);
|
||||||
|
case IndexRecord.sid: return new IndexRecord(in);
|
||||||
|
case InterfaceEndRecord.sid: return new InterfaceEndRecord(in);
|
||||||
|
case InterfaceHdrRecord.sid: return new InterfaceHdrRecord(in);
|
||||||
|
case IterationRecord.sid: return new IterationRecord(in);
|
||||||
|
case LabelRecord.sid: return new LabelRecord(in);
|
||||||
|
case LabelSSTRecord.sid: return new LabelSSTRecord(in);
|
||||||
|
case LeftMarginRecord.sid: return new LeftMarginRecord(in);
|
||||||
|
case LegendRecord.sid: return new LegendRecord(in);
|
||||||
|
case LineFormatRecord.sid: return new LineFormatRecord(in);
|
||||||
|
case LinkedDataRecord.sid: return new LinkedDataRecord(in);
|
||||||
|
case MMSRecord.sid: return new MMSRecord(in);
|
||||||
|
case MergeCellsRecord.sid: return new MergeCellsRecord(in);
|
||||||
|
case MulBlankRecord.sid: return new MulBlankRecord(in);
|
||||||
|
case MulRKRecord.sid: return new MulRKRecord(in);
|
||||||
|
case NameRecord.sid: return new NameRecord(in);
|
||||||
|
case NoteRecord.sid: return new NoteRecord(in);
|
||||||
|
case NumberRecord.sid: return new NumberRecord(in);
|
||||||
|
case ObjRecord.sid: return new ObjRecord(in);
|
||||||
|
case ObjectLinkRecord.sid: return new ObjectLinkRecord(in);
|
||||||
|
case PaletteRecord.sid: return new PaletteRecord(in);
|
||||||
|
case PaneRecord.sid: return new PaneRecord(in);
|
||||||
|
case PasswordRecord.sid: return new PasswordRecord(in);
|
||||||
|
case PasswordRev4Record.sid: return new PasswordRev4Record(in);
|
||||||
|
case PlotAreaRecord.sid: return new PlotAreaRecord(in);
|
||||||
|
case PlotGrowthRecord.sid: return new PlotGrowthRecord(in);
|
||||||
|
case PrecisionRecord.sid: return new PrecisionRecord(in);
|
||||||
|
case PrintGridlinesRecord.sid: return new PrintGridlinesRecord(in);
|
||||||
|
case PrintHeadersRecord.sid: return new PrintHeadersRecord(in);
|
||||||
|
case PrintSetupRecord.sid: return new PrintSetupRecord(in);
|
||||||
|
case ProtectRecord.sid: return new ProtectRecord(in);
|
||||||
|
case ProtectionRev4Record.sid: return new ProtectionRev4Record(in);
|
||||||
|
case RKRecord.sid: return new RKRecord(in);
|
||||||
|
case RefModeRecord.sid: return new RefModeRecord(in);
|
||||||
|
case RefreshAllRecord.sid: return new RefreshAllRecord(in);
|
||||||
|
case RightMarginRecord.sid: return new RightMarginRecord(in);
|
||||||
|
case RowRecord.sid: return new RowRecord(in);
|
||||||
|
case SCLRecord.sid: return new SCLRecord(in);
|
||||||
|
case SSTRecord.sid: return new SSTRecord(in);
|
||||||
|
case SaveRecalcRecord.sid: return new SaveRecalcRecord(in);
|
||||||
|
case SelectionRecord.sid: return new SelectionRecord(in);
|
||||||
|
case SeriesIndexRecord.sid: return new SeriesIndexRecord(in);
|
||||||
|
case SeriesListRecord.sid: return new SeriesListRecord(in);
|
||||||
|
case SeriesRecord.sid: return new SeriesRecord(in);
|
||||||
|
case SeriesTextRecord.sid: return new SeriesTextRecord(in);
|
||||||
|
case SeriesToChartGroupRecord.sid: return new SeriesToChartGroupRecord(in);
|
||||||
|
case SharedFormulaRecord.sid: return new SharedFormulaRecord(in);
|
||||||
|
case SheetPropertiesRecord.sid:return new SheetPropertiesRecord(in);
|
||||||
|
case StringRecord.sid: return new StringRecord(in);
|
||||||
|
case StyleRecord.sid: return new StyleRecord(in);
|
||||||
|
case SupBookRecord.sid: return new SupBookRecord(in);
|
||||||
|
case TabIdRecord.sid: return new TabIdRecord(in);
|
||||||
|
case TableRecord.sid: return new TableRecord(in);
|
||||||
|
case TextObjectRecord.sid: return new TextObjectRecord(in);
|
||||||
|
case TextRecord.sid: return new TextRecord(in);
|
||||||
|
case TickRecord.sid: return new TickRecord(in);
|
||||||
|
case TopMarginRecord.sid: return new TopMarginRecord(in);
|
||||||
|
case UnitsRecord.sid: return new UnitsRecord(in);
|
||||||
|
case UseSelFSRecord.sid: return new UseSelFSRecord(in);
|
||||||
|
case VCenterRecord.sid: return new VCenterRecord(in);
|
||||||
|
case ValueRangeRecord.sid: return new ValueRangeRecord(in);
|
||||||
|
case VerticalPageBreakRecord.sid: return new VerticalPageBreakRecord(in);
|
||||||
|
case WSBoolRecord.sid: return new WSBoolRecord(in);
|
||||||
|
case WindowOneRecord.sid: return new WindowOneRecord(in);
|
||||||
|
case WindowProtectRecord.sid: return new WindowProtectRecord(in);
|
||||||
|
case WindowTwoRecord.sid: return new WindowTwoRecord(in);
|
||||||
|
case WriteAccessRecord.sid: return new WriteAccessRecord(in);
|
||||||
|
case WriteProtectRecord.sid: return new WriteProtectRecord(in);
|
||||||
|
|
||||||
|
}
|
||||||
|
return new UnknownRecord(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method main with 1 argument just run straight biffview against given
|
||||||
|
* file<P>
|
||||||
|
*
|
||||||
|
* with 2 arguments where the second argument is "on" - run biffviewer<P>
|
||||||
|
*
|
||||||
|
* with hex dumps of records <P>
|
||||||
|
*
|
||||||
|
* with 2 arguments where the second argument is "bfd" just run a big fat
|
||||||
|
* hex dump of the file...don't worry about biffviewing it at all
|
||||||
|
* <p>
|
||||||
|
* Define the system property <code>poi.deserialize.escher</code> to turn on
|
||||||
|
* deserialization of escher records.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
/**
|
System.setProperty("poi.deserialize.escher", "true");
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (args.length == 0) {
|
||||||
|
System.out.println( "Biff viewer needs a filename" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
try {
|
||||||
* Create an array of records from an input stream
|
String inFileName = args[0];
|
||||||
*
|
File inputFile = new File(inFileName);
|
||||||
*@param in the InputStream from which the records
|
if(!inputFile.exists()) {
|
||||||
* will be obtained
|
throw new RuntimeException("specified inputFile '" + inFileName + "' does not exist");
|
||||||
*@param dump
|
}
|
||||||
*@return an array of Records created from the
|
PrintStream ps;
|
||||||
* InputStream
|
if (false) { // set to true to output to file
|
||||||
*@exception RecordFormatException on error processing the InputStream
|
OutputStream os = new FileOutputStream(inFileName + ".out");
|
||||||
*/
|
ps = new PrintStream(os);
|
||||||
public static Record[] createRecords(InputStream in, boolean dump, PrintStream ps)
|
} else {
|
||||||
throws RecordFormatException {
|
ps = System.out;
|
||||||
ArrayList records = new ArrayList();
|
}
|
||||||
RecordDetails activeRecord = null;
|
|
||||||
|
if (args.length > 1 && args[1].equals("bfd")) {
|
||||||
|
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(inputFile));
|
||||||
|
InputStream stream = fs.createDocumentInputStream("Workbook");
|
||||||
|
int size = stream.available();
|
||||||
|
byte[] data = new byte[size];
|
||||||
|
|
||||||
BiffviewRecordInputStream recStream = new BiffviewRecordInputStream(in);
|
stream.read(data);
|
||||||
while (recStream.hasNextRecord()) {
|
HexDump.dump(data, 0, System.out, 0);
|
||||||
recStream.nextRecord();
|
} else {
|
||||||
if (recStream.getSid() != 0) {
|
boolean dumpInterpretedRecords = true;
|
||||||
Record record = createRecord (recStream);
|
boolean dumpHex = args.length > 1 && args[1].equals("on");
|
||||||
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 (dump) {
|
|
||||||
recStream.dumpBytes(ps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (activeRecord != null) {
|
|
||||||
activeRecord.dump(ps);
|
|
||||||
}
|
|
||||||
Record[] retval = new Record[records.size()];
|
|
||||||
records.toArray(retval);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
private static final class BiffRecordListener implements IBiffRecordListener {
|
||||||
* Essentially a duplicate of RecordFactory. Kept separate as not to screw
|
private final Writer _hexDumpWriter;
|
||||||
* up non-debug operations.
|
private final List _headers;
|
||||||
*
|
public BiffRecordListener(Writer hexDumpWriter) {
|
||||||
*/
|
_hexDumpWriter = hexDumpWriter;
|
||||||
private static Record createRecord( RecordInputStream in )
|
_headers = new ArrayList();
|
||||||
{
|
}
|
||||||
switch ( in.getSid() )
|
|
||||||
{
|
|
||||||
case AreaFormatRecord.sid: return new AreaFormatRecord(in);
|
|
||||||
case AreaRecord.sid: return new AreaRecord(in);
|
|
||||||
case AxisLineFormatRecord.sid: return new AxisLineFormatRecord(in);
|
|
||||||
case AxisOptionsRecord.sid: return new AxisOptionsRecord(in);
|
|
||||||
case AxisParentRecord.sid: return new AxisParentRecord(in);
|
|
||||||
case AxisRecord.sid: return new AxisRecord(in);
|
|
||||||
case AxisUsedRecord.sid: return new AxisUsedRecord(in);
|
|
||||||
case BOFRecord.sid: return new BOFRecord(in);
|
|
||||||
case BackupRecord.sid: return new BackupRecord(in);
|
|
||||||
case BarRecord.sid: return new BarRecord(in);
|
|
||||||
case BeginRecord.sid: return new BeginRecord(in);
|
|
||||||
case BlankRecord.sid: return new BlankRecord(in);
|
|
||||||
case BookBoolRecord.sid: return new BookBoolRecord(in);
|
|
||||||
case BoolErrRecord.sid: return new BoolErrRecord(in);
|
|
||||||
case BottomMarginRecord.sid: return new BottomMarginRecord(in);
|
|
||||||
case BoundSheetRecord.sid: return new BoundSheetRecord(in);
|
|
||||||
case CFHeaderRecord.sid: return new CFHeaderRecord(in);
|
|
||||||
case CFRuleRecord.sid: return new CFRuleRecord(in);
|
|
||||||
case CalcCountRecord.sid: return new CalcCountRecord(in);
|
|
||||||
case CalcModeRecord.sid: return new CalcModeRecord(in);
|
|
||||||
case CategorySeriesAxisRecord.sid: return new CategorySeriesAxisRecord(in);
|
|
||||||
case ChartFormatRecord.sid: return new ChartFormatRecord(in);
|
|
||||||
case ChartRecord.sid: return new ChartRecord(in);
|
|
||||||
case CodepageRecord.sid: return new CodepageRecord(in);
|
|
||||||
case ColumnInfoRecord.sid: return new ColumnInfoRecord(in);
|
|
||||||
case ContinueRecord.sid: return new ContinueRecord(in);
|
|
||||||
case CountryRecord.sid: return new CountryRecord(in);
|
|
||||||
case DBCellRecord.sid: return new DBCellRecord(in);
|
|
||||||
case DSFRecord.sid: return new DSFRecord(in);
|
|
||||||
case DatRecord.sid: return new DatRecord(in);
|
|
||||||
case DataFormatRecord.sid: return new DataFormatRecord(in);
|
|
||||||
case DateWindow1904Record.sid: return new DateWindow1904Record(in);
|
|
||||||
case DefaultColWidthRecord.sid:return new DefaultColWidthRecord(in);
|
|
||||||
case DefaultDataLabelTextPropertiesRecord.sid: return new DefaultDataLabelTextPropertiesRecord(in);
|
|
||||||
case DefaultRowHeightRecord.sid: return new DefaultRowHeightRecord(in);
|
|
||||||
case DeltaRecord.sid: return new DeltaRecord(in);
|
|
||||||
case DimensionsRecord.sid: return new DimensionsRecord(in);
|
|
||||||
case DrawingGroupRecord.sid: return new DrawingGroupRecord(in);
|
|
||||||
case DrawingRecordForBiffViewer.sid: return new DrawingRecordForBiffViewer(in);
|
|
||||||
case DrawingSelectionRecord.sid: return new DrawingSelectionRecord(in);
|
|
||||||
case DVRecord.sid: return new DVRecord(in);
|
|
||||||
case DVALRecord.sid: return new DVALRecord(in);
|
|
||||||
case EOFRecord.sid: return new EOFRecord(in);
|
|
||||||
case EndRecord.sid: return new EndRecord(in);
|
|
||||||
case ExtSSTRecord.sid: return new ExtSSTRecord(in);
|
|
||||||
case ExtendedFormatRecord.sid: return new ExtendedFormatRecord(in);
|
|
||||||
case ExternSheetRecord.sid: return new ExternSheetRecord(in);
|
|
||||||
case FilePassRecord.sid: return new FilePassRecord(in);
|
|
||||||
case FileSharingRecord.sid: return new FileSharingRecord(in);
|
|
||||||
case FnGroupCountRecord.sid: return new FnGroupCountRecord(in);
|
|
||||||
case FontBasisRecord.sid: return new FontBasisRecord(in);
|
|
||||||
case FontIndexRecord.sid: return new FontIndexRecord(in);
|
|
||||||
case FontRecord.sid: return new FontRecord(in);
|
|
||||||
case FooterRecord.sid: return new FooterRecord(in);
|
|
||||||
case FormatRecord.sid: return new FormatRecord(in);
|
|
||||||
case FormulaRecord.sid: return new FormulaRecord(in);
|
|
||||||
case FrameRecord.sid: return new FrameRecord(in);
|
|
||||||
case GridsetRecord.sid: return new GridsetRecord(in);
|
|
||||||
case GutsRecord.sid: return new GutsRecord(in);
|
|
||||||
case HCenterRecord.sid: return new HCenterRecord(in);
|
|
||||||
case HeaderRecord.sid: return new HeaderRecord(in);
|
|
||||||
case HideObjRecord.sid: return new HideObjRecord(in);
|
|
||||||
case HorizontalPageBreakRecord.sid: return new HorizontalPageBreakRecord(in);
|
|
||||||
case HyperlinkRecord.sid: return new HyperlinkRecord(in);
|
|
||||||
case IndexRecord.sid: return new IndexRecord(in);
|
|
||||||
case InterfaceEndRecord.sid: return new InterfaceEndRecord(in);
|
|
||||||
case InterfaceHdrRecord.sid: return new InterfaceHdrRecord(in);
|
|
||||||
case IterationRecord.sid: return new IterationRecord(in);
|
|
||||||
case LabelRecord.sid: return new LabelRecord(in);
|
|
||||||
case LabelSSTRecord.sid: return new LabelSSTRecord(in);
|
|
||||||
case LeftMarginRecord.sid: return new LeftMarginRecord(in);
|
|
||||||
case LegendRecord.sid: return new LegendRecord(in);
|
|
||||||
case LineFormatRecord.sid: return new LineFormatRecord(in);
|
|
||||||
case LinkedDataRecord.sid: return new LinkedDataRecord(in);
|
|
||||||
case MMSRecord.sid: return new MMSRecord(in);
|
|
||||||
case MergeCellsRecord.sid: return new MergeCellsRecord(in);
|
|
||||||
case MulBlankRecord.sid: return new MulBlankRecord(in);
|
|
||||||
case MulRKRecord.sid: return new MulRKRecord(in);
|
|
||||||
case NameRecord.sid: return new NameRecord(in);
|
|
||||||
case NoteRecord.sid: return new NoteRecord(in);
|
|
||||||
case NumberRecord.sid: return new NumberRecord(in);
|
|
||||||
case ObjRecord.sid: return new ObjRecord(in);
|
|
||||||
case ObjectLinkRecord.sid: return new ObjectLinkRecord(in);
|
|
||||||
case PaletteRecord.sid: return new PaletteRecord(in);
|
|
||||||
case PaneRecord.sid: return new PaneRecord(in);
|
|
||||||
case PasswordRecord.sid: return new PasswordRecord(in);
|
|
||||||
case PasswordRev4Record.sid: return new PasswordRev4Record(in);
|
|
||||||
case PlotAreaRecord.sid: return new PlotAreaRecord(in);
|
|
||||||
case PlotGrowthRecord.sid: return new PlotGrowthRecord(in);
|
|
||||||
case PrecisionRecord.sid: return new PrecisionRecord(in);
|
|
||||||
case PrintGridlinesRecord.sid: return new PrintGridlinesRecord(in);
|
|
||||||
case PrintHeadersRecord.sid: return new PrintHeadersRecord(in);
|
|
||||||
case PrintSetupRecord.sid: return new PrintSetupRecord(in);
|
|
||||||
case ProtectRecord.sid: return new ProtectRecord(in);
|
|
||||||
case ProtectionRev4Record.sid: return new ProtectionRev4Record(in);
|
|
||||||
case RKRecord.sid: return new RKRecord(in);
|
|
||||||
case RefModeRecord.sid: return new RefModeRecord(in);
|
|
||||||
case RefreshAllRecord.sid: return new RefreshAllRecord(in);
|
|
||||||
case RightMarginRecord.sid: return new RightMarginRecord(in);
|
|
||||||
case RowRecord.sid: return new RowRecord(in);
|
|
||||||
case SCLRecord.sid: return new SCLRecord(in);
|
|
||||||
case SSTRecord.sid: return new SSTRecord(in);
|
|
||||||
case SaveRecalcRecord.sid: return new SaveRecalcRecord(in);
|
|
||||||
case SelectionRecord.sid: return new SelectionRecord(in);
|
|
||||||
case SeriesIndexRecord.sid: return new SeriesIndexRecord(in);
|
|
||||||
case SeriesListRecord.sid: return new SeriesListRecord(in);
|
|
||||||
case SeriesRecord.sid: return new SeriesRecord(in);
|
|
||||||
case SeriesTextRecord.sid: return new SeriesTextRecord(in);
|
|
||||||
case SeriesToChartGroupRecord.sid: return new SeriesToChartGroupRecord(in);
|
|
||||||
case SharedFormulaRecord.sid: return new SharedFormulaRecord(in);
|
|
||||||
case SheetPropertiesRecord.sid:return new SheetPropertiesRecord(in);
|
|
||||||
case StringRecord.sid: return new StringRecord(in);
|
|
||||||
case StyleRecord.sid: return new StyleRecord(in);
|
|
||||||
case SupBookRecord.sid: return new SupBookRecord(in);
|
|
||||||
case TabIdRecord.sid: return new TabIdRecord(in);
|
|
||||||
case TableRecord.sid: return new TableRecord(in);
|
|
||||||
case TextObjectRecord.sid: return new TextObjectRecord(in);
|
|
||||||
case TextRecord.sid: return new TextRecord(in);
|
|
||||||
case TickRecord.sid: return new TickRecord(in);
|
|
||||||
case TopMarginRecord.sid: return new TopMarginRecord(in);
|
|
||||||
case UnitsRecord.sid: return new UnitsRecord(in);
|
|
||||||
case UseSelFSRecord.sid: return new UseSelFSRecord(in);
|
|
||||||
case VCenterRecord.sid: return new VCenterRecord(in);
|
|
||||||
case ValueRangeRecord.sid: return new ValueRangeRecord(in);
|
|
||||||
case VerticalPageBreakRecord.sid: return new VerticalPageBreakRecord(in);
|
|
||||||
case WSBoolRecord.sid: return new WSBoolRecord(in);
|
|
||||||
case WindowOneRecord.sid: return new WindowOneRecord(in);
|
|
||||||
case WindowProtectRecord.sid: return new WindowProtectRecord(in);
|
|
||||||
case WindowTwoRecord.sid: return new WindowTwoRecord(in);
|
|
||||||
case WriteAccessRecord.sid: return new WriteAccessRecord(in);
|
|
||||||
case WriteProtectRecord.sid: return new WriteProtectRecord(in);
|
|
||||||
|
|
||||||
}
|
|
||||||
return new UnknownRecord(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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);
|
||||||
* Method setDump - hex dump out data or not.
|
|
||||||
*/
|
}
|
||||||
public void setDump(boolean dump) {
|
|
||||||
this.dump = dump;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps a plain {@link InputStream} and allows BIFF record information to be tapped off
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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 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 int read() throws IOException {
|
||||||
* Method main with 1 argument just run straight biffview against given
|
if (_currentPos >= _currentSize) {
|
||||||
* file<P>
|
fillNextBuffer();
|
||||||
*
|
}
|
||||||
* with 2 arguments where the second argument is "on" - run biffviewer<P>
|
if (_currentPos >= _currentSize) {
|
||||||
*
|
return -1;
|
||||||
* with hex dumps of records <P>
|
}
|
||||||
*
|
int result = _data[_currentPos] & 0x00FF;
|
||||||
* with 2 arguments where the second argument is "bfd" just run a big fat
|
_currentPos ++;
|
||||||
* hex dump of the file...don't worry about biffviewing it at all
|
_overallStreamPos ++;
|
||||||
* <p>
|
formatBufferIfAtEndOfRec();
|
||||||
* Define the system property <code>poi.deserialize.escher</code> to turn on
|
return result;
|
||||||
* deserialization of escher records.
|
}
|
||||||
*
|
public int read(byte[] b, int off, int len) throws IOException {
|
||||||
*/
|
if (_currentPos >= _currentSize) {
|
||||||
public static void main(String[] args) {
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
System.setProperty("poi.deserialize.escher", "true");
|
public int available() throws IOException {
|
||||||
|
return _currentSize - _currentPos + _is.available();
|
||||||
|
}
|
||||||
|
private void fillNextBuffer() throws IOException {
|
||||||
|
if (_innerHasReachedEOF) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (args.length == 0) {
|
private static void hexDumpLine(Writer w, byte[] data, int lineStartAddress, int lineDataOffset, int startDelta, int endDelta) {
|
||||||
System.out.println( "Biff viewer needs a filename" );
|
if (startDelta >= endDelta) {
|
||||||
return;
|
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);
|
||||||
|
|
||||||
try {
|
// interpreted ascii
|
||||||
String inFileName = args[0];
|
for (int i=0; i< DUMP_LINE_LEN; i++) {
|
||||||
File inputFile = new File(inFileName);
|
if (i >= startDelta && i < endDelta) {
|
||||||
if(!inputFile.exists()) {
|
w.write(getPrintableChar(data[lineDataOffset+i]));
|
||||||
throw new RuntimeException("specified inputFile '" + inFileName + "' does not exist");
|
} else {
|
||||||
}
|
w.write(" ");
|
||||||
PrintStream ps;
|
}
|
||||||
if (false) { // set to true to output to file
|
}
|
||||||
OutputStream os = new FileOutputStream(inFileName + ".out");
|
w.write(NEW_LINE_CHARS);
|
||||||
ps = new PrintStream(os);
|
} catch (IOException e) {
|
||||||
} else {
|
throw new RuntimeException(e);
|
||||||
ps = System.out;
|
}
|
||||||
}
|
}
|
||||||
BiffViewer viewer = new BiffViewer(inputFile, ps);
|
|
||||||
|
|
||||||
if (args.length > 1 && args[1].equals("on")) {
|
private static char getPrintableChar(byte b) {
|
||||||
viewer.setDump(true);
|
char ib = (char) (b & 0x00FF);
|
||||||
}
|
if (ib < 32 || ib > 126) {
|
||||||
if (args.length > 1 && args[1].equals("bfd")) {
|
return '.';
|
||||||
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(inputFile));
|
}
|
||||||
InputStream stream = fs.createDocumentInputStream("Workbook");
|
return ib;
|
||||||
int size = stream.available();
|
}
|
||||||
byte[] data = new byte[size];
|
|
||||||
|
|
||||||
stream.read(data);
|
|
||||||
HexDump.dump(data, 0, System.out, 0);
|
|
||||||
} else {
|
|
||||||
viewer.run();
|
|
||||||
}
|
|
||||||
ps.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This record supports dumping of completed continue records.
|
|
||||||
*/
|
|
||||||
private static final class RecordDetails
|
|
||||||
{
|
|
||||||
short rectype, recsize;
|
|
||||||
int startloc;
|
|
||||||
Record record;
|
|
||||||
|
|
||||||
public RecordDetails( short rectype, short recsize, int startloc, Record record )
|
|
||||||
{
|
|
||||||
this.rectype = rectype;
|
|
||||||
this.recsize = recsize;
|
|
||||||
this.startloc = startloc;
|
|
||||||
this.record = record;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getRectype()
|
|
||||||
{
|
|
||||||
return rectype;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getRecsize()
|
|
||||||
{
|
|
||||||
return recsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Record getRecord()
|
|
||||||
{
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
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() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class BiffviewRecordInputStream extends RecordInputStream {
|
|
||||||
public BiffviewRecordInputStream(InputStream in) {
|
|
||||||
super(in);
|
|
||||||
}
|
|
||||||
public void dumpBytes(PrintStream ps) {
|
|
||||||
ps.println(HexDump.dump(this.data, 0, this.currentLength));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,15 +138,11 @@ public class TextboxShape
|
|||||||
HSSFTextbox shape = hssfShape;
|
HSSFTextbox shape = hssfShape;
|
||||||
|
|
||||||
TextObjectRecord obj = new TextObjectRecord();
|
TextObjectRecord obj = new TextObjectRecord();
|
||||||
obj.setHorizontalTextAlignment( hssfShape.getHorizontalAlignment() );
|
obj.setHorizontalTextAlignment(hssfShape.getHorizontalAlignment());
|
||||||
obj.setVerticalTextAlignment( hssfShape.getVerticalAlignment());
|
obj.setVerticalTextAlignment(hssfShape.getVerticalAlignment());
|
||||||
obj.setTextLocked( true );
|
obj.setTextLocked(true);
|
||||||
obj.setTextOrientation( TextObjectRecord.TEXT_ORIENTATION_NONE );
|
obj.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_NONE);
|
||||||
int frLength = ( shape.getString().numFormattingRuns() + 1 ) * 8;
|
obj.setStr(shape.getString());
|
||||||
obj.setFormattingRunLength( (short) frLength );
|
|
||||||
obj.setTextLength( (short) shape.getString().length() );
|
|
||||||
obj.setStr( shape.getString() );
|
|
||||||
obj.setReserved7( 0 );
|
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -22,76 +22,44 @@ package org.apache.poi.hssf.record;
|
|||||||
import org.apache.poi.util.LittleEndian;
|
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
|
* Description: handles overflow for prior record in the input
|
||||||
* stream; content is tailored to that prior record<P>
|
* stream; content is tailored to that prior record<P>
|
||||||
* @author Marc Johnson (mjohnson at apache dot org)
|
* @author Marc Johnson (mjohnson at apache dot org)
|
||||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||||
* @author Csaba Nagy (ncsaba at yahoo dot com)
|
* @author Csaba Nagy (ncsaba at yahoo dot com)
|
||||||
* @version 2.0-pre
|
|
||||||
*/
|
*/
|
||||||
|
public final class ContinueRecord extends Record {
|
||||||
public class ContinueRecord
|
|
||||||
extends Record
|
|
||||||
{
|
|
||||||
public final static short sid = 0x003C;
|
public final static short sid = 0x003C;
|
||||||
private byte[] field_1_data;
|
private byte[] _data;
|
||||||
|
|
||||||
/**
|
public ContinueRecord(byte[] data) {
|
||||||
* default constructor
|
_data = data;
|
||||||
*/
|
|
||||||
|
|
||||||
public ContinueRecord()
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* USE ONLY within "processContinue"
|
* USE ONLY within "processContinue"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public byte [] serialize()
|
public byte [] serialize()
|
||||||
{
|
{
|
||||||
byte[] retval = new byte[ field_1_data.length + 4 ];
|
byte[] retval = new byte[ _data.length + 4 ];
|
||||||
serialize(0, retval);
|
serialize(0, retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int serialize(int offset, byte [] data)
|
public int serialize(int offset, byte[] data) {
|
||||||
{
|
return write(data, offset, null, _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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the data for continuation
|
* get the data for continuation
|
||||||
* @return byte array containing all of the continued data
|
* @return byte array containing all of the continued data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public byte [] getData()
|
public byte [] getData()
|
||||||
{
|
{
|
||||||
return field_1_data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Debugging toString
|
|
||||||
*
|
|
||||||
* @return string representation
|
|
||||||
*/
|
|
||||||
|
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
@ -113,19 +81,36 @@ public class ContinueRecord
|
|||||||
*
|
*
|
||||||
* @param in the RecordInputstream to read the record from
|
* @param in the RecordInputstream to read the record from
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public ContinueRecord(RecordInputStream in)
|
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() {
|
public static int write(byte[] destBuf, int destOffset, Byte initialDataByte, byte[] srcData) {
|
||||||
ContinueRecord clone = new ContinueRecord();
|
return write(destBuf, destOffset, initialDataByte, srcData, 0, srcData.length);
|
||||||
clone.setData(field_1_data);
|
}
|
||||||
return clone;
|
/**
|
||||||
|
* @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;
|
package org.apache.poi.hssf.record;
|
||||||
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.formula.Ptg;
|
import org.apache.poi.hssf.record.formula.Ptg;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.StringUtil;
|
import org.apache.poi.util.StringUtil;
|
||||||
@ -124,11 +122,7 @@ public final class ExternalNameRecord extends Record {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getNameDefinitionSize() {
|
private int getNameDefinitionSize() {
|
||||||
int result = 0;
|
return Ptg.getEncodedSize(field_5_name_definition);
|
||||||
for (int i = 0; i < field_5_name_definition.length; i++) {
|
|
||||||
result += field_5_name_definition[i].getSize();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,47 +20,38 @@ package org.apache.poi.hssf.record;
|
|||||||
import org.apache.poi.hssf.record.formula.Ptg;
|
import org.apache.poi.hssf.record.formula.Ptg;
|
||||||
import org.apache.poi.util.LittleEndian;
|
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
|
* Not implemented yet. May commit it anyway just so people can see
|
||||||
* where I'm heading.
|
* where I'm heading.
|
||||||
*
|
*
|
||||||
* @author Glen Stampoultzis (glens at apache.org)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
*/
|
*/
|
||||||
public final class LinkedDataFormulaField implements CustomField {
|
public final class LinkedDataFormulaField {
|
||||||
Stack formulaTokens = new Stack();
|
private Ptg[] formulaTokens;
|
||||||
|
|
||||||
public int getSize()
|
public int getSize()
|
||||||
{
|
{
|
||||||
int size = 0;
|
return 2 + Ptg.getEncodedSize(formulaTokens);
|
||||||
for ( Iterator iterator = formulaTokens.iterator(); iterator.hasNext(); )
|
|
||||||
{
|
|
||||||
Ptg token = (Ptg) iterator.next();
|
|
||||||
size += token.getSize();
|
|
||||||
}
|
|
||||||
return size + 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int fillField( RecordInputStream in )
|
public int fillField( RecordInputStream in )
|
||||||
{
|
{
|
||||||
short tokenSize = in.readShort();
|
int tokenSize = in.readUShort();
|
||||||
formulaTokens = Ptg.createParsedExpressionTokens(tokenSize, in);
|
formulaTokens = Ptg.readTokens(tokenSize, in);
|
||||||
|
|
||||||
return tokenSize + 2;
|
return tokenSize + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void toString( StringBuffer buffer )
|
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 " )
|
buffer.append( "Formula " )
|
||||||
.append( k )
|
.append( k )
|
||||||
.append( "=" )
|
.append( "=" )
|
||||||
.append( formulaTokens.get( k ).toString() )
|
.append(ptg.toString() )
|
||||||
.append( "\n" )
|
.append( "\n" )
|
||||||
.append( ( (Ptg) formulaTokens.get( k ) ).toDebugString() )
|
.append(ptg.toDebugString() )
|
||||||
.append( "\n" );
|
.append( "\n" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,34 +66,26 @@ public final class LinkedDataFormulaField implements CustomField {
|
|||||||
public int serializeField( int offset, byte[] data )
|
public int serializeField( int offset, byte[] data )
|
||||||
{
|
{
|
||||||
int size = getSize();
|
int size = getSize();
|
||||||
LittleEndian.putShort(data, offset, (short)(size - 2));
|
LittleEndian.putUShort(data, offset, size - 2);
|
||||||
int pos = offset + 2;
|
int pos = offset + 2;
|
||||||
pos += Ptg.serializePtgStack(formulaTokens, data, pos);
|
pos += Ptg.serializePtgs(formulaTokens, data, pos);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object clone()
|
public void setFormulaTokens(Ptg[] ptgs)
|
||||||
{
|
{
|
||||||
try
|
this.formulaTokens = (Ptg[])ptgs.clone();
|
||||||
{
|
|
||||||
// todo: clone tokens? or are they immutable?
|
|
||||||
return super.clone();
|
|
||||||
}
|
|
||||||
catch ( CloneNotSupportedException e )
|
|
||||||
{
|
|
||||||
// should not happen
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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_2_referenceType = field_2_referenceType;
|
||||||
rec.field_3_options = field_3_options;
|
rec.field_3_options = field_3_options;
|
||||||
rec.field_4_indexNumberFmtRecord = field_4_indexNumberFmtRecord;
|
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;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,51 +321,54 @@ public final class RecordFactory {
|
|||||||
Record lastRecord = null;
|
Record lastRecord = null;
|
||||||
while (recStream.hasNextRecord()) {
|
while (recStream.hasNextRecord()) {
|
||||||
recStream.nextRecord();
|
recStream.nextRecord();
|
||||||
if (recStream.getSid() != 0) {
|
if (recStream.getSid() == 0) {
|
||||||
Record[] recs = createRecord(recStream); // handle MulRK records
|
// After EOF, Excel seems to pad block with zeros
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Record[] recs = createRecord(recStream); // handle MulRK records
|
||||||
|
|
||||||
if (recs.length > 1) {
|
if (recs.length > 1) {
|
||||||
for (int k = 0; k < recs.length; k++) {
|
for (int k = 0; k < recs.length; k++) {
|
||||||
records.add(recs[ k ]); // these will be number records
|
records.add(recs[ k ]); // these will be number records
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Record record = recs[ 0 ];
|
|
||||||
|
|
||||||
if (record != null) {
|
|
||||||
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))) {
|
|
||||||
// Drawing records have a very strange continue behaviour.
|
|
||||||
//There can actually be OBJ records mixed between the continues.
|
|
||||||
lastDrawingRecord.processContinueRecord( ((ContinueRecord)record).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,
|
|
||||||
//that happen to be continued
|
|
||||||
records.add(record);
|
|
||||||
} else
|
|
||||||
throw new RecordFormatException("Unhandled Continue Record");
|
|
||||||
} else {
|
|
||||||
lastRecord = record;
|
|
||||||
if (record instanceof DrawingRecord) {
|
|
||||||
lastDrawingRecord = (DrawingRecord) record;
|
|
||||||
}
|
|
||||||
records.add(record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Record record = recs[ 0 ];
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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(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 (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 {
|
||||||
|
throw new RecordFormatException("Unhandled Continue Record");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lastRecord = record;
|
||||||
|
if (record instanceof DrawingRecord) {
|
||||||
|
lastDrawingRecord = (DrawingRecord) record;
|
||||||
|
}
|
||||||
|
records.add(record);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return records;
|
return records;
|
||||||
|
@ -29,19 +29,19 @@ import java.io.ByteArrayOutputStream;
|
|||||||
*
|
*
|
||||||
* @author Jason Height (jheight @ apache dot org)
|
* @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*/
|
/** Maximum size of a single record (minus the 4 byte header) without a continue*/
|
||||||
public final static short MAX_RECORD_DATA_SIZE = 8224;
|
public final static short MAX_RECORD_DATA_SIZE = 8224;
|
||||||
private static final int INVALID_SID_VALUE = -1;
|
private static final int INVALID_SID_VALUE = -1;
|
||||||
|
|
||||||
private InputStream in;
|
private InputStream in;
|
||||||
protected short currentSid;
|
private short currentSid;
|
||||||
protected short currentLength = -1;
|
private short currentLength = -1;
|
||||||
protected short nextSid;
|
private short nextSid;
|
||||||
|
|
||||||
protected byte[] data = new byte[MAX_RECORD_DATA_SIZE];
|
private final byte[] data = new byte[MAX_RECORD_DATA_SIZE];
|
||||||
protected short recordOffset;
|
private short recordOffset;
|
||||||
protected long pos;
|
private long pos;
|
||||||
|
|
||||||
private boolean autoContinue = true;
|
private boolean autoContinue = true;
|
||||||
|
|
||||||
@ -218,54 +218,81 @@ public class RecordInputStream extends InputStream {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String readString() {
|
||||||
* given a byte array of 16-bit unicode characters, compress to 8-bit and
|
int requestedLength = readUShort();
|
||||||
* return a string
|
byte compressFlag = readByte();
|
||||||
*
|
return readStringCommon(requestedLength, compressFlag == 0);
|
||||||
* { 0x16, 0x00 } -0x16
|
}
|
||||||
*
|
/**
|
||||||
* @param length the length of the final string
|
* given a byte array of 16-bit unicode characters, compress to 8-bit and
|
||||||
* @return the converted string
|
* return a string
|
||||||
* @exception IllegalArgumentException if len is too large (i.e.,
|
*
|
||||||
* there is not enough data in string to create a String of that
|
* { 0x16, 0x00 } -0x16
|
||||||
* length)
|
*
|
||||||
*/
|
* @param requestedLength the length of the final string
|
||||||
public String readUnicodeLEString(int length) {
|
* @return the converted string
|
||||||
if ((length < 0) || (((remaining() / 2) < length) && !isContinueNext())) {
|
* @exception IllegalArgumentException if len is too large (i.e.,
|
||||||
throw new IllegalArgumentException("Illegal length - asked for " + length + " but only " + (remaining()/2) + " left!");
|
* there is not enough data in string to create a String of that
|
||||||
}
|
* length)
|
||||||
|
*/
|
||||||
|
public String readUnicodeLEString(int requestedLength) {
|
||||||
|
return readStringCommon(requestedLength, false);
|
||||||
|
}
|
||||||
|
|
||||||
StringBuffer buf = new StringBuffer(length);
|
public String readCompressedUnicode(int requestedLength) {
|
||||||
for (int i=0;i<length;i++) {
|
return readStringCommon(requestedLength, true);
|
||||||
if ((remaining() == 0) && (isContinueNext())){
|
}
|
||||||
nextRecord();
|
|
||||||
int compressByte = readByte();
|
|
||||||
if(compressByte != 1) throw new IllegalArgumentException("compressByte in continue records must be 1 while reading unicode LE string");
|
|
||||||
}
|
|
||||||
char ch = (char)readShort();
|
|
||||||
buf.append(ch);
|
|
||||||
}
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String readCompressedUnicode(int length) {
|
private String readStringCommon(int requestedLength, boolean pIsCompressedEncoding) {
|
||||||
if ((length < 0) || ((remaining() < length) && !isContinueNext())) {
|
// Sanity check to detect garbage string lengths
|
||||||
throw new IllegalArgumentException("Illegal length " + length);
|
if (requestedLength < 0 || requestedLength > 0x100000) { // 16 million chars?
|
||||||
}
|
throw new IllegalArgumentException("Bad requested string length (" + requestedLength + ")");
|
||||||
|
}
|
||||||
StringBuffer buf = new StringBuffer(length);
|
char[] buf = new char[requestedLength];
|
||||||
for (int i=0;i<length;i++) {
|
boolean isCompressedEncoding = pIsCompressedEncoding;
|
||||||
if ((remaining() == 0) && (isContinueNext())) {
|
int curLen = 0;
|
||||||
nextRecord();
|
while(true) {
|
||||||
int compressByte = readByte();
|
int availableChars =isCompressedEncoding ? remaining() : remaining() / LittleEndian.SHORT_SIZE;
|
||||||
if(compressByte != 0) throw new IllegalArgumentException("compressByte in continue records must be 0 while reading compressed unicode");
|
if (requestedLength - curLen <= availableChars) {
|
||||||
}
|
// enough space in current record, so just read it out
|
||||||
byte b = readByte();
|
while(curLen < requestedLength) {
|
||||||
char ch = (char)(0x00FF & b); // avoid sex
|
char ch;
|
||||||
buf.append(ch);
|
if (isCompressedEncoding) {
|
||||||
}
|
ch = (char)readUByte();
|
||||||
return buf.toString();
|
} 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();
|
||||||
|
// note - the compressed flag may change on the fly
|
||||||
|
byte compressFlag = readByte();
|
||||||
|
isCompressedEncoding = (compressFlag == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns an excel style unicode string from the bytes reminaing in the record.
|
/** Returns an excel style unicode string from the bytes reminaing in the record.
|
||||||
* <i>Note:</i> Unicode strings differ from <b>normal</b> strings due to the addition of
|
* <i>Note:</i> Unicode strings differ from <b>normal</b> strings due to the addition of
|
||||||
|
@ -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 java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.record.formula.Ptg;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
|
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.HexDump;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
public class TextObjectRecord
|
/**
|
||||||
extends TextObjectBaseRecord
|
* 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
|
||||||
HSSFRichTextString str;
|
* 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
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TextObjectRecord( RecordInputStream in )
|
private static final BitField HorizontalTextAlignment = BitFieldFactory.getInstance(0x000E);
|
||||||
{
|
private static final BitField VerticalTextAlignment = BitFieldFactory.getInstance(0x0070);
|
||||||
super( in );
|
private static final BitField textLocked = BitFieldFactory.getInstance(0x0200);
|
||||||
|
|
||||||
if (getTextLength() > 0) {
|
public final static short HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED = 1;
|
||||||
if (in.isContinueNext() && in.remaining() == 0) {
|
public final static short HORIZONTAL_TEXT_ALIGNMENT_CENTERED = 2;
|
||||||
//1st Continue
|
public final static short HORIZONTAL_TEXT_ALIGNMENT_RIGHT_ALIGNED = 3;
|
||||||
in.nextRecord();
|
public final static short HORIZONTAL_TEXT_ALIGNMENT_JUSTIFIED = 4;
|
||||||
processRawString(in);
|
public final static short VERTICAL_TEXT_ALIGNMENT_TOP = 1;
|
||||||
} else
|
public final static short VERTICAL_TEXT_ALIGNMENT_CENTER = 2;
|
||||||
throw new RecordFormatException("Expected Continue record to hold string data for TextObjectRecord");
|
public final static short VERTICAL_TEXT_ALIGNMENT_BOTTOM = 3;
|
||||||
}
|
public final static short VERTICAL_TEXT_ALIGNMENT_JUSTIFY = 4;
|
||||||
if (getFormattingRunLength() > 0) {
|
|
||||||
if (in.isContinueNext() && in.remaining() == 0) {
|
public final static short TEXT_ORIENTATION_NONE = 0;
|
||||||
in.nextRecord();
|
public final static short TEXT_ORIENTATION_TOP_TO_BOTTOM = 1;
|
||||||
processFontRuns(in);
|
public final static short TEXT_ORIENTATION_ROT_RIGHT = 2;
|
||||||
} else throw new RecordFormatException("Expected Continue Record to hold font runs for TextObjectRecord");
|
public final static short TEXT_ORIENTATION_ROT_LEFT = 3;
|
||||||
}
|
|
||||||
if (str == null)
|
private int field_1_options;
|
||||||
str = new HSSFRichTextString("");
|
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) {
|
||||||
|
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 (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");
|
||||||
|
}
|
||||||
|
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, _text, field_7_formattingDataLength);
|
||||||
|
} else {
|
||||||
|
throw new RecordFormatException(
|
||||||
|
"Expected Continue Record to hold font runs for TextObjectRecord");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
+ ")");
|
||||||
|
}
|
||||||
|
if (in.remaining() != formattingRunDataLength) {
|
||||||
|
throw new RecordFormatException("Expected " + formattingRunDataLength
|
||||||
|
+ " bytes but got " + in.remaining());
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getSid() {
|
||||||
|
return sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 4 + dataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 getRecordSize()
|
public int serialize(int offset, byte[] data) {
|
||||||
{
|
|
||||||
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;
|
int expectedTotalSize = getRecordSize();
|
||||||
continue1Size += 1 + 4;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
continue2Size = (str.numFormattingRuns() + 1) * 8 + 4;
|
/**
|
||||||
}
|
* Note - this total size includes all potential {@link ContinueRecord}s written
|
||||||
return super.getRecordSize() + continue1Size + continue2Size;
|
*/
|
||||||
}
|
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
|
||||||
|
|
||||||
public int serialize( int offset, byte[] data )
|
return result;
|
||||||
{
|
}
|
||||||
// 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 )
|
* Sets the Horizontal text alignment field value.
|
||||||
{
|
*/
|
||||||
ContinueRecord c2 = createContinue2();
|
public void setHorizontalTextAlignment(int value) {
|
||||||
int bytesWritten2 = 0;
|
field_1_options = HorizontalTextAlignment.setValue(field_1_options, value);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
/**
|
||||||
{
|
* @return the Horizontal text alignment field value.
|
||||||
byte[] c1Data = str.getString().getBytes( "UTF-16LE" );
|
*/
|
||||||
int length = c1Data.length;
|
public int getHorizontalTextAlignment() {
|
||||||
|
return HorizontalTextAlignment.getValue(field_1_options);
|
||||||
|
}
|
||||||
|
|
||||||
int charsWritten = 0;
|
/**
|
||||||
int spos = pos;
|
* Sets the Vertical text alignment field value.
|
||||||
while(length > 0){
|
*/
|
||||||
int chunkSize = Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE-2 , length);
|
public void setVerticalTextAlignment(int value) {
|
||||||
length -= chunkSize;
|
field_1_options = VerticalTextAlignment.setValue(field_1_options, value);
|
||||||
|
}
|
||||||
|
|
||||||
//continue header
|
/**
|
||||||
LittleEndian.putShort(data, spos, ContinueRecord.sid);
|
* @return the Vertical text alignment field value.
|
||||||
spos += LittleEndian.SHORT_SIZE;
|
*/
|
||||||
LittleEndian.putShort(data, spos, (short)(chunkSize+1));
|
public int getVerticalTextAlignment() {
|
||||||
spos += LittleEndian.SHORT_SIZE;
|
return VerticalTextAlignment.getValue(field_1_options);
|
||||||
|
}
|
||||||
|
|
||||||
//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).
|
* Sets the text locked field value.
|
||||||
data[spos] = 1;
|
*/
|
||||||
spos += LittleEndian.BYTE_SIZE;
|
public void setTextLocked(boolean value) {
|
||||||
|
field_1_options = textLocked.setBoolean(field_1_options, value);
|
||||||
|
}
|
||||||
|
|
||||||
//copy characters data
|
/**
|
||||||
System.arraycopy(c1Data, charsWritten, data, spos, chunkSize);
|
* @return the text locked field value.
|
||||||
spos += chunkSize;
|
*/
|
||||||
charsWritten += chunkSize;
|
public boolean isTextLocked() {
|
||||||
}
|
return textLocked.isSet(field_1_options);
|
||||||
|
}
|
||||||
|
|
||||||
bytesWritten2 = (spos-pos);
|
/**
|
||||||
}
|
* Get the text orientation field for the TextObjectBase record.
|
||||||
catch ( UnsupportedEncodingException e )
|
*
|
||||||
{
|
* @return One of TEXT_ORIENTATION_NONE TEXT_ORIENTATION_TOP_TO_BOTTOM
|
||||||
throw new RuntimeException( e.getMessage(), e );
|
* TEXT_ORIENTATION_ROT_RIGHT TEXT_ORIENTATION_ROT_LEFT
|
||||||
}
|
*/
|
||||||
|
public int getTextOrientation() {
|
||||||
|
return field_2_textOrientation;
|
||||||
|
}
|
||||||
|
|
||||||
pos += bytesWritten2;
|
/**
|
||||||
int bytesWritten3 = c2.serialize( pos, data );
|
* Set the text orientation field for the TextObjectBase record.
|
||||||
pos += bytesWritten3;
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
int size = bytesWritten1 + bytesWritten2 + bytesWritten3;
|
public HSSFRichTextString getStr() {
|
||||||
if ( size != getRecordSize() )
|
return _text;
|
||||||
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()
|
public void setStr(HSSFRichTextString str) {
|
||||||
{
|
_text = str;
|
||||||
ContinueRecord c2 = new ContinueRecord();
|
}
|
||||||
byte[] c2Data = new byte[str.numFormattingRuns() * 8 + 8];
|
|
||||||
int pos = 0;
|
public Ptg getLinkRefPtg() {
|
||||||
for ( int i = 0; i < str.numFormattingRuns(); i++ )
|
return _linkRefPtg;
|
||||||
{
|
}
|
||||||
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 );
|
public String toString() {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
return c2;
|
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");
|
||||||
|
|
||||||
private void processFontRuns( RecordInputStream in )
|
sb.append(" .string = ").append(_text).append('\n');
|
||||||
{
|
|
||||||
while (in.remaining() > 0)
|
|
||||||
{
|
|
||||||
short index = in.readShort();
|
|
||||||
short iFont = in.readShort();
|
|
||||||
in.readInt(); // skip reserved.
|
|
||||||
|
|
||||||
str.applyFont( index, str.length(), iFont );
|
for (int i = 0; i < _text.numFormattingRuns(); i++) {
|
||||||
}
|
sb.append(" .textrun = ").append(_text.getFontOfFormattingRun(i)).append('\n');
|
||||||
}
|
|
||||||
|
|
||||||
private void processRawString( RecordInputStream in )
|
}
|
||||||
{
|
sb.append("[/TXO]\n");
|
||||||
String s;
|
return sb.toString();
|
||||||
byte compressByte = in.readByte();
|
}
|
||||||
boolean isCompressed = compressByte == 0;
|
|
||||||
if ( isCompressed )
|
|
||||||
{
|
|
||||||
s = in.readCompressedUnicode(getTextLength());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s = in.readUnicodeLEString(getTextLength());
|
|
||||||
}
|
|
||||||
str = new HSSFRichTextString( s );
|
|
||||||
}
|
|
||||||
|
|
||||||
public HSSFRichTextString getStr()
|
public Object clone() {
|
||||||
{
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStr( HSSFRichTextString str )
|
TextObjectRecord rec = new TextObjectRecord();
|
||||||
{
|
rec._text = _text;
|
||||||
this.str = str;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString()
|
rec.field_1_options = field_1_options;
|
||||||
{
|
rec.field_2_textOrientation = field_2_textOrientation;
|
||||||
StringBuffer buffer = new StringBuffer();
|
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;
|
||||||
|
|
||||||
buffer.append( "[TXO]\n" );
|
rec._text = _text; // clone needed?
|
||||||
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" ) );
|
|
||||||
|
|
||||||
buffer.append( " .string = " ).append(str).append('\n');
|
|
||||||
|
|
||||||
for (int i = 0; i < str.numFormattingRuns(); i++) {
|
|
||||||
buffer.append( " .textrun = " ).append(str.getFontOfFormattingRun(i)).append('\n');
|
|
||||||
|
|
||||||
}
|
|
||||||
buffer.append( "[/TXO]\n" );
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object clone() {
|
|
||||||
|
|
||||||
TextObjectRecord rec = new TextObjectRecord();
|
|
||||||
rec.str = str;
|
|
||||||
|
|
||||||
rec.setOptions(getOptions());
|
|
||||||
rec.setTextOrientation(getTextOrientation());
|
|
||||||
rec.setReserved4(getReserved4());
|
|
||||||
rec.setReserved5(getReserved5());
|
|
||||||
rec.setReserved6(getReserved6());
|
|
||||||
rec.setTextLength(getTextLength());
|
|
||||||
rec.setFormattingRunLength(getFormattingRunLength());
|
|
||||||
rec.setReserved7(getReserved7());
|
|
||||||
return rec;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.RecordInputStream;
|
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
|
* <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.
|
* 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) {
|
public static Ptg[] readTokens(int size, RecordInputStream in) {
|
||||||
Stack temp = createParsedExpressionTokens((short)size, in);
|
List temp = new ArrayList(4 + size / 2);
|
||||||
return toPtgArray(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated - use readTokens()
|
|
||||||
*/
|
|
||||||
public static Stack createParsedExpressionTokens(short size, RecordInputStream in) {
|
|
||||||
Stack stack = new Stack();
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
List arrayPtgs = null;
|
List arrayPtgs = null;
|
||||||
while (pos < size) {
|
while (pos < size) {
|
||||||
@ -71,7 +61,7 @@ public abstract class Ptg implements Cloneable {
|
|||||||
} else {
|
} else {
|
||||||
pos += ptg.getSize();
|
pos += ptg.getSize();
|
||||||
}
|
}
|
||||||
stack.push( ptg );
|
temp.add( ptg );
|
||||||
}
|
}
|
||||||
if(pos != size) {
|
if(pos != size) {
|
||||||
throw new RuntimeException("Ptg array size mismatch");
|
throw new RuntimeException("Ptg array size mismatch");
|
||||||
@ -82,7 +72,7 @@ public abstract class Ptg implements Cloneable {
|
|||||||
p.readTokenValues(in);
|
p.readTokenValues(in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stack;
|
return toPtgArray(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Ptg createPtg(RecordInputStream in) {
|
public static Ptg createPtg(RecordInputStream in) {
|
||||||
@ -200,19 +190,11 @@ public abstract class Ptg implements Cloneable {
|
|||||||
l.toArray(result);
|
l.toArray(result);
|
||||||
return 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[])}
|
* This method will return the same result as {@link #getEncodedSizeWithoutArrayData(Ptg[])}
|
||||||
* if there are no array tokens present.
|
* if there are no array tokens present.
|
||||||
* @return the full size taken to encode the specified <tt>Ptg</tt>s
|
* @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) {
|
public static int getEncodedSize(Ptg[] ptgs) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for (int i = 0; i < ptgs.length; i++) {
|
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.
|
* The 2 byte encode length field is <b>not</b> written by this method.
|
||||||
* @return number of bytes written
|
* @return number of bytes written
|
||||||
*/
|
*/
|
||||||
public static int serializePtgs(Ptg[] ptgs, byte[] data, int offset) {
|
public static int serializePtgs(Ptg[] ptgs, byte[] array, int offset) {
|
||||||
return serializePtgStack(createStack(ptgs), data, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated use serializePtgs()
|
|
||||||
*/
|
|
||||||
public static int serializePtgStack(Stack expression, byte[] array, int offset) {
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
int size = 0;
|
int size = ptgs.length;
|
||||||
if (expression != null)
|
|
||||||
size = expression.size();
|
|
||||||
|
|
||||||
List arrayPtgs = null;
|
List arrayPtgs = null;
|
||||||
|
|
||||||
for (int k = 0; k < size; k++) {
|
for (int k = 0; k < size; k++) {
|
||||||
Ptg ptg = ( Ptg ) expression.get(k);
|
Ptg ptg = ptgs[k];
|
||||||
|
|
||||||
ptg.writeBytes(array, pos + offset);
|
ptg.writeBytes(array, pos + offset);
|
||||||
if (ptg instanceof ArrayPtg) {
|
if (ptg instanceof ArrayPtg) {
|
||||||
|
@ -149,10 +149,7 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
|||||||
if (hstring.numFormattingRuns() == 0) hstring.applyFont((short)0);
|
if (hstring.numFormattingRuns() == 0) hstring.applyFont((short)0);
|
||||||
|
|
||||||
if (txo != null) {
|
if (txo != null) {
|
||||||
int frLength = ( hstring.numFormattingRuns() + 1 ) * 8;
|
txo.setStr(hstring);
|
||||||
txo.setFormattingRunLength( (short) frLength );
|
|
||||||
txo.setTextLength( (short) hstring.length() );
|
|
||||||
txo.setStr( hstring );
|
|
||||||
}
|
}
|
||||||
super.setString(string);
|
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()
|
public int length()
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,6 @@ package org.apache.poi.hssf.usermodel;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.AreaFormatRecord;
|
import org.apache.poi.hssf.record.AreaFormatRecord;
|
||||||
import org.apache.poi.hssf.record.AxisLineFormatRecord;
|
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.VCenterRecord;
|
||||||
import org.apache.poi.hssf.record.ValueRangeRecord;
|
import org.apache.poi.hssf.record.ValueRangeRecord;
|
||||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
||||||
|
import org.apache.poi.hssf.record.formula.Ptg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has methods for construction of a chart object.
|
* Has methods for construction of a chart object.
|
||||||
@ -759,11 +759,9 @@ public final class HSSFChart {
|
|||||||
r.setCustomNumberFormat( false );
|
r.setCustomNumberFormat( false );
|
||||||
r.setIndexNumberFmtRecord( (short) 0 );
|
r.setIndexNumberFmtRecord( (short) 0 );
|
||||||
LinkedDataFormulaField formula = new LinkedDataFormulaField();
|
LinkedDataFormulaField formula = new LinkedDataFormulaField();
|
||||||
Stack tokens = new Stack();
|
|
||||||
Area3DPtg p = new Area3DPtg(0, 31, 1, 1,
|
Area3DPtg p = new Area3DPtg(0, 31, 1, 1,
|
||||||
false, false, false, false, 0);
|
false, false, false, false, 0);
|
||||||
tokens.add( p );
|
formula.setFormulaTokens(new Ptg[] { p, });
|
||||||
formula.setFormulaTokens( tokens );
|
|
||||||
r.setFormulaOfLink( formula );
|
r.setFormulaOfLink( formula );
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -776,11 +774,9 @@ public final class HSSFChart {
|
|||||||
r.setCustomNumberFormat( false );
|
r.setCustomNumberFormat( false );
|
||||||
r.setIndexNumberFmtRecord( (short) 0 );
|
r.setIndexNumberFmtRecord( (short) 0 );
|
||||||
LinkedDataFormulaField formula = new LinkedDataFormulaField();
|
LinkedDataFormulaField formula = new LinkedDataFormulaField();
|
||||||
Stack tokens = new Stack();
|
|
||||||
Area3DPtg p = new Area3DPtg(0, 31, 0, 0,
|
Area3DPtg p = new Area3DPtg(0, 31, 0, 0,
|
||||||
false, false, false, false, 0);
|
false, false, false, false, 0);
|
||||||
tokens.add( p );
|
formula.setFormulaTokens(new Ptg[] { p, });
|
||||||
formula.setFormulaTokens( tokens );
|
|
||||||
r.setFormulaOfLink( formula );
|
r.setFormulaOfLink( formula );
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -87,10 +87,8 @@ public final class TestEventRecordFactory extends TestCase {
|
|||||||
bof.setHistoryBitMask(BOFRecord.HISTORY_MASK);
|
bof.setHistoryBitMask(BOFRecord.HISTORY_MASK);
|
||||||
|
|
||||||
byte[] bytes = bof.serialize();
|
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.length must be 1, was ="+records.length,records.length == 1);
|
||||||
assertTrue("record is the same", compareRec(bof,records[0]));
|
assertTrue("record is the same", compareRec(bof,records[0]));
|
||||||
|
@ -84,6 +84,7 @@ public final class AllRecordTests {
|
|||||||
result.addTestSuite(TestPaneRecord.class);
|
result.addTestSuite(TestPaneRecord.class);
|
||||||
result.addTestSuite(TestPlotAreaRecord.class);
|
result.addTestSuite(TestPlotAreaRecord.class);
|
||||||
result.addTestSuite(TestPlotGrowthRecord.class);
|
result.addTestSuite(TestPlotGrowthRecord.class);
|
||||||
|
result.addTestSuite(TestRecordInputStream.class);
|
||||||
result.addTestSuite(TestRecordFactory.class);
|
result.addTestSuite(TestRecordFactory.class);
|
||||||
result.addTestSuite(TestSCLRecord.class);
|
result.addTestSuite(TestSCLRecord.class);
|
||||||
result.addTestSuite(TestSSTDeserializer.class);
|
result.addTestSuite(TestSSTDeserializer.class);
|
||||||
|
@ -41,7 +41,7 @@ public final class TestAreaFormatRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( 0xFFFFFF, record.getForegroundColor());
|
||||||
assertEquals( 0x000000, record.getBackgroundColor());
|
assertEquals( 0x000000, record.getBackgroundColor());
|
||||||
assertEquals( 1, record.getPattern());
|
assertEquals( 1, record.getPattern());
|
||||||
|
@ -35,7 +35,7 @@ public final class TestAreaRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( 2, record.getFormatFlags());
|
||||||
assertEquals( false, record.isStacked() );
|
assertEquals( false, record.isStacked() );
|
||||||
assertEquals( true, record.isDisplayAsPercentage() );
|
assertEquals( true, record.isDisplayAsPercentage() );
|
||||||
|
@ -34,7 +34,7 @@ public final class TestAxisLineFormatRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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( AxisLineFormatRecord.AXIS_TYPE_MAJOR_GRID_LINE, record.getAxisType());
|
||||||
|
|
||||||
assertEquals( 6, record.getRecordSize() );
|
assertEquals( 6, record.getRecordSize() );
|
||||||
|
@ -37,7 +37,7 @@ public final class TestAxisOptionsRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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.getMinimumCategory());
|
||||||
assertEquals( 0, record.getMaximumCategory());
|
assertEquals( 0, record.getMaximumCategory());
|
||||||
assertEquals( 1, record.getMajorUnitValue());
|
assertEquals( 1, record.getMajorUnitValue());
|
||||||
|
@ -37,7 +37,7 @@ public final class TestAxisParentRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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( AxisParentRecord.AXIS_TYPE_MAIN, record.getAxisType());
|
||||||
assertEquals( 0x021d, record.getX());
|
assertEquals( 0x021d, record.getX());
|
||||||
assertEquals( 0xdd, record.getY());
|
assertEquals( 0xdd, record.getY());
|
||||||
|
@ -39,7 +39,7 @@ public final class TestAxisRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( AxisRecord.AXIS_TYPE_CATEGORY_OR_X_AXIS, record.getAxisType());
|
||||||
assertEquals( 0, record.getReserved1());
|
assertEquals( 0, record.getReserved1());
|
||||||
assertEquals( 0, record.getReserved2());
|
assertEquals( 0, record.getReserved2());
|
||||||
|
@ -34,7 +34,7 @@ public final class TestAxisUsedRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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( 1, record.getNumAxis());
|
||||||
|
|
||||||
assertEquals( 6, record.getRecordSize() );
|
assertEquals( 6, record.getRecordSize() );
|
||||||
|
@ -37,7 +37,7 @@ public final class TestBarRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( 0, record.getBarSpace());
|
||||||
assertEquals( 0x96, record.getCategorySpace());
|
assertEquals( 0x96, record.getCategorySpace());
|
||||||
assertEquals( 0, record.getFormatFlags());
|
assertEquals( 0, record.getFormatFlags());
|
||||||
|
@ -69,7 +69,7 @@ public final class TestBoundSheetRecord extends TestCase {
|
|||||||
// </str>
|
// </str>
|
||||||
};
|
};
|
||||||
|
|
||||||
RecordInputStream in = new TestcaseRecordInputStream(BoundSheetRecord.sid, data);
|
RecordInputStream in = TestcaseRecordInputStream.create(BoundSheetRecord.sid, data);
|
||||||
BoundSheetRecord bsr = new BoundSheetRecord(in);
|
BoundSheetRecord bsr = new BoundSheetRecord(in);
|
||||||
// sheet name is unicode Russian for 'minor page'
|
// sheet name is unicode Russian for 'minor page'
|
||||||
assertEquals("\u0421\u0442\u0440\u0430\u043D\u0438\u0447\u043A\u0430", bsr.getSheetname());
|
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,
|
(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());
|
assertEquals("#CFRULES", 3, record.getNumberOfConditionalFormats());
|
||||||
assertTrue(record.getNeedRecalculation());
|
assertTrue(record.getNeedRecalculation());
|
||||||
@ -143,7 +143,7 @@ public final class TestCFHeaderRecord extends TestCase
|
|||||||
|
|
||||||
CFHeaderRecord record;
|
CFHeaderRecord record;
|
||||||
try {
|
try {
|
||||||
record = new CFHeaderRecord(new TestcaseRecordInputStream(CFHeaderRecord.sid, (short)recordData.length, recordData));
|
record = new CFHeaderRecord(TestcaseRecordInputStream.create(CFHeaderRecord.sid, recordData));
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
if(e.getMessage().equals("invalid cell range (-25536, 2, -15536, 2)")) {
|
if(e.getMessage().equals("invalid cell range (-25536, 2, -15536, 2)")) {
|
||||||
throw new AssertionFailedError("Identified bug 44739b");
|
throw new AssertionFailedError("Identified bug 44739b");
|
||||||
|
@ -54,7 +54,7 @@ public final class TestCFRuleRecord extends TestCase
|
|||||||
System.arraycopy(serializedRecord, 4, recordData, 0, recordData.length);
|
System.arraycopy(serializedRecord, 4, recordData, 0, recordData.length);
|
||||||
|
|
||||||
// Deserialize
|
// Deserialize
|
||||||
record = new CFRuleRecord(new TestcaseRecordInputStream(CFRuleRecord.sid, (short)recordData.length, recordData));
|
record = new CFRuleRecord(TestcaseRecordInputStream.create(CFRuleRecord.sid, recordData));
|
||||||
|
|
||||||
// Serialize again
|
// Serialize again
|
||||||
byte[] output = record.serialize();
|
byte[] output = record.serialize();
|
||||||
@ -317,7 +317,7 @@ public final class TestCFRuleRecord extends TestCase
|
|||||||
*/
|
*/
|
||||||
public void testReserializeRefNTokens() {
|
public void testReserializeRefNTokens() {
|
||||||
|
|
||||||
RecordInputStream is = new TestcaseRecordInputStream(CFRuleRecord.sid, DATA_REFN);
|
RecordInputStream is = TestcaseRecordInputStream.create(CFRuleRecord.sid, DATA_REFN);
|
||||||
CFRuleRecord rr = new CFRuleRecord(is);
|
CFRuleRecord rr = new CFRuleRecord(is);
|
||||||
Ptg[] ptgs = rr.getParsedExpression1();
|
Ptg[] ptgs = rr.getParsedExpression1();
|
||||||
assertEquals(3, ptgs.length);
|
assertEquals(3, ptgs.length);
|
||||||
|
@ -38,7 +38,7 @@ public final class TestCategorySeriesAxisRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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.getCrossingPoint());
|
||||||
assertEquals( 1, record.getLabelFrequency());
|
assertEquals( 1, record.getLabelFrequency());
|
||||||
assertEquals( 1, record.getTickMarkFrequency());
|
assertEquals( 1, record.getTickMarkFrequency());
|
||||||
|
@ -38,7 +38,7 @@ public final class TestChartRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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.getX());
|
||||||
assertEquals( 0, record.getY());
|
assertEquals( 0, record.getY());
|
||||||
assertEquals( 30474216, record.getWidth());
|
assertEquals( 30474216, record.getWidth());
|
||||||
|
@ -38,7 +38,7 @@ public final class TestCommonObjectDataSubRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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( CommonObjectDataSubRecord.OBJECT_TYPE_LIST_BOX, record.getObjectType());
|
||||||
assertEquals( (short)1, record.getObjectId());
|
assertEquals( (short)1, record.getObjectId());
|
||||||
|
@ -35,7 +35,7 @@ public final class TestDatRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( 0xD, record.getOptions());
|
||||||
assertEquals( true, record.isHorizontalBorder() );
|
assertEquals( true, record.isHorizontalBorder() );
|
||||||
assertEquals( false, record.isVerticalBorder() );
|
assertEquals( false, record.isVerticalBorder() );
|
||||||
|
@ -38,7 +38,7 @@ public final class TestDataFormatRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( (short)0xFFFF, record.getPointNumber());
|
||||||
assertEquals( 0, record.getSeriesIndex());
|
assertEquals( 0, record.getSeriesIndex());
|
||||||
assertEquals( 0, record.getSeriesNumber());
|
assertEquals( 0, record.getSeriesNumber());
|
||||||
|
@ -35,7 +35,7 @@ public final class TestDefaultDataLabelTextPropertiesRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( 2, record.getCategoryDataType());
|
||||||
|
|
||||||
assertEquals( 6, record.getRecordSize() );
|
assertEquals( 6, record.getRecordSize() );
|
||||||
|
@ -127,7 +127,7 @@ public final class TestEmbeddedObjectRefSubRecord extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void confirmRead(byte[] data, int i) {
|
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);
|
EmbeddedObjectRefSubRecord rec = new EmbeddedObjectRefSubRecord(in);
|
||||||
byte[] ser2 = rec.serialize();
|
byte[] ser2 = rec.serialize();
|
||||||
|
@ -33,7 +33,7 @@ public final class TestEndSubRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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() );
|
assertEquals( 4, record.getRecordSize() );
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public final class TestExtendedFormatRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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.getFontIndex());
|
||||||
assertEquals(0, record.getFormatIndex());
|
assertEquals(0, record.getFormatIndex());
|
||||||
assertEquals(0xF5-256, record.getCellOptions());
|
assertEquals(0xF5-256, record.getCellOptions());
|
||||||
@ -117,7 +117,7 @@ public final class TestExtendedFormatRecord extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testCloneOnto() throws Exception {
|
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();
|
ExtendedFormatRecord other = new ExtendedFormatRecord();
|
||||||
other.cloneStyleFrom(base);
|
other.cloneStyleFrom(base);
|
||||||
|
@ -43,7 +43,7 @@ public final class TestExternalNameRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private static ExternalNameRecord createSimpleENR(byte[] data) {
|
private static ExternalNameRecord createSimpleENR(byte[] data) {
|
||||||
return new ExternalNameRecord(new TestcaseRecordInputStream((short)0x0023, data));
|
return new ExternalNameRecord(TestcaseRecordInputStream.create(0x0023, data));
|
||||||
}
|
}
|
||||||
public void testBasicDeserializeReserialize() {
|
public void testBasicDeserializeReserialize() {
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ public final class TestFontBasisRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( 0x1a28, record.getXBasis());
|
||||||
assertEquals( 0x0f9c, record.getYBasis());
|
assertEquals( 0x0f9c, record.getYBasis());
|
||||||
assertEquals( 0xc8, record.getHeightBasis());
|
assertEquals( 0xc8, record.getHeightBasis());
|
||||||
|
@ -35,7 +35,7 @@ public final class TestFontIndexRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( 5, record.getFontIndex());
|
||||||
|
|
||||||
assertEquals( 6, record.getRecordSize() );
|
assertEquals( 6, record.getRecordSize() );
|
||||||
|
@ -44,7 +44,7 @@ public final class TestFontRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( 0xc8, record.getFontHeight());
|
||||||
assertEquals( 0x00, record.getAttributes());
|
assertEquals( 0x00, record.getAttributes());
|
||||||
assertFalse( record.isItalic());
|
assertFalse( record.isItalic());
|
||||||
@ -100,7 +100,7 @@ public final class TestFontRecord extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testCloneOnto() throws Exception {
|
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();
|
FontRecord other = new FontRecord();
|
||||||
other.cloneStyleFrom(base);
|
other.cloneStyleFrom(base);
|
||||||
@ -112,8 +112,8 @@ public final class TestFontRecord extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testSameProperties() throws Exception {
|
public void testSameProperties() throws Exception {
|
||||||
FontRecord f1 = new FontRecord(new TestcaseRecordInputStream((short)0x31, (short)data.length, data));
|
FontRecord f1 = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
|
||||||
FontRecord f2 = new FontRecord(new TestcaseRecordInputStream((short)0x31, (short)data.length, data));
|
FontRecord f2 = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
|
||||||
|
|
||||||
assertTrue(f1.sameProperties(f2));
|
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("Row", 0, record.getRow());
|
||||||
assertEquals("Column", 0, record.getColumn());
|
assertEquals("Column", 0, record.getColumn());
|
||||||
assertEquals(HSSFCell.CELL_TYPE_ERROR, record.getCachedResultType());
|
assertEquals(HSSFCell.CELL_TYPE_ERROR, record.getCachedResultType());
|
||||||
@ -108,7 +108,7 @@ public final class TestFormulaRecord extends TestCase {
|
|||||||
formulaByte[19]=(byte)0xFD;
|
formulaByte[19]=(byte)0xFD;
|
||||||
formulaByte[20]=(byte)0x05;
|
formulaByte[20]=(byte)0x05;
|
||||||
formulaByte[22]=(byte)0x01;
|
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("Row", 0, record.getRow());
|
||||||
assertEquals("Column", 0, record.getColumn());
|
assertEquals("Column", 0, record.getColumn());
|
||||||
byte[] output = record.serialize();
|
byte[] output = record.serialize();
|
||||||
|
@ -36,7 +36,7 @@ public final class TestFrameRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( FrameRecord.BORDER_TYPE_REGULAR, record.getBorderType());
|
||||||
assertEquals( 2, record.getOptions());
|
assertEquals( 2, record.getOptions());
|
||||||
assertEquals( false, record.isAutoSize() );
|
assertEquals( false, record.isAutoSize() );
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
package org.apache.poi.hssf.record;
|
package org.apache.poi.hssf.record;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
@ -28,7 +27,7 @@ import junit.framework.TestCase;
|
|||||||
* @author Nick Burch
|
* @author Nick Burch
|
||||||
* @author Yegor Kozlov
|
* @author Yegor Kozlov
|
||||||
*/
|
*/
|
||||||
public class TestHyperlinkRecord extends TestCase {
|
public final class TestHyperlinkRecord extends TestCase {
|
||||||
|
|
||||||
//link to http://www.lakings.com/
|
//link to http://www.lakings.com/
|
||||||
byte[] data1 = { 0x02, 0x00, //First row of the hyperlink
|
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};
|
0x00, 0x41, 0x00, 0x31, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
public void testReadURLLink(){
|
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);
|
HyperlinkRecord link = new HyperlinkRecord(is);
|
||||||
assertEquals(2, link.getFirstRow());
|
assertEquals(2, link.getFirstRow());
|
||||||
assertEquals(2, link.getLastRow());
|
assertEquals(2, link.getLastRow());
|
||||||
@ -184,7 +183,7 @@ public class TestHyperlinkRecord extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testReadFileLink(){
|
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);
|
HyperlinkRecord link = new HyperlinkRecord(is);
|
||||||
assertEquals(0, link.getFirstRow());
|
assertEquals(0, link.getFirstRow());
|
||||||
assertEquals(0, link.getLastRow());
|
assertEquals(0, link.getLastRow());
|
||||||
@ -202,7 +201,7 @@ public class TestHyperlinkRecord extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testReadEmailLink(){
|
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);
|
HyperlinkRecord link = new HyperlinkRecord(is);
|
||||||
assertEquals(1, link.getFirstRow());
|
assertEquals(1, link.getFirstRow());
|
||||||
assertEquals(1, link.getLastRow());
|
assertEquals(1, link.getLastRow());
|
||||||
@ -220,7 +219,7 @@ public class TestHyperlinkRecord extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testReadDocumentLink(){
|
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);
|
HyperlinkRecord link = new HyperlinkRecord(is);
|
||||||
assertEquals(3, link.getFirstRow());
|
assertEquals(3, link.getFirstRow());
|
||||||
assertEquals(3, link.getLastRow());
|
assertEquals(3, link.getLastRow());
|
||||||
@ -237,7 +236,7 @@ public class TestHyperlinkRecord extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void serialize(byte[] data){
|
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);
|
HyperlinkRecord link = new HyperlinkRecord(is);
|
||||||
byte[] bytes1 = link.serialize();
|
byte[] bytes1 = link.serialize();
|
||||||
is = new RecordInputStream(new ByteArrayInputStream(bytes1));
|
is = new RecordInputStream(new ByteArrayInputStream(bytes1));
|
||||||
@ -318,7 +317,7 @@ public class TestHyperlinkRecord extends TestCase {
|
|||||||
public void testClone() throws Exception {
|
public void testClone() throws Exception {
|
||||||
byte[][] data = {data1, data2, data3, data4};
|
byte[][] data = {data1, data2, data3, data4};
|
||||||
for (int i = 0; i < data.length; i++) {
|
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 link = new HyperlinkRecord(is);
|
||||||
HyperlinkRecord clone = (HyperlinkRecord)link.clone();
|
HyperlinkRecord clone = (HyperlinkRecord)link.clone();
|
||||||
assertTrue(Arrays.equals(link.serialize(), clone.serialize()));
|
assertTrue(Arrays.equals(link.serialize(), clone.serialize()));
|
||||||
|
@ -17,80 +17,73 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record;
|
package org.apache.poi.hssf.record;
|
||||||
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the serialization and deserialization of the LegendRecord
|
* Tests the serialization and deserialization of the LegendRecord class works
|
||||||
* class works correctly. Test data taken directly from a real
|
* correctly. Test data taken directly from a real Excel file.
|
||||||
* Excel file.
|
*
|
||||||
*
|
*
|
||||||
|
|
||||||
* @author Andrew C. Oliver (acoliver at apache.org)
|
* @author Andrew C. Oliver (acoliver at apache.org)
|
||||||
*/
|
*/
|
||||||
public class TestLegendRecord extends TestCase {
|
public final class TestLegendRecord extends TestCase {
|
||||||
byte[] data = new byte[] {
|
byte[] data = new byte[] { (byte) 0x76, (byte) 0x0E, (byte) 0x00, (byte) 0x00, (byte) 0x86,
|
||||||
(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
|
(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() {
|
public void testLoad() {
|
||||||
LegendRecord record = new LegendRecord(new TestcaseRecordInputStream((short)0x1015, (short)data.length, data));
|
LegendRecord record = new LegendRecord(TestcaseRecordInputStream.create(0x1015, data));
|
||||||
|
|
||||||
|
|
||||||
assertEquals( (int)0xe76, record.getXAxisUpperLeft());
|
assertEquals(0xe76, record.getXAxisUpperLeft());
|
||||||
|
|
||||||
assertEquals( (int)0x786, record.getYAxisUpperLeft());
|
assertEquals(0x786, record.getYAxisUpperLeft());
|
||||||
|
|
||||||
assertEquals( (int)0x119, record.getXSize());
|
assertEquals(0x119, record.getXSize());
|
||||||
|
|
||||||
assertEquals( (int)0x8b, record.getYSize());
|
assertEquals(0x8b, record.getYSize());
|
||||||
|
|
||||||
assertEquals( (byte)0x3, record.getType());
|
assertEquals((byte) 0x3, record.getType());
|
||||||
|
|
||||||
assertEquals( (byte)0x1, record.getSpacing());
|
assertEquals((byte) 0x1, record.getSpacing());
|
||||||
|
|
||||||
assertEquals( (short)0x1f, record.getOptions());
|
assertEquals((short) 0x1f, record.getOptions());
|
||||||
assertEquals( true, record.isAutoPosition() );
|
assertEquals(true, record.isAutoPosition());
|
||||||
assertEquals( true, record.isAutoSeries() );
|
assertEquals(true, record.isAutoSeries());
|
||||||
assertEquals( true, record.isAutoXPositioning() );
|
assertEquals(true, record.isAutoXPositioning());
|
||||||
assertEquals( true, record.isAutoYPositioning() );
|
assertEquals(true, record.isAutoYPositioning());
|
||||||
assertEquals( true, record.isVertical() );
|
assertEquals(true, record.isVertical());
|
||||||
assertEquals( false, record.isDataTable() );
|
assertEquals(false, record.isDataTable());
|
||||||
|
|
||||||
|
assertEquals(24, record.getRecordSize());
|
||||||
|
}
|
||||||
|
|
||||||
assertEquals( 24, record.getRecordSize() );
|
public void testStore() {
|
||||||
}
|
LegendRecord record = new LegendRecord();
|
||||||
|
|
||||||
public void testStore()
|
record.setXAxisUpperLeft(0xe76);
|
||||||
{
|
|
||||||
LegendRecord record = new LegendRecord();
|
|
||||||
|
|
||||||
|
record.setYAxisUpperLeft(0x786);
|
||||||
|
|
||||||
|
record.setXSize(0x119);
|
||||||
|
|
||||||
record.setXAxisUpperLeft( (int)0xe76 );
|
record.setYSize(0x8b);
|
||||||
|
|
||||||
record.setYAxisUpperLeft( (int)0x786 );
|
record.setType((byte) 0x3);
|
||||||
|
|
||||||
record.setXSize( (int)0x119 );
|
record.setSpacing((byte) 0x1);
|
||||||
|
|
||||||
record.setYSize( (int)0x8b );
|
record.setOptions((short) 0x1f);
|
||||||
|
record.setAutoPosition(true);
|
||||||
|
record.setAutoSeries(true);
|
||||||
|
record.setAutoXPositioning(true);
|
||||||
|
record.setAutoYPositioning(true);
|
||||||
|
record.setVertical(true);
|
||||||
|
record.setDataTable(false);
|
||||||
|
|
||||||
record.setType( (byte)0x3 );
|
byte[] recordBytes = record.serialize();
|
||||||
|
assertEquals(recordBytes.length - 4, data.length);
|
||||||
record.setSpacing( (byte)0x1 );
|
for (int i = 0; i < data.length; i++)
|
||||||
|
assertEquals("At offset " + i, data[i], recordBytes[i + 4]);
|
||||||
record.setOptions( (short)0x1f );
|
}
|
||||||
record.setAutoPosition( true );
|
|
||||||
record.setAutoSeries( true );
|
|
||||||
record.setAutoXPositioning( true );
|
|
||||||
record.setAutoYPositioning( true );
|
|
||||||
record.setVertical( true );
|
|
||||||
record.setDataTable( false );
|
|
||||||
|
|
||||||
|
|
||||||
byte [] recordBytes = record.serialize();
|
|
||||||
assertEquals(recordBytes.length - 4, data.length);
|
|
||||||
for (int i = 0; i < data.length; i++)
|
|
||||||
assertEquals("At offset " + i, data[i], recordBytes[i+4]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ import junit.framework.TestCase;
|
|||||||
|
|
||||||
* @author Glen Stampoultzis (glens at apache.org)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
*/
|
*/
|
||||||
public class TestLineFormatRecord extends TestCase {
|
public final class TestLineFormatRecord extends TestCase {
|
||||||
byte[] data = new byte[] {
|
byte[] data = new byte[] {
|
||||||
(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, // colour
|
(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, // colour
|
||||||
(byte)0x00,(byte)0x00, // pattern
|
(byte)0x00,(byte)0x00, // pattern
|
||||||
@ -38,7 +38,7 @@ public class TestLineFormatRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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.getLineColor());
|
||||||
assertEquals( 0, record.getLinePattern());
|
assertEquals( 0, record.getLinePattern());
|
||||||
assertEquals( 0, record.getWeight());
|
assertEquals( 0, record.getWeight());
|
||||||
|
@ -19,9 +19,9 @@ package org.apache.poi.hssf.record;
|
|||||||
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
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
|
* Tests the serialization and deserialization of the LinkedDataRecord
|
||||||
@ -157,7 +157,7 @@ recordid = 0x1051, size =8
|
|||||||
|
|
||||||
public void testLoad() {
|
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.LINK_TYPE_VALUES, record.getLinkType());
|
||||||
assertEquals( LinkedDataRecord.REFERENCE_TYPE_WORKSHEET, record.getReferenceType());
|
assertEquals( LinkedDataRecord.REFERENCE_TYPE_WORKSHEET, record.getReferenceType());
|
||||||
assertEquals( 0, record.getOptions());
|
assertEquals( 0, record.getOptions());
|
||||||
@ -167,7 +167,7 @@ recordid = 0x1051, size =8
|
|||||||
Area3DPtg ptgExpected = new Area3DPtg(0, 7936, 0, 0,
|
Area3DPtg ptgExpected = new Area3DPtg(0, 7936, 0, 0,
|
||||||
false, false, false, false, 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(ptgExpected.toString(), ptgActual.toString());
|
||||||
|
|
||||||
assertEquals( data.length + 4, record.getRecordSize() );
|
assertEquals( data.length + 4, record.getRecordSize() );
|
||||||
@ -182,10 +182,8 @@ recordid = 0x1051, size =8
|
|||||||
record.setIndexNumberFmtRecord( (short)0 );
|
record.setIndexNumberFmtRecord( (short)0 );
|
||||||
Area3DPtg ptg = new Area3DPtg(0, 7936, 0, 0,
|
Area3DPtg ptg = new Area3DPtg(0, 7936, 0, 0,
|
||||||
false, false, false, false, 0);
|
false, false, false, false, 0);
|
||||||
Stack s = new Stack();
|
|
||||||
s.push(ptg);
|
|
||||||
LinkedDataFormulaField formulaOfLink = new LinkedDataFormulaField();
|
LinkedDataFormulaField formulaOfLink = new LinkedDataFormulaField();
|
||||||
formulaOfLink.setFormulaTokens(s);
|
formulaOfLink.setFormulaTokens(new Ptg[] { ptg, });
|
||||||
record.setFormulaOfLink(formulaOfLink );
|
record.setFormulaOfLink(formulaOfLink );
|
||||||
|
|
||||||
byte [] recordBytes = record.serialize();
|
byte [] recordBytes = record.serialize();
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
/* ====================================================================
|
/* ====================================================================
|
||||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
contributor license agreements. See the NOTICE file distributed with
|
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)
|
* @author Danny Mui (dmui at apache dot org)
|
||||||
*/
|
*/
|
||||||
public class TestNameRecord
|
public final class TestNameRecord extends TestCase {
|
||||||
extends TestCase
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes sure that additional name information is parsed properly such as menu/description
|
* 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();
|
String description = name.getDescriptionText();
|
||||||
assertNotNull( description );
|
assertNotNull( description );
|
||||||
assertTrue( "text contains ALLWOR", description.indexOf( "ALLWOR" ) > 0 );
|
assertTrue( "text contains ALLWOR", description.indexOf( "ALLWOR" ) > 0 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,9 +29,7 @@ import java.util.Arrays;
|
|||||||
*
|
*
|
||||||
* @author Yegor Kozlov
|
* @author Yegor Kozlov
|
||||||
*/
|
*/
|
||||||
public class TestNoteRecord
|
public final class TestNoteRecord extends TestCase {
|
||||||
extends TestCase
|
|
||||||
{
|
|
||||||
private byte[] data = new byte[] {
|
private byte[] data = new byte[] {
|
||||||
0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x04, 0x1A, 0x00,
|
0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x04, 0x1A, 0x00,
|
||||||
0x00, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x20, 0x53, 0x6F,
|
0x00, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x20, 0x53, 0x6F,
|
||||||
@ -41,7 +39,7 @@ public class TestNoteRecord
|
|||||||
|
|
||||||
public void testRead() {
|
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(NoteRecord.sid, record.getSid());
|
||||||
assertEquals(6, record.getRow());
|
assertEquals(6, record.getRow());
|
||||||
|
@ -38,7 +38,7 @@ public final class TestNoteStructureSubRecord extends TestCase {
|
|||||||
|
|
||||||
public void testRead() {
|
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(NoteStructureSubRecord.sid, record.getSid());
|
||||||
assertEquals(data.length + 4, record.getRecordSize());
|
assertEquals(data.length + 4, record.getRecordSize());
|
||||||
|
@ -35,7 +35,7 @@ public final class TestNumberFormatIndexRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( 5, record.getFormatIndex());
|
||||||
|
|
||||||
assertEquals( 6, record.getRecordSize() );
|
assertEquals( 6, record.getRecordSize() );
|
||||||
|
@ -51,7 +51,7 @@ public final class TestObjRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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);
|
assertEquals(28, record.getRecordSize() - 4);
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ public final class TestObjRecord extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testStore() {
|
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();
|
byte [] recordBytes = record.serialize();
|
||||||
assertEquals(28, recordBytes.length - 4);
|
assertEquals(28, recordBytes.length - 4);
|
||||||
@ -91,7 +91,7 @@ public final class TestObjRecord extends TestCase {
|
|||||||
byte [] bytes = new byte[recordBytes.length-4];
|
byte [] bytes = new byte[recordBytes.length-4];
|
||||||
System.arraycopy(recordBytes, 4, bytes, 0, bytes.length);
|
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();
|
List subrecords = record.getSubRecords();
|
||||||
assertEquals( 2, subrecords.size() );
|
assertEquals( 2, subrecords.size() );
|
||||||
assertTrue( subrecords.get(0) instanceof CommonObjectDataSubRecord);
|
assertTrue( subrecords.get(0) instanceof CommonObjectDataSubRecord);
|
||||||
@ -99,7 +99,7 @@ public final class TestObjRecord extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testReadWriteWithPadding_bug45133() {
|
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) {
|
if (record.getRecordSize() == 34) {
|
||||||
throw new AssertionFailedError("Identified bug 45133");
|
throw new AssertionFailedError("Identified bug 45133");
|
||||||
|
@ -34,7 +34,7 @@ public final class TestObjectLinkRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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)3, record.getAnchorId());
|
||||||
assertEquals( (short)0x00, record.getLink1());
|
assertEquals( (short)0x00, record.getLink1());
|
||||||
|
@ -37,7 +37,7 @@ public final class TestPaneRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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)1, record.getX());
|
||||||
assertEquals( (short)2, record.getY());
|
assertEquals( (short)2, record.getY());
|
||||||
|
@ -34,7 +34,7 @@ public final class TestPlotAreaRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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() );
|
assertEquals( 4, record.getRecordSize() );
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ public final class TestPlotGrowthRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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.getHorizontalScale());
|
||||||
assertEquals( 65536, record.getVerticalScale());
|
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
|
0, 6, 5, 0, -2, 28, -51, 7, -55, 64, 0, 0, 6, 1, 0, 0
|
||||||
};
|
};
|
||||||
short size = 16;
|
short size = 16;
|
||||||
Record[] record = RecordFactory.createRecord(new TestcaseRecordInputStream(recType, size, data));
|
Record[] record = RecordFactory.createRecord(TestcaseRecordInputStream.create(recType, data));
|
||||||
|
|
||||||
assertEquals(BOFRecord.class.getName(),
|
assertEquals(BOFRecord.class.getName(),
|
||||||
record[ 0 ].getClass().getName());
|
record[ 0 ].getClass().getName());
|
||||||
@ -69,7 +69,7 @@ public final class TestRecordFactory extends TestCase {
|
|||||||
{
|
{
|
||||||
0, 0
|
0, 0
|
||||||
};
|
};
|
||||||
record = RecordFactory.createRecord(new TestcaseRecordInputStream(recType, size, data));
|
record = RecordFactory.createRecord(TestcaseRecordInputStream.create(recType, data));
|
||||||
assertEquals(MMSRecord.class.getName(),
|
assertEquals(MMSRecord.class.getName(),
|
||||||
record[ 0 ].getClass().getName());
|
record[ 0 ].getClass().getName());
|
||||||
MMSRecord mmsRecord = ( MMSRecord ) record[ 0 ];
|
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
|
0, 0, 0, 0, 21, 0, 0, 0, 0, 0
|
||||||
};
|
};
|
||||||
short size = 10;
|
short size = 10;
|
||||||
Record[] record = RecordFactory.createRecord(new TestcaseRecordInputStream(recType, size, data));
|
Record[] record = RecordFactory.createRecord(TestcaseRecordInputStream.create(recType, data));
|
||||||
|
|
||||||
assertEquals(NumberRecord.class.getName(),
|
assertEquals(NumberRecord.class.getName(),
|
||||||
record[ 0 ].getClass().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() {
|
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( 3, record.getNumerator());
|
||||||
assertEquals( 4, record.getDenominator());
|
assertEquals( 4, record.getDenominator());
|
||||||
|
|
||||||
|
@ -32,31 +32,30 @@ import org.apache.poi.util.IntMapper;
|
|||||||
* @author Glen Stampoultzis (glens at apache.org)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
*/
|
*/
|
||||||
public final class TestSSTDeserializer extends TestCase {
|
public final class TestSSTDeserializer extends TestCase {
|
||||||
|
private static final int FAKE_SID = -5555;
|
||||||
|
|
||||||
|
private static byte[] concat(byte[] a, byte[] b) {
|
||||||
private byte[] joinArray(byte[] array1, byte[] array2) {
|
byte[] result = new byte[a.length + b.length];
|
||||||
byte[] bigArray = new byte[array1.length + array2.length];
|
System.arraycopy(a, 0, result, 0, a.length);
|
||||||
System.arraycopy(array1, 0, bigArray, 0, array1.length);
|
System.arraycopy(b, 0, result, a.length, b.length);
|
||||||
System.arraycopy(array2, 0, bigArray, array1.length, array2.length);
|
return result;
|
||||||
return bigArray;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] readSampleHexData(String sampleFileName, String sectionName) {
|
private static byte[] readSampleHexData(String sampleFileName, String sectionName, int recSid) {
|
||||||
InputStream is = HSSFTestDataSamples.openSampleFileStream(sampleFileName);
|
InputStream is = HSSFTestDataSamples.openSampleFileStream(sampleFileName);
|
||||||
|
byte[] data;
|
||||||
try {
|
try {
|
||||||
return HexRead.readData(is, sectionName);
|
data = HexRead.readData(is, sectionName);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
return TestcaseRecordInputStream.mergeDataAndSid(recSid, data.length, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSpanRichTextToPlainText()
|
public void testSpanRichTextToPlainText() {
|
||||||
throws Exception
|
byte[] header = readSampleHexData("richtextdata.txt", "header", FAKE_SID);
|
||||||
{
|
byte[] continueBytes = readSampleHexData("richtextdata.txt", "continue1", ContinueRecord.sid);
|
||||||
byte[] header = readSampleHexData("richtextdata.txt", "header" );
|
RecordInputStream in = TestcaseRecordInputStream.create(concat(header, continueBytes));
|
||||||
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));
|
|
||||||
|
|
||||||
|
|
||||||
IntMapper strings = new IntMapper();
|
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 ) + "" );
|
assertEquals( "At a dinner party orAt At At ", strings.get( 0 ) + "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testContinuationWithNoOverlap()
|
public void testContinuationWithNoOverlap() {
|
||||||
throws Exception
|
byte[] header = readSampleHexData("evencontinuation.txt", "header", FAKE_SID);
|
||||||
{
|
byte[] continueBytes = readSampleHexData("evencontinuation.txt", "continue1", ContinueRecord.sid);
|
||||||
byte[] header = readSampleHexData("evencontinuation.txt", "header" );
|
RecordInputStream in = TestcaseRecordInputStream.create(concat(header, continueBytes));
|
||||||
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));
|
|
||||||
|
|
||||||
IntMapper strings = new IntMapper();
|
IntMapper strings = new IntMapper();
|
||||||
SSTDeserializer deserializer = new SSTDeserializer( strings );
|
SSTDeserializer deserializer = new SSTDeserializer( strings );
|
||||||
@ -85,18 +81,12 @@ public final class TestSSTDeserializer extends TestCase {
|
|||||||
/**
|
/**
|
||||||
* Strings can actually span across more than one continuation.
|
* Strings can actually span across more than one continuation.
|
||||||
*/
|
*/
|
||||||
public void testStringAcross2Continuations()
|
public void testStringAcross2Continuations() {
|
||||||
throws Exception
|
byte[] header = readSampleHexData("stringacross2continuations.txt", "header", FAKE_SID);
|
||||||
{
|
byte[] continue1 = readSampleHexData("stringacross2continuations.txt", "continue1", ContinueRecord.sid);
|
||||||
byte[] header = readSampleHexData("stringacross2continuations.txt", "header" );
|
byte[] continue2 = readSampleHexData("stringacross2continuations.txt", "continue2", ContinueRecord.sid);
|
||||||
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);
|
|
||||||
|
|
||||||
byte[] bytes = joinArray(header, continue1);
|
RecordInputStream in = TestcaseRecordInputStream.create(concat(header, concat(continue1, continue2)));
|
||||||
bytes = joinArray(bytes, continue2);
|
|
||||||
TestcaseRecordInputStream in = new TestcaseRecordInputStream((short)0, (short)header.length, bytes);
|
|
||||||
|
|
||||||
IntMapper strings = new IntMapper();
|
IntMapper strings = new IntMapper();
|
||||||
SSTDeserializer deserializer = new SSTDeserializer( strings );
|
SSTDeserializer deserializer = new SSTDeserializer( strings );
|
||||||
@ -107,10 +97,9 @@ public final class TestSSTDeserializer extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testExtendedStrings() {
|
public void testExtendedStrings() {
|
||||||
byte[] header = readSampleHexData("extendedtextstrings.txt", "rich-header" );
|
byte[] header = readSampleHexData("extendedtextstrings.txt", "rich-header", FAKE_SID);
|
||||||
byte[] continueBytes = readSampleHexData("extendedtextstrings.txt", "rich-continue1" );
|
byte[] continueBytes = readSampleHexData("extendedtextstrings.txt", "rich-continue1", ContinueRecord.sid);
|
||||||
continueBytes = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continueBytes.length, continueBytes);
|
RecordInputStream in = TestcaseRecordInputStream.create(concat(header, continueBytes));
|
||||||
TestcaseRecordInputStream in = new TestcaseRecordInputStream((short)0, (short)header.length, joinArray(header, continueBytes));
|
|
||||||
|
|
||||||
IntMapper strings = new IntMapper();
|
IntMapper strings = new IntMapper();
|
||||||
SSTDeserializer deserializer = new SSTDeserializer( strings );
|
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 ) + "" );
|
assertEquals( "At a dinner party orAt At At ", strings.get( 0 ) + "" );
|
||||||
|
|
||||||
|
|
||||||
header = readSampleHexData("extendedtextstrings.txt", "norich-header" );
|
header = readSampleHexData("extendedtextstrings.txt", "norich-header", FAKE_SID);
|
||||||
continueBytes = readSampleHexData("extendedtextstrings.txt", "norich-continue1" );
|
continueBytes = readSampleHexData("extendedtextstrings.txt", "norich-continue1", ContinueRecord.sid);
|
||||||
continueBytes = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continueBytes.length, continueBytes);
|
in = TestcaseRecordInputStream.create(concat(header, continueBytes));
|
||||||
in = new TestcaseRecordInputStream((short)0, (short)header.length, joinArray(header, continueBytes));
|
|
||||||
|
|
||||||
strings = new IntMapper();
|
strings = new IntMapper();
|
||||||
deserializer = new SSTDeserializer( strings );
|
deserializer = new SSTDeserializer( strings );
|
||||||
|
@ -33,7 +33,7 @@ public final class TestSeriesChartGroupIndexRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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( 0, record.getChartGroupIndex());
|
||||||
|
|
||||||
assertEquals( 6, record.getRecordSize() );
|
assertEquals( 6, record.getRecordSize() );
|
||||||
|
@ -34,7 +34,7 @@ public final class TestSeriesIndexRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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( (short)3, record.getIndex());
|
||||||
assertEquals( 6, record.getRecordSize() );
|
assertEquals( 6, record.getRecordSize() );
|
||||||
|
@ -34,7 +34,7 @@ public final class TestSeriesLabelsRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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( 3, record.getFormatFlags());
|
||||||
assertEquals( true, record.isShowActual() );
|
assertEquals( true, record.isShowActual() );
|
||||||
assertEquals( true, record.isShowPercent() );
|
assertEquals( true, record.isShowPercent() );
|
||||||
|
@ -35,7 +35,7 @@ public final class TestSeriesListRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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)0x2001, record.getSeriesNumbers()[0]);
|
||||||
assertEquals( (short)0xf0ff, record.getSeriesNumbers()[1]);
|
assertEquals( (short)0xf0ff, record.getSeriesNumbers()[1]);
|
||||||
assertEquals( 2, record.getSeriesNumbers().length);
|
assertEquals( 2, record.getSeriesNumbers().length);
|
||||||
|
@ -39,7 +39,7 @@ public final class TestSeriesRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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.CATEGORY_DATA_TYPE_NUMERIC, record.getCategoryDataType());
|
||||||
assertEquals( SeriesRecord.VALUES_DATA_TYPE_NUMERIC, record.getValuesDataType());
|
assertEquals( SeriesRecord.VALUES_DATA_TYPE_NUMERIC, record.getValuesDataType());
|
||||||
assertEquals( 27, record.getNumCategories());
|
assertEquals( 27, record.getNumCategories());
|
||||||
|
@ -34,7 +34,7 @@ public final class TestSeriesTextRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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( (short)0, record.getId());
|
||||||
assertEquals( (byte)0x0C, record.getTextLength());
|
assertEquals( (byte)0x0C, record.getTextLength());
|
||||||
|
@ -34,7 +34,7 @@ public final class TestSeriesToChartGroupRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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( 0x0, record.getChartGroupIndex());
|
||||||
|
|
||||||
assertEquals( 0x6, record.getRecordSize() );
|
assertEquals( 0x6, record.getRecordSize() );
|
||||||
|
@ -59,7 +59,7 @@ public final class TestSharedFormulaRecord extends TestCase {
|
|||||||
*/
|
*/
|
||||||
public void testConvertSharedFormulasOperandClasses_bug45123() {
|
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();
|
int encodedLen = in.readUShort();
|
||||||
Ptg[] sharedFormula = Ptg.readTokens(encodedLen, in);
|
Ptg[] sharedFormula = Ptg.readTokens(encodedLen, in);
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ public final class TestSheetPropertiesRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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( 10, record.getFlags());
|
||||||
assertEquals( false, record.isChartTypeManuallyFormatted() );
|
assertEquals( false, record.isChartTypeManuallyFormatted() );
|
||||||
assertEquals( true, record.isPlotVisibleOnly() );
|
assertEquals( true, record.isPlotVisibleOnly() );
|
||||||
|
@ -27,7 +27,7 @@ import junit.framework.TestCase;
|
|||||||
*
|
*
|
||||||
* @author Glen Stampoultzis (glens at apache.org)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
*/
|
*/
|
||||||
public class TestStringRecord extends TestCase {
|
public final class TestStringRecord extends TestCase {
|
||||||
byte[] data = new byte[] {
|
byte[] data = new byte[] {
|
||||||
(byte)0x0B,(byte)0x00, // length
|
(byte)0x0B,(byte)0x00, // length
|
||||||
(byte)0x00, // option
|
(byte)0x00, // option
|
||||||
@ -37,7 +37,7 @@ public class TestStringRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( "Fahrzeugtyp", record.getString());
|
||||||
|
|
||||||
assertEquals( 18, record.getRecordSize() );
|
assertEquals( 18, record.getRecordSize() );
|
||||||
|
@ -51,7 +51,7 @@ public final class TestSupBookRecord extends TestCase {
|
|||||||
*/
|
*/
|
||||||
public void testLoadIR() {
|
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
|
assertTrue( record.isInternalReferences() ); //expected flag
|
||||||
assertEquals( 0x4, record.getNumberOfSheets() ); //expected # of sheets
|
assertEquals( 0x4, record.getNumberOfSheets() ); //expected # of sheets
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ public final class TestSupBookRecord extends TestCase {
|
|||||||
*/
|
*/
|
||||||
public void testLoadER() {
|
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
|
assertTrue( record.isExternalReferences() ); //expected flag
|
||||||
assertEquals( 0x2, record.getNumberOfSheets() ); //expected # of sheets
|
assertEquals( 0x2, record.getNumberOfSheets() ); //expected # of sheets
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ public final class TestSupBookRecord extends TestCase {
|
|||||||
*/
|
*/
|
||||||
public void testLoadAIF() {
|
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
|
assertTrue( record.isAddInFunctions() ); //expected flag
|
||||||
assertEquals( 0x1, record.getNumberOfSheets() ); //expected # of sheets
|
assertEquals( 0x1, record.getNumberOfSheets() ); //expected # of sheets
|
||||||
assertEquals( 8, record.getRecordSize() ); //sid+size+data
|
assertEquals( 8, record.getRecordSize() ); //sid+size+data
|
||||||
|
@ -44,7 +44,7 @@ public final class TestTableRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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();
|
CellRangeAddress8Bit range = record.getRange();
|
||||||
assertEquals(3, range.getFirstRow());
|
assertEquals(3, range.getFirstRow());
|
||||||
|
@ -18,6 +18,11 @@
|
|||||||
package org.apache.poi.hssf.record;
|
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;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,63 +30,62 @@ import junit.framework.TestCase;
|
|||||||
* class works correctly. Test data taken directly from a real
|
* class works correctly. Test data taken directly from a real
|
||||||
* Excel file.
|
* Excel file.
|
||||||
*
|
*
|
||||||
|
|
||||||
* @author Glen Stampoultzis (glens at apache.org)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
*/
|
*/
|
||||||
public class TestTextObjectBaseRecord extends TestCase {
|
public final class TestTextObjectBaseRecord extends TestCase {
|
||||||
byte[] data = new byte[] {
|
/** data for one TXO rec and two continue recs */
|
||||||
0x44, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
private static final byte[] data = HexRead.readFromString(
|
||||||
0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
|
"B6 01 " + // TextObjectRecord.sid
|
||||||
0x00, 0x00,
|
"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() {
|
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(TextObjectRecord.HORIZONTAL_TEXT_ALIGNMENT_CENTERED, record.getHorizontalTextAlignment());
|
||||||
assertEquals( false, record.isReserved1() );
|
assertEquals(TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_JUSTIFY, record.getVerticalTextAlignment());
|
||||||
assertEquals( TextObjectBaseRecord.HORIZONTAL_TEXT_ALIGNMENT_CENTERED, record.getHorizontalTextAlignment() );
|
assertEquals(true, record.isTextLocked());
|
||||||
assertEquals( TextObjectBaseRecord.VERTICAL_TEXT_ALIGNMENT_JUSTIFY, record.getVerticalTextAlignment() );
|
assertEquals(TextObjectRecord.TEXT_ORIENTATION_ROT_RIGHT, record.getTextOrientation());
|
||||||
assertEquals( 0, record.getReserved2() );
|
|
||||||
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(51, record.getRecordSize() );
|
||||||
assertEquals( 22, record.getRecordSize() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStore()
|
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.setHorizontalTextAlignment(TextObjectRecord.HORIZONTAL_TEXT_ALIGNMENT_CENTERED);
|
||||||
record.setReserved1( false );
|
record.setVerticalTextAlignment(TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_JUSTIFY);
|
||||||
record.setHorizontalTextAlignment( TextObjectBaseRecord.HORIZONTAL_TEXT_ALIGNMENT_CENTERED );
|
record.setTextLocked(true);
|
||||||
record.setVerticalTextAlignment( TextObjectBaseRecord.VERTICAL_TEXT_ALIGNMENT_JUSTIFY );
|
record.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_ROT_RIGHT);
|
||||||
record.setReserved2( (short)0 );
|
record.setStr(str);
|
||||||
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 );
|
|
||||||
|
|
||||||
byte [] recordBytes = record.serialize();
|
byte [] recordBytes = record.serialize();
|
||||||
assertEquals(recordBytes.length - 4, data.length);
|
assertEquals(recordBytes.length, data.length);
|
||||||
for (int i = 0; i < data.length; i++)
|
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 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.hssf.usermodel.HSSFRichTextString;
|
||||||
|
import org.apache.poi.util.HexRead;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that serialization and deserialization of the TextObjectRecord .
|
* 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 {
|
public final class TestTextObjectRecord extends TestCase {
|
||||||
|
|
||||||
byte[] data = {(byte)0xB6, 0x01, 0x12, 0x00, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00,
|
private static final byte[] simpleData = HexRead.readFromString(
|
||||||
0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
|
"B6 01 12 00 " +
|
||||||
0x00, 0x3C, 0x00, 0x1B, 0x00, 0x01, 0x48, 0x00, 0x65, 0x00, 0x6C,
|
"12 02 00 00 00 00 00 00" +
|
||||||
0x00, 0x6C, 0x00, 0x6F, 0x00, 0x2C, 0x00, 0x20, 0x00, 0x57, 0x00,
|
"00 00 0D 00 08 00 00 00" +
|
||||||
0x6F, 0x00, 0x72, 0x00, 0x6C, 0x00, 0x64, 0x00, 0x21, 0x00, 0x3C,
|
"00 00 " +
|
||||||
0x00, 0x08, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
"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() {
|
public void testRead() {
|
||||||
|
|
||||||
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(data));
|
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(simpleData));
|
||||||
is.nextRecord();
|
is.nextRecord();
|
||||||
TextObjectRecord record = new TextObjectRecord(is);
|
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.HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED, record.getHorizontalTextAlignment());
|
||||||
assertEquals(TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_TOP, record.getVerticalTextAlignment());
|
assertEquals(TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_TOP, record.getVerticalTextAlignment());
|
||||||
assertEquals(TextObjectRecord.TEXT_ORIENTATION_NONE, record.getTextOrientation());
|
assertEquals(TextObjectRecord.TEXT_ORIENTATION_NONE, record.getTextOrientation());
|
||||||
assertEquals(0, record.getReserved7());
|
|
||||||
assertEquals("Hello, World!", record.getStr().getString());
|
assertEquals("Hello, World!", record.getStr().getString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWrite()
|
public void testWrite() {
|
||||||
{
|
|
||||||
HSSFRichTextString str = new HSSFRichTextString("Hello, World!");
|
HSSFRichTextString str = new HSSFRichTextString("Hello, World!");
|
||||||
|
|
||||||
TextObjectRecord record = new TextObjectRecord();
|
TextObjectRecord record = new TextObjectRecord();
|
||||||
int frLength = ( str.numFormattingRuns() + 1 ) * 8;
|
record.setStr(str);
|
||||||
record.setFormattingRunLength( (short) frLength );
|
|
||||||
record.setTextLength( (short) str.length() );
|
|
||||||
record.setStr( str );
|
|
||||||
record.setHorizontalTextAlignment( TextObjectRecord.HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED );
|
record.setHorizontalTextAlignment( TextObjectRecord.HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED );
|
||||||
record.setVerticalTextAlignment( TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_TOP );
|
record.setVerticalTextAlignment( TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_TOP );
|
||||||
record.setTextLocked( true );
|
record.setTextLocked( true );
|
||||||
record.setTextOrientation( TextObjectRecord.TEXT_ORIENTATION_NONE );
|
record.setTextOrientation( TextObjectRecord.TEXT_ORIENTATION_NONE );
|
||||||
record.setReserved7( 0 );
|
|
||||||
|
|
||||||
byte [] ser = record.serialize();
|
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
|
//read again
|
||||||
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(data));
|
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(simpleData));
|
||||||
is.nextRecord();
|
is.nextRecord();
|
||||||
record = new TextObjectRecord(is);
|
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,10 +120,7 @@ public final class TestTextObjectRecord extends TestCase {
|
|||||||
HSSFRichTextString str = new HSSFRichTextString(buff.toString());
|
HSSFRichTextString str = new HSSFRichTextString(buff.toString());
|
||||||
|
|
||||||
TextObjectRecord obj = new TextObjectRecord();
|
TextObjectRecord obj = new TextObjectRecord();
|
||||||
int frLength = ( str.numFormattingRuns() + 1 ) * 8;
|
obj.setStr(str);
|
||||||
obj.setFormattingRunLength( (short) frLength );
|
|
||||||
obj.setTextLength( (short) str.length() );
|
|
||||||
obj.setStr( str );
|
|
||||||
|
|
||||||
byte [] data = obj.serialize();
|
byte [] data = obj.serialize();
|
||||||
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(data));
|
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(data));
|
||||||
@ -120,30 +142,12 @@ public final class TestTextObjectRecord extends TestCase {
|
|||||||
HSSFRichTextString str = new HSSFRichTextString(text);
|
HSSFRichTextString str = new HSSFRichTextString(text);
|
||||||
|
|
||||||
TextObjectRecord obj = new TextObjectRecord();
|
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 );
|
obj.setStr( str );
|
||||||
|
|
||||||
|
|
||||||
TextObjectRecord cloned = (TextObjectRecord)obj.clone();
|
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.getRecordSize(), cloned.getRecordSize());
|
||||||
assertEquals(obj.getOptions(), cloned.getOptions());
|
|
||||||
assertEquals(obj.getHorizontalTextAlignment(), cloned.getHorizontalTextAlignment());
|
assertEquals(obj.getHorizontalTextAlignment(), cloned.getHorizontalTextAlignment());
|
||||||
assertEquals(obj.getFormattingRunLength(), cloned.getFormattingRunLength());
|
|
||||||
assertEquals(obj.getStr().getString(), cloned.getStr().getString());
|
assertEquals(obj.getStr().getString(), cloned.getStr().getString());
|
||||||
|
|
||||||
//finally check that the serialized data is the same
|
//finally check that the serialized data is the same
|
||||||
@ -151,4 +155,47 @@ public final class TestTextObjectRecord extends TestCase {
|
|||||||
byte[] cln = cloned.serialize();
|
byte[] cln = cloned.serialize();
|
||||||
assertTrue(Arrays.equals(src, cln));
|
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)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
*/
|
*/
|
||||||
public class TestTextRecord extends TestCase {
|
public final class TestTextRecord extends TestCase {
|
||||||
byte[] data = new byte[] {
|
byte[] data = new byte[] {
|
||||||
(byte)0x02, // horiz align
|
(byte)0x02, // horiz align
|
||||||
(byte)0x02, // vert align
|
(byte)0x02, // vert align
|
||||||
@ -45,7 +45,7 @@ public class TestTextRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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.HORIZONTAL_ALIGNMENT_CENTER, record.getHorizontalAlignment());
|
||||||
assertEquals( TextRecord.VERTICAL_ALIGNMENT_CENTER, record.getVerticalAlignment());
|
assertEquals( TextRecord.VERTICAL_ALIGNMENT_CENTER, record.getVerticalAlignment());
|
||||||
assertEquals( TextRecord.DISPLAY_MODE_TRANSPARENT, record.getDisplayMode());
|
assertEquals( TextRecord.DISPLAY_MODE_TRANSPARENT, record.getDisplayMode());
|
||||||
|
@ -40,7 +40,7 @@ public final class TestTickRecord extends TestCase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void testLoad() {
|
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)2, record.getMajorTickType());
|
||||||
assertEquals( (byte)0, record.getMinorTickType());
|
assertEquals( (byte)0, record.getMinorTickType());
|
||||||
assertEquals( (byte)3, record.getLabelPosition());
|
assertEquals( (byte)3, record.getLabelPosition());
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
/* ====================================================================
|
/* ====================================================================
|
||||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
contributor license agreements. See the NOTICE file distributed with
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
@ -19,6 +18,8 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record;
|
package org.apache.poi.hssf.record;
|
||||||
|
|
||||||
|
import org.apache.poi.util.HexRead;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,18 +27,10 @@ import junit.framework.TestCase;
|
|||||||
*
|
*
|
||||||
* @author Jason Height (jheight at apache.org)
|
* @author Jason Height (jheight at apache.org)
|
||||||
*/
|
*/
|
||||||
public class TestUnicodeString
|
public final class TestUnicodeString extends TestCase {
|
||||||
extends TestCase
|
|
||||||
{
|
|
||||||
|
|
||||||
public TestUnicodeString( String s )
|
|
||||||
{
|
|
||||||
super( s );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSmallStringSize()
|
public void testSmallStringSize() {
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
//Test a basic string
|
//Test a basic string
|
||||||
UnicodeString s = makeUnicodeString("Test");
|
UnicodeString s = makeUnicodeString("Test");
|
||||||
UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
|
UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
|
||||||
@ -80,9 +73,7 @@ public class TestUnicodeString
|
|||||||
assertEquals(30, stats.recordSize);
|
assertEquals(30, stats.recordSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPerfectStringSize()
|
public void testPerfectStringSize() {
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
//Test a basic string
|
//Test a basic string
|
||||||
UnicodeString s = makeUnicodeString(SSTRecord.MAX_RECORD_SIZE-2-1);
|
UnicodeString s = makeUnicodeString(SSTRecord.MAX_RECORD_SIZE-2-1);
|
||||||
UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
|
UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
|
||||||
@ -99,9 +90,7 @@ public class TestUnicodeString
|
|||||||
assertEquals(SSTRecord.MAX_RECORD_SIZE-1, stats.recordSize);
|
assertEquals(SSTRecord.MAX_RECORD_SIZE-1, stats.recordSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPerfectRichStringSize()
|
public void testPerfectRichStringSize() {
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
//Test a rich text string
|
//Test a rich text string
|
||||||
UnicodeString s = makeUnicodeString(SSTRecord.MAX_RECORD_SIZE-2-1-8-2);
|
UnicodeString s = makeUnicodeString(SSTRecord.MAX_RECORD_SIZE-2-1-8-2);
|
||||||
s.addFormatRun(new UnicodeString.FormatRun((short)1,(short)0));
|
s.addFormatRun(new UnicodeString.FormatRun((short)1,(short)0));
|
||||||
@ -123,7 +112,7 @@ public class TestUnicodeString
|
|||||||
assertEquals(SSTRecord.MAX_RECORD_SIZE-1, stats.recordSize);
|
assertEquals(SSTRecord.MAX_RECORD_SIZE-1, stats.recordSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testContinuedStringSize() throws Exception {
|
public void testContinuedStringSize() {
|
||||||
//Test a basic string
|
//Test a basic string
|
||||||
UnicodeString s = makeUnicodeString(SSTRecord.MAX_RECORD_SIZE-2-1+20);
|
UnicodeString s = makeUnicodeString(SSTRecord.MAX_RECORD_SIZE-2-1+20);
|
||||||
UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
|
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*/
|
/** 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
|
//Test a basic string
|
||||||
int strSize = SSTRecord.MAX_RECORD_SIZE*2;
|
int strSize = SSTRecord.MAX_RECORD_SIZE*2;
|
||||||
//String overhead
|
//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);
|
UnicodeString st = new UnicodeString(s);
|
||||||
st.setOptionFlags((byte)0);
|
st.setOptionFlags((byte)0);
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
private UnicodeString makeUnicodeString( int numChars) {
|
private static UnicodeString makeUnicodeString( int numChars) {
|
||||||
StringBuffer b = new StringBuffer(numChars);
|
StringBuffer b = new StringBuffer(numChars);
|
||||||
for (int i=0;i<numChars;i++) {
|
for (int i=0;i<numChars;i++) {
|
||||||
b.append(i%10);
|
b.append(i%10);
|
||||||
}
|
}
|
||||||
return makeUnicodeString(b.toString());
|
return makeUnicodeString(b.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ public final class TestUnitsRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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( 0, record.getUnits());
|
||||||
|
|
||||||
assertEquals( 6, record.getRecordSize() );
|
assertEquals( 6, record.getRecordSize() );
|
||||||
|
@ -40,7 +40,7 @@ public final class TestValueRangeRecord extends TestCase {
|
|||||||
|
|
||||||
public void testLoad() {
|
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.getMinimumAxisValue(), 0.001);
|
||||||
assertEquals( 0.0, record.getMaximumAxisValue(), 0.001);
|
assertEquals( 0.0, record.getMaximumAxisValue(), 0.001);
|
||||||
assertEquals( 0.0, record.getMajorIncrement(), 0.001);
|
assertEquals( 0.0, record.getMajorIncrement(), 0.001);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package org.apache.poi.hssf.record;
|
package org.apache.poi.hssf.record;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
@ -30,27 +31,51 @@ import org.apache.poi.util.LittleEndian;
|
|||||||
*
|
*
|
||||||
* @author Jason Height (jheight at apache.org)
|
* @author Jason Height (jheight at apache.org)
|
||||||
*/
|
*/
|
||||||
public class TestcaseRecordInputStream
|
public final class TestcaseRecordInputStream {
|
||||||
extends RecordInputStream
|
|
||||||
{
|
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
|
* Convenience constructor
|
||||||
*/
|
*/
|
||||||
public TestcaseRecordInputStream(int sid, byte[] data)
|
// public TestcaseRecordInputStream(int sid, byte[] data)
|
||||||
{
|
// {
|
||||||
super(new ByteArrayInputStream(mergeDataAndSid((short)sid, (short)data.length, data)));
|
// super(new ByteArrayInputStream(mergeDataAndSid(sid, data.length, data)));
|
||||||
nextRecord();
|
// nextRecord();
|
||||||
}
|
// }
|
||||||
public TestcaseRecordInputStream(short sid, short length, byte[] data)
|
// public TestcaseRecordInputStream(short sid, short length, byte[] data)
|
||||||
{
|
// {
|
||||||
super(new ByteArrayInputStream(mergeDataAndSid(sid, length, data)));
|
// super(new ByteArrayInputStream(mergeDataAndSid(sid, length, data)));
|
||||||
nextRecord();
|
// 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];
|
byte[] result = new byte[data.length + 4];
|
||||||
LittleEndian.putShort(result, 0, sid);
|
LittleEndian.putUShort(result, 0, sid);
|
||||||
LittleEndian.putShort(result, 2, length);
|
LittleEndian.putUShort(result, 2, length);
|
||||||
System.arraycopy(data, 0, result, 4, data.length);
|
System.arraycopy(data, 0, result, 4, data.length);
|
||||||
return result;
|
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.TestcaseRecordInputStream;
|
||||||
import org.apache.poi.hssf.record.UnicodeString;
|
import org.apache.poi.hssf.record.UnicodeString;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
|
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
|
||||||
|
import org.apache.poi.util.HexRead;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
@ -37,13 +38,12 @@ public final class TestConstantValueParser extends TestCase {
|
|||||||
new UnicodeString("Sample text"),
|
new UnicodeString("Sample text"),
|
||||||
ErrorConstant.valueOf(HSSFErrorConstants.ERROR_DIV_0),
|
ErrorConstant.valueOf(HSSFErrorConstants.ERROR_DIV_0),
|
||||||
};
|
};
|
||||||
private static final byte[] SAMPLE_ENCODING = {
|
private static final byte[] SAMPLE_ENCODING = HexRead.readFromString(
|
||||||
4, 1, 0, 0, 0, 0, 0, 0, 0,
|
"04 01 00 00 00 00 00 00 00 " +
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
"00 00 00 00 00 00 00 00 00 " +
|
||||||
1, -102, -103, -103, -103, -103, -103, -15, 63,
|
"01 9A 99 99 99 99 99 F1 3F " +
|
||||||
2, 11, 0, 0, 83, 97, 109, 112, 108, 101, 32, 116, 101, 120, 116,
|
"02 0B 00 00 53 61 6D 70 6C 65 20 74 65 78 74 " +
|
||||||
16, 7, 0, 0, 0, 0, 0, 0, 0,
|
"10 07 00 00 00 00 00 00 00");
|
||||||
};
|
|
||||||
|
|
||||||
public void testGetEncodedSize() {
|
public void testGetEncodedSize() {
|
||||||
int actual = ConstantValueParser.getEncodedSize(SAMPLE_VALUES);
|
int actual = ConstantValueParser.getEncodedSize(SAMPLE_VALUES);
|
||||||
@ -59,7 +59,7 @@ public final class TestConstantValueParser extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void testDecode() {
|
public void testDecode() {
|
||||||
RecordInputStream in = new TestcaseRecordInputStream(0x0001, SAMPLE_ENCODING);
|
RecordInputStream in = TestcaseRecordInputStream.createWithFakeSid(SAMPLE_ENCODING);
|
||||||
|
|
||||||
Object[] values = ConstantValueParser.parse(in, 4);
|
Object[] values = ConstantValueParser.parse(in, 4);
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
|
@ -54,9 +54,9 @@ public final class TestArrayPtg extends TestCase {
|
|||||||
*/
|
*/
|
||||||
public void testReadWriteTokenValueBytes() {
|
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(3, ptg.getColumnCount());
|
||||||
assertEquals(2, ptg.getRowCount());
|
assertEquals(2, ptg.getRowCount());
|
||||||
Object[][] values = ptg.getTokenArrayValues();
|
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.
|
* Excel stores array elements column by column. This test makes sure POI does the same.
|
||||||
*/
|
*/
|
||||||
public void testElementOrdering() {
|
public void testElementOrdering() {
|
||||||
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(3, ptg.getColumnCount());
|
||||||
assertEquals(2, ptg.getRowCount());
|
assertEquals(2, ptg.getRowCount());
|
||||||
|
|
||||||
@ -113,9 +113,9 @@ public final class TestArrayPtg extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testToFormulaString() {
|
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;
|
String actualFormula;
|
||||||
try {
|
try {
|
||||||
@ -146,7 +146,7 @@ public final class TestArrayPtg extends TestCase {
|
|||||||
// Force encoded operand class for tArray
|
// Force encoded operand class for tArray
|
||||||
fullData[0] = (byte) (ArrayPtg.sid + operandClass);
|
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);
|
Ptg[] ptgs = Ptg.readTokens(ENCODED_PTG_DATA.length, in);
|
||||||
assertEquals(1, ptgs.length);
|
assertEquals(1, ptgs.length);
|
||||||
|
@ -34,7 +34,7 @@ public final class TestFuncPtg extends TestCase {
|
|||||||
0,
|
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( "Len formula index is not 32(20H)", 0x20, ptg.getFunctionIndex() );
|
||||||
assertEquals( "Number of operands in the len formula", 1, ptg.getNumberOfOperands() );
|
assertEquals( "Number of operands in the len formula", 1, ptg.getNumberOfOperands() );
|
||||||
assertEquals( "Function Name", "LEN", ptg.getName() );
|
assertEquals( "Function Name", "LEN", ptg.getName() );
|
||||||
|
@ -18,12 +18,12 @@
|
|||||||
package org.apache.poi.hssf.record.formula;
|
package org.apache.poi.hssf.record.formula;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
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.record.TestcaseRecordInputStream;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
@ -94,10 +94,10 @@ public final class TestReferencePtg extends TestCase {
|
|||||||
0x2C, 33, 44, 55, 66,
|
0x2C, 33, 44, 55, 66,
|
||||||
};
|
};
|
||||||
public void testReadWrite_tRefN_bug45091() {
|
public void testReadWrite_tRefN_bug45091() {
|
||||||
TestcaseRecordInputStream in = new TestcaseRecordInputStream(-1, tRefN_data);
|
RecordInputStream in = TestcaseRecordInputStream.createWithFakeSid(tRefN_data);
|
||||||
Stack ptgs = Ptg.createParsedExpressionTokens((short)tRefN_data.length, in);
|
Ptg[] ptgs = Ptg.readTokens(tRefN_data.length, in);
|
||||||
byte[] outData = new byte[5];
|
byte[] outData = new byte[5];
|
||||||
Ptg.serializePtgStack(ptgs, outData, 0);
|
Ptg.serializePtgs(ptgs, outData, 0);
|
||||||
if (outData[0] == 0x24) {
|
if (outData[0] == 0x24) {
|
||||||
throw new AssertionFailedError("Identified bug 45091");
|
throw new AssertionFailedError("Identified bug 45091");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user