aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanny Mui <dmui@apache.org>2003-03-29 19:59:38 +0000
committerDanny Mui <dmui@apache.org>2003-03-29 19:59:38 +0000
commit72ef1b85ce066f1d40c6ea8f9b0b81ef5236767e (patch)
tree143d8c4133c1f30e58eeb86b7bd68b9ecb21e6ad
parent35aa8b0b60bb39dc058dec35ecdae5924590c0f3 (diff)
downloadpoi-72ef1b85ce066f1d40c6ea8f9b0b81ef5236767e.tar.gz
poi-72ef1b85ce066f1d40c6ea8f9b0b81ef5236767e.zip
FormulaRecord patch (and testcase) to preserve Excel's NaN representation when dealing with NaN formula value. We currently have NaN support in LittleEndian but the constant for NaN seems to change so we need to preserve the original bits on fill fields. Thanks Glen for your input!
PR: 18114, 18155 Submitted by: Additional bug report submitted by jsun@teloptica.com (Jerry Sun) git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353037 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/poi/hssf/record/FormulaRecord.java32
-rw-r--r--src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java36
2 files changed, 61 insertions, 7 deletions
diff --git a/src/java/org/apache/poi/hssf/record/FormulaRecord.java b/src/java/org/apache/poi/hssf/record/FormulaRecord.java
index ea8c9183d8..61994208d8 100644
--- a/src/java/org/apache/poi/hssf/record/FormulaRecord.java
+++ b/src/java/org/apache/poi/hssf/record/FormulaRecord.java
@@ -2,7 +2,7 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
- * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * Copyright (c) 2002, 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -60,11 +60,11 @@
*/
package org.apache.poi.hssf.record;
-import java.util.Stack;
import java.util.List;
+import java.util.Stack;
+import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.util.LittleEndian;
-import org.apache.poi.hssf.record.formula.*;
/**
* Formula Record.
@@ -94,6 +94,10 @@ public class FormulaRecord
private short field_7_expression_len;
private Stack field_8_parsed_expr;
+ /**
+ * Since the NaN support seems sketchy (different constants) we'll store and spit it out directly
+ */
+ private byte[] value_data;
private byte[] all_data; //if formula support is not enabled then
//we'll just store/reserialize
@@ -141,7 +145,13 @@ public class FormulaRecord
field_2_column = LittleEndian.getShort(data, 2 + offset);
field_3_xf = LittleEndian.getShort(data, 4 + offset);
field_4_value = LittleEndian.getDouble(data, 6 + offset);
- field_5_options = LittleEndian.getShort(data, 14 + offset);
+ field_5_options = LittleEndian.getShort(data, 14 + offset);
+
+ if (Double.isNaN(field_4_value)) {
+ value_data = new byte[8];
+ System.arraycopy(data, offset+6, value_data, 0, 8);
+ }
+
field_6_zero = LittleEndian.getInt(data, 16 + offset);
field_7_expression_len = LittleEndian.getShort(data, 20 + offset);
field_8_parsed_expr = getParsedExpressionTokens(data, size,
@@ -371,9 +381,19 @@ 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, field_4_value);
+
+ //only reserialize if the value is still NaN and we have old nan data
+ if (Double.isNaN(this.getValue()) && value_data != null) {
+ System.arraycopy(value_data,0,data,10 + offset,value_data.length);
+ } else {
+ LittleEndian.putDouble(data, 10 + offset, field_4_value);
+ }
+
LittleEndian.putShort(data, 18 + offset, getOptions());
- LittleEndian.putInt(data, 20 + offset, field_6_zero);
+
+ //when writing the chn field (offset 20), it's supposed to be 0 but ignored on read
+ //Microsoft Excel Developer's Kit Page 318
+ LittleEndian.putInt(data, 20 + offset, 0);
LittleEndian.putShort(data, 24 + offset, getExpressionLength());
serializePtgs(data, 26+offset);
} else {
diff --git a/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java b/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java
index fa340d722a..5d7e02b4bf 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java
@@ -2,7 +2,7 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
- * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * Copyright (c) 2002, 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -87,6 +87,40 @@ public class TestFormulaRecord
assertEquals(record.getXFIndex(),(short)4);
}
+ /**
+ * Make sure a NAN value is preserved
+ * This formula record is a representation of =1/0 at row 0, column 0
+ */
+ public void testCheckNanPreserve() {
+ byte[] formulaByte = new byte[29];
+ for (int i = 0; i < formulaByte.length; i++) formulaByte[i] = (byte)0;
+ formulaByte[4] = (byte)0x0F;
+ formulaByte[6] = (byte)0x02;
+ formulaByte[8] = (byte)0x07;
+ formulaByte[12] = (byte)0xFF;
+ formulaByte[13] = (byte)0xFF;
+ formulaByte[18] = (byte)0xE0;
+ formulaByte[19] = (byte)0xFC;
+ formulaByte[20] = (byte)0x07;
+ formulaByte[22] = (byte)0x1E;
+ formulaByte[23] = (byte)0x01;
+ formulaByte[25] = (byte)0x1E;
+ formulaByte[28] = (byte)0x06;
+
+ FormulaRecord record = new FormulaRecord(FormulaRecord.sid, (short)29, formulaByte);
+ assertEquals("Row", 0, record.getRow());
+ assertEquals("Column", 0, record.getColumn());
+ assertTrue("Value is not NaN", Double.isNaN(record.getValue()));
+
+ byte[] output = record.serialize();
+ assertEquals("Output size", 33, output.length); //includes sid+recordlength
+
+ for (int i = 5; i < 13;i++) {
+ assertEquals("FormulaByte NaN doesn't match", formulaByte[i], output[i+4]);
+ }
+
+ }
+
public static void main(String [] ignored_args)
{
String filename = System.getProperty("HSSF.testdata.path");