Made RecordInputStream final (major clean-up in test cases and BiffViewer)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@703596 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-10-10 22:59:14 +00:00
parent b86b4b5ef2
commit b2988b3666
66 changed files with 698 additions and 540 deletions

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

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

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

@ -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

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

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

@ -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

@ -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

@ -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

@ -23,6 +23,7 @@ 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;
@ -93,7 +94,7 @@ public final class TestReferencePtg extends TestCase {
0x2C, 33, 44, 55, 66,
};
public void testReadWrite_tRefN_bug45091() {
TestcaseRecordInputStream in = new TestcaseRecordInputStream(-1, tRefN_data);
RecordInputStream in = TestcaseRecordInputStream.createWithFakeSid(tRefN_data);
Ptg[] ptgs = Ptg.readTokens(tRefN_data.length, in);
byte[] outData = new byte[5];
Ptg.serializePtgs(ptgs, outData, 0);