]> source.dussan.org Git - poi.git/commitdiff
MERGE from REL_2_BRANCH: bug 15228 and related fixes
authorAvik Sengupta <avik@apache.org>
Sun, 27 Jul 2003 19:15:16 +0000 (19:15 +0000)
committerAvik Sengupta <avik@apache.org>
Sun, 27 Jul 2003 19:15:16 +0000 (19:15 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353261 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/model/Workbook.java
src/java/org/apache/poi/hssf/record/NameRecord.java
src/java/org/apache/poi/hssf/record/StyleRecord.java
src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java
src/java/org/apache/poi/hssf/record/formula/NamePtg.java
src/java/org/apache/poi/hssf/record/formula/StringPtg.java
src/testcases/org/apache/poi/hssf/data/15228.xls [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java [new file with mode: 0644]

index d1abd2cf3c31ad37e68cf90787a990476e6c82f4..9cc2389c78ecda8f7f35bf250043708c47193eab 100644 (file)
@@ -1738,15 +1738,17 @@ public class Workbook implements Model {
     }
 
     public SheetReferences getSheetReferences() {
-       SheetReferences refs = new SheetReferences();
-
-       if (externSheet != null) {
-          for (int k = 0; k < externSheet.getNumOfREFStructures(); k++) {
-              String sheetName = findSheetNameFromExternSheet((short)k);
-              refs.addSheetReference(sheetName, k);
-          }
-       }
-       return refs;
+        SheetReferences refs = new SheetReferences();
+        
+        if (externSheet != null) {
+            for (int k = 0; k < externSheet.getNumOfREFStructures(); k++) {
+                
+                String sheetName = findSheetNameFromExternSheet((short)k);
+                refs.addSheetReference(sheetName, k);
+                
+            }
+        }
+        return refs;
     }
 
     /** finds the sheet name by his extern sheet index
@@ -1754,10 +1756,12 @@ public class Workbook implements Model {
      * @return sheet name
      */
     public String findSheetNameFromExternSheet(short num){
-        String result;
+        String result="";
 
         short indexToSheet = externSheet.getREFRecordAt(num).getIndexToFirstSupBook();
-        result = getSheetName(indexToSheet);
+        if (indexToSheet>-1) { //error check, bail out gracefully!
+            result = getSheetName(indexToSheet);
+        }
 
         return result;
     }
index 09bf2a416dae07f840aef48ab92a255bf4e9e6d3..01fe777dfc717abb4ee563301083ff643ae6384a 100644 (file)
@@ -794,6 +794,8 @@ public class NameRecord extends Record {
                 pos += ptg.getSize();
                 sizeCounter += ptg.getSize();
                 stack.push(ptg);
+                field_13_raw_name_definition=new byte[size];
+                System.arraycopy(data,offset,field_13_raw_name_definition,0,size);
             }
         } catch (java.lang.UnsupportedOperationException uoe) {
             System.err.println("[WARNING] Unknown Ptg "
@@ -880,7 +882,7 @@ public class NameRecord extends Record {
             .append("\n");
         buffer.append("    .unused                   = ").append( field_5_index_to_sheet )
             .append("\n");
-        buffer.append("    .( 0 = Global name, otherwise index to sheet (one-based) ) = ").append( field_6_equals_to_index_to_sheet )
+        buffer.append("    .index to sheet (1-based, 0=Global)           = ").append( field_6_equals_to_index_to_sheet )
             .append("\n");
         buffer.append("    .Length of menu text (character count)        = ").append( field_7_length_custom_menu )
             .append("\n");
@@ -906,6 +908,7 @@ public class NameRecord extends Record {
             .append("\n");
         buffer.append("    .Status bar text (Unicode string without length field)  = ").append( field_17_status_bar_text )
             .append("\n");
+        buffer.append(org.apache.poi.util.HexDump.dump(this.field_13_raw_name_definition,0,0));
         buffer.append("[/NAME]\n");
         
         return buffer.toString();
index c4f8ee35cc6bbc00b6990c6ae5d5ab6421d7db72..d6bb482e5cddc21bf770553ca1fcbe1dcbe77a87 100644 (file)
@@ -57,12 +57,14 @@ package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.StringUtil;
+import org.apache.poi.util.BitField;
 
 /**
  * Title:        Style Record<P>
  * Description:  Describes a builtin to the gui or user defined style<P>
  * REFERENCE:  PG 390 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
  * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author aviks : string fixes for UserDefined Style
  * @version 2.0-pre
  */
 
@@ -81,8 +83,10 @@ public class StyleRecord
     private byte              field_3_outline_style_level;
 
     // only for user defined styles
-    private byte              field_2_name_length;
-    private String            field_3_name;
+    private short              field_2_name_length; //OO doc says 16 bit length, so we believe
+    private byte               field_3_string_options;
+    private BitField fHighByte;
+    private String             field_4_name;
 
     public StyleRecord()
     {
@@ -125,17 +129,24 @@ public class StyleRecord
 
     protected void fillFields(byte [] data, short size, int offset)
     {
+        fHighByte = new BitField(0x01); //have to init here, since we are being called
+                                        //from super, and class level init hasnt been done. 
         field_1_xf_index = LittleEndian.getShort(data, 0 + offset);
-        if (getType() == 1)
+        if (getType() == STYLE_BUILT_IN)
         {
             field_2_builtin_style       = data[ 2 + offset ];
             field_3_outline_style_level = data[ 3 + offset ];
         }
-        else if (getType() == 0)
+        else if (getType() == STYLE_USER_DEFINED)
         {
-            field_2_name_length = data[ 2 + offset ];
-            field_3_name        = StringUtil.getFromCompressedUnicode(data, 3 + offset,
-                                             LittleEndian.ubyteToInt(field_2_name_length));
+            field_2_name_length = LittleEndian.getShort(data, 2 + offset );
+            field_3_string_options = data[4+offset];
+            
+            if (fHighByte.isSet(field_3_string_options)) {
+                field_4_name= StringUtil.getFromUnicode(data,offset+5,field_2_name_length);
+            }else {
+                field_4_name=StringUtil.getFromCompressedUnicode(data,offset+5,field_2_name_length);
+            }
         }
 
         // todo sanity check exception to make sure we're one or the other
@@ -199,7 +210,8 @@ public class StyleRecord
 
     public void setName(String name)
     {
-        field_3_name = name;
+        field_4_name = name;
+        //TODO set name length and string options
     }
 
     // end user defined
@@ -273,7 +285,7 @@ public class StyleRecord
      * @see #getName()
      */
 
-    public byte getNameLength()
+    public short getNameLength()
     {
         return field_2_name_length;
     }
@@ -286,7 +298,7 @@ public class StyleRecord
 
     public String getName()
     {
-        return field_3_name;
+        return field_4_name;
     }
 
     // end user defined
@@ -361,7 +373,7 @@ public class StyleRecord
         else
         {
             LittleEndian.putShort(data, 2 + offset,
-                                  (( short ) (0x03 + getNameLength())));
+                                  (( short ) (getRecordSize()-4)));
         }
         LittleEndian.putShort(data, 4 + offset, getIndex());
         if (getType() == STYLE_BUILT_IN)
@@ -371,8 +383,9 @@ public class StyleRecord
         }
         else
         {
-            data[ 6 + offset ] = getNameLength();
-            StringUtil.putCompressedUnicode(getName(), data, 7 + offset);
+            LittleEndian.putShort(data, 6 + offset , getNameLength());
+            data[8+offset]=this.field_3_string_options;
+            StringUtil.putCompressedUnicode(getName(), data, 9 + offset);
         }
         return getRecordSize();
     }
@@ -387,7 +400,11 @@ public class StyleRecord
         }
         else
         {
-            retval = 7 + getNameLength();
+             if (fHighByte.isSet(field_3_string_options))  {
+                 retval= 9+2*getNameLength();
+             }else {
+                retval = 9 + getNameLength();
+             }
         }
         return retval;
     }
index 9a7575c21ee41395179ccf4e2a345d322f375da7..e3eb40e2014fdedcaa5c449c15812ffac994c5dd 100644 (file)
@@ -119,14 +119,14 @@ public class FormulaRecordAggregate
     {
         int pos = offset;
         pos += formulaRecord.serialize(pos, data);
-        if (stringRecord != null)
-        {
-            pos += stringRecord.serialize(pos, data);
-        }
         if (this.getSharedFormulaRecord() != null) 
         {
                        pos += getSharedFormulaRecord().serialize(pos, data);
         }      
+         if (stringRecord != null)
+        {
+            pos += stringRecord.serialize(pos, data);
+        }
         return pos - offset;
         
     }
index 57c6dccb5964047a634ef33faaf45262aa6069cf..3786cdd69468cec62c0e733a588179f80747c30f 100644 (file)
@@ -73,10 +73,10 @@ public class NamePtg
     extends Ptg
 {
     public final static short sid  = 0x23;
-    private final static int  SIZE = 7;
-    private short             field_1_ixti;   // unknown function
-    private short             field_2_label_index;
-    private short             field_3_zero;   // reserved must be 0
+    private final static int  SIZE = 5;
+    private short             field_1_label_index;
+    private short             field_2_zero;   // reserved must be 0
+    boolean xtra=false;
 
 
     private NamePtg() {
@@ -95,13 +95,17 @@ public class NamePtg
     public NamePtg(byte [] data, int offset)
     {
         offset++;
-        field_1_ixti        = LittleEndian.getShort(data, offset);
-        field_2_label_index = LittleEndian.getShort(data, offset + 2);
-        field_3_zero        = LittleEndian.getShort(data, offset + 4);
+        //field_1_ixti        = LittleEndian.getShort(data, offset);
+        field_1_label_index = LittleEndian.getShort(data, offset );
+        field_2_zero        = LittleEndian.getShort(data, offset + 2);
+        //if (data[offset+6]==0) xtra=true;
     }
 
     public void writeBytes(byte [] array, int offset)
     {
+        array[offset+0]= (byte) (sid + ptgClass);
+        LittleEndian.putShort(array,offset+1,field_1_label_index);
+        LittleEndian.putShort(array,offset+3, field_2_zero);
     }
 
     public int getSize()
@@ -111,17 +115,15 @@ public class NamePtg
 
     public String toFormulaString(SheetReferences refs)
     {
-        return "NO IDEA - NAME";
+        return "NAMED RANGE";
     }
     
     public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
 
     public Object clone() {
       NamePtg ptg = new NamePtg();
-      ptg.field_1_ixti = field_1_ixti;
-      ptg.field_2_label_index = field_2_label_index;
-      ptg.field_3_zero = field_3_zero;
-      ptg.setClass(ptgClass);
+      ptg.field_1_label_index = field_1_label_index;
+      ptg.field_2_zero = field_2_zero;
       return ptg;
     }
 }
index 022fffd83c0ae9beb9667198519874b1b57fe3f6..a66861914ed8fa348ced601de6c95507224fecfd 100644 (file)
@@ -55,8 +55,9 @@
 package org.apache.poi.hssf.record.formula;
 
 import org.apache.poi.util.LittleEndian;
-
+import org.apache.poi.util.BitField;
 import org.apache.poi.hssf.util.SheetReferences;
+import org.apache.poi.util.StringUtil;
 
 /**
  * Number
@@ -70,7 +71,12 @@ public class StringPtg
 {
     public final static int  SIZE = 9;
     public final static byte sid  = 0x17;
-    private String            field_1_value;
+    //NOTE: OO doc says 16bit lenght, but BiffViewer says 8
+    // Book says something totally different, so dont look there!
+    byte field_1_length;
+    byte field_2_options;
+    BitField fHighByte = new BitField(0x01);
+    private String            field_3_string;
 
     private StringPtg() {
       //Required for clone methods
@@ -79,7 +85,16 @@ public class StringPtg
     /** Create a StringPtg from a byte array read from disk */
     public StringPtg(byte [] data, int offset)
     {
-        setValue(new String(data, offset+3, data[offset+1] + 256*data[offset+2]));
+        offset++;
+        field_1_length = data[offset];
+        field_2_options = data[offset+1];
+        if (fHighByte.isSet(field_2_options)) {
+            field_3_string= StringUtil.getFromUnicode(data,offset+2,field_1_length);
+        }else {
+            field_3_string=StringUtil.getFromCompressedUnicode(data,offset+2,field_1_length);
+        }
+                                
+        //setValue(new String(data, offset+3, data[offset+1] + 256*data[offset+2]));
     }
 
     /** Create a StringPtg from a string representation of  the number
@@ -88,32 +103,46 @@ public class StringPtg
      *  @param value : String representation of a floating point number
      */
     public StringPtg(String value) {
-        setValue(value);
+        if (value.length() >255) {
+            throw new IllegalArgumentException("String literals in formulas cant be bigger than 255 characters ASCII");
+        }
+        this.field_2_options=0;
+        this.fHighByte.setBoolean(field_2_options, false);
+        this.field_3_string=value;
+        this.field_1_length=(byte)value.length(); //for the moment, we support only ASCII strings in formulas we create
     }
 
-
+    /*
     public void setValue(String value)
     {
         field_1_value = value;
-    }
+    }*/
 
 
     public String getValue()
     {
-        return field_1_value;
+        return field_3_string;
     }
 
     public void writeBytes(byte [] array, int offset)
     {
         array[ offset + 0 ] = sid;
-        array[ offset + 1 ] = (byte)(getValue().length() % 256);
-        array[ offset + 2 ] = (byte)(getValue().length() / 256);
-        System.arraycopy(getValue().getBytes(), 0, array, offset + 3, getValue().length());
+        array[ offset + 1 ] = field_1_length;
+        array[ offset + 2 ] = field_2_options;
+        if (fHighByte.isSet(field_2_options)) {
+            StringUtil.putUncompressedUnicode(getValue(),array,offset+3);
+        }else {
+            StringUtil.putCompressedUnicode(getValue(),array,offset+3);
+        }
     }
 
     public int getSize()
     {
-        return field_1_value.length() + 3;
+        if (fHighByte.isSet(field_2_options)) {
+            return 2*field_1_length+3;
+        }else {
+            return field_1_length+3;
+        }
     }
 
     public String toFormulaString(SheetReferences refs)
@@ -126,7 +155,9 @@ public class StringPtg
 
    public Object clone() {
      StringPtg ptg = new StringPtg();
-     ptg.field_1_value = field_1_value;
+     ptg.field_1_length = field_1_length;
+     ptg.field_2_options=field_2_options;
+     ptg.field_3_string=field_3_string;
      return ptg;
    }
 
diff --git a/src/testcases/org/apache/poi/hssf/data/15228.xls b/src/testcases/org/apache/poi/hssf/data/15228.xls
new file mode 100644 (file)
index 0000000..3b26ed1
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/15228.xls differ
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
new file mode 100644 (file)
index 0000000..48cec01
--- /dev/null
@@ -0,0 +1,98 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2003, 2003 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hssf.usermodel;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Date;
+
+import junit.framework.TestCase;
+
+
+
+/**
+ * @author Avik Sengupta
+ */
+
+public class TestBugs
+extends TestCase {
+    public TestBugs(String s) {
+        super(s);
+    }
+    
+          public void test15228()
+        throws java.io.IOException
+    {
+         String readFilename = System.getProperty("HSSF.testdata.path");
+          FileInputStream in = new FileInputStream(readFilename+File.separator+"15228.xls");
+          HSSFWorkbook wb = new HSSFWorkbook(in);
+          HSSFSheet s = wb.getSheetAt(0);
+          HSSFRow r = s.createRow(0);
+          HSSFCell c = r.createCell((short)0);
+          c.setCellValue(10);
+          File file = File.createTempFile("test15228",".xls");
+          FileOutputStream out    = new FileOutputStream(file);
+          wb.write(out);
+          assertTrue("No exception thrown", true); 
+          assertTrue("File Should Exist", file.exists());
+            
+    }
+    
+}
+    
+
+