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 &lt; 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:
Josh Micich 2008-10-25 01:47:25 +00:00
parent dfb6d9f84f
commit 18e5d2d0db
87 changed files with 1542 additions and 1591 deletions

View File

@ -66,7 +66,12 @@
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling PowerPoint files, irrespective of if they are .ppt or .pptx</action>
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
</release>
<release version="3.2-alpha1" date="2008-??-??">
<release version="3.5-beta4" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">YK: remove me. required to keep Forrest DTD compiler quiet</action>
</release>
<release version="3.2-FINAL" date="2008-10-19">
<action dev="POI-DEVELOPERS" type="fix">45866 - allowed for change of unicode compression across Continue records</action>
<action dev="POI-DEVELOPERS" type="fix">45964 - support for link formulas in Text Objects</action>
<action dev="POI-DEVELOPERS" type="fix">43354 - support for evalating formulas with missing args</action>
<action dev="POI-DEVELOPERS" type="fix">45912 - fixed ArrayIndexOutOfBoundsException in EmbeddedObjectRefSubRecord</action>
<action dev="POI-DEVELOPERS" type="fix">45889 - fixed ArrayIndexOutOfBoundsException when constructing HSLF Table with a single row </action>

View File

@ -44,10 +44,10 @@
People interested should also follow the
<link href="mailinglists.html">dev list</link> to track progress.</p>
</section>
<section><title>POI 3.1-FINAL Released (2008-06-29)</title>
<section><title>POI 3.2-FINAL Released (2008-10-19)</title>
<p>
The POI team is pleased to announce the release of 3.1 FINAL, the latest release of Apache POI.
There have been many important bug fixes since the 3.0.2 release and a lot of new features.
The POI team is pleased to announce the release of 3.2 FINAL, the latest release of Apache POI.
There have been many important bug fixes since the 3.1 release and a lot of new features.
</p><p> A full list of changes is available in
<link href="./changes.html">the changelog</link>, and
<link href="http://www.apache.org/dyn/closer.cgi/poi/release/">download</link>
@ -56,7 +56,7 @@
</p>
<p>
The release is also available from the central Maven repository
under Group ID "org.apache.poi" and Version "3.1-FINAL".
under Group ID "org.apache.poi" and Version "3.2-FINAL".
</p>
</section>

View File

@ -63,7 +63,12 @@
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling PowerPoint files, irrespective of if they are .ppt or .pptx</action>
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
</release>
<release version="3.2-alpha1" date="2008-??-??">
<release version="3.5-beta4" date="2008-??-??">
<action dev="POI-DEVELOPERS" type="fix">YK: remove me. required to keep Forrest DTD compiler quiet</action>
</release>
<release version="3.2-FINAL" date="2008-10-19">
<action dev="POI-DEVELOPERS" type="fix">45866 - allowed for change of unicode compression across Continue records</action>
<action dev="POI-DEVELOPERS" type="fix">45964 - support for link formulas in Text Objects</action>
<action dev="POI-DEVELOPERS" type="fix">43354 - support for evalating formulas with missing args</action>
<action dev="POI-DEVELOPERS" type="fix">45912 - fixed ArrayIndexOutOfBoundsException in EmbeddedObjectRefSubRecord</action>
<action dev="POI-DEVELOPERS" type="fix">45889 - fixed ArrayIndexOutOfBoundsException when constructing HSLF Table with a single row </action>

View File

@ -17,17 +17,23 @@
package org.apache.poi.hssf.dev;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.record.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
/**
* Utillity for reading in BIFF8 records and displaying data from them.
@ -37,333 +43,488 @@ import org.apache.poi.util.HexDump;
*@see #main
*/
public final class BiffViewer {
private final File _inputFile;
private boolean dump;
private final PrintStream _ps;
static final char[] NEW_LINE_CHARS = System.getProperty("line.separator").toCharArray();
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;
_ps = ps;
}
/**
* Essentially a duplicate of RecordFactory. Kept separate as not to screw
* 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) {
/**
* 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();
}
}
System.setProperty("poi.deserialize.escher", "true");
if (args.length == 0) {
System.out.println( "Biff viewer needs a filename" );
return;
}
/**
* Create an array of records from an input stream
*
*@param in the InputStream from which the records
* will be obtained
*@param dump
*@return an array of Records created from the
* InputStream
*@exception RecordFormatException on error processing the InputStream
*/
public static Record[] createRecords(InputStream in, boolean dump, PrintStream ps)
throws RecordFormatException {
ArrayList records = new ArrayList();
RecordDetails activeRecord = null;
try {
String inFileName = args[0];
File inputFile = new File(inFileName);
if(!inputFile.exists()) {
throw new RuntimeException("specified inputFile '" + inFileName + "' does not exist");
}
PrintStream ps;
if (false) { // set to true to output to file
OutputStream os = new FileOutputStream(inFileName + ".out");
ps = new PrintStream(os);
} else {
ps = System.out;
}
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);
while (recStream.hasNextRecord()) {
recStream.nextRecord();
if (recStream.getSid() != 0) {
Record record = createRecord (recStream);
if (record.getSid() != ContinueRecord.sid)
{
records.add(record);
if (activeRecord != null)
activeRecord.dump(ps);
int startPos = (int)(recStream.getPos()-recStream.getLength() - 4);
activeRecord = new RecordDetails(recStream.getSid(), recStream.getLength(), startPos, record);
}
if (dump) {
recStream.dumpBytes(ps);
}
}
}
if (activeRecord != null) {
activeRecord.dump(ps);
}
Record[] retval = new Record[records.size()];
records.toArray(retval);
return retval;
}
stream.read(data);
HexDump.dump(data, 0, System.out, 0);
} else {
boolean dumpInterpretedRecords = true;
boolean dumpHex = args.length > 1 && args[1].equals("on");
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(inputFile));
InputStream is = fs.createDocumentInputStream("Workbook");
BiffRecordListener recListener = new BiffRecordListener(dumpHex ? new OutputStreamWriter(ps) : null);
is = new BiffDumpingStream(is, recListener);
createRecords(is, ps, recListener, dumpInterpretedRecords);
}
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Essentially a duplicate of RecordFactory. Kept separate as not to screw
* 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 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);
}
private static final class BiffRecordListener implements IBiffRecordListener {
private final Writer _hexDumpWriter;
private final List _headers;
public BiffRecordListener(Writer hexDumpWriter) {
_hexDumpWriter = hexDumpWriter;
_headers = new ArrayList();
}
public void processRecord(int globalOffset, int recordCounter, int sid, int dataSize,
byte[] data) {
String header = formatRecordDetails(globalOffset, sid, dataSize, recordCounter);
_headers.add(header);
Writer w = _hexDumpWriter;
if (w != null) {
try {
w.write(header);
w.write(NEW_LINE_CHARS);
hexDumpAligned(w, data, 0, dataSize+4, globalOffset);
w.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public String[] getRecentHeaders() {
String[] result = new String[_headers.size()];
_headers.toArray(result);
_headers.clear();
return result;
}
private static String formatRecordDetails(int globalOffset, int sid, int size, int recordCounter) {
StringBuffer sb = new StringBuffer(64);
sb.append("Offset=").append(HexDump.intToHex(globalOffset)).append("(").append(globalOffset).append(")");
sb.append(" recno=").append(recordCounter);
sb.append( " sid=").append(HexDump.shortToHex(sid));
sb.append( " size=").append(HexDump.shortToHex(size)).append("(").append(size).append(")");
return sb.toString();
}
}
private static interface IBiffRecordListener {
/**
* Method setDump - hex dump out data or not.
*/
public void setDump(boolean dump) {
this.dump = dump;
}
void processRecord(int globalOffset, int recordCounter, int sid, int dataSize, byte[] data);
}
/**
* 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;
}
/**
* 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) {
public int read() throws IOException {
if (_currentPos >= _currentSize) {
fillNextBuffer();
}
if (_currentPos >= _currentSize) {
return -1;
}
int result = _data[_currentPos] & 0x00FF;
_currentPos ++;
_overallStreamPos ++;
formatBufferIfAtEndOfRec();
return result;
}
public int read(byte[] b, int off, int len) throws IOException {
if (_currentPos >= _currentSize) {
fillNextBuffer();
}
if (_currentPos >= _currentSize) {
return -1;
}
int availSize = _currentSize - _currentPos;
int result;
if (len > availSize) {
System.err.println("Unexpected request to read past end of current biff record");
result = availSize;
} else {
result = len;
}
System.arraycopy(_data, _currentPos, b, off, result);
_currentPos += result;
_overallStreamPos += result;
formatBufferIfAtEndOfRec();
return result;
}
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) {
System.out.println( "Biff viewer needs a filename" );
return;
}
private static void hexDumpLine(Writer w, byte[] data, int lineStartAddress, int lineDataOffset, int startDelta, int endDelta) {
if (startDelta >= endDelta) {
throw new IllegalArgumentException("Bad start/end delta");
}
try {
writeHex(w, lineStartAddress, 8);
w.write(COLUMN_SEPARATOR);
// raw hex data
for (int i=0; i< DUMP_LINE_LEN; i++) {
if (i>0) {
w.write(" ");
}
if (i >= startDelta && i < endDelta) {
writeHex(w, data[lineDataOffset+i], 2);
} else {
w.write(" ");
}
}
w.write(COLUMN_SEPARATOR);
try {
String inFileName = args[0];
File inputFile = new File(inFileName);
if(!inputFile.exists()) {
throw new RuntimeException("specified inputFile '" + inFileName + "' does not exist");
}
PrintStream ps;
if (false) { // set to true to output to file
OutputStream os = new FileOutputStream(inFileName + ".out");
ps = new PrintStream(os);
} else {
ps = System.out;
}
BiffViewer viewer = new BiffViewer(inputFile, ps);
// interpreted ascii
for (int i=0; i< DUMP_LINE_LEN; i++) {
if (i >= startDelta && i < endDelta) {
w.write(getPrintableChar(data[lineDataOffset+i]));
} else {
w.write(" ");
}
}
w.write(NEW_LINE_CHARS);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (args.length > 1 && args[1].equals("on")) {
viewer.setDump(true);
}
if (args.length > 1 && args[1].equals("bfd")) {
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(inputFile));
InputStream stream = fs.createDocumentInputStream("Workbook");
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 char getPrintableChar(byte b) {
char ib = (char) (b & 0x00FF);
if (ib < 32 || ib > 126) {
return '.';
}
return ib;
}
private static void writeHex(Writer w, int value, int nDigits) throws IOException {
char[] buf = new char[nDigits];
int acc = value;
for(int i=nDigits-1; i>=0; i--) {
int digit = acc & 0x0F;
buf[i] = (char) (digit < 10 ? ('0' + digit) : ('A' + digit - 10));
acc >>= 4;
}
w.write(buf);
}
}

View File

@ -138,15 +138,11 @@ public class TextboxShape
HSSFTextbox shape = hssfShape;
TextObjectRecord obj = new TextObjectRecord();
obj.setHorizontalTextAlignment( hssfShape.getHorizontalAlignment() );
obj.setVerticalTextAlignment( hssfShape.getVerticalAlignment());
obj.setTextLocked( true );
obj.setTextOrientation( TextObjectRecord.TEXT_ORIENTATION_NONE );
int frLength = ( shape.getString().numFormattingRuns() + 1 ) * 8;
obj.setFormattingRunLength( (short) frLength );
obj.setTextLength( (short) shape.getString().length() );
obj.setStr( shape.getString() );
obj.setReserved7( 0 );
obj.setHorizontalTextAlignment(hssfShape.getHorizontalAlignment());
obj.setVerticalTextAlignment(hssfShape.getVerticalAlignment());
obj.setTextLocked(true);
obj.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_NONE);
obj.setStr(shape.getString());
return obj;
}

View File

@ -22,76 +22,44 @@ package org.apache.poi.hssf.record;
import org.apache.poi.util.LittleEndian;
/**
* Title: Continue Record - Helper class used primarily for SST Records <P>
* Title: Continue Record(0x003C) - Helper class used primarily for SST Records <P>
* Description: handles overflow for prior record in the input
* stream; content is tailored to that prior record<P>
* @author Marc Johnson (mjohnson at apache dot org)
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Csaba Nagy (ncsaba at yahoo dot com)
* @version 2.0-pre
*/
public class ContinueRecord
extends Record
{
public final class ContinueRecord extends Record {
public final static short sid = 0x003C;
private byte[] field_1_data;
private byte[] _data;
/**
* default constructor
*/
public ContinueRecord()
{
public ContinueRecord(byte[] data) {
_data = data;
}
/**
* USE ONLY within "processContinue"
*/
public byte [] serialize()
{
byte[] retval = new byte[ field_1_data.length + 4 ];
byte[] retval = new byte[ _data.length + 4 ];
serialize(0, retval);
return retval;
}
public int serialize(int offset, byte [] data)
{
LittleEndian.putShort(data, offset, sid);
LittleEndian.putShort(data, offset + 2, ( short ) field_1_data.length);
System.arraycopy(field_1_data, 0, data, offset + 4, field_1_data.length);
return field_1_data.length + 4;
// throw new RecordFormatException(
// "You're not supposed to serialize Continue records like this directly");
}
/*
* @param data raw data
*/
public void setData(byte [] data)
{
field_1_data = data;
public int serialize(int offset, byte[] data) {
return write(data, offset, null, _data);
}
/**
* get the data for continuation
* @return byte array containing all of the continued data
*/
public byte [] getData()
{
return field_1_data;
return _data;
}
/**
* Debugging toString
*
* @return string representation
*/
public String toString()
{
StringBuffer buffer = new StringBuffer();
@ -113,19 +81,36 @@ public class ContinueRecord
*
* @param in the RecordInputstream to read the record from
*/
public ContinueRecord(RecordInputStream in)
{
field_1_data = in.readRemainder();
_data = in.readRemainder();
}
public Object clone() {
return new ContinueRecord(_data);
}
/**
* Clone this record.
* Writes the full encoding of a Continue record without making an instance
*/
public Object clone() {
ContinueRecord clone = new ContinueRecord();
clone.setData(field_1_data);
return clone;
public static int write(byte[] destBuf, int destOffset, Byte initialDataByte, byte[] srcData) {
return write(destBuf, destOffset, initialDataByte, srcData, 0, srcData.length);
}
/**
* @param initialDataByte (optional - often used for unicode flag).
* If supplied, this will be written before srcData
* @return the total number of bytes written
*/
public static int write(byte[] destBuf, int destOffset, Byte initialDataByte, byte[] srcData, int srcOffset, int len) {
int totalLen = len + (initialDataByte == null ? 0 : 1);
LittleEndian.putUShort(destBuf, destOffset, sid);
LittleEndian.putUShort(destBuf, destOffset + 2, totalLen);
int pos = destOffset + 4;
if (initialDataByte != null) {
LittleEndian.putByte(destBuf, pos, initialDataByte.byteValue());
pos += 1;
}
System.arraycopy(srcData, srcOffset, destBuf, pos, len);
return 4 + totalLen;
}
}

View File

@ -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);
}

View File

@ -17,8 +17,6 @@
package org.apache.poi.hssf.record;
import java.util.Stack;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.StringUtil;
@ -124,11 +122,7 @@ public final class ExternalNameRecord extends Record {
}
private int getNameDefinitionSize() {
int result = 0;
for (int i = 0; i < field_5_name_definition.length; i++) {
result += field_5_name_definition[i].getSize();
}
return result;
return Ptg.getEncodedSize(field_5_name_definition);
}

View File

@ -20,47 +20,38 @@ package org.apache.poi.hssf.record;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.util.LittleEndian;
import java.util.Stack;
import java.util.Iterator;
/**
* Not implemented yet. May commit it anyway just so people can see
* where I'm heading.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public final class LinkedDataFormulaField implements CustomField {
Stack formulaTokens = new Stack();
public final class LinkedDataFormulaField {
private Ptg[] formulaTokens;
public int getSize()
{
int size = 0;
for ( Iterator iterator = formulaTokens.iterator(); iterator.hasNext(); )
{
Ptg token = (Ptg) iterator.next();
size += token.getSize();
}
return size + 2;
return 2 + Ptg.getEncodedSize(formulaTokens);
}
public int fillField( RecordInputStream in )
{
short tokenSize = in.readShort();
formulaTokens = Ptg.createParsedExpressionTokens(tokenSize, in);
int tokenSize = in.readUShort();
formulaTokens = Ptg.readTokens(tokenSize, in);
return tokenSize + 2;
}
public void toString( StringBuffer buffer )
{
for ( int k = 0; k < formulaTokens.size(); k++ )
for ( int k = 0; k < formulaTokens.length; k++ )
{
Ptg ptg = formulaTokens[k];
buffer.append( "Formula " )
.append( k )
.append( "=" )
.append( formulaTokens.get( k ).toString() )
.append(ptg.toString() )
.append( "\n" )
.append( ( (Ptg) formulaTokens.get( k ) ).toDebugString() )
.append(ptg.toDebugString() )
.append( "\n" );
}
}
@ -75,34 +66,26 @@ public final class LinkedDataFormulaField implements CustomField {
public int serializeField( int offset, byte[] data )
{
int size = getSize();
LittleEndian.putShort(data, offset, (short)(size - 2));
LittleEndian.putUShort(data, offset, size - 2);
int pos = offset + 2;
pos += Ptg.serializePtgStack(formulaTokens, data, pos);
pos += Ptg.serializePtgs(formulaTokens, data, pos);
return size;
}
public Object clone()
public void setFormulaTokens(Ptg[] ptgs)
{
try
{
// todo: clone tokens? or are they immutable?
return super.clone();
}
catch ( CloneNotSupportedException e )
{
// should not happen
return null;
}
this.formulaTokens = (Ptg[])ptgs.clone();
}
public void setFormulaTokens( Stack formulaTokens )
public Ptg[] getFormulaTokens()
{
this.formulaTokens = (Stack) formulaTokens.clone();
}
public Stack getFormulaTokens()
{
return (Stack)this.formulaTokens.clone();
return (Ptg[])this.formulaTokens.clone();
}
public LinkedDataFormulaField copy() {
LinkedDataFormulaField result = new LinkedDataFormulaField();
result.formulaTokens = getFormulaTokens();
return result;
}
}

View File

@ -125,7 +125,7 @@ public final class LinkedDataRecord extends Record {
rec.field_2_referenceType = field_2_referenceType;
rec.field_3_options = field_3_options;
rec.field_4_indexNumberFmtRecord = field_4_indexNumberFmtRecord;
rec.field_5_formulaOfLink = ((LinkedDataFormulaField)field_5_formulaOfLink.clone());
rec.field_5_formulaOfLink = field_5_formulaOfLink.copy();
return rec;
}

View File

@ -321,51 +321,54 @@ public final class RecordFactory {
Record lastRecord = null;
while (recStream.hasNextRecord()) {
recStream.nextRecord();
if (recStream.getSid() != 0) {
Record[] recs = createRecord(recStream); // handle MulRK records
if (recStream.getSid() == 0) {
// After EOF, Excel seems to pad block with zeros
continue;
}
Record[] recs = createRecord(recStream); // handle MulRK records
if (recs.length > 1) {
for (int k = 0; k < recs.length; k++) {
records.add(recs[ k ]); // these will be number records
}
} else {
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);
}
}
if (recs.length > 1) {
for (int k = 0; k < recs.length; k++) {
records.add(recs[ k ]); // these will be number records
}
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;

View File

@ -29,19 +29,19 @@ import java.io.ByteArrayOutputStream;
*
* @author Jason Height (jheight @ apache dot org)
*/
public class RecordInputStream extends InputStream {
/** Maximum size of a single record (minus the 4 byte header) without a continue*/
public final static short MAX_RECORD_DATA_SIZE = 8224;
private static final int INVALID_SID_VALUE = -1;
public final class RecordInputStream extends InputStream {
/** Maximum size of a single record (minus the 4 byte header) without a continue*/
public final static short MAX_RECORD_DATA_SIZE = 8224;
private static final int INVALID_SID_VALUE = -1;
private InputStream in;
protected short currentSid;
protected short currentLength = -1;
protected short nextSid;
private InputStream in;
private short currentSid;
private short currentLength = -1;
private short nextSid;
protected byte[] data = new byte[MAX_RECORD_DATA_SIZE];
protected short recordOffset;
protected long pos;
private final byte[] data = new byte[MAX_RECORD_DATA_SIZE];
private short recordOffset;
private long pos;
private boolean autoContinue = true;
@ -218,54 +218,81 @@ public class RecordInputStream extends InputStream {
return result;
}
/**
* given a byte array of 16-bit unicode characters, compress to 8-bit and
* return a string
*
* { 0x16, 0x00 } -0x16
*
* @param length the length of the final string
* @return the converted string
* @exception IllegalArgumentException if len is too large (i.e.,
* there is not enough data in string to create a String of that
* length)
*/
public String readUnicodeLEString(int length) {
if ((length < 0) || (((remaining() / 2) < length) && !isContinueNext())) {
throw new IllegalArgumentException("Illegal length - asked for " + length + " but only " + (remaining()/2) + " left!");
}
public String readString() {
int requestedLength = readUShort();
byte compressFlag = readByte();
return readStringCommon(requestedLength, compressFlag == 0);
}
/**
* given a byte array of 16-bit unicode characters, compress to 8-bit and
* return a string
*
* { 0x16, 0x00 } -0x16
*
* @param requestedLength the length of the final string
* @return the converted string
* @exception IllegalArgumentException if len is too large (i.e.,
* there is not enough data in string to create a String of that
* length)
*/
public String readUnicodeLEString(int requestedLength) {
return readStringCommon(requestedLength, false);
}
StringBuffer buf = new StringBuffer(length);
for (int i=0;i<length;i++) {
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 requestedLength) {
return readStringCommon(requestedLength, true);
}
public String readCompressedUnicode(int length) {
if ((length < 0) || ((remaining() < length) && !isContinueNext())) {
throw new IllegalArgumentException("Illegal length " + length);
}
StringBuffer buf = new StringBuffer(length);
for (int i=0;i<length;i++) {
if ((remaining() == 0) && (isContinueNext())) {
nextRecord();
int compressByte = readByte();
if(compressByte != 0) throw new IllegalArgumentException("compressByte in continue records must be 0 while reading compressed unicode");
}
byte b = readByte();
char ch = (char)(0x00FF & b); // avoid sex
buf.append(ch);
}
return buf.toString();
}
private String readStringCommon(int requestedLength, boolean pIsCompressedEncoding) {
// Sanity check to detect garbage string lengths
if (requestedLength < 0 || requestedLength > 0x100000) { // 16 million chars?
throw new IllegalArgumentException("Bad requested string length (" + requestedLength + ")");
}
char[] buf = new char[requestedLength];
boolean isCompressedEncoding = pIsCompressedEncoding;
int curLen = 0;
while(true) {
int availableChars =isCompressedEncoding ? remaining() : remaining() / LittleEndian.SHORT_SIZE;
if (requestedLength - curLen <= availableChars) {
// enough space in current record, so just read it out
while(curLen < requestedLength) {
char ch;
if (isCompressedEncoding) {
ch = (char)readUByte();
} else {
ch = (char)readShort();
}
buf[curLen] = ch;
curLen++;
}
return new String(buf);
}
// else string has been spilled into next continue record
// so read what's left of the current record
while(availableChars > 0) {
char ch;
if (isCompressedEncoding) {
ch = (char)readUByte();
} else {
ch = (char)readShort();
}
buf[curLen] = ch;
curLen++;
availableChars--;
}
if (!isContinueNext()) {
throw new RecordFormatException("Expected to find a ContinueRecord in order to read remaining "
+ (requestedLength-curLen) + " of " + requestedLength + " chars");
}
if(remaining() != 0) {
throw new RecordFormatException("Odd number of bytes(" + remaining() + ") left behind");
}
nextRecord();
// 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.
* <i>Note:</i> Unicode strings differ from <b>normal</b> strings due to the addition of

View File

@ -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);
}
}

View File

@ -19,253 +19,427 @@ package org.apache.poi.hssf.record;
import java.io.UnsupportedEncodingException;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
public class TextObjectRecord
extends TextObjectBaseRecord
{
HSSFRichTextString str;
/**
* The TXO record (0x01B6) is used to define the properties of a text box. It is
* followed by two or more continue records unless there is no actual text. The
* first continue records contain the text data and the last continue record
* contains the formatting runs.<p/>
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public final class TextObjectRecord extends Record {
public final static short sid = 0x01B6;
public TextObjectRecord()
{
}
private static final int FORMAT_RUN_ENCODED_SIZE = 8; // 2 shorts and 4 bytes reserved
public TextObjectRecord( RecordInputStream in )
{
super( in );
private static final BitField HorizontalTextAlignment = BitFieldFactory.getInstance(0x000E);
private static final BitField VerticalTextAlignment = BitFieldFactory.getInstance(0x0070);
private static final BitField textLocked = BitFieldFactory.getInstance(0x0200);
if (getTextLength() > 0) {
if (in.isContinueNext() && in.remaining() == 0) {
//1st Continue
in.nextRecord();
processRawString(in);
} else
throw new RecordFormatException("Expected Continue record to hold string data for TextObjectRecord");
}
if (getFormattingRunLength() > 0) {
if (in.isContinueNext() && in.remaining() == 0) {
in.nextRecord();
processFontRuns(in);
} else throw new RecordFormatException("Expected Continue Record to hold font runs for TextObjectRecord");
}
if (str == null)
str = new HSSFRichTextString("");
}
public final static short HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED = 1;
public final static short HORIZONTAL_TEXT_ALIGNMENT_CENTERED = 2;
public final static short HORIZONTAL_TEXT_ALIGNMENT_RIGHT_ALIGNED = 3;
public final static short HORIZONTAL_TEXT_ALIGNMENT_JUSTIFIED = 4;
public final static short VERTICAL_TEXT_ALIGNMENT_TOP = 1;
public final static short VERTICAL_TEXT_ALIGNMENT_CENTER = 2;
public final static short VERTICAL_TEXT_ALIGNMENT_BOTTOM = 3;
public final static short VERTICAL_TEXT_ALIGNMENT_JUSTIFY = 4;
public final static short TEXT_ORIENTATION_NONE = 0;
public final static short TEXT_ORIENTATION_TOP_TO_BOTTOM = 1;
public final static short TEXT_ORIENTATION_ROT_RIGHT = 2;
public final static short TEXT_ORIENTATION_ROT_LEFT = 3;
private int field_1_options;
private int field_2_textOrientation;
private int field_3_reserved4;
private int field_4_reserved5;
private int field_5_reserved6;
private int field_8_reserved7;
private HSSFRichTextString _text;
/*
* Note - the next three fields are very similar to those on
* EmbededObjectRefSubRecord(ftPictFmla 0x0009)
*
* some observed values for the 4 bytes preceding the formula: C0 5E 86 03
* C0 11 AC 02 80 F1 8A 03 D4 F0 8A 03
*/
private int _unknownPreFormulaInt;
/** expect tRef, tRef3D, tArea, tArea3D or tName */
private Ptg _linkRefPtg;
/**
* Not clear if needed . Excel seems to be OK if this byte is not present.
* Value is often the same as the earlier firstColumn byte. */
private Byte _unknownPostFormulaByte;
public TextObjectRecord() {
}
public TextObjectRecord(RecordInputStream in) {
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()
{
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;
public int serialize(int offset, byte[] data) {
continue1Size += chunkSize;
continue1Size += 1 + 4;
}
int expectedTotalSize = getRecordSize();
int totalSize = serializeTXORecord(offset, data);
if (_text.getString().length() > 0) {
totalSize += serializeTrailingRecords(offset+totalSize, data);
}
if (totalSize != expectedTotalSize)
throw new RecordFormatException(totalSize
+ " bytes written but getRecordSize() reports " + expectedTotalSize);
return totalSize;
}
continue2Size = (str.numFormattingRuns() + 1) * 8 + 4;
}
return super.getRecordSize() + continue1Size + continue2Size;
}
/**
* Note - this total size includes all potential {@link ContinueRecord}s written
*/
public int getRecordSize() {
int baseSize = 4 + getDataSize();
return baseSize + getTrailingRecordsSize();
}
private int getFormattingDataLength() {
if (_text.length() < 1) {
// important - no formatting data if text is empty
return 0;
}
return (_text.numFormattingRuns() + 1) * FORMAT_RUN_ENCODED_SIZE;
}
private static byte[] createFormatData(HSSFRichTextString str) {
int nRuns = str.numFormattingRuns();
byte[] result = new byte[(nRuns + 1) * FORMAT_RUN_ENCODED_SIZE];
int pos = 0;
for (int i = 0; i < nRuns; i++) {
LittleEndian.putUShort(result, pos, str.getIndexOfFormattingRun(i));
pos += 2;
int fontIndex = str.getFontOfFormattingRun(i);
LittleEndian.putUShort(result, pos, fontIndex == str.NO_FONT ? 0 : fontIndex);
pos += 2;
pos += 4; // skip reserved
}
LittleEndian.putUShort(result, pos, str.length());
pos += 2;
LittleEndian.putUShort(result, pos, 0);
pos += 2;
pos += 4; // skip reserved
public int serialize( int offset, byte[] data )
{
// Temporarily blank out str so that record size is calculated without the continue records.
HSSFRichTextString temp = str;
str = new HSSFRichTextString("");
int bytesWritten1 = super.serialize( offset, data );
str = temp;
return result;
}
int pos = offset + bytesWritten1;
if ( str.getString().equals( "" ) == false )
{
ContinueRecord c2 = createContinue2();
int bytesWritten2 = 0;
/**
* Sets the Horizontal text alignment field value.
*/
public void setHorizontalTextAlignment(int value) {
field_1_options = HorizontalTextAlignment.setValue(field_1_options, value);
}
try
{
byte[] c1Data = str.getString().getBytes( "UTF-16LE" );
int length = c1Data.length;
/**
* @return the Horizontal text alignment field value.
*/
public int getHorizontalTextAlignment() {
return HorizontalTextAlignment.getValue(field_1_options);
}
int charsWritten = 0;
int spos = pos;
while(length > 0){
int chunkSize = Math.min(RecordInputStream.MAX_RECORD_DATA_SIZE-2 , length);
length -= chunkSize;
/**
* Sets the Vertical text alignment field value.
*/
public void setVerticalTextAlignment(int value) {
field_1_options = VerticalTextAlignment.setValue(field_1_options, value);
}
//continue header
LittleEndian.putShort(data, spos, ContinueRecord.sid);
spos += LittleEndian.SHORT_SIZE;
LittleEndian.putShort(data, spos, (short)(chunkSize+1));
spos += LittleEndian.SHORT_SIZE;
/**
* @return the Vertical text alignment field value.
*/
public int getVerticalTextAlignment() {
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).
data[spos] = 1;
spos += LittleEndian.BYTE_SIZE;
/**
* Sets the text locked field value.
*/
public void setTextLocked(boolean value) {
field_1_options = textLocked.setBoolean(field_1_options, value);
}
//copy characters data
System.arraycopy(c1Data, charsWritten, data, spos, chunkSize);
spos += chunkSize;
charsWritten += chunkSize;
}
/**
* @return the text locked field value.
*/
public boolean isTextLocked() {
return textLocked.isSet(field_1_options);
}
bytesWritten2 = (spos-pos);
}
catch ( UnsupportedEncodingException e )
{
throw new RuntimeException( e.getMessage(), e );
}
/**
* Get the text orientation field for the TextObjectBase record.
*
* @return One of TEXT_ORIENTATION_NONE TEXT_ORIENTATION_TOP_TO_BOTTOM
* TEXT_ORIENTATION_ROT_RIGHT TEXT_ORIENTATION_ROT_LEFT
*/
public int getTextOrientation() {
return field_2_textOrientation;
}
pos += bytesWritten2;
int bytesWritten3 = c2.serialize( pos, data );
pos += bytesWritten3;
/**
* Set the text orientation field for the TextObjectBase record.
*
* @param textOrientation
* One of TEXT_ORIENTATION_NONE TEXT_ORIENTATION_TOP_TO_BOTTOM
* TEXT_ORIENTATION_ROT_RIGHT TEXT_ORIENTATION_ROT_LEFT
*/
public void setTextOrientation(int textOrientation) {
this.field_2_textOrientation = textOrientation;
}
int size = bytesWritten1 + bytesWritten2 + bytesWritten3;
if ( size != getRecordSize() )
throw new RecordFormatException(size + " bytes written but getRecordSize() reports " + getRecordSize());
return size;
}
if ( bytesWritten1 != getRecordSize() )
throw new RecordFormatException(bytesWritten1 + " bytes written but getRecordSize() reports " + getRecordSize());
return bytesWritten1;
}
public HSSFRichTextString getStr() {
return _text;
}
private ContinueRecord createContinue2()
{
ContinueRecord c2 = new ContinueRecord();
byte[] c2Data = new byte[str.numFormattingRuns() * 8 + 8];
int pos = 0;
for ( int i = 0; i < str.numFormattingRuns(); i++ )
{
LittleEndian.putShort( c2Data, pos, (short) str.getIndexOfFormattingRun( i ) );
pos += 2;
LittleEndian.putShort( c2Data, pos, str.getFontOfFormattingRun( i ) == str.NO_FONT ? 0 : str.getFontOfFormattingRun( i ) );
pos += 2;
pos += 4; // skip reserved
}
LittleEndian.putShort( c2Data, pos, (short) str.length() );
pos += 2;
LittleEndian.putShort( c2Data, pos, (short) 0 );
pos += 2;
pos += 4; // skip reserved
public void setStr(HSSFRichTextString str) {
_text = str;
}
public Ptg getLinkRefPtg() {
return _linkRefPtg;
}
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 )
{
while (in.remaining() > 0)
{
short index = in.readShort();
short iFont = in.readShort();
in.readInt(); // skip reserved.
sb.append(" .string = ").append(_text).append('\n');
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 )
{
String s;
byte compressByte = in.readByte();
boolean isCompressed = compressByte == 0;
if ( isCompressed )
{
s = in.readCompressedUnicode(getTextLength());
}
else
{
s = in.readUnicodeLEString(getTextLength());
}
str = new HSSFRichTextString( s );
}
}
sb.append("[/TXO]\n");
return sb.toString();
}
public HSSFRichTextString getStr()
{
return str;
}
public Object clone() {
public void setStr( HSSFRichTextString str )
{
this.str = str;
}
TextObjectRecord rec = new TextObjectRecord();
rec._text = _text;
public String toString()
{
StringBuffer buffer = new StringBuffer();
rec.field_1_options = field_1_options;
rec.field_2_textOrientation = field_2_textOrientation;
rec.field_3_reserved4 = field_3_reserved4;
rec.field_4_reserved5 = field_4_reserved5;
rec.field_5_reserved6 = field_5_reserved6;
rec.field_8_reserved7 = field_8_reserved7;
buffer.append( "[TXO]\n" );
buffer.append( " .options = " )
.append( "0x" ).append( HexDump.toHex( getOptions() ) )
.append( " (" ).append( getOptions() ).append( " )" );
buffer.append( System.getProperty( "line.separator" ) );
buffer.append( " .reserved1 = " ).append( isReserved1() ).append( '\n' );
buffer.append( " .HorizontalTextAlignment = " ).append( getHorizontalTextAlignment() ).append( '\n' );
buffer.append( " .VerticalTextAlignment = " ).append( getVerticalTextAlignment() ).append( '\n' );
buffer.append( " .reserved2 = " ).append( getReserved2() ).append( '\n' );
buffer.append( " .textLocked = " ).append( isTextLocked() ).append( '\n' );
buffer.append( " .reserved3 = " ).append( getReserved3() ).append( '\n' );
buffer.append( " .textOrientation = " )
.append( "0x" ).append( HexDump.toHex( getTextOrientation() ) )
.append( " (" ).append( getTextOrientation() ).append( " )" );
buffer.append( System.getProperty( "line.separator" ) );
buffer.append( " .reserved4 = " )
.append( "0x" ).append( HexDump.toHex( getReserved4() ) )
.append( " (" ).append( getReserved4() ).append( " )" );
buffer.append( System.getProperty( "line.separator" ) );
buffer.append( " .reserved5 = " )
.append( "0x" ).append( HexDump.toHex( getReserved5() ) )
.append( " (" ).append( getReserved5() ).append( " )" );
buffer.append( System.getProperty( "line.separator" ) );
buffer.append( " .reserved6 = " )
.append( "0x" ).append( HexDump.toHex( getReserved6() ) )
.append( " (" ).append( getReserved6() ).append( " )" );
buffer.append( System.getProperty( "line.separator" ) );
buffer.append( " .textLength = " )
.append( "0x" ).append( HexDump.toHex( getTextLength() ) )
.append( " (" ).append( getTextLength() ).append( " )" );
buffer.append( System.getProperty( "line.separator" ) );
buffer.append( " .reserved7 = " )
.append( "0x" ).append( HexDump.toHex( getReserved7() ) )
.append( " (" ).append( getReserved7() ).append( " )" );
buffer.append( System.getProperty( "line.separator" ) );
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;
}
rec._text = _text; // clone needed?
if (_linkRefPtg != null) {
rec._unknownPreFormulaInt = _unknownPreFormulaInt;
rec._linkRefPtg = _linkRefPtg.copy();
rec._unknownPostFormulaByte = rec._unknownPostFormulaByte;
}
return rec;
}
}

View File

@ -19,10 +19,8 @@ package org.apache.poi.hssf.record.formula;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
/**
* <tt>Ptg</tt> represents a syntactic token in a formula. 'PTG' is an acronym for
@ -49,15 +47,7 @@ public abstract class Ptg implements Cloneable {
* Extra data (beyond <tt>size</tt>) may be read if and <tt>ArrayPtg</tt>s are present.
*/
public static Ptg[] readTokens(int size, RecordInputStream in) {
Stack temp = createParsedExpressionTokens((short)size, in);
return toPtgArray(temp);
}
/**
* @deprecated - use readTokens()
*/
public static Stack createParsedExpressionTokens(short size, RecordInputStream in) {
Stack stack = new Stack();
List temp = new ArrayList(4 + size / 2);
int pos = 0;
List arrayPtgs = null;
while (pos < size) {
@ -71,7 +61,7 @@ public abstract class Ptg implements Cloneable {
} else {
pos += ptg.getSize();
}
stack.push( ptg );
temp.add( ptg );
}
if(pos != size) {
throw new RuntimeException("Ptg array size mismatch");
@ -82,7 +72,7 @@ public abstract class Ptg implements Cloneable {
p.readTokenValues(in);
}
}
return stack;
return toPtgArray(temp);
}
public static Ptg createPtg(RecordInputStream in) {
@ -200,19 +190,11 @@ public abstract class Ptg implements Cloneable {
l.toArray(result);
return result;
}
private static Stack createStack(Ptg[] formulaTokens) {
Stack result = new Stack();
for (int i = 0; i < formulaTokens.length; i++) {
result.add(formulaTokens[i]);
}
return result;
}
/**
* This method will return the same result as {@link #getEncodedSizeWithoutArrayData(Ptg[])}
* if there are no array tokens present.
* @return the full size taken to encode the specified <tt>Ptg</tt>s
*/
// TODO - several duplicates of this code should be refactored here
public static int getEncodedSize(Ptg[] ptgs) {
int result = 0;
for (int i = 0; i < ptgs.length; i++) {
@ -243,23 +225,14 @@ public abstract class Ptg implements Cloneable {
* The 2 byte encode length field is <b>not</b> written by this method.
* @return number of bytes written
*/
public static int serializePtgs(Ptg[] ptgs, byte[] data, int offset) {
return serializePtgStack(createStack(ptgs), data, offset);
}
/**
* @deprecated use serializePtgs()
*/
public static int serializePtgStack(Stack expression, byte[] array, int offset) {
public static int serializePtgs(Ptg[] ptgs, byte[] array, int offset) {
int pos = 0;
int size = 0;
if (expression != null)
size = expression.size();
int size = ptgs.length;
List arrayPtgs = null;
for (int k = 0; k < size; k++) {
Ptg ptg = ( Ptg ) expression.get(k);
Ptg ptg = ptgs[k];
ptg.writeBytes(array, pos + offset);
if (ptg instanceof ArrayPtg) {

View File

@ -149,10 +149,7 @@ public class HSSFComment extends HSSFTextbox implements Comment {
if (hstring.numFormattingRuns() == 0) hstring.applyFont((short)0);
if (txo != null) {
int frLength = ( hstring.numFormattingRuns() + 1 ) * 8;
txo.setFormattingRunLength( (short) frLength );
txo.setTextLength( (short) hstring.length() );
txo.setStr( hstring );
txo.setStr(hstring);
}
super.setString(string);
}

View File

@ -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()
{

View File

@ -20,7 +20,6 @@ package org.apache.poi.hssf.usermodel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import org.apache.poi.hssf.record.AreaFormatRecord;
import org.apache.poi.hssf.record.AxisLineFormatRecord;
@ -68,6 +67,7 @@ import org.apache.poi.hssf.record.UnknownRecord;
import org.apache.poi.hssf.record.VCenterRecord;
import org.apache.poi.hssf.record.ValueRangeRecord;
import org.apache.poi.hssf.record.formula.Area3DPtg;
import org.apache.poi.hssf.record.formula.Ptg;
/**
* Has methods for construction of a chart object.
@ -759,11 +759,9 @@ public final class HSSFChart {
r.setCustomNumberFormat( false );
r.setIndexNumberFmtRecord( (short) 0 );
LinkedDataFormulaField formula = new LinkedDataFormulaField();
Stack tokens = new Stack();
Area3DPtg p = new Area3DPtg(0, 31, 1, 1,
false, false, false, false, 0);
tokens.add( p );
formula.setFormulaTokens( tokens );
formula.setFormulaTokens(new Ptg[] { p, });
r.setFormulaOfLink( formula );
return r;
}
@ -776,11 +774,9 @@ public final class HSSFChart {
r.setCustomNumberFormat( false );
r.setIndexNumberFmtRecord( (short) 0 );
LinkedDataFormulaField formula = new LinkedDataFormulaField();
Stack tokens = new Stack();
Area3DPtg p = new Area3DPtg(0, 31, 0, 0,
false, false, false, false, 0);
tokens.add( p );
formula.setFormulaTokens( tokens );
formula.setFormulaTokens(new Ptg[] { p, });
r.setFormulaOfLink( formula );
return r;
}

View File

@ -87,10 +87,8 @@ public final class TestEventRecordFactory extends TestCase {
bof.setHistoryBitMask(BOFRecord.HISTORY_MASK);
byte[] bytes = bof.serialize();
byte[] nbytes = new byte[bytes.length - 4];
System.arraycopy(bytes,4,nbytes,0,nbytes.length);
Record[] records = RecordFactory.createRecord(new TestcaseRecordInputStream(bof.getSid(),(short)nbytes.length,nbytes));
Record[] records = RecordFactory.createRecord(TestcaseRecordInputStream.create(bytes));
assertTrue("record.length must be 1, was ="+records.length,records.length == 1);
assertTrue("record is the same", compareRec(bof,records[0]));

View File

@ -84,6 +84,7 @@ public final class AllRecordTests {
result.addTestSuite(TestPaneRecord.class);
result.addTestSuite(TestPlotAreaRecord.class);
result.addTestSuite(TestPlotGrowthRecord.class);
result.addTestSuite(TestRecordInputStream.class);
result.addTestSuite(TestRecordFactory.class);
result.addTestSuite(TestSCLRecord.class);
result.addTestSuite(TestSSTDeserializer.class);

View File

@ -41,7 +41,7 @@ public final class TestAreaFormatRecord extends TestCase {
public void testLoad() {
AreaFormatRecord record = new AreaFormatRecord(new TestcaseRecordInputStream((short)0x100a, (short)data.length, data));
AreaFormatRecord record = new AreaFormatRecord(TestcaseRecordInputStream.create(0x100a, data));
assertEquals( 0xFFFFFF, record.getForegroundColor());
assertEquals( 0x000000, record.getBackgroundColor());
assertEquals( 1, record.getPattern());

View File

@ -35,7 +35,7 @@ public final class TestAreaRecord extends TestCase {
public void testLoad() {
AreaRecord record = new AreaRecord(new TestcaseRecordInputStream((short)0x101A, (short)data.length, data));
AreaRecord record = new AreaRecord(TestcaseRecordInputStream.create(0x101A, data));
assertEquals( 2, record.getFormatFlags());
assertEquals( false, record.isStacked() );
assertEquals( true, record.isDisplayAsPercentage() );

View File

@ -34,7 +34,7 @@ public final class TestAxisLineFormatRecord extends TestCase {
};
public void testLoad() {
AxisLineFormatRecord record = new AxisLineFormatRecord(new TestcaseRecordInputStream((short)0x1021, (short)data.length, data));
AxisLineFormatRecord record = new AxisLineFormatRecord(TestcaseRecordInputStream.create(0x1021, data));
assertEquals( AxisLineFormatRecord.AXIS_TYPE_MAJOR_GRID_LINE, record.getAxisType());
assertEquals( 6, record.getRecordSize() );

View File

@ -37,7 +37,7 @@ public final class TestAxisOptionsRecord extends TestCase {
};
public void testLoad() {
AxisOptionsRecord record = new AxisOptionsRecord(new TestcaseRecordInputStream((short)0x1062, (short)data.length, data));
AxisOptionsRecord record = new AxisOptionsRecord(TestcaseRecordInputStream.create(0x1062, data));
assertEquals( 0, record.getMinimumCategory());
assertEquals( 0, record.getMaximumCategory());
assertEquals( 1, record.getMajorUnitValue());

View File

@ -37,7 +37,7 @@ public final class TestAxisParentRecord extends TestCase {
};
public void testLoad() {
AxisParentRecord record = new AxisParentRecord(new TestcaseRecordInputStream((short)0x1041, (short)data.length, data));
AxisParentRecord record = new AxisParentRecord(TestcaseRecordInputStream.create(0x1041, data));
assertEquals( AxisParentRecord.AXIS_TYPE_MAIN, record.getAxisType());
assertEquals( 0x021d, record.getX());
assertEquals( 0xdd, record.getY());

View File

@ -39,7 +39,7 @@ public final class TestAxisRecord extends TestCase {
public void testLoad() {
AxisRecord record = new AxisRecord(new TestcaseRecordInputStream((short)0x101d, (short)data.length, data));
AxisRecord record = new AxisRecord(TestcaseRecordInputStream.create(0x101d, data));
assertEquals( AxisRecord.AXIS_TYPE_CATEGORY_OR_X_AXIS, record.getAxisType());
assertEquals( 0, record.getReserved1());
assertEquals( 0, record.getReserved2());

View File

@ -34,7 +34,7 @@ public final class TestAxisUsedRecord extends TestCase {
};
public void testLoad() {
AxisUsedRecord record = new AxisUsedRecord(new TestcaseRecordInputStream((short)0x1046, (short)data.length, data));
AxisUsedRecord record = new AxisUsedRecord(TestcaseRecordInputStream.create(0x1046, data));
assertEquals( 1, record.getNumAxis());
assertEquals( 6, record.getRecordSize() );

View File

@ -37,7 +37,7 @@ public final class TestBarRecord extends TestCase {
public void testLoad() {
BarRecord record = new BarRecord(new TestcaseRecordInputStream((short)0x1017, (short)data.length, data));
BarRecord record = new BarRecord(TestcaseRecordInputStream.create(0x1017, data));
assertEquals( 0, record.getBarSpace());
assertEquals( 0x96, record.getCategorySpace());
assertEquals( 0, record.getFormatFlags());

View File

@ -69,7 +69,7 @@ public final class TestBoundSheetRecord extends TestCase {
// </str>
};
RecordInputStream in = new TestcaseRecordInputStream(BoundSheetRecord.sid, data);
RecordInputStream in = TestcaseRecordInputStream.create(BoundSheetRecord.sid, data);
BoundSheetRecord bsr = new BoundSheetRecord(in);
// sheet name is unicode Russian for 'minor page'
assertEquals("\u0421\u0442\u0440\u0430\u043D\u0438\u0447\u043A\u0430", bsr.getSheetname());

View File

@ -90,7 +90,7 @@ public final class TestCFHeaderRecord extends TestCase
(byte)0x03, (byte)0x00,
};
CFHeaderRecord record = new CFHeaderRecord(new TestcaseRecordInputStream(CFHeaderRecord.sid, (short)recordData.length, recordData));
CFHeaderRecord record = new CFHeaderRecord(TestcaseRecordInputStream.create(CFHeaderRecord.sid, recordData));
assertEquals("#CFRULES", 3, record.getNumberOfConditionalFormats());
assertTrue(record.getNeedRecalculation());
@ -143,7 +143,7 @@ public final class TestCFHeaderRecord extends TestCase
CFHeaderRecord record;
try {
record = new CFHeaderRecord(new TestcaseRecordInputStream(CFHeaderRecord.sid, (short)recordData.length, recordData));
record = new CFHeaderRecord(TestcaseRecordInputStream.create(CFHeaderRecord.sid, recordData));
} catch (IllegalArgumentException e) {
if(e.getMessage().equals("invalid cell range (-25536, 2, -15536, 2)")) {
throw new AssertionFailedError("Identified bug 44739b");

View File

@ -54,7 +54,7 @@ public final class TestCFRuleRecord extends TestCase
System.arraycopy(serializedRecord, 4, recordData, 0, recordData.length);
// Deserialize
record = new CFRuleRecord(new TestcaseRecordInputStream(CFRuleRecord.sid, (short)recordData.length, recordData));
record = new CFRuleRecord(TestcaseRecordInputStream.create(CFRuleRecord.sid, recordData));
// Serialize again
byte[] output = record.serialize();
@ -317,7 +317,7 @@ public final class TestCFRuleRecord extends TestCase
*/
public void testReserializeRefNTokens() {
RecordInputStream is = new TestcaseRecordInputStream(CFRuleRecord.sid, DATA_REFN);
RecordInputStream is = TestcaseRecordInputStream.create(CFRuleRecord.sid, DATA_REFN);
CFRuleRecord rr = new CFRuleRecord(is);
Ptg[] ptgs = rr.getParsedExpression1();
assertEquals(3, ptgs.length);

View File

@ -38,7 +38,7 @@ public final class TestCategorySeriesAxisRecord extends TestCase {
public void testLoad() {
CategorySeriesAxisRecord record = new CategorySeriesAxisRecord(new TestcaseRecordInputStream((short)0x1020, (short)data.length, data));
CategorySeriesAxisRecord record = new CategorySeriesAxisRecord(TestcaseRecordInputStream.create(0x1020, data));
assertEquals( 1, record.getCrossingPoint());
assertEquals( 1, record.getLabelFrequency());
assertEquals( 1, record.getTickMarkFrequency());

View File

@ -38,7 +38,7 @@ public final class TestChartRecord extends TestCase {
public void testLoad() {
ChartRecord record = new ChartRecord(new TestcaseRecordInputStream((short)0x1002, (short)data.length, data));
ChartRecord record = new ChartRecord(TestcaseRecordInputStream.create(0x1002, data));
assertEquals( 0, record.getX());
assertEquals( 0, record.getY());
assertEquals( 30474216, record.getWidth());

View File

@ -38,7 +38,7 @@ public final class TestCommonObjectDataSubRecord extends TestCase {
};
public void testLoad() {
CommonObjectDataSubRecord record = new CommonObjectDataSubRecord(new TestcaseRecordInputStream((short)0x15, (short)data.length, data));
CommonObjectDataSubRecord record = new CommonObjectDataSubRecord(TestcaseRecordInputStream.create(0x15, data));
assertEquals( CommonObjectDataSubRecord.OBJECT_TYPE_LIST_BOX, record.getObjectType());
assertEquals( (short)1, record.getObjectId());

View File

@ -35,7 +35,7 @@ public final class TestDatRecord extends TestCase {
public void testLoad() {
DatRecord record = new DatRecord(new TestcaseRecordInputStream((short)0x1063, (short)data.length, data));
DatRecord record = new DatRecord(TestcaseRecordInputStream.create(0x1063, data));
assertEquals( 0xD, record.getOptions());
assertEquals( true, record.isHorizontalBorder() );
assertEquals( false, record.isVerticalBorder() );

View File

@ -38,7 +38,7 @@ public final class TestDataFormatRecord extends TestCase {
public void testLoad() {
DataFormatRecord record = new DataFormatRecord(new TestcaseRecordInputStream((short)0x1006, (short)data.length, data));
DataFormatRecord record = new DataFormatRecord(TestcaseRecordInputStream.create(0x1006, data));
assertEquals( (short)0xFFFF, record.getPointNumber());
assertEquals( 0, record.getSeriesIndex());
assertEquals( 0, record.getSeriesNumber());

View File

@ -35,7 +35,7 @@ public final class TestDefaultDataLabelTextPropertiesRecord extends TestCase {
public void testLoad() {
DefaultDataLabelTextPropertiesRecord record = new DefaultDataLabelTextPropertiesRecord(new TestcaseRecordInputStream((short)0x1024, (short)data.length, data));
DefaultDataLabelTextPropertiesRecord record = new DefaultDataLabelTextPropertiesRecord(TestcaseRecordInputStream.create(0x1024, data));
assertEquals( 2, record.getCategoryDataType());
assertEquals( 6, record.getRecordSize() );

View File

@ -127,7 +127,7 @@ public final class TestEmbeddedObjectRefSubRecord extends TestCase {
}
private static void confirmRead(byte[] data, int i) {
RecordInputStream in = new TestcaseRecordInputStream(EmbeddedObjectRefSubRecord.sid, (short)data.length, data);
RecordInputStream in = TestcaseRecordInputStream.create(EmbeddedObjectRefSubRecord.sid, data);
EmbeddedObjectRefSubRecord rec = new EmbeddedObjectRefSubRecord(in);
byte[] ser2 = rec.serialize();

View File

@ -33,7 +33,7 @@ public final class TestEndSubRecord extends TestCase {
};
public void testLoad() {
EndSubRecord record = new EndSubRecord(new TestcaseRecordInputStream((short)0x00, (short)data.length, data));
EndSubRecord record = new EndSubRecord(TestcaseRecordInputStream.create(0x00, data));
assertEquals( 4, record.getRecordSize() );
}

View File

@ -37,7 +37,7 @@ public final class TestExtendedFormatRecord extends TestCase {
};
public void testLoad() {
ExtendedFormatRecord record = new ExtendedFormatRecord(new TestcaseRecordInputStream((short)0xe0, (short)data.length, data));
ExtendedFormatRecord record = new ExtendedFormatRecord(TestcaseRecordInputStream.create(0xe0, data));
assertEquals(0, record.getFontIndex());
assertEquals(0, record.getFormatIndex());
assertEquals(0xF5-256, record.getCellOptions());
@ -117,7 +117,7 @@ public final class TestExtendedFormatRecord extends TestCase {
}
public void testCloneOnto() throws Exception {
ExtendedFormatRecord base = new ExtendedFormatRecord(new TestcaseRecordInputStream((short)0xe0, (short)data.length, data));
ExtendedFormatRecord base = new ExtendedFormatRecord(TestcaseRecordInputStream.create(0xe0, data));
ExtendedFormatRecord other = new ExtendedFormatRecord();
other.cloneStyleFrom(base);

View File

@ -43,7 +43,7 @@ public final class TestExternalNameRecord extends TestCase {
};
private static ExternalNameRecord createSimpleENR(byte[] data) {
return new ExternalNameRecord(new TestcaseRecordInputStream((short)0x0023, data));
return new ExternalNameRecord(TestcaseRecordInputStream.create(0x0023, data));
}
public void testBasicDeserializeReserialize() {

View File

@ -39,7 +39,7 @@ public final class TestFontBasisRecord extends TestCase {
public void testLoad() {
FontBasisRecord record = new FontBasisRecord(new TestcaseRecordInputStream((short)0x1060, (short)data.length, data));
FontBasisRecord record = new FontBasisRecord(TestcaseRecordInputStream.create(0x1060, data));
assertEquals( 0x1a28, record.getXBasis());
assertEquals( 0x0f9c, record.getYBasis());
assertEquals( 0xc8, record.getHeightBasis());

View File

@ -35,7 +35,7 @@ public final class TestFontIndexRecord extends TestCase {
public void testLoad() {
FontIndexRecord record = new FontIndexRecord(new TestcaseRecordInputStream((short)0x1026, (short)data.length, data));
FontIndexRecord record = new FontIndexRecord(TestcaseRecordInputStream.create(0x1026, data));
assertEquals( 5, record.getFontIndex());
assertEquals( 6, record.getRecordSize() );

View File

@ -44,7 +44,7 @@ public final class TestFontRecord extends TestCase {
public void testLoad() {
FontRecord record = new FontRecord(new TestcaseRecordInputStream((short)0x31, (short)data.length, data));
FontRecord record = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
assertEquals( 0xc8, record.getFontHeight());
assertEquals( 0x00, record.getAttributes());
assertFalse( record.isItalic());
@ -100,7 +100,7 @@ public final class TestFontRecord extends TestCase {
}
public void testCloneOnto() throws Exception {
FontRecord base = new FontRecord(new TestcaseRecordInputStream((short)0x31, (short)data.length, data));
FontRecord base = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
FontRecord other = new FontRecord();
other.cloneStyleFrom(base);
@ -112,8 +112,8 @@ public final class TestFontRecord extends TestCase {
}
public void testSameProperties() throws Exception {
FontRecord f1 = new FontRecord(new TestcaseRecordInputStream((short)0x31, (short)data.length, data));
FontRecord f2 = new FontRecord(new TestcaseRecordInputStream((short)0x31, (short)data.length, data));
FontRecord f1 = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
FontRecord f2 = new FontRecord(TestcaseRecordInputStream.create(0x31, data));
assertTrue(f1.sameProperties(f2));

View File

@ -82,7 +82,7 @@ public final class TestFormulaRecord extends TestCase {
};
FormulaRecord record = new FormulaRecord(new TestcaseRecordInputStream(FormulaRecord.sid, (short)29, formulaByte));
FormulaRecord record = new FormulaRecord(TestcaseRecordInputStream.create(FormulaRecord.sid, formulaByte));
assertEquals("Row", 0, record.getRow());
assertEquals("Column", 0, record.getColumn());
assertEquals(HSSFCell.CELL_TYPE_ERROR, record.getCachedResultType());
@ -108,7 +108,7 @@ public final class TestFormulaRecord extends TestCase {
formulaByte[19]=(byte)0xFD;
formulaByte[20]=(byte)0x05;
formulaByte[22]=(byte)0x01;
FormulaRecord record = new FormulaRecord(new TestcaseRecordInputStream(FormulaRecord.sid, (short)27, formulaByte));
FormulaRecord record = new FormulaRecord(TestcaseRecordInputStream.create(FormulaRecord.sid, formulaByte));
assertEquals("Row", 0, record.getRow());
assertEquals("Column", 0, record.getColumn());
byte[] output = record.serialize();

View File

@ -36,7 +36,7 @@ public final class TestFrameRecord extends TestCase {
public void testLoad() {
FrameRecord record = new FrameRecord(new TestcaseRecordInputStream((short)0x1032, (short)data.length, data));
FrameRecord record = new FrameRecord(TestcaseRecordInputStream.create(0x1032, data));
assertEquals( FrameRecord.BORDER_TYPE_REGULAR, record.getBorderType());
assertEquals( 2, record.getOptions());
assertEquals( false, record.isAutoSize() );

View File

@ -17,7 +17,6 @@
package org.apache.poi.hssf.record;
import java.io.ByteArrayInputStream;
import java.net.URL;
import java.util.Arrays;
import junit.framework.TestCase;
@ -28,7 +27,7 @@ import junit.framework.TestCase;
* @author Nick Burch
* @author Yegor Kozlov
*/
public class TestHyperlinkRecord extends TestCase {
public final class TestHyperlinkRecord extends TestCase {
//link to http://www.lakings.com/
byte[] data1 = { 0x02, 0x00, //First row of the hyperlink
@ -165,7 +164,7 @@ public class TestHyperlinkRecord extends TestCase {
0x00, 0x41, 0x00, 0x31, 0x00, 0x00, 0x00};
public void testReadURLLink(){
RecordInputStream is = new TestcaseRecordInputStream((short)HyperlinkRecord.sid, (short)data1.length, data1);
RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data1);
HyperlinkRecord link = new HyperlinkRecord(is);
assertEquals(2, link.getFirstRow());
assertEquals(2, link.getLastRow());
@ -184,7 +183,7 @@ public class TestHyperlinkRecord extends TestCase {
}
public void testReadFileLink(){
RecordInputStream is = new TestcaseRecordInputStream((short)HyperlinkRecord.sid, (short)data2.length, data2);
RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data2);
HyperlinkRecord link = new HyperlinkRecord(is);
assertEquals(0, link.getFirstRow());
assertEquals(0, link.getLastRow());
@ -202,7 +201,7 @@ public class TestHyperlinkRecord extends TestCase {
}
public void testReadEmailLink(){
RecordInputStream is = new TestcaseRecordInputStream((short)HyperlinkRecord.sid, (short)data3.length, data3);
RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data3);
HyperlinkRecord link = new HyperlinkRecord(is);
assertEquals(1, link.getFirstRow());
assertEquals(1, link.getLastRow());
@ -220,7 +219,7 @@ public class TestHyperlinkRecord extends TestCase {
}
public void testReadDocumentLink(){
RecordInputStream is = new TestcaseRecordInputStream((short)HyperlinkRecord.sid, (short)data4.length, data4);
RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data4);
HyperlinkRecord link = new HyperlinkRecord(is);
assertEquals(3, link.getFirstRow());
assertEquals(3, link.getLastRow());
@ -237,7 +236,7 @@ public class TestHyperlinkRecord extends TestCase {
}
private void serialize(byte[] data){
RecordInputStream is = new TestcaseRecordInputStream((short)HyperlinkRecord.sid, (short)data.length, data);
RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data);
HyperlinkRecord link = new HyperlinkRecord(is);
byte[] bytes1 = link.serialize();
is = new RecordInputStream(new ByteArrayInputStream(bytes1));
@ -318,7 +317,7 @@ public class TestHyperlinkRecord extends TestCase {
public void testClone() throws Exception {
byte[][] data = {data1, data2, data3, data4};
for (int i = 0; i < data.length; i++) {
RecordInputStream is = new TestcaseRecordInputStream((short)HyperlinkRecord.sid, (short)data[i].length, data[i]);
RecordInputStream is = TestcaseRecordInputStream.create(HyperlinkRecord.sid, data[i]);
HyperlinkRecord link = new HyperlinkRecord(is);
HyperlinkRecord clone = (HyperlinkRecord)link.clone();
assertTrue(Arrays.equals(link.serialize(), clone.serialize()));

View File

@ -17,80 +17,73 @@
package org.apache.poi.hssf.record;
import junit.framework.TestCase;
/**
* Tests the serialization and deserialization of the LegendRecord
* class works correctly. Test data taken directly from a real
* Excel file.
*
* Tests the serialization and deserialization of the LegendRecord class works
* correctly. Test data taken directly from a real Excel file.
*
*
* @author Andrew C. Oliver (acoliver at apache.org)
*/
public class TestLegendRecord extends TestCase {
byte[] data = new byte[] {
(byte)0x76,(byte)0x0E,(byte)0x00,(byte)0x00,(byte)0x86,(byte)0x07,(byte)0x00,(byte)0x00,(byte)0x19,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x8B,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x03,(byte)0x01,(byte)0x1F,(byte)0x00
};
public final class TestLegendRecord extends TestCase {
byte[] data = new byte[] { (byte) 0x76, (byte) 0x0E, (byte) 0x00, (byte) 0x00, (byte) 0x86,
(byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0x19, (byte) 0x01, (byte) 0x00,
(byte) 0x00, (byte) 0x8B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03,
(byte) 0x01, (byte) 0x1F, (byte) 0x00 };
public void testLoad() {
LegendRecord record = new LegendRecord(new TestcaseRecordInputStream((short)0x1015, (short)data.length, data));
public void testLoad() {
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( true, record.isAutoPosition() );
assertEquals( true, record.isAutoSeries() );
assertEquals( true, record.isAutoXPositioning() );
assertEquals( true, record.isAutoYPositioning() );
assertEquals( true, record.isVertical() );
assertEquals( false, record.isDataTable() );
assertEquals((short) 0x1f, record.getOptions());
assertEquals(true, record.isAutoPosition());
assertEquals(true, record.isAutoSeries());
assertEquals(true, record.isAutoXPositioning());
assertEquals(true, record.isAutoYPositioning());
assertEquals(true, record.isVertical());
assertEquals(false, record.isDataTable());
assertEquals(24, record.getRecordSize());
}
assertEquals( 24, record.getRecordSize() );
}
public void testStore() {
LegendRecord record = new LegendRecord();
public void testStore()
{
LegendRecord record = new LegendRecord();
record.setXAxisUpperLeft(0xe76);
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 );
record.setSpacing( (byte)0x1 );
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]);
}
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]);
}
}

View File

@ -28,7 +28,7 @@ import junit.framework.TestCase;
* @author Glen Stampoultzis (glens at apache.org)
*/
public class TestLineFormatRecord extends TestCase {
public final class TestLineFormatRecord extends TestCase {
byte[] data = new byte[] {
(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, // colour
(byte)0x00,(byte)0x00, // pattern
@ -38,7 +38,7 @@ public class TestLineFormatRecord extends TestCase {
};
public void testLoad() {
LineFormatRecord record = new LineFormatRecord(new TestcaseRecordInputStream((short)0x1007, (short)data.length, data));
LineFormatRecord record = new LineFormatRecord(TestcaseRecordInputStream.create(0x1007, data));
assertEquals( 0, record.getLineColor());
assertEquals( 0, record.getLinePattern());
assertEquals( 0, record.getWeight());

View File

@ -19,9 +19,9 @@ package org.apache.poi.hssf.record;
import junit.framework.TestCase;
import org.apache.poi.hssf.record.formula.Area3DPtg;
import java.util.Stack;
import org.apache.poi.hssf.record.formula.Area3DPtg;
import org.apache.poi.hssf.record.formula.Ptg;
/**
* Tests the serialization and deserialization of the LinkedDataRecord
@ -157,7 +157,7 @@ recordid = 0x1051, size =8
public void testLoad() {
LinkedDataRecord record = new LinkedDataRecord(new TestcaseRecordInputStream((short)0x1051, (short)data.length, data));
LinkedDataRecord record = new LinkedDataRecord(TestcaseRecordInputStream.create(0x1051, data));
assertEquals( LinkedDataRecord.LINK_TYPE_VALUES, record.getLinkType());
assertEquals( LinkedDataRecord.REFERENCE_TYPE_WORKSHEET, record.getReferenceType());
assertEquals( 0, record.getOptions());
@ -167,7 +167,7 @@ recordid = 0x1051, size =8
Area3DPtg ptgExpected = new Area3DPtg(0, 7936, 0, 0,
false, false, false, false, 0);
Object ptgActual = record.getFormulaOfLink().getFormulaTokens().get(0);
Object ptgActual = record.getFormulaOfLink().getFormulaTokens()[0];
assertEquals(ptgExpected.toString(), ptgActual.toString());
assertEquals( data.length + 4, record.getRecordSize() );
@ -182,10 +182,8 @@ recordid = 0x1051, size =8
record.setIndexNumberFmtRecord( (short)0 );
Area3DPtg ptg = new Area3DPtg(0, 7936, 0, 0,
false, false, false, false, 0);
Stack s = new Stack();
s.push(ptg);
LinkedDataFormulaField formulaOfLink = new LinkedDataFormulaField();
formulaOfLink.setFormulaTokens(s);
formulaOfLink.setFormulaTokens(new Ptg[] { ptg, });
record.setFormulaOfLink(formulaOfLink );
byte [] recordBytes = record.serialize();

View File

@ -1,4 +1,3 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@ -25,9 +24,7 @@ import junit.framework.TestCase;
*
* @author Danny Mui (dmui at apache dot org)
*/
public class TestNameRecord
extends TestCase
{
public final class TestNameRecord extends TestCase {
/**
* Makes sure that additional name information is parsed properly such as menu/description
@ -55,13 +52,11 @@ public class TestNameRecord
};
NameRecord name = new NameRecord(new TestcaseRecordInputStream(NameRecord.sid, (short) examples.length, examples));
NameRecord name = new NameRecord(TestcaseRecordInputStream.create(NameRecord.sid, examples));
String description = name.getDescriptionText();
assertNotNull( description );
assertTrue( "text contains ALLWOR", description.indexOf( "ALLWOR" ) > 0 );
}
}

View File

@ -29,9 +29,7 @@ import java.util.Arrays;
*
* @author Yegor Kozlov
*/
public class TestNoteRecord
extends TestCase
{
public final class TestNoteRecord extends TestCase {
private byte[] data = new byte[] {
0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x04, 0x1A, 0x00,
0x00, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x20, 0x53, 0x6F,
@ -41,7 +39,7 @@ public class TestNoteRecord
public void testRead() {
NoteRecord record = new NoteRecord(new TestcaseRecordInputStream(NoteRecord.sid, (short)data.length, data));
NoteRecord record = new NoteRecord(TestcaseRecordInputStream.create(NoteRecord.sid, data));
assertEquals(NoteRecord.sid, record.getSid());
assertEquals(6, record.getRow());

View File

@ -38,7 +38,7 @@ public final class TestNoteStructureSubRecord extends TestCase {
public void testRead() {
NoteStructureSubRecord record = new NoteStructureSubRecord(new TestcaseRecordInputStream(NoteStructureSubRecord.sid, (short)data.length, data));
NoteStructureSubRecord record = new NoteStructureSubRecord(TestcaseRecordInputStream.create(NoteStructureSubRecord.sid, data));
assertEquals(NoteStructureSubRecord.sid, record.getSid());
assertEquals(data.length + 4, record.getRecordSize());

View File

@ -35,7 +35,7 @@ public final class TestNumberFormatIndexRecord extends TestCase {
public void testLoad() {
NumberFormatIndexRecord record = new NumberFormatIndexRecord(new TestcaseRecordInputStream((short)0x104e, (short)data.length, data));
NumberFormatIndexRecord record = new NumberFormatIndexRecord(TestcaseRecordInputStream.create(0x104e, data));
assertEquals( 5, record.getFormatIndex());
assertEquals( 6, record.getRecordSize() );

View File

@ -51,7 +51,7 @@ public final class TestObjRecord extends TestCase {
};
public void testLoad() {
ObjRecord record = new ObjRecord(new TestcaseRecordInputStream(ObjRecord.sid, (short)recdata.length, recdata));
ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdata));
assertEquals(28, record.getRecordSize() - 4);
@ -63,7 +63,7 @@ public final class TestObjRecord extends TestCase {
}
public void testStore() {
ObjRecord record = new ObjRecord(new TestcaseRecordInputStream(ObjRecord.sid, (short)recdata.length, recdata));
ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdata));
byte [] recordBytes = record.serialize();
assertEquals(28, recordBytes.length - 4);
@ -91,7 +91,7 @@ public final class TestObjRecord extends TestCase {
byte [] bytes = new byte[recordBytes.length-4];
System.arraycopy(recordBytes, 4, bytes, 0, bytes.length);
record = new ObjRecord(new TestcaseRecordInputStream(ObjRecord.sid, (short)bytes.length, bytes));
record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, bytes));
List subrecords = record.getSubRecords();
assertEquals( 2, subrecords.size() );
assertTrue( subrecords.get(0) instanceof CommonObjectDataSubRecord);
@ -99,7 +99,7 @@ public final class TestObjRecord extends TestCase {
}
public void testReadWriteWithPadding_bug45133() {
ObjRecord record = new ObjRecord(new TestcaseRecordInputStream(ObjRecord.sid, (short)recdataNeedingPadding.length, recdataNeedingPadding));
ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdataNeedingPadding));
if (record.getRecordSize() == 34) {
throw new AssertionFailedError("Identified bug 45133");

View File

@ -34,7 +34,7 @@ public final class TestObjectLinkRecord extends TestCase {
};
public void testLoad() {
ObjectLinkRecord record = new ObjectLinkRecord(new TestcaseRecordInputStream((short)0x1027, (short)data.length, data));
ObjectLinkRecord record = new ObjectLinkRecord(TestcaseRecordInputStream.create(0x1027, data));
assertEquals( (short)3, record.getAnchorId());
assertEquals( (short)0x00, record.getLink1());

View File

@ -37,7 +37,7 @@ public final class TestPaneRecord extends TestCase {
};
public void testLoad() {
PaneRecord record = new PaneRecord(new TestcaseRecordInputStream((short)0x41, (short)data.length, data));
PaneRecord record = new PaneRecord(TestcaseRecordInputStream.create(0x41, data));
assertEquals( (short)1, record.getX());
assertEquals( (short)2, record.getY());

View File

@ -34,7 +34,7 @@ public final class TestPlotAreaRecord extends TestCase {
};
public void testLoad() {
PlotAreaRecord record = new PlotAreaRecord(new TestcaseRecordInputStream((short)0x1035, (short)data.length, data));
PlotAreaRecord record = new PlotAreaRecord(TestcaseRecordInputStream.create(0x1035, data));
assertEquals( 4, record.getRecordSize() );
}

View File

@ -35,7 +35,7 @@ public final class TestPlotGrowthRecord extends TestCase {
public void testLoad() {
PlotGrowthRecord record = new PlotGrowthRecord(new TestcaseRecordInputStream((short)0x1064, (short)data.length, data));
PlotGrowthRecord record = new PlotGrowthRecord(TestcaseRecordInputStream.create(0x1064, data));
assertEquals( 65536, record.getHorizontalScale());
assertEquals( 65536, record.getVerticalScale());

View File

@ -49,7 +49,7 @@ public final class TestRecordFactory extends TestCase {
0, 6, 5, 0, -2, 28, -51, 7, -55, 64, 0, 0, 6, 1, 0, 0
};
short size = 16;
Record[] record = RecordFactory.createRecord(new TestcaseRecordInputStream(recType, size, data));
Record[] record = RecordFactory.createRecord(TestcaseRecordInputStream.create(recType, data));
assertEquals(BOFRecord.class.getName(),
record[ 0 ].getClass().getName());
@ -69,7 +69,7 @@ public final class TestRecordFactory extends TestCase {
{
0, 0
};
record = RecordFactory.createRecord(new TestcaseRecordInputStream(recType, size, data));
record = RecordFactory.createRecord(TestcaseRecordInputStream.create(recType, data));
assertEquals(MMSRecord.class.getName(),
record[ 0 ].getClass().getName());
MMSRecord mmsRecord = ( MMSRecord ) record[ 0 ];
@ -94,7 +94,7 @@ public final class TestRecordFactory extends TestCase {
0, 0, 0, 0, 21, 0, 0, 0, 0, 0
};
short size = 10;
Record[] record = RecordFactory.createRecord(new TestcaseRecordInputStream(recType, size, data));
Record[] record = RecordFactory.createRecord(TestcaseRecordInputStream.create(recType, data));
assertEquals(NumberRecord.class.getName(),
record[ 0 ].getClass().getName());

View File

@ -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);
}
}

View File

@ -34,7 +34,7 @@ public final class TestSCLRecord extends TestCase {
};
public void testLoad() {
SCLRecord record = new SCLRecord(new TestcaseRecordInputStream((short)0xa0, (short)data.length, data));
SCLRecord record = new SCLRecord(TestcaseRecordInputStream.create(0xa0, data));
assertEquals( 3, record.getNumerator());
assertEquals( 4, record.getDenominator());

View File

@ -32,31 +32,30 @@ import org.apache.poi.util.IntMapper;
* @author Glen Stampoultzis (glens at apache.org)
*/
public final class TestSSTDeserializer extends TestCase {
private static final int FAKE_SID = -5555;
private byte[] joinArray(byte[] array1, byte[] array2) {
byte[] bigArray = new byte[array1.length + array2.length];
System.arraycopy(array1, 0, bigArray, 0, array1.length);
System.arraycopy(array2, 0, bigArray, array1.length, array2.length);
return bigArray;
private static byte[] concat(byte[] a, byte[] b) {
byte[] result = new byte[a.length + b.length];
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, a.length, b.length);
return result;
}
private static byte[] readSampleHexData(String sampleFileName, String sectionName) {
private static byte[] readSampleHexData(String sampleFileName, String sectionName, int recSid) {
InputStream is = HSSFTestDataSamples.openSampleFileStream(sampleFileName);
byte[] data;
try {
return HexRead.readData(is, sectionName);
data = HexRead.readData(is, sectionName);
} catch (IOException e) {
throw new RuntimeException(e);
}
return TestcaseRecordInputStream.mergeDataAndSid(recSid, data.length, data);
}
public void testSpanRichTextToPlainText()
throws Exception
{
byte[] header = readSampleHexData("richtextdata.txt", "header" );
byte[] continueBytes = readSampleHexData("richtextdata.txt", "continue1" );
continueBytes = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continueBytes.length, continueBytes);
TestcaseRecordInputStream in = new TestcaseRecordInputStream((short)0, (short)header.length, joinArray(header, continueBytes));
public void testSpanRichTextToPlainText() {
byte[] header = readSampleHexData("richtextdata.txt", "header", FAKE_SID);
byte[] continueBytes = readSampleHexData("richtextdata.txt", "continue1", ContinueRecord.sid);
RecordInputStream in = TestcaseRecordInputStream.create(concat(header, continueBytes));
IntMapper strings = new IntMapper();
@ -66,13 +65,10 @@ public final class TestSSTDeserializer extends TestCase {
assertEquals( "At a dinner party orAt At At ", strings.get( 0 ) + "" );
}
public void testContinuationWithNoOverlap()
throws Exception
{
byte[] header = readSampleHexData("evencontinuation.txt", "header" );
byte[] continueBytes = readSampleHexData("evencontinuation.txt", "continue1" );
continueBytes = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continueBytes.length, continueBytes);
TestcaseRecordInputStream in = new TestcaseRecordInputStream((short)0, (short)header.length, joinArray(header, continueBytes));
public void testContinuationWithNoOverlap() {
byte[] header = readSampleHexData("evencontinuation.txt", "header", FAKE_SID);
byte[] continueBytes = readSampleHexData("evencontinuation.txt", "continue1", ContinueRecord.sid);
RecordInputStream in = TestcaseRecordInputStream.create(concat(header, continueBytes));
IntMapper strings = new IntMapper();
SSTDeserializer deserializer = new SSTDeserializer( strings );
@ -85,18 +81,12 @@ public final class TestSSTDeserializer extends TestCase {
/**
* Strings can actually span across more than one continuation.
*/
public void testStringAcross2Continuations()
throws Exception
{
byte[] header = readSampleHexData("stringacross2continuations.txt", "header" );
byte[] continue1 = readSampleHexData("stringacross2continuations.txt", "continue1" );
continue1 = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continue1.length, continue1);
byte[] continue2 = readSampleHexData("stringacross2continuations.txt", "continue2" );
continue2 = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continue2.length, continue2);
public void testStringAcross2Continuations() {
byte[] header = readSampleHexData("stringacross2continuations.txt", "header", FAKE_SID);
byte[] continue1 = readSampleHexData("stringacross2continuations.txt", "continue1", ContinueRecord.sid);
byte[] continue2 = readSampleHexData("stringacross2continuations.txt", "continue2", ContinueRecord.sid);
byte[] bytes = joinArray(header, continue1);
bytes = joinArray(bytes, continue2);
TestcaseRecordInputStream in = new TestcaseRecordInputStream((short)0, (short)header.length, bytes);
RecordInputStream in = TestcaseRecordInputStream.create(concat(header, concat(continue1, continue2)));
IntMapper strings = new IntMapper();
SSTDeserializer deserializer = new SSTDeserializer( strings );
@ -107,10 +97,9 @@ public final class TestSSTDeserializer extends TestCase {
}
public void testExtendedStrings() {
byte[] header = readSampleHexData("extendedtextstrings.txt", "rich-header" );
byte[] continueBytes = readSampleHexData("extendedtextstrings.txt", "rich-continue1" );
continueBytes = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continueBytes.length, continueBytes);
TestcaseRecordInputStream in = new TestcaseRecordInputStream((short)0, (short)header.length, joinArray(header, continueBytes));
byte[] header = readSampleHexData("extendedtextstrings.txt", "rich-header", FAKE_SID);
byte[] continueBytes = readSampleHexData("extendedtextstrings.txt", "rich-continue1", ContinueRecord.sid);
RecordInputStream in = TestcaseRecordInputStream.create(concat(header, continueBytes));
IntMapper strings = new IntMapper();
SSTDeserializer deserializer = new SSTDeserializer( strings );
@ -119,10 +108,9 @@ public final class TestSSTDeserializer extends TestCase {
assertEquals( "At a dinner party orAt At At ", strings.get( 0 ) + "" );
header = readSampleHexData("extendedtextstrings.txt", "norich-header" );
continueBytes = readSampleHexData("extendedtextstrings.txt", "norich-continue1" );
continueBytes = TestcaseRecordInputStream.mergeDataAndSid(ContinueRecord.sid, (short)continueBytes.length, continueBytes);
in = new TestcaseRecordInputStream((short)0, (short)header.length, joinArray(header, continueBytes));
header = readSampleHexData("extendedtextstrings.txt", "norich-header", FAKE_SID);
continueBytes = readSampleHexData("extendedtextstrings.txt", "norich-continue1", ContinueRecord.sid);
in = TestcaseRecordInputStream.create(concat(header, continueBytes));
strings = new IntMapper();
deserializer = new SSTDeserializer( strings );

View File

@ -33,7 +33,7 @@ public final class TestSeriesChartGroupIndexRecord extends TestCase {
};
public void testLoad() {
SeriesChartGroupIndexRecord record = new SeriesChartGroupIndexRecord(new TestcaseRecordInputStream((short)0x1045, (short)data.length, data));
SeriesChartGroupIndexRecord record = new SeriesChartGroupIndexRecord(TestcaseRecordInputStream.create(0x1045, data));
assertEquals( 0, record.getChartGroupIndex());
assertEquals( 6, record.getRecordSize() );

View File

@ -34,7 +34,7 @@ public final class TestSeriesIndexRecord extends TestCase {
};
public void testLoad() {
SeriesIndexRecord record = new SeriesIndexRecord(new TestcaseRecordInputStream((short)0x1065, (short)data.length, data));
SeriesIndexRecord record = new SeriesIndexRecord(TestcaseRecordInputStream.create(0x1065, data));
assertEquals( (short)3, record.getIndex());
assertEquals( 6, record.getRecordSize() );

View File

@ -34,7 +34,7 @@ public final class TestSeriesLabelsRecord extends TestCase {
};
public void testLoad() {
SeriesLabelsRecord record = new SeriesLabelsRecord(new TestcaseRecordInputStream((short)0x100c, (short)data.length, data));
SeriesLabelsRecord record = new SeriesLabelsRecord(TestcaseRecordInputStream.create(0x100c, data));
assertEquals( 3, record.getFormatFlags());
assertEquals( true, record.isShowActual() );
assertEquals( true, record.isShowPercent() );

View File

@ -35,7 +35,7 @@ public final class TestSeriesListRecord extends TestCase {
public void testLoad() {
SeriesListRecord record = new SeriesListRecord(new TestcaseRecordInputStream((short)0x1016, (short)data.length, data));
SeriesListRecord record = new SeriesListRecord(TestcaseRecordInputStream.create(0x1016, data));
assertEquals( (short)0x2001, record.getSeriesNumbers()[0]);
assertEquals( (short)0xf0ff, record.getSeriesNumbers()[1]);
assertEquals( 2, record.getSeriesNumbers().length);

View File

@ -39,7 +39,7 @@ public final class TestSeriesRecord extends TestCase {
public void testLoad() {
SeriesRecord record = new SeriesRecord(new TestcaseRecordInputStream((short)0x1003, (short)data.length, data));
SeriesRecord record = new SeriesRecord(TestcaseRecordInputStream.create(0x1003, data));
assertEquals( SeriesRecord.CATEGORY_DATA_TYPE_NUMERIC, record.getCategoryDataType());
assertEquals( SeriesRecord.VALUES_DATA_TYPE_NUMERIC, record.getValuesDataType());
assertEquals( 27, record.getNumCategories());

View File

@ -34,7 +34,7 @@ public final class TestSeriesTextRecord extends TestCase {
};
public void testLoad() {
SeriesTextRecord record = new SeriesTextRecord(new TestcaseRecordInputStream((short)0x100d, (short)data.length, data));
SeriesTextRecord record = new SeriesTextRecord(TestcaseRecordInputStream.create(0x100d, data));
assertEquals( (short)0, record.getId());
assertEquals( (byte)0x0C, record.getTextLength());

View File

@ -34,7 +34,7 @@ public final class TestSeriesToChartGroupRecord extends TestCase {
};
public void testLoad() {
SeriesToChartGroupRecord record = new SeriesToChartGroupRecord(new TestcaseRecordInputStream((short)0x1045, (short)data.length, data));
SeriesToChartGroupRecord record = new SeriesToChartGroupRecord(TestcaseRecordInputStream.create(0x1045, data));
assertEquals( 0x0, record.getChartGroupIndex());
assertEquals( 0x6, record.getRecordSize() );

View File

@ -59,7 +59,7 @@ public final class TestSharedFormulaRecord extends TestCase {
*/
public void testConvertSharedFormulasOperandClasses_bug45123() {
TestcaseRecordInputStream in = new TestcaseRecordInputStream(0, SHARED_FORMULA_WITH_REF_ARRAYS_DATA);
RecordInputStream in = TestcaseRecordInputStream.createWithFakeSid(SHARED_FORMULA_WITH_REF_ARRAYS_DATA);
int encodedLen = in.readUShort();
Ptg[] sharedFormula = Ptg.readTokens(encodedLen, in);

View File

@ -36,7 +36,7 @@ public final class TestSheetPropertiesRecord extends TestCase {
};
public void testLoad() {
SheetPropertiesRecord record = new SheetPropertiesRecord(new TestcaseRecordInputStream((short)0x1044, (short)data.length, data));
SheetPropertiesRecord record = new SheetPropertiesRecord(TestcaseRecordInputStream.create(0x1044, data));
assertEquals( 10, record.getFlags());
assertEquals( false, record.isChartTypeManuallyFormatted() );
assertEquals( true, record.isPlotVisibleOnly() );

View File

@ -27,7 +27,7 @@ import junit.framework.TestCase;
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class TestStringRecord extends TestCase {
public final class TestStringRecord extends TestCase {
byte[] data = new byte[] {
(byte)0x0B,(byte)0x00, // length
(byte)0x00, // option
@ -37,7 +37,7 @@ public class TestStringRecord extends TestCase {
public void testLoad() {
StringRecord record = new StringRecord(new TestcaseRecordInputStream((short)0x207, (short)data.length, data));
StringRecord record = new StringRecord(TestcaseRecordInputStream.create(0x207, data));
assertEquals( "Fahrzeugtyp", record.getString());
assertEquals( 18, record.getRecordSize() );

View File

@ -51,7 +51,7 @@ public final class TestSupBookRecord extends TestCase {
*/
public void testLoadIR() {
SupBookRecord record = new SupBookRecord(new TestcaseRecordInputStream((short)0x01AE, dataIR));
SupBookRecord record = new SupBookRecord(TestcaseRecordInputStream.create(0x01AE, dataIR));
assertTrue( record.isInternalReferences() ); //expected flag
assertEquals( 0x4, record.getNumberOfSheets() ); //expected # of sheets
@ -62,7 +62,7 @@ public final class TestSupBookRecord extends TestCase {
*/
public void testLoadER() {
SupBookRecord record = new SupBookRecord(new TestcaseRecordInputStream((short)0x01AE, dataER));
SupBookRecord record = new SupBookRecord(TestcaseRecordInputStream.create(0x01AE, dataER));
assertTrue( record.isExternalReferences() ); //expected flag
assertEquals( 0x2, record.getNumberOfSheets() ); //expected # of sheets
@ -80,7 +80,7 @@ public final class TestSupBookRecord extends TestCase {
*/
public void testLoadAIF() {
SupBookRecord record = new SupBookRecord(new TestcaseRecordInputStream((short)0x01AE, dataAIF));
SupBookRecord record = new SupBookRecord(TestcaseRecordInputStream.create(0x01AE, dataAIF));
assertTrue( record.isAddInFunctions() ); //expected flag
assertEquals( 0x1, record.getNumberOfSheets() ); //expected # of sheets
assertEquals( 8, record.getRecordSize() ); //sid+size+data

View File

@ -44,7 +44,7 @@ public final class TestTableRecord extends TestCase {
public void testLoad() {
TableRecord record = new TableRecord(new TestcaseRecordInputStream((short)0x236, (short)data.length, data));
TableRecord record = new TableRecord(TestcaseRecordInputStream.create(0x236, data));
CellRangeAddress8Bit range = record.getRange();
assertEquals(3, range.getFirstRow());

View File

@ -18,6 +18,11 @@
package org.apache.poi.hssf.record;
import java.io.ByteArrayInputStream;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.util.HexRead;
import junit.framework.TestCase;
/**
@ -25,63 +30,62 @@ import junit.framework.TestCase;
* class works correctly. Test data taken directly from a real
* Excel file.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class TestTextObjectBaseRecord extends TestCase {
byte[] data = new byte[] {
0x44, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00,
};
public final class TestTextObjectBaseRecord extends TestCase {
/** data for one TXO rec and two continue recs */
private static final byte[] data = HexRead.readFromString(
"B6 01 " + // TextObjectRecord.sid
"12 00 " + // size 18
"44 02 02 00 00 00 00 00" +
"00 00 " +
"02 00 " + // strLen 2
"10 00 " + // 16 bytes for 2 format runs
"00 00" +
"00 00 " +
"3C 00 " + // ContinueRecord.sid
"05 00 " + // size 5
"01 " + // unicode uncompressed
"41 00 42 00 " + // 'AB'
"3C 00 " + // ContinueRecord.sid
"10 00 " + // size 16
"00 00 18 00 00 00 00 00 " +
"02 00 00 00 00 00 00 00 "
);
public void testLoad() {
TextObjectBaseRecord record = new TextObjectBaseRecord(new TestcaseRecordInputStream((short)0x1B6, (short)data.length, data));
RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(data));
in.nextRecord();
TextObjectRecord record = new TextObjectRecord(in);
// assertEquals( (short), record.getOptions());
assertEquals( false, record.isReserved1() );
assertEquals( TextObjectBaseRecord.HORIZONTAL_TEXT_ALIGNMENT_CENTERED, record.getHorizontalTextAlignment() );
assertEquals( TextObjectBaseRecord.VERTICAL_TEXT_ALIGNMENT_JUSTIFY, record.getVerticalTextAlignment() );
assertEquals( 0, record.getReserved2() );
assertEquals( true, record.isTextLocked() );
assertEquals( 0, record.getReserved3() );
assertEquals( TextObjectBaseRecord.TEXT_ORIENTATION_ROT_RIGHT, record.getTextOrientation());
assertEquals( 0, record.getReserved4());
assertEquals( 0, record.getReserved5());
assertEquals( 0, record.getReserved6());
assertEquals( 2, record.getTextLength());
assertEquals( 2, record.getFormattingRunLength());
assertEquals( 0, record.getReserved7());
assertEquals(TextObjectRecord.HORIZONTAL_TEXT_ALIGNMENT_CENTERED, record.getHorizontalTextAlignment());
assertEquals(TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_JUSTIFY, record.getVerticalTextAlignment());
assertEquals(true, record.isTextLocked());
assertEquals(TextObjectRecord.TEXT_ORIENTATION_ROT_RIGHT, record.getTextOrientation());
assertEquals( 22, record.getRecordSize() );
assertEquals(51, record.getRecordSize() );
}
public void testStore()
{
TextObjectBaseRecord record = new TextObjectBaseRecord();
TextObjectRecord record = new TextObjectRecord();
HSSFRichTextString str = new HSSFRichTextString("AB");
str.applyFont(0, 2, (short)0x0018);
str.applyFont(2, 2, (short)0x0320);
// record.setOptions( (short) 0x0000);
record.setReserved1( false );
record.setHorizontalTextAlignment( TextObjectBaseRecord.HORIZONTAL_TEXT_ALIGNMENT_CENTERED );
record.setVerticalTextAlignment( TextObjectBaseRecord.VERTICAL_TEXT_ALIGNMENT_JUSTIFY );
record.setReserved2( (short)0 );
record.setTextLocked( true );
record.setReserved3( (short)0 );
record.setTextOrientation( TextObjectBaseRecord.TEXT_ORIENTATION_ROT_RIGHT );
record.setReserved4( (short)0 );
record.setReserved5( (short)0 );
record.setReserved6( (short)0 );
record.setTextLength( (short)2 );
record.setFormattingRunLength( (short)2 );
record.setReserved7( 0 );
record.setHorizontalTextAlignment(TextObjectRecord.HORIZONTAL_TEXT_ALIGNMENT_CENTERED);
record.setVerticalTextAlignment(TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_JUSTIFY);
record.setTextLocked(true);
record.setTextOrientation(TextObjectRecord.TEXT_ORIENTATION_ROT_RIGHT);
record.setStr(str);
byte [] recordBytes = record.serialize();
assertEquals(recordBytes.length - 4, data.length);
assertEquals(recordBytes.length, data.length);
for (int i = 0; i < data.length; i++)
assertEquals("At offset " + i, data[i], recordBytes[i+4]);
assertEquals("At offset " + i, data[i], recordBytes[i]);
}
}

View File

@ -22,7 +22,11 @@ import java.util.Arrays;
import junit.framework.TestCase;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.util.HexRead;
import org.apache.poi.util.LittleEndian;
/**
* Tests that serialization and deserialization of the TextObjectRecord .
@ -32,17 +36,23 @@ import org.apache.poi.hssf.usermodel.HSSFRichTextString;
*/
public final class TestTextObjectRecord extends TestCase {
byte[] data = {(byte)0xB6, 0x01, 0x12, 0x00, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3C, 0x00, 0x1B, 0x00, 0x01, 0x48, 0x00, 0x65, 0x00, 0x6C,
0x00, 0x6C, 0x00, 0x6F, 0x00, 0x2C, 0x00, 0x20, 0x00, 0x57, 0x00,
0x6F, 0x00, 0x72, 0x00, 0x6C, 0x00, 0x64, 0x00, 0x21, 0x00, 0x3C,
0x00, 0x08, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
private static final byte[] simpleData = HexRead.readFromString(
"B6 01 12 00 " +
"12 02 00 00 00 00 00 00" +
"00 00 0D 00 08 00 00 00" +
"00 00 " +
"3C 00 1B 00 " +
"01 48 00 65 00 6C 00 6C 00 6F 00 " +
"2C 00 20 00 57 00 6F 00 72 00 6C " +
"00 64 00 21 00 " +
"3C 00 08 " +
"00 0D 00 00 00 00 00 00 00"
);
public void testRead() {
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(data));
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(simpleData));
is.nextRecord();
TextObjectRecord record = new TextObjectRecord(is);
@ -50,36 +60,51 @@ public final class TestTextObjectRecord extends TestCase {
assertEquals(TextObjectRecord.HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED, record.getHorizontalTextAlignment());
assertEquals(TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_TOP, record.getVerticalTextAlignment());
assertEquals(TextObjectRecord.TEXT_ORIENTATION_NONE, record.getTextOrientation());
assertEquals(0, record.getReserved7());
assertEquals("Hello, World!", record.getStr().getString());
}
public void testWrite()
{
public void testWrite() {
HSSFRichTextString str = new HSSFRichTextString("Hello, World!");
TextObjectRecord record = new TextObjectRecord();
int frLength = ( str.numFormattingRuns() + 1 ) * 8;
record.setFormattingRunLength( (short) frLength );
record.setTextLength( (short) str.length() );
record.setStr( str );
record.setStr(str);
record.setHorizontalTextAlignment( TextObjectRecord.HORIZONTAL_TEXT_ALIGNMENT_LEFT_ALIGNED );
record.setVerticalTextAlignment( TextObjectRecord.VERTICAL_TEXT_ALIGNMENT_TOP );
record.setTextLocked( true );
record.setTextOrientation( TextObjectRecord.TEXT_ORIENTATION_NONE );
record.setReserved7( 0 );
byte [] ser = record.serialize();
//assertEquals(ser.length , data.length);
assertEquals(ser.length , simpleData.length);
//assertTrue(Arrays.equals(data, ser));
assertTrue(Arrays.equals(simpleData, ser));
//read again
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(data));
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(simpleData));
is.nextRecord();
record = new TextObjectRecord(is);
}
/**
* Zero {@link ContinueRecord}s follow a {@link TextObjectRecord} if the text is empty
*/
public void testWriteEmpty() {
HSSFRichTextString str = new HSSFRichTextString("");
TextObjectRecord record = new TextObjectRecord();
record.setStr(str);
byte [] ser = record.serialize();
int formatDataLen = LittleEndian.getUShort(ser, 16);
assertEquals("formatDataLength", 0, formatDataLen);
assertEquals(22, ser.length); // just the TXO record
//read again
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(ser));
is.nextRecord();
record = new TextObjectRecord(is);
assertEquals(0, record.getStr().length());
}
/**
@ -95,10 +120,7 @@ public final class TestTextObjectRecord extends TestCase {
HSSFRichTextString str = new HSSFRichTextString(buff.toString());
TextObjectRecord obj = new TextObjectRecord();
int frLength = ( str.numFormattingRuns() + 1 ) * 8;
obj.setFormattingRunLength( (short) frLength );
obj.setTextLength( (short) str.length() );
obj.setStr( str );
obj.setStr(str);
byte [] data = obj.serialize();
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(data));
@ -120,30 +142,12 @@ public final class TestTextObjectRecord extends TestCase {
HSSFRichTextString str = new HSSFRichTextString(text);
TextObjectRecord obj = new TextObjectRecord();
int frLength = ( str.numFormattingRuns() + 1 ) * 8;
obj.setFormattingRunLength( (short) frLength );
obj.setTextLength( (short) str.length() );
obj.setReserved1(true);
obj.setReserved2((short)2);
obj.setReserved3((short)3);
obj.setReserved4((short)4);
obj.setReserved5((short)5);
obj.setReserved6((short)6);
obj.setReserved7((short)7);
obj.setStr( str );
TextObjectRecord cloned = (TextObjectRecord)obj.clone();
assertEquals(obj.getReserved2(), cloned.getReserved2());
assertEquals(obj.getReserved3(), cloned.getReserved3());
assertEquals(obj.getReserved4(), cloned.getReserved4());
assertEquals(obj.getReserved5(), cloned.getReserved5());
assertEquals(obj.getReserved6(), cloned.getReserved6());
assertEquals(obj.getReserved7(), cloned.getReserved7());
assertEquals(obj.getRecordSize(), cloned.getRecordSize());
assertEquals(obj.getOptions(), cloned.getOptions());
assertEquals(obj.getHorizontalTextAlignment(), cloned.getHorizontalTextAlignment());
assertEquals(obj.getFormattingRunLength(), cloned.getFormattingRunLength());
assertEquals(obj.getStr().getString(), cloned.getStr().getString());
//finally check that the serialized data is the same
@ -151,4 +155,47 @@ public final class TestTextObjectRecord extends TestCase {
byte[] cln = cloned.serialize();
assertTrue(Arrays.equals(src, cln));
}
/** similar to {@link #simpleData} but with link formula at end of TXO rec*/
private static final byte[] linkData = HexRead.readFromString(
"B6 01 " + // TextObjectRecord.sid
"1E 00 " + // size 18
"44 02 02 00 00 00 00 00" +
"00 00 " +
"02 00 " + // strLen 2
"10 00 " + // 16 bytes for 2 format runs
"00 00 00 00 " +
"05 00 " + // formula size
"D4 F0 8A 03 " + // unknownInt
"24 01 00 13 C0 " + //tRef(T2)
"13 " + // ??
"3C 00 " + // ContinueRecord.sid
"05 00 " + // size 5
"01 " + // unicode uncompressed
"41 00 42 00 " + // 'AB'
"3C 00 " + // ContinueRecord.sid
"10 00 " + // size 16
"00 00 18 00 00 00 00 00 " +
"02 00 00 00 00 00 00 00 "
);
public void testLinkFormula() {
RecordInputStream is = new RecordInputStream(new ByteArrayInputStream(linkData));
is.nextRecord();
TextObjectRecord rec = new TextObjectRecord(is);
Ptg ptg = rec.getLinkRefPtg();
assertNotNull(ptg);
assertEquals(RefPtg.class, ptg.getClass());
RefPtg rptg = (RefPtg) ptg;
assertEquals("T2", rptg.toFormulaString());
byte [] data2 = rec.serialize();
assertEquals(linkData.length, data2.length);
assertTrue(Arrays.equals(linkData, data2));
}
}

View File

@ -27,7 +27,7 @@ import junit.framework.TestCase;
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class TestTextRecord extends TestCase {
public final class TestTextRecord extends TestCase {
byte[] data = new byte[] {
(byte)0x02, // horiz align
(byte)0x02, // vert align
@ -45,7 +45,7 @@ public class TestTextRecord extends TestCase {
public void testLoad() {
TextRecord record = new TextRecord(new TestcaseRecordInputStream((short)0x1025, (short)data.length, data));
TextRecord record = new TextRecord(TestcaseRecordInputStream.create(0x1025, data));
assertEquals( TextRecord.HORIZONTAL_ALIGNMENT_CENTER, record.getHorizontalAlignment());
assertEquals( TextRecord.VERTICAL_ALIGNMENT_CENTER, record.getVerticalAlignment());
assertEquals( TextRecord.DISPLAY_MODE_TRANSPARENT, record.getDisplayMode());

View File

@ -40,7 +40,7 @@ public final class TestTickRecord extends TestCase {
};
public void testLoad() {
TickRecord record = new TickRecord(new TestcaseRecordInputStream((short)0x101e, (short)data.length, data));
TickRecord record = new TickRecord(TestcaseRecordInputStream.create(0x101e, data));
assertEquals( (byte)2, record.getMajorTickType());
assertEquals( (byte)0, record.getMinorTickType());
assertEquals( (byte)3, record.getLabelPosition());

View File

@ -1,4 +1,3 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@ -19,6 +18,8 @@
package org.apache.poi.hssf.record;
import org.apache.poi.util.HexRead;
import junit.framework.TestCase;
/**
@ -26,18 +27,10 @@ import junit.framework.TestCase;
*
* @author Jason Height (jheight at apache.org)
*/
public class TestUnicodeString
extends TestCase
{
public final class TestUnicodeString extends TestCase {
public TestUnicodeString( String s )
{
super( s );
}
public void testSmallStringSize()
throws Exception
{
public void testSmallStringSize() {
//Test a basic string
UnicodeString s = makeUnicodeString("Test");
UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
@ -80,9 +73,7 @@ public class TestUnicodeString
assertEquals(30, stats.recordSize);
}
public void testPerfectStringSize()
throws Exception
{
public void testPerfectStringSize() {
//Test a basic string
UnicodeString s = makeUnicodeString(SSTRecord.MAX_RECORD_SIZE-2-1);
UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
@ -99,9 +90,7 @@ public class TestUnicodeString
assertEquals(SSTRecord.MAX_RECORD_SIZE-1, stats.recordSize);
}
public void testPerfectRichStringSize()
throws Exception
{
public void testPerfectRichStringSize() {
//Test a rich text string
UnicodeString s = makeUnicodeString(SSTRecord.MAX_RECORD_SIZE-2-1-8-2);
s.addFormatRun(new UnicodeString.FormatRun((short)1,(short)0));
@ -123,7 +112,7 @@ public class TestUnicodeString
assertEquals(SSTRecord.MAX_RECORD_SIZE-1, stats.recordSize);
}
public void testContinuedStringSize() throws Exception {
public void testContinuedStringSize() {
//Test a basic string
UnicodeString s = makeUnicodeString(SSTRecord.MAX_RECORD_SIZE-2-1+20);
UnicodeString.UnicodeRecordStats stats = new UnicodeString.UnicodeRecordStats();
@ -132,7 +121,7 @@ public class TestUnicodeString
}
/** Tests that a string size calculation that fits neatly in two records, the second being a continue*/
public void testPerfectContinuedStringSize() throws Exception {
public void testPerfectContinuedStringSize() {
//Test a basic string
int strSize = SSTRecord.MAX_RECORD_SIZE*2;
//String overhead
@ -150,19 +139,18 @@ public class TestUnicodeString
private UnicodeString makeUnicodeString( String s )
private static UnicodeString makeUnicodeString( String s )
{
UnicodeString st = new UnicodeString(s);
st.setOptionFlags((byte)0);
return st;
}
private UnicodeString makeUnicodeString( int numChars) {
private static UnicodeString makeUnicodeString( int numChars) {
StringBuffer b = new StringBuffer(numChars);
for (int i=0;i<numChars;i++) {
b.append(i%10);
}
return makeUnicodeString(b.toString());
}
}

View File

@ -35,7 +35,7 @@ public final class TestUnitsRecord extends TestCase {
public void testLoad() {
UnitsRecord record = new UnitsRecord(new TestcaseRecordInputStream((short)0x1001, (short)data.length, data));
UnitsRecord record = new UnitsRecord(TestcaseRecordInputStream.create(0x1001, data));
assertEquals( 0, record.getUnits());
assertEquals( 6, record.getRecordSize() );

View File

@ -40,7 +40,7 @@ public final class TestValueRangeRecord extends TestCase {
public void testLoad() {
ValueRangeRecord record = new ValueRangeRecord(new TestcaseRecordInputStream((short)0x101f, (short)data.length, data));
ValueRangeRecord record = new ValueRangeRecord(TestcaseRecordInputStream.create(0x101f, data));
assertEquals( 0.0, record.getMinimumAxisValue(), 0.001);
assertEquals( 0.0, record.getMaximumAxisValue(), 0.001);
assertEquals( 0.0, record.getMajorIncrement(), 0.001);

View File

@ -18,6 +18,7 @@
package org.apache.poi.hssf.record;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import junit.framework.Assert;
@ -30,27 +31,51 @@ import org.apache.poi.util.LittleEndian;
*
* @author Jason Height (jheight at apache.org)
*/
public class TestcaseRecordInputStream
extends RecordInputStream
{
public final class TestcaseRecordInputStream {
private TestcaseRecordInputStream() {
// no instances of this class
}
/**
* Prepends a mock record identifier to the supplied data and opens a record input stream
*/
public static RecordInputStream createWithFakeSid(byte[] data) {
return create(-5555, data);
}
public static RecordInputStream create(int sid, byte[] data) {
return create(mergeDataAndSid(sid, data.length, data));
}
/**
* First 4 bytes of <tt>data</tt> are assumed to be record identifier and length. The supplied
* <tt>data</tt> can contain multiple records (sequentially encoded in the same way)
*/
public static RecordInputStream create(byte[] data) {
InputStream is = new ByteArrayInputStream(data);
RecordInputStream result = new RecordInputStream(is);
result.nextRecord();
return result;
}
/**
* Convenience constructor
*/
public TestcaseRecordInputStream(int sid, byte[] data)
{
super(new ByteArrayInputStream(mergeDataAndSid((short)sid, (short)data.length, data)));
nextRecord();
}
public TestcaseRecordInputStream(short sid, short length, byte[] data)
{
super(new ByteArrayInputStream(mergeDataAndSid(sid, length, data)));
nextRecord();
}
// public TestcaseRecordInputStream(int sid, byte[] data)
// {
// super(new ByteArrayInputStream(mergeDataAndSid(sid, data.length, data)));
// nextRecord();
// }
// public TestcaseRecordInputStream(short sid, short length, byte[] data)
// {
// super(new ByteArrayInputStream(mergeDataAndSid(sid, length, data)));
// nextRecord();
// }
public static byte[] mergeDataAndSid(short sid, short length, byte[] data) {
public static byte[] mergeDataAndSid(int sid, int length, byte[] data) {
byte[] result = new byte[data.length + 4];
LittleEndian.putShort(result, 0, sid);
LittleEndian.putShort(result, 2, length);
LittleEndian.putUShort(result, 0, sid);
LittleEndian.putUShort(result, 2, length);
System.arraycopy(data, 0, result, 4, data.length);
return result;
}

View File

@ -25,6 +25,7 @@ import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.record.TestcaseRecordInputStream;
import org.apache.poi.hssf.record.UnicodeString;
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
import org.apache.poi.util.HexRead;
/**
*
* @author Josh Micich
@ -37,13 +38,12 @@ public final class TestConstantValueParser extends TestCase {
new UnicodeString("Sample text"),
ErrorConstant.valueOf(HSSFErrorConstants.ERROR_DIV_0),
};
private static final byte[] SAMPLE_ENCODING = {
4, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
1, -102, -103, -103, -103, -103, -103, -15, 63,
2, 11, 0, 0, 83, 97, 109, 112, 108, 101, 32, 116, 101, 120, 116,
16, 7, 0, 0, 0, 0, 0, 0, 0,
};
private static final byte[] SAMPLE_ENCODING = HexRead.readFromString(
"04 01 00 00 00 00 00 00 00 " +
"00 00 00 00 00 00 00 00 00 " +
"01 9A 99 99 99 99 99 F1 3F " +
"02 0B 00 00 53 61 6D 70 6C 65 20 74 65 78 74 " +
"10 07 00 00 00 00 00 00 00");
public void testGetEncodedSize() {
int actual = ConstantValueParser.getEncodedSize(SAMPLE_VALUES);
@ -59,7 +59,7 @@ public final class TestConstantValueParser extends TestCase {
}
}
public void testDecode() {
RecordInputStream in = new TestcaseRecordInputStream(0x0001, SAMPLE_ENCODING);
RecordInputStream in = TestcaseRecordInputStream.createWithFakeSid(SAMPLE_ENCODING);
Object[] values = ConstantValueParser.parse(in, 4);
for (int i = 0; i < values.length; i++) {

View File

@ -54,9 +54,9 @@ public final class TestArrayPtg extends TestCase {
*/
public void testReadWriteTokenValueBytes() {
ArrayPtg ptg = new ArrayPtg(new TestcaseRecordInputStream(ArrayPtg.sid, ENCODED_PTG_DATA));
ArrayPtg ptg = new ArrayPtg(TestcaseRecordInputStream.createWithFakeSid(ENCODED_PTG_DATA));
ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
ptg.readTokenValues(TestcaseRecordInputStream.createWithFakeSid(ENCODED_CONSTANT_DATA));
assertEquals(3, ptg.getColumnCount());
assertEquals(2, ptg.getRowCount());
Object[][] values = ptg.getTokenArrayValues();
@ -82,8 +82,8 @@ public final class TestArrayPtg extends TestCase {
* Excel stores array elements column by column. This test makes sure POI does the same.
*/
public void testElementOrdering() {
ArrayPtg ptg = new ArrayPtg(new TestcaseRecordInputStream(ArrayPtg.sid, ENCODED_PTG_DATA));
ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
ArrayPtg ptg = new ArrayPtg(TestcaseRecordInputStream.createWithFakeSid(ENCODED_PTG_DATA));
ptg.readTokenValues(TestcaseRecordInputStream.createWithFakeSid(ENCODED_CONSTANT_DATA));
assertEquals(3, ptg.getColumnCount());
assertEquals(2, ptg.getRowCount());
@ -113,9 +113,9 @@ public final class TestArrayPtg extends TestCase {
}
public void testToFormulaString() {
ArrayPtg ptg = new ArrayPtg(new TestcaseRecordInputStream(ArrayPtg.sid, ENCODED_PTG_DATA));
ArrayPtg ptg = new ArrayPtg(TestcaseRecordInputStream.createWithFakeSid(ENCODED_PTG_DATA));
ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
ptg.readTokenValues(TestcaseRecordInputStream.createWithFakeSid(ENCODED_CONSTANT_DATA));
String actualFormula;
try {
@ -146,7 +146,7 @@ public final class TestArrayPtg extends TestCase {
// Force encoded operand class for tArray
fullData[0] = (byte) (ArrayPtg.sid + operandClass);
RecordInputStream in = new TestcaseRecordInputStream(ArrayPtg.sid, fullData);
RecordInputStream in = TestcaseRecordInputStream.createWithFakeSid(fullData);
Ptg[] ptgs = Ptg.readTokens(ENCODED_PTG_DATA.length, in);
assertEquals(1, ptgs.length);

View File

@ -34,7 +34,7 @@ public final class TestFuncPtg extends TestCase {
0,
};
FuncPtg ptg = new FuncPtg( new TestcaseRecordInputStream((short)0, (short)fakeData.length, fakeData) );
FuncPtg ptg = new FuncPtg(TestcaseRecordInputStream.createWithFakeSid(fakeData) );
assertEquals( "Len formula index is not 32(20H)", 0x20, ptg.getFunctionIndex() );
assertEquals( "Number of operands in the len formula", 1, ptg.getNumberOfOperands() );
assertEquals( "Function Name", "LEN", ptg.getName() );

View File

@ -18,12 +18,12 @@
package org.apache.poi.hssf.record.formula;
import java.util.Arrays;
import java.util.Stack;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.record.TestcaseRecordInputStream;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@ -94,10 +94,10 @@ public final class TestReferencePtg extends TestCase {
0x2C, 33, 44, 55, 66,
};
public void testReadWrite_tRefN_bug45091() {
TestcaseRecordInputStream in = new TestcaseRecordInputStream(-1, tRefN_data);
Stack ptgs = Ptg.createParsedExpressionTokens((short)tRefN_data.length, in);
RecordInputStream in = TestcaseRecordInputStream.createWithFakeSid(tRefN_data);
Ptg[] ptgs = Ptg.readTokens(tRefN_data.length, in);
byte[] outData = new byte[5];
Ptg.serializePtgStack(ptgs, outData, 0);
Ptg.serializePtgs(ptgs, outData, 0);
if (outData[0] == 0x24) {
throw new AssertionFailedError("Identified bug 45091");
}