]> source.dussan.org Git - poi.git/commitdiff
fix for bug 9908, gracefully warn and write back for unknown ptg in namerecord
authorAvik Sengupta <avik@apache.org>
Mon, 17 Jun 2002 17:20:16 +0000 (17:20 +0000)
committerAvik Sengupta <avik@apache.org>
Mon, 17 Jun 2002 17:20:16 +0000 (17:20 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352704 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/NameRecord.java

index 7c31899c3bd56e5b0d0c0d4dfdfe736c7c9c8963..20c5ba43baa688524d25af8c3d537fe6158288cb 100644 (file)
@@ -89,22 +89,23 @@ public class NameRecord extends Record {
     private byte              field_11_compressed_unicode_flag;   // not documented
     private String            field_12_name_text;
     private Stack             field_13_name_definition;
+    private byte[]            field_13_raw_name_definition = null; // raw data
     private String            field_14_custom_menu_text;
     private String            field_15_description_text;
     private String            field_16_help_topic_text;
     private String            field_17_status_bar_text;
-    
+
     /** Creates new NameRecord */
     public NameRecord() {
         field_13_name_definition = new Stack();
-        
+
         field_12_name_text = new String();
         field_14_custom_menu_text = new String();
         field_15_description_text = new String();
         field_16_help_topic_text = new String();
         field_17_status_bar_text = new String();
     }
-    
+
     /**
      * Constructs a Name record and sets its fields appropriately.
      *
@@ -115,7 +116,7 @@ public class NameRecord extends Record {
     public NameRecord(short id, short size, byte [] data) {
         super(id, size, data);
     }
-    
+
     /**
      * Constructs a Name record and sets its fields appropriately.
      *
@@ -127,232 +128,232 @@ public class NameRecord extends Record {
     public NameRecord(short id, short size, byte [] data, int offset) {
         super(id, size, data, offset);
     }
-    
+
     /** sets the option flag for the named range
      * @param flag option flag
      */
     public void setOptionFlag(short flag){
         field_1_option_flag = flag;
     }
-    
+
     /** sets the keyboard shortcut
      * @param shortcut keyboard shortcut
      */
     public void setKeyboardShortcut(byte shortcut){
         field_2_keyboard_shortcut = shortcut;
     }
-    
+
     /** sets the name of the named range length
      * @param length name length
      */
     public void setNameTextLength(byte length){
         field_3_length_name_text = length;
     }
-    
+
     /** sets the definition (reference - formula) length
      * @param length defenition length
      */
     public void setDefinitionTextLength(short length){
         field_4_length_name_definition = length;
     }
-    
+
     /** sets the index number to the extern sheet (thats is what writen in ducomentetion
      *  but as i saw , its work direrent)
      * @param index extern sheet index
      */
     public void setIndexToSheet(short index){
         field_5_index_to_sheet = index;
-        
+
         // field_6_equals_to_index_to_sheet is equal to field_5_index_to_sheet
         field_6_equals_to_index_to_sheet = index;
     }
-    
+
     /** sets the custom menu length
      * @param length custom menu length
      */
     public void setCustomMenuLength(byte length){
         field_7_length_custom_menu = length;
     }
-    
+
     /** sets the length of named range description
      * @param length description length
      */
     public void setDescriptionTextLength(byte length){
         field_8_length_description_text = length;
     }
-    
+
     /** sets the help topic length
      * @param length help topic length
      */
     public void setHelpTopicLength(byte length){
         field_9_length_help_topic_text = length;
     }
-    
+
     /** sets the length of the status bar text
      * @param length status bar text length
      */
     public void setStatusBarLength(byte length){
         field_10_length_status_bar_text = length;
     }
-    
+
     /** sets the compressed unicode flag
      * @param flag unicode flag
      */
     public void setCompressedUnicodeFlag(byte flag) {
         field_11_compressed_unicode_flag = flag;
     }
-    
+
     /** sets the name of the named range
      * @param name named range name
      */
     public void setNameText(String name){
         field_12_name_text = name;
     }
-    
+
     //    public void setNameDefintion(String definition){
     //        test = definition;
     //    }
-    
+
     /** sets the custom menu text
      * @param text custom menu text
      */
     public void setCustomMenuText(String text){
         field_14_custom_menu_text = text;
     }
-    
+
     /** sets the description text
      * @param text the description text
      */
     public void setDescriptionText(String text){
         field_15_description_text = text;
     }
-    
+
     /** sets the help topic text
      * @param text help topix text
      */
     public void setHelpTopicText(String text){
         field_16_help_topic_text = text;
     }
-    
+
     /** sets the status bar text
      * @param text status bar text
      */
     public void setStatusBarText(String text){
         field_17_status_bar_text = text;
     }
-    
+
     /** gets the option flag
      * @return option flag
      */
     public short getOptionFlag(){
         return field_1_option_flag;
     }
-    
+
     /** returns the keyboard shortcut
      * @return keyboard shortcut
      */
     public byte getKeyboardShortcut(){
         return field_2_keyboard_shortcut ;
     }
-    
+
     /** gets the name length
      * @return name length
      */
     public byte getNameTextLength(){
         return field_3_length_name_text;
     }
-    
+
     /** get the definition length
      * @return definition length
      */
     public short getDefinitionTextLength(){
         return field_4_length_name_definition;
     }
-    
+
     /** gets the index to extern sheet
      * @return index to extern sheet
      */
     public short getIndexToSheet(){
         return field_5_index_to_sheet;
     }
-    
+
     /** gets the custom menu length
      * @return custom menu length
      */
     public byte getCustomMenuLength(){
         return field_7_length_custom_menu;
     }
-    
+
     /** gets the description text length
      * @return description text length
      */
     public byte getDescriptionTextLength(){
         return field_8_length_description_text;
     }
-    
+
     /** gets the help topic length
      * @return help topic length
      */
     public byte getHelpTopicLength(){
         return field_9_length_help_topic_text;
     }
-    
+
     /** get the status bar text length
      * @return satus bar length
      */
     public byte getStatusBarLength(){
         return field_10_length_status_bar_text;
     }
-    
+
     /** gets the name compressed Unicode flag
      * @return compressed unicode flag
      */
     public byte getCompressedUnicodeFlag() {
         return field_11_compressed_unicode_flag;
     }
-    
+
     /** gets the name
      * @return name
      */
     public String getNameText(){
         return field_12_name_text;
     }
-    
+
     /** gets the definition, reference (Formula)
-     * @return definition
+     * @return definition -- can be null if we cant parse ptgs
      */
-    public List getNameDefinition() {
+    protected List getNameDefinition() {
         return ( List ) field_13_name_definition;
     }
-    
+
     /** get the custom menu text
      * @return custom menu text
      */
     public String getCustomMenuText(){
         return field_14_custom_menu_text;
     }
-    
+
     /** gets the description text
      * @return description text
      */
     public String getDescriptionText(){
         return field_15_description_text;
     }
-    
+
     /** get the help topic text
      * @return gelp topic text
      */
     public String getHelpTopicText(){
         return field_16_help_topic_text;
     }
-    
+
     /** gets the status bar text
      * @return status bar text
      */
     public String getStatusBarText(){
         return field_17_status_bar_text;
     }
-    
+
     /**
      * called by constructor, should throw runtime exception in the event of a
      * record passed with a differing ID.
@@ -364,7 +365,7 @@ public class NameRecord extends Record {
             throw new RecordFormatException("NOT A valid Name RECORD");
         }
     }
-    
+
     /**
      * called by the class that is responsible for writing this sucker.
      * Subclasses should implement this so that their data is passed back in a
@@ -388,125 +389,133 @@ public class NameRecord extends Record {
         data [16 + offset] =  getHelpTopicLength();
         data [17 + offset] =  getStatusBarLength();
         data [18 + offset] =  getCompressedUnicodeFlag();
-        
+
         StringUtil.putCompressedUnicode(getNameText(), data , 19 + offset);
-        
+
         int start_of_name_definition    = 19  + field_3_length_name_text;
-        serializePtgs(data, start_of_name_definition + offset);        
-        
+        if (this.field_13_name_definition != null) {
+            serializePtgs(data, start_of_name_definition + offset);
+        } else {
+            System.arraycopy(field_13_raw_name_definition,0,data
+            ,start_of_name_definition + offset,field_13_raw_name_definition.length);
+        }
+
         int start_of_custom_menu_text   = start_of_name_definition + field_4_length_name_definition;
         StringUtil.putCompressedUnicode(getCustomMenuText(), data , start_of_custom_menu_text + offset);
-        
+
         int start_of_description_text   = start_of_custom_menu_text + field_8_length_description_text;
         StringUtil.putCompressedUnicode(getDescriptionText(), data , start_of_description_text + offset);
-        
+
         int start_of_help_topic_text    = start_of_description_text + field_9_length_help_topic_text;
         StringUtil.putCompressedUnicode(getHelpTopicText(), data , start_of_help_topic_text + offset);
-        
+
         int start_of_status_bar_text       = start_of_help_topic_text + field_10_length_status_bar_text;
         StringUtil.putCompressedUnicode(getStatusBarText(), data , start_of_status_bar_text + offset);
-        
-        
+
+
         return getRecordSize();
     }
-    
+
     private void serializePtgs(byte [] data, int offset) {
         int pos = offset;
-        
+
         for (int k = 0; k < field_13_name_definition.size(); k++) {
             Ptg ptg = ( Ptg ) field_13_name_definition.get(k);
-            
+
             ptg.writeBytes(data, pos);
             pos += ptg.getSize();
         }
     }
-    
-    
+
+
     /** gets the length of all texts
      * @return total length
      */
     public int getTextsLength(){
         int result;
-        
+
         result = getNameTextLength() + getDefinitionTextLength() + getDescriptionTextLength() +
         getHelpTopicLength() + getStatusBarLength();
-        
-        
+
+
         return result;
     }
-    
+
     /** returns the record size
      */
     public int getRecordSize(){
         int result;
-        
+
         result = 19 + getTextsLength();
-        
+
         return result;
     }
-    
+
     /** gets the extern sheet number
      * @return extern sheet index
      */
     public short getExternSheetNumber(){
+        if (field_13_name_definition == null) return 0;
         Ptg ptg = (Ptg) field_13_name_definition.peek();
         short result = 0;
-        
+
         if (ptg.getClass() == Area3DPtg.class){
             result = ((Area3DPtg) ptg).getExternSheetIndex();
-            
+
         } else if (ptg.getClass() == Ref3DPtg.class){
             result = ((Ref3DPtg) ptg).getExternSheetIndex();
         }
-        
+
         return result;
     }
-    
+
     /** sets the extern sheet number
      * @param externSheetNumber extern sheet number
      */
     public void setExternSheetNumber(short externSheetNumber){
         Ptg ptg;
-        
-        if (field_13_name_definition.isEmpty()){
+
+        if (field_13_name_definition == null || field_13_name_definition.isEmpty()){
+            field_13_name_definition = new Stack();
             ptg = createNewPtg();
         } else {
             ptg = (Ptg) field_13_name_definition.peek();
         }
-        
+
         if (ptg.getClass() == Area3DPtg.class){
             ((Area3DPtg) ptg).setExternSheetIndex(externSheetNumber);
-            
+
         } else if (ptg.getClass() == Ref3DPtg.class){
             ((Ref3DPtg) ptg).setExternSheetIndex(externSheetNumber);
         }
-        
+
     }
-    
+
     private Ptg createNewPtg(){
         Ptg ptg = new Area3DPtg();
         field_13_name_definition.push(ptg);
-        
+
         return ptg;
     }
-    
+
     /** gets the reference , the area only (range)
      * @return area reference
      */
     public String getAreaReference(){
+        if (field_13_name_definition == null) return "#REF!";
         Ptg ptg = (Ptg) field_13_name_definition.peek();
         String result = "";
-        
+
         if (ptg.getClass() == Area3DPtg.class){
             result = ((Area3DPtg) ptg).getArea();
-            
+
         } else if (ptg.getClass() == Ref3DPtg.class){
             result = ((Ref3DPtg) ptg).getArea();
         }
-        
+
         return result;
     }
-    
+
     /** sets the reference , the area only (range)
      * @param ref area reference
      */
@@ -515,23 +524,24 @@ public class NameRecord extends Record {
         RangeAddress ra = new RangeAddress(ref);
         Ptg oldPtg;
         Ptg ptg;
-        
-        if (field_13_name_definition.isEmpty()){
+
+        if (field_13_name_definition==null ||field_13_name_definition.isEmpty()){
+            field_13_name_definition = new Stack();
             oldPtg = createNewPtg();
         } else {
             //Trying to find extern sheet index
             oldPtg = (Ptg) field_13_name_definition.pop();
         }
-        
+
         short externSheetIndex = 0;
-        
+
         if (oldPtg.getClass() == Area3DPtg.class){
             externSheetIndex =  ((Area3DPtg) oldPtg).getExternSheetIndex();
-            
+
         } else if (oldPtg.getClass() == Ref3DPtg.class){
             externSheetIndex =  ((Ref3DPtg) oldPtg).getExternSheetIndex();
         }
-        
+
         if (ra.hasRange()) {
             ptg = new Area3DPtg();
             ((Area3DPtg) ptg).setExternSheetIndex(externSheetIndex);
@@ -543,11 +553,11 @@ public class NameRecord extends Record {
             ((Ref3DPtg) ptg).setArea(ref);
             this.setDefinitionTextLength((short)((Ref3DPtg) ptg).getSize());
         }
-        
+
         field_13_name_definition.push(ptg);
-        
+
     }
-    
+
     /**
      * called by the constructor, should set class level fields.  Should throw
      * runtime exception for bad/icomplete data.
@@ -567,55 +577,62 @@ public class NameRecord extends Record {
         field_8_length_description_text = data [11 + offset];
         field_9_length_help_topic_text  = data [12 + offset];
         field_10_length_status_bar_text = data [13 + offset];
-        
+
         field_11_compressed_unicode_flag= data [14 + offset];
         field_12_name_text = new String(data, 15 + offset,
         LittleEndian.ubyteToInt(field_3_length_name_text));
-        
+
         int start_of_name_definition    = 15 + field_3_length_name_text;
         field_13_name_definition = getParsedExpressionTokens(data, field_4_length_name_definition,
         offset, start_of_name_definition);
-        
+
         int start_of_custom_menu_text   = start_of_name_definition + field_4_length_name_definition;
         field_14_custom_menu_text       = new String(data, start_of_custom_menu_text + offset,
         LittleEndian.ubyteToInt(field_7_length_custom_menu));
-        
+
         int start_of_description_text   = start_of_custom_menu_text + field_8_length_description_text;
         field_15_description_text       = new String(data, start_of_description_text + offset,
         LittleEndian.ubyteToInt(field_8_length_description_text));
-        
+
         int start_of_help_topic_text    = start_of_description_text + field_9_length_help_topic_text;
         field_16_help_topic_text        = new String(data, start_of_help_topic_text + offset,
         LittleEndian.ubyteToInt(field_9_length_help_topic_text));
-        
+
         int start_of_status_bar_text       = start_of_help_topic_text + field_10_length_status_bar_text;
         field_17_status_bar_text        = new String(data, start_of_status_bar_text +  offset,
         LittleEndian.ubyteToInt(field_10_length_status_bar_text));
-        
+
     }
-    
+
     private Stack getParsedExpressionTokens(byte [] data, short size,
     int offset, int start_of_expression) {
         Stack stack = new Stack();
         int   pos           = start_of_expression + offset;
         int   sizeCounter   = 0;
-        
-        while (sizeCounter < size) {
-            Ptg ptg = Ptg.createPtg(data, pos);
-            
-            pos += ptg.getSize();
-            sizeCounter += ptg.getSize();
-            stack.push(ptg);
+        try {
+            while (sizeCounter < size) {
+                Ptg ptg = Ptg.createPtg(data, pos);
+
+                pos += ptg.getSize();
+                sizeCounter += ptg.getSize();
+                stack.push(ptg);
+            }
+        } catch (java.lang.UnsupportedOperationException uoe) {
+            System.err.println("[WARNING] Unknown Ptg "
+                    + uoe.getMessage() );
+            field_13_raw_name_definition=new byte[size];
+            System.arraycopy(data,offset,field_13_raw_name_definition,0,size);
+            return null;
         }
         return stack;
     }
-    
-    
+
+
     /**
      * return the non static version of the id for this record.
      */
     public short getSid() {
         return this.sid;
     }
-    
+
 }