diff --git a/src/java/org/apache/poi/hssf/eventmodel/HSSFEventFactory.java b/src/java/org/apache/poi/hssf/eventmodel/HSSFEventFactory.java
index 4935f1ef4..5e07c953f 100644
--- a/src/java/org/apache/poi/hssf/eventmodel/HSSFEventFactory.java
+++ b/src/java/org/apache/poi/hssf/eventmodel/HSSFEventFactory.java
@@ -78,7 +78,7 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem;
* @see org.apache.poi.hssf.dev.EFHSSF
*
* @author Andrew C. Oliver (acoliver at apache dot org)
- * @authro Carey Sublette (careysub@earthling.net)
+ * @author Carey Sublette (careysub@earthling.net)
*/
public class HSSFEventFactory
@@ -103,7 +103,7 @@ public class HSSFEventFactory
processEvents(req, in);
}
-
+
/**
* Processes a file into essentially record events.
*
@@ -111,7 +111,7 @@ public class HSSFEventFactory
* @param fs a POIFS filesystem containing your workbook
* @return numeric user-specified result code.
*/
-
+
public short abortableProcessWorkbookEvents(HSSFRequest req, POIFSFileSystem fs)
throws IOException, HSSFUserException
{
@@ -121,9 +121,9 @@ public class HSSFEventFactory
/**
* Processes a DocumentInputStream into essentially Record events.
- *
+ *
* If an AbortableHSSFListener
causes a halt to processing during this call
- * the method will return just as with abortableProcessEvents
, but no
+ * the method will return just as with abortableProcessEvents
, but no
* user code or HSSFUserException
will be passed back.
*
* @see org.apache.poi.poifs.filesystem.POIFSFileSystem#createDocumentInputStream(String)
@@ -133,15 +133,15 @@ public class HSSFEventFactory
public void processEvents(HSSFRequest req, InputStream in)
throws IOException
- {
+ {
try
{
genericProcessEvents(req, in);
}
- catch (HSSFUserException hue)
+ catch (HSSFUserException hue)
{/*If an HSSFUserException user exception is thrown, ignore it.*/ }
}
-
+
/**
* Processes a DocumentInputStream into essentially Record events.
@@ -153,11 +153,11 @@ public class HSSFEventFactory
*/
public short abortableProcessEvents(HSSFRequest req, InputStream in)
- throws IOException, HSSFUserException
+ throws IOException, HSSFUserException
{
return genericProcessEvents(req, in);
- }
-
+ }
+
/**
* Processes a DocumentInputStream into essentially Record events.
*
diff --git a/src/java/org/apache/poi/hssf/model/Sheet.java b/src/java/org/apache/poi/hssf/model/Sheet.java
index 9b88a67f9..0fc37939a 100644
--- a/src/java/org/apache/poi/hssf/model/Sheet.java
+++ b/src/java/org/apache/poi/hssf/model/Sheet.java
@@ -59,12 +59,10 @@ import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
-import org.apache.poi.util.POILogFactory;
import org.apache.poi.hssf
.record.*; // normally I don't do this, buy we literally mean ALL
import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.util.IntList;
-import org.apache.poi.util.POILogger;
+import org.apache.poi.util.*;
import org.apache.poi.hssf.record
.aggregates.*; // normally I don't do this, buy we literally mean ALL
@@ -91,35 +89,33 @@ import org.apache.poi.hssf.record
public class Sheet
extends java.lang.Object
{
- public static final short LeftMargin = 0;
- public static final short RightMargin = 1;
- public static final short TopMargin = 2;
- public static final short BottomMargin = 3;
+ public static final short LeftMargin = 0;
+ public static final short RightMargin = 1;
+ public static final short TopMargin = 2;
+ public static final short BottomMargin = 3;
- protected ArrayList records = null;
- int preoffset = 0; // offset of the sheet in a new file
- int loc = 0;
- protected boolean containsLabels = false;
- ;
- protected int dimsloc = 0;
- protected DimensionsRecord dims;
- protected DefaultColWidthRecord defaultcolwidth = null;
- protected DefaultRowHeightRecord defaultrowheight = null;
- protected GridsetRecord gridset = null;
- protected PrintSetupRecord printSetup = null;
- protected HeaderRecord header = null;
- protected FooterRecord footer = null;
- protected PrintGridlinesRecord printGridlines = null;
- protected MergeCellsRecord merged = null;
- protected int mergedloc = 0;
- private static POILogger log =
- POILogFactory.getLogger(Sheet.class);
- private ArrayList columnSizes =
- null; // holds column info
- protected ValueRecordsAggregate cells = null;
- protected RowRecordsAggregate rows = null;
- private Iterator valueRecIterator = null;
- private Iterator rowRecIterator = null;
+ protected ArrayList records = null;
+ int preoffset = 0; // offset of the sheet in a new file
+ int loc = 0;
+ protected boolean containsLabels = false;
+ protected int dimsloc = 0;
+ protected DimensionsRecord dims;
+ protected DefaultColWidthRecord defaultcolwidth = null;
+ protected DefaultRowHeightRecord defaultrowheight = null;
+ protected GridsetRecord gridset = null;
+ protected PrintSetupRecord printSetup = null;
+ protected HeaderRecord header = null;
+ protected FooterRecord footer = null;
+ protected PrintGridlinesRecord printGridlines = null;
+ protected MergeCellsRecord merged = null;
+ protected int mergedloc = 0;
+ private static POILogger log = POILogFactory.getLogger(Sheet.class);
+ private ArrayList columnSizes = null; // holds column info
+ protected ValueRecordsAggregate cells = null;
+ protected RowRecordsAggregate rows = null;
+ private Iterator valueRecIterator = null;
+ private Iterator rowRecIterator = null;
+ protected int eofLoc = 0;
/**
* Creates new Sheet with no intialization --useless at this point
@@ -164,19 +160,23 @@ public class Sheet
if (rec.getSid() == LabelRecord.sid)
{
- log.log(log.DEBUG, "Hit label record");
+ log.log(log.DEBUG, "Hit label record.");
retval.containsLabels = true;
}
else if (rec.getSid() == BOFRecord.sid)
{
bofEofNestingLevel++;
+ log.log(log.DEBUG, "Hit BOF record. Nesting increased to " + bofEofNestingLevel);
}
- else if ((rec.getSid() == EOFRecord.sid)
- && (--bofEofNestingLevel == 0))
+ else if (rec.getSid() == EOFRecord.sid)
{
- log.log(log.DEBUG, "Hit EOF record at ");
- records.add(rec);
- break;
+ --bofEofNestingLevel;
+ log.log(log.DEBUG, "Hit EOF record. Nesting decreased to " + bofEofNestingLevel);
+ if (bofEofNestingLevel == 0) {
+ records.add(rec);
+ retval.eofLoc = k;
+ break;
+ }
}
else if (rec.getSid() == DimensionsRecord.sid)
{
@@ -204,7 +204,7 @@ public class Sheet
{
retval.defaultrowheight = ( DefaultRowHeightRecord ) rec;
}
- else if ( rec.isValue() )
+ else if ( rec.isValue() && bofEofNestingLevel == 1 )
{
if ( isfirstcell )
{
@@ -218,6 +218,10 @@ public class Sheet
rec = null;
}
}
+ else if ( rec.getSid() == StringRecord.sid )
+ {
+ rec = null;
+ }
else if ( rec.getSid() == RowRecord.sid )
{
if ( isfirstrow )
@@ -255,6 +259,14 @@ public class Sheet
}
}
retval.records = records;
+ if (retval.rows == null)
+ {
+ retval.rows = new RowRecordsAggregate();
+ }
+ if (retval.cells == null)
+ {
+ retval.cells = new ValueRecordsAggregate();
+ }
log.log(log.DEBUG, "sheet createSheet (existing file) exited");
return retval;
}
@@ -421,7 +433,7 @@ public class Sheet
newrec.setColumn(oldrec.getColumn());
newrec.setXFIndex(oldrec.getXFIndex());
newrec.setSSTIndex(stringid);
- records.add(k, newrec);
+ records.add(k, newrec);
}
}
}
@@ -608,11 +620,19 @@ public class Sheet
// }
for (int k = 0; k < records.size(); k++)
{
-
- // byte[] rec = (( byte [] ) bytes.get(k));
+// byte[] rec = (( byte [] ) bytes.get(k));
// System.arraycopy(rec, 0, data, offset + pos, rec.length);
- pos += (( Record ) records.get(k)).serialize(pos + offset,
- data); // rec.length;
+ Record record = (( Record ) records.get(k));
+
+ //uncomment to test record sizes
+// byte[] data2 = new byte[record.getRecordSize()];
+// record.serialize(0, data2 ); // rec.length;
+// if (LittleEndian.getUShort(data2, 2) != record.getRecordSize() - 4
+// && record instanceof RowRecordsAggregate == false && record instanceof ValueRecordsAggregate == false)
+// throw new RuntimeException("Blah!!!");
+
+ pos += record.serialize(pos + offset, data ); // rec.length;
+
}
log.log(log.DEBUG, "Sheet.serialize returning ");
return pos;
@@ -2116,4 +2136,10 @@ public class Sheet
}
m.setMargin(size);
}
+
+ public int getEofLoc()
+ {
+ return eofLoc;
+ }
+
}
diff --git a/src/java/org/apache/poi/hssf/record/DBCellRecord.java b/src/java/org/apache/poi/hssf/record/DBCellRecord.java
index 3ccfbe127..24ae29b90 100644
--- a/src/java/org/apache/poi/hssf/record/DBCellRecord.java
+++ b/src/java/org/apache/poi/hssf/record/DBCellRecord.java
@@ -57,8 +57,6 @@ package org.apache.poi.hssf.record;
import org.apache.poi.util.LittleEndian;
-import java.util.ArrayList;
-
/**
* Title: DBCell Record (Currently read only. Not required.)
* Description: Used to find rows in blocks...TODO
@@ -130,7 +128,7 @@ public class DBCellRecord * sets offset from the start of this DBCellRecord to the start of the first cell in * the next DBCell block. * - * @param rowoffset to the start of the first cell in the next DBCell block + * @param offset offset to the start of the first cell in the next DBCell block */ public void setRowOffset(int offset) diff --git a/src/java/org/apache/poi/hssf/record/FormulaRecord.java b/src/java/org/apache/poi/hssf/record/FormulaRecord.java index b5ee198f1..836bd08d9 100644 --- a/src/java/org/apache/poi/hssf/record/FormulaRecord.java +++ b/src/java/org/apache/poi/hssf/record/FormulaRecord.java @@ -370,7 +370,7 @@ public class FormulaRecord LittleEndian.putShort(data, 4 + offset, ( short ) getRow()); LittleEndian.putShort(data, 6 + offset, getColumn()); LittleEndian.putShort(data, 8 + offset, getXFIndex()); - LittleEndian.putDouble(data, 10 + offset, getValue()); + LittleEndian.putDouble(data, 10 + offset, field_4_value); LittleEndian.putShort(data, 18 + offset, getOptions()); LittleEndian.putInt(data, 20 + offset, field_6_zero); LittleEndian.putShort(data, 24 + offset, getExpressionLength()); diff --git a/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java index c949e6fc5..f30a5afd5 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java @@ -55,9 +55,7 @@ package org.apache.poi.hssf.record.aggregates; -import org.apache.poi.hssf.record.CellValueRecordInterface; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.UnknownRecord; +import org.apache.poi.hssf.record.*; import java.util.Iterator; import java.util.List; @@ -100,7 +98,8 @@ public class ValueRecordsAggregate }*/ // XYLocator xy = new XYLocator(cell.getRow(), cell.getColumn()); - records.put(cell, cell); + Object o = records.put(cell, cell); + if ((cell.getColumn() < firstcell) || (firstcell == -1)) { firstcell = cell.getColumn(); @@ -138,15 +137,26 @@ public class ValueRecordsAggregate { int k = 0; + FormulaRecordAggregate lastFormulaAggregate = null; + for (k = offset; k < records.size(); k++) { Record rec = ( Record ) records.get(k); - if (!rec.isInValueSection() && !(rec instanceof UnknownRecord)) + if (rec instanceof StringRecord == false && !rec.isInValueSection() && !(rec instanceof UnknownRecord)) { break; } - if (rec.isValue()) + if (rec instanceof FormulaRecord) + { + lastFormulaAggregate = new FormulaRecordAggregate((FormulaRecord)rec, null); + insertCell( lastFormulaAggregate ); + } + else if (rec instanceof StringRecord) + { + lastFormulaAggregate.setStringRecord((StringRecord)rec); + } + else if (rec.isValue()) { insertCell(( CellValueRecordInterface ) rec); } @@ -175,7 +185,6 @@ public class ValueRecordsAggregate } return pos - offset; } - /** * called by the constructor, should set class level fields. Should throw * runtime exception for bad/icomplete data. diff --git a/src/java/org/apache/poi/hssf/record/formula/Ptg.java b/src/java/org/apache/poi/hssf/record/formula/Ptg.java index 9bebec869..0781c3cac 100644 --- a/src/java/org/apache/poi/hssf/record/formula/Ptg.java +++ b/src/java/org/apache/poi/hssf/record/formula/Ptg.java @@ -299,14 +299,14 @@ public abstract class Ptg */ public abstract String toFormulaString(SheetReferences refs); /** - * dump a debug representation (hexdump) to a strnig + * dump a debug representation (hexdump) to a string */ public String toDebugString() { byte[] ba = new byte[getSize()]; String retval=null; writeBytes(ba,0); try { - retval = org.apache.poi.util.HexDump.dump(ba,0,0); + retval = org.apache.poi.util.HexDump.dump(ba,0,0); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index 6ba0c63f7..27d9d681e 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -71,6 +71,7 @@ import org.apache.poi.hssf.record.NumberRecord; import org.apache.poi.hssf.record.BlankRecord; import org.apache.poi.hssf.record.BoolErrRecord; import org.apache.poi.hssf.record.ExtendedFormatRecord; +import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; import org.apache.poi.hssf.record.formula.Ptg; import org.apache.poi.hssf.util.SheetReferences; @@ -259,10 +260,11 @@ public class HSSFCell break; case CELL_TYPE_FORMULA : - record = new FormulaRecord(); - (( FormulaRecord ) record).setColumn(col); - (( FormulaRecord ) record).setRow(row); - (( FormulaRecord ) record).setXFIndex(( short ) 0); + FormulaRecord formulaRecord = new FormulaRecord(); + record = new FormulaRecordAggregate(formulaRecord,null); + formulaRecord.setColumn(col); + formulaRecord.setRow(row); + formulaRecord.setXFIndex(( short ) 0); case CELL_TYPE_BOOLEAN : record = new BoolErrRecord(); (( BoolErrRecord ) record).setColumn(col); @@ -314,15 +316,14 @@ public class HSSFCell case CELL_TYPE_STRING : stringValue = - book - .getSSTString((( LabelSSTRecord ) cval).getSSTIndex()); + book.getSSTString( ( (LabelSSTRecord ) cval).getSSTIndex()); break; case CELL_TYPE_BLANK : break; case CELL_TYPE_FORMULA : - cellValue = (( FormulaRecord ) cval).getValue(); + cellValue = (( FormulaRecordAggregate ) cval).getFormulaRecord().getValue(); break; case CELL_TYPE_BOOLEAN : @@ -369,7 +370,7 @@ public class HSSFCell retval = HSSFCell.CELL_TYPE_STRING; break; - case FormulaRecord.sid : + case FormulaRecordAggregate.sid : retval = HSSFCell.CELL_TYPE_FORMULA; break; @@ -446,20 +447,20 @@ public class HSSFCell { case CELL_TYPE_FORMULA : - FormulaRecord frec = null; + FormulaRecordAggregate frec = null; if (cellType != this.cellType) { - frec = new FormulaRecord(); + frec = new FormulaRecordAggregate(new FormulaRecord(),null); } else { - frec = ( FormulaRecord ) record; + frec = ( FormulaRecordAggregate ) record; } frec.setColumn(getCellNum()); if (setValue) { - frec.setValue(getNumericCellValue()); + frec.getFormulaRecord().setValue(getNumericCellValue()); } frec.setXFIndex(( short ) cellStyle.getIndex()); frec.setRow(row); @@ -676,8 +677,7 @@ public class HSSFCell } else { - if ((cellType != CELL_TYPE_STRING) - && (cellType != CELL_TYPE_FORMULA)) + if ((cellType != CELL_TYPE_STRING ) && ( cellType != CELL_TYPE_FORMULA)) { setCellType(CELL_TYPE_STRING, false); } @@ -702,9 +702,9 @@ public class HSSFCell setCellType(CELL_TYPE_BLANK,false); } else { setCellType(CELL_TYPE_FORMULA,false); - FormulaRecord rec = (FormulaRecord) record; - rec.setOptions(( short ) 2); - rec.setValue(0); + FormulaRecordAggregate rec = (FormulaRecordAggregate) record; + rec.getFormulaRecord().setOptions(( short ) 2); + rec.getFormulaRecord().setValue(0); rec.setXFIndex(( short ) 0x0f); FormulaParser fp = new FormulaParser(formula+";",book); fp.parse(); @@ -713,9 +713,9 @@ public class HSSFCell //System.out.println("got Ptgs " + ptg.length); for (int k = 0; k < ptg.length; k++) { size += ptg[ k ].getSize(); - rec.pushExpressionToken(ptg[ k ]); + rec.getFormulaRecord().pushExpressionToken(ptg[ k ]); } - rec.setExpressionLength(( short ) size); + rec.getFormulaRecord().setExpressionLength(( short ) size); //Workbook.currentBook = null; } } @@ -723,7 +723,7 @@ public class HSSFCell public String getCellFormula() { //Workbook.currentBook=book; SheetReferences refs = book.getSheetReferences(); - String retval = FormulaParser.toFormulaString(refs, ((FormulaRecord)record).getParsedExpression()); + String retval = FormulaParser.toFormulaString(refs, ((FormulaRecordAggregate)record).getFormulaRecord().getParsedExpression()); //Workbook.currentBook=null; return retval; } @@ -825,8 +825,7 @@ public class HSSFCell public void setCellValue(boolean value) { - if ((cellType != CELL_TYPE_BOOLEAN) - && (cellType != CELL_TYPE_FORMULA)) + if ((cellType != CELL_TYPE_BOOLEAN ) && ( cellType != CELL_TYPE_FORMULA)) { setCellType(CELL_TYPE_BOOLEAN, false); } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index 3c9df3c27..89d4b1b18 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -152,14 +152,14 @@ public class HSSFWorkbook workbook = Workbook.createWorkbook(records); setPropertiesFromWorkbook(workbook); - int numRecords = workbook.getNumRecords(); + int recOffset = workbook.getNumRecords(); int sheetNum = 0; - while (numRecords < records.size()) + while (recOffset < records.size()) { - Sheet sheet = Sheet.createSheet(records, sheetNum++, numRecords); + Sheet sheet = Sheet.createSheet(records, sheetNum++, recOffset ); - numRecords += sheet.getNumRecords(); + recOffset = sheet.getEofLoc()+1; sheet.convertLabelRecords( workbook); // convert all LabelRecord records to LabelSSTRecord HSSFSheet hsheet = new HSSFSheet(workbook, sheet); @@ -511,8 +511,8 @@ public class HSSFWorkbook { totalsize = 4096; } - byte[] retval = new byte[totalsize]; - int pos = workbook.serialize(0, retval); + byte[] data = new byte[totalsize]; + int pos = workbook.serialize(0, data); // System.arraycopy(wb, 0, retval, 0, wb.length); for (int k = 0; k < sheets.size(); k++) @@ -521,13 +521,13 @@ public class HSSFWorkbook // byte[] sb = (byte[])sheetbytes.get(k); // System.arraycopy(sb, 0, retval, pos, sb.length); pos += ((HSSFSheet) sheets.get(k)).getSheet().serialize(pos, - retval); // sb.length; + data); // sb.length; } for (int k = pos; k < totalsize; k++) { - retval[k] = 0; + data[k] = 0; } - return retval; + return data; } public int addSSTString(String string) diff --git a/src/java/org/apache/poi/util/LittleEndian.java b/src/java/org/apache/poi/util/LittleEndian.java index 95752e56a..935fd5a66 100644 --- a/src/java/org/apache/poi/util/LittleEndian.java +++ b/src/java/org/apache/poi/util/LittleEndian.java @@ -386,7 +386,7 @@ public class LittleEndian public static void putDouble(final byte[] data, final int offset, final double value) { - putNumber(data, offset, Double.doubleToLongBits(value), DOUBLE_SIZE); + putNumber(data, offset, Double.doubleToRawLongBits(value), DOUBLE_SIZE); } diff --git a/src/testcases/org/apache/poi/util/TestLittleEndian.java b/src/testcases/org/apache/poi/util/TestLittleEndian.java index a42686cea..56d830cc0 100644 --- a/src/testcases/org/apache/poi/util/TestLittleEndian.java +++ b/src/testcases/org/apache/poi/util/TestLittleEndian.java @@ -147,9 +147,13 @@ public class TestLittleEndian { 56, 50, -113, -4, -63, -64, -13, 63, 76, -32, -42, -35, 60, -43, 3, 64 }; + private static final byte[] _nan_double_array = + { + (byte)0x00, (byte)0x00, (byte)0x3C, (byte)0x00, (byte)0x20, (byte)0x04, (byte)0xFF, (byte)0xFF + }; private static final double[] _doubles = { - 1.23456, 2.47912 + 1.23456, 2.47912, Double.NaN }; /** @@ -158,10 +162,21 @@ public class TestLittleEndian public void testGetDouble() { - assertEquals(_doubles[ 0 ], LittleEndian.getDouble(_double_array), - 0.000001); - assertEquals(_doubles[ 1 ], LittleEndian - .getDouble(_double_array, LittleEndian.DOUBLE_SIZE), 0.000001); + assertEquals(_doubles[ 0 ], LittleEndian.getDouble(_double_array), 0.000001 ); + assertEquals(_doubles[ 1 ], LittleEndian.getDouble( _double_array, LittleEndian.DOUBLE_SIZE), 0.000001); + assertTrue(Double.isNaN(LittleEndian.getDouble(_nan_double_array))); + + // does not work. apparently nan does not always equal nan! + //assertEquals(_doubles[ 2 ], LittleEndian.getDouble(_nan_double_array), 0.000001); + + double nan = LittleEndian.getDouble(_nan_double_array); + byte[] data = new byte[8]; + LittleEndian.putDouble(data, nan); + for ( int i = 0; i < data.length; i++ ) + { + byte b = data[i]; + assertEquals(data[i], _nan_double_array[i]); + } } /**