From: Avik Sengupta Date: Thu, 28 Apr 2005 13:35:38 +0000 (+0000) Subject: PR:17039 - DBCS chars in header and footer X-Git-Tag: BEFORE_RICHTEXT~113 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=90bc3e260a0edfaa1e2dc75539c1c81bf64e86ba;p=poi.git PR:17039 - DBCS chars in header and footer 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 --- diff --git a/src/java/org/apache/poi/hssf/record/FooterRecord.java b/src/java/org/apache/poi/hssf/record/FooterRecord.java index a4ec36c937..06a1497e8b 100644 --- a/src/java/org/apache/poi/hssf/record/FooterRecord.java +++ b/src/java/org/apache/poi/hssf/record/FooterRecord.java @@ -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; } } diff --git a/src/java/org/apache/poi/hssf/record/HeaderRecord.java b/src/java/org/apache/poi/hssf/record/HeaderRecord.java index f5a48ec9fb..9af6297f8b 100644 --- a/src/java/org/apache/poi/hssf/record/HeaderRecord.java +++ b/src/java/org/apache/poi/hssf/record/HeaderRecord.java @@ -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 index 0000000000..d97daf1edb Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/DBCSHeader.xls differ diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFHeaderFooter.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFHeaderFooter.java index ca6173ba13..310d2f6e10 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFHeaderFooter.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFHeaderFooter.java @@ -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"); + } }