]> source.dussan.org Git - poi.git/commitdiff
PR:17039 - DBCS chars in header and footer
authorAvik Sengupta <avik@apache.org>
Thu, 28 Apr 2005 13:35:38 +0000 (13:35 +0000)
committerAvik Sengupta <avik@apache.org>
Thu, 28 Apr 2005 13:35:38 +0000 (13:35 +0000)
Obtained from: kamoshida.toshiaki@future.co.jp
Tweaked and tests added by self.

git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353654 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/FooterRecord.java
src/java/org/apache/poi/hssf/record/HeaderRecord.java
src/testcases/org/apache/poi/hssf/data/DBCSHeader.xls [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFHeaderFooter.java

index a4ec36c9378348b6ab882735d708759f5e70ebef..06a1497e8b8a91cccf02b3d16631312352ac81ed 100644 (file)
@@ -36,7 +36,8 @@ public class FooterRecord
 {
     public final static short sid = 0x15;
     private byte              field_1_footer_len;
-    private String            field_2_footer;
+    private byte              field_2_unicode_flag;
+    private String            field_3_footer;
 
     public FooterRecord()
     {
@@ -82,11 +83,46 @@ public class FooterRecord
         if (size > 0)
         {
             field_1_footer_len = data[ 0 + offset ];
-            field_2_footer     = StringUtil.getFromCompressedUnicode(data, 3 + offset, // [Shawn] Changed 1 to 3 for offset of string
-                                            LittleEndian.ubyteToInt( field_1_footer_len) );
+            field_2_unicode_flag = data[ 2 + offset ];
+                         if(isMultibyte())
+                         {
+                             field_3_footer = StringUtil.getFromUnicodeLE(
+                                     data,3 + offset,LittleEndian.ubyteToInt(field_1_footer_len));
+                         }
+                         else
+                         {
+                             field_3_footer     = new String(data, 3 + offset, // [Shawn] Changed 1 to 3 for offset of string
+                                                        LittleEndian.ubyteToInt( field_1_footer_len) );
+                         }
         }
     }
 
+    /**
+     * see the unicode flag
+     *
+     * @return boolean flag
+     *  true:footer string has at least one multibyte character
+     */
+     public boolean isMultibyte() {
+         return ((field_2_unicode_flag & 0xFF) == 1);
+    }
+
+    /**
+     * check the parameter has multibyte character
+     *
+     * @param value  string to check
+     * @return  boolean result
+     *  true:string has at least one multibyte character
+     */
+    private static boolean hasMultibyte(String value){
+        if( value == null )return false;
+        for(int i = 0 ; i < value.length() ; i++ ){
+            char c = value.charAt(i);
+            if(c > 0xFF )return true;
+        }
+        return false;
+    }
+
     /**
      * set the length of the footer string
      *
@@ -108,7 +144,9 @@ public class FooterRecord
 
     public void setFooter(String footer)
     {
-        field_2_footer = footer;
+        field_3_footer = footer;
+        field_2_unicode_flag = 
+            (byte) (hasMultibyte(field_3_footer) ? 1 : 0);
     }
 
     /**
@@ -132,7 +170,7 @@ public class FooterRecord
 
     public String getFooter()
     {
-        return field_2_footer;
+        return field_3_footer;
     }
 
     public String toString()
@@ -156,13 +194,23 @@ public class FooterRecord
         {
             len+=3; // [Shawn] Fixed for two null bytes in the length
         }
+        short bytelen = (short)(isMultibyte() ?
+            getFooterLength()*2 : getFooterLength() );
         LittleEndian.putShort(data, 0 + offset, sid);
         LittleEndian.putShort(data, 2 + offset,
-                              ( short ) ((len - 4) + getFooterLength()));
+                              ( short ) ((len - 4) + bytelen ));
         if (getFooterLength() > 0)
         {
             data[ 4 + offset ] = (byte)getFooterLength();
-            StringUtil.putCompressedUnicode(getFooter(), data, 7 + offset); // [Shawn] Place the string in the correct offset
+            data[ 6 + offset ] = field_2_unicode_flag;
+            if(isMultibyte())
+            {
+                StringUtil.putUnicodeLE(getFooter(), data, 7 + offset);
+            }
+            else
+            {
+                StringUtil.putCompressedUnicode(getFooter(), data, 7 + offset); // [Shawn] Place the string in the correct offset
+            }
         }
         return getRecordSize();
     }
@@ -175,7 +223,8 @@ public class FooterRecord
         {
             retval+=3; // [Shawn] Fixed for two null bytes in the length
         }
-        return retval + getFooterLength();
+        return (isMultibyte() ? 
+            (retval + getFooterLength()*2) : (retval + getFooterLength()));
     }
 
     public short getSid()
@@ -186,7 +235,8 @@ public class FooterRecord
     public Object clone() {
       FooterRecord rec = new FooterRecord();
       rec.field_1_footer_len = field_1_footer_len;
-      rec.field_2_footer = field_2_footer;
+      rec.field_2_unicode_flag = field_2_unicode_flag;
+      rec.field_3_footer = field_3_footer;
       return rec;
     }
 }
index f5a48ec9fb9ceae83f5de46048fdb9d81b7a0ea0..9af6297f8b80f904acd0e16074872cb8f9ddc985 100644 (file)
@@ -36,7 +36,8 @@ public class HeaderRecord
 {
     public final static short sid = 0x14;
     private byte              field_1_header_len;
-    private String            field_2_header;
+    private byte              field_2_unicode_flag;
+    private String            field_3_header;
 
     public HeaderRecord()
     {
@@ -82,11 +83,46 @@ public class HeaderRecord
         if (size > 0)
         {
             field_1_header_len = data[ 0 + offset ];
-            field_2_header     = StringUtil.getFromCompressedUnicode(data, 3 + offset, // [Shawn] Changed 1 to 3 for offset of string
-                                            LittleEndian.ubyteToInt(field_1_header_len));
+            field_2_unicode_flag = data[ 2 + offset ];
+                         if(isMultibyte())
+                         {
+                             field_3_header = StringUtil.getFromUnicodeLE(
+                                     data,3 + offset,LittleEndian.ubyteToInt(field_1_header_len));
+                         }
+                         else
+                         {
+                             field_3_header     = new String(data, 3 + offset, // [Shawn] Changed 1 to 3 for offset of string
+                                                         LittleEndian.ubyteToInt( field_1_header_len) );
+                         }
         }
     }
 
+    /**
+     * see the unicode flag
+     *
+     * @return boolean flag
+     *  true:footer string has at least one multibyte character
+     */
+     public boolean isMultibyte() {
+         return ((field_2_unicode_flag & 0xFF) == 1);
+    }
+
+    /**
+     * check the parameter has multibyte character
+     *
+     * @param value  string to check
+     * @return  boolean result
+     *  true:string has at least one multibyte character
+     */
+    private static boolean hasMultibyte(String value){
+        if( value == null )return false;
+        for(int i = 0 ; i < value.length() ; i++ ){
+            char c = value.charAt(i);
+            if(c > 0xFF )return true;
+        }
+        return false;
+    }
+
     /**
      * set the length of the header string
      *
@@ -108,7 +144,9 @@ public class HeaderRecord
 
     public void setHeader(String header)
     {
-        field_2_header = header;
+        field_3_header = header;
+        field_2_unicode_flag = 
+            (byte) (hasMultibyte(field_3_header) ? 1 : 0);
     }
 
     /**
@@ -132,7 +170,7 @@ public class HeaderRecord
 
     public String getHeader()
     {
-        return field_2_header;
+        return field_3_header;
     }
 
     public String toString()
@@ -156,14 +194,24 @@ public class HeaderRecord
         {
             len+=3; // [Shawn] Fixed for two null bytes in the length
         }
+        short bytelen = (short)(isMultibyte() ?
+            getHeaderLength()*2 : getHeaderLength() );
         LittleEndian.putShort(data, 0 + offset, sid);
         LittleEndian.putShort(data, 2 + offset,
-                              ( short ) ((len - 4) + getHeaderLength()));
+                              ( short ) ((len - 4) + bytelen));
 
         if (getHeaderLength() > 0)
         {
             data[ 4 + offset ] = (byte)getHeaderLength();
-            StringUtil.putCompressedUnicode(getHeader(), data, 7 + offset); // [Shawn] Place the string in the correct offset
+            data[ 6 + offset ] = field_2_unicode_flag;
+            if(isMultibyte())
+            {
+                StringUtil.putUnicodeLE(getHeader(), data, 7 + offset);
+            }
+            else
+            {
+                StringUtil.putCompressedUnicode(getHeader(), data, 7 + offset); // [Shawn] Place the string in the correct offset
+            }
         }
         return getRecordSize();
     }
@@ -176,8 +224,8 @@ public class HeaderRecord
         {
             retval+=3; // [Shawn] Fixed for two null bytes in the length
         }
-        retval += getHeaderLength();
-        return retval;
+       return (isMultibyte() ? 
+            (retval + getHeaderLength()*2) : (retval + getHeaderLength()));
     }
 
     public short getSid()
@@ -188,7 +236,8 @@ public class HeaderRecord
     public Object clone() {
       HeaderRecord rec = new HeaderRecord();
       rec.field_1_header_len = field_1_header_len;
-      rec.field_2_header = field_2_header;
+      rec.field_2_unicode_flag = field_2_unicode_flag;
+      rec.field_3_header = field_3_header;
       return rec;
     }
 }
diff --git a/src/testcases/org/apache/poi/hssf/data/DBCSHeader.xls b/src/testcases/org/apache/poi/hssf/data/DBCSHeader.xls
new file mode 100644 (file)
index 0000000..d97daf1
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/DBCSHeader.xls differ
index ca6173ba13f112bf11af71ef29c967862949527a..310d2f6e1004d0fc3158c4e3030a221ad814b6fa 100644 (file)
@@ -24,6 +24,8 @@ import org.apache.poi.hssf.usermodel.HSSFFooter;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -86,5 +88,65 @@ public class TestHSSFHeaderFooter extends TestCase {
        assertEquals("Bottom Center", foot.getCenter());
        assertEquals("Bottom Right", foot.getRight());
     }
+    
+    /**
+        * Testcase for Bug 17039 HSSFHeader  doesnot support DBCS 
+        */
+       public void testHeaderHas16bitCharacter() throws Exception {
+                       HSSFWorkbook b = new HSSFWorkbook();
+                       HSSFSheet s = b.createSheet("Test");
+                       HSSFHeader h = s.getHeader();
+                       h.setLeft("\u0391");
+                       h.setCenter("\u0392");
+                       h.setRight("\u0393");
+                       
+                       ByteArrayOutputStream out = new ByteArrayOutputStream();
+                       b.write(out);
+                       
+                       HSSFWorkbook b2 = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray()));
+                       HSSFHeader h2 = b2.getSheet("Test").getHeader();
+                       
+                       assertEquals(h2.getLeft(),"\u0391");
+                       assertEquals(h2.getCenter(),"\u0392");
+                       assertEquals(h2.getRight(),"\u0393");
+       }
+       
+       /**
+        * Testcase for Bug 17039 HSSFFooter doesnot support DBCS 
+        */
+        public void testFooterHas16bitCharacter() throws Exception{
+                       HSSFWorkbook b = new HSSFWorkbook();
+                       HSSFSheet s = b.createSheet("Test");
+                       HSSFFooter f = s.getFooter();
+                       f.setLeft("\u0391");
+                       f.setCenter("\u0392");
+                       f.setRight("\u0393");
+                       
+                       ByteArrayOutputStream out = new ByteArrayOutputStream();
+                       b.write(out);
+                       
+                       HSSFWorkbook b2 = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray()));
+                       HSSFFooter f2 = b2.getSheet("Test").getFooter();
+                       
+                       assertEquals(f2.getLeft(),"\u0391");
+                       assertEquals(f2.getCenter(),"\u0392");
+                       assertEquals(f2.getRight(),"\u0393");
+       }
+
+       public void testReadDBCSHeaderFooter() throws Exception{
+               String readFilename = System.getProperty("HSSF.testdata.path");
+        FileInputStream in = new FileInputStream(readFilename+File.separator+"DBCSHeader.xls");
+        HSSFWorkbook wb = new HSSFWorkbook(in);
+        HSSFSheet s = wb.getSheetAt(0);
+        HSSFHeader h = s.getHeader();
+        assertEquals("Header Left " ,h.getLeft(),"\u090f\u0915");
+        assertEquals("Header Center " ,h.getCenter(),"\u0939\u094b\u0917\u093e");
+        assertEquals("Header Right " ,h.getRight(),"\u091c\u093e");
+               
+        HSSFFooter f = s.getFooter();
+        assertEquals("Footer Left " ,f.getLeft(),"\u091c\u093e");
+        assertEquals("Footer Center " ,f.getCenter(),"\u091c\u093e");
+        assertEquals("Footer Right " ,f.getRight(),"\u091c\u093e");
+       }
 }