poi-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject cvs commit: jakarta-poi/src/testcases/org/apache/poi/hssf/record TestFormulaRecord.java
Date Sat, 29 Mar 2003 19:59:39 GMT
dmui        2003/03/29 11:59:39

  Modified:    src/java/org/apache/poi/hssf/record FormulaRecord.java
               src/testcases/org/apache/poi/hssf/record
                        TestFormulaRecord.java
  Log:
  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)
  
  Revision  Changes    Path
  1.18      +26 -6     jakarta-poi/src/java/org/apache/poi/hssf/record/FormulaRecord.java
  
  Index: FormulaRecord.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/FormulaRecord.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- FormulaRecord.java	28 Nov 2002 18:57:35 -0000	1.17
  +++ FormulaRecord.java	29 Mar 2003 19:59:38 -0000	1.18
  @@ -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 @@
       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 @@
           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 @@
           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 {
  
  
  
  1.3       +35 -1     jakarta-poi/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java
  
  Index: TestFormulaRecord.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestFormulaRecord.java	10 May 2002 03:01:11 -0000	1.2
  +++ TestFormulaRecord.java	29 Mar 2003 19:59:38 -0000	1.3
  @@ -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
  @@ -85,6 +85,40 @@
           //assertEquals(record.getRow(),(short)1);
           assertEquals((short)record.getRow(),(short)1);
           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)
  
  
  

Mime
View raw message