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
This commit is contained in:
Avik Sengupta 2005-04-28 13:35:38 +00:00
parent b05501d7b9
commit 7d1fe480a5
4 changed files with 180 additions and 19 deletions

View File

@ -36,7 +36,8 @@ public class FooterRecord
{ {
public final static short sid = 0x15; public final static short sid = 0x15;
private byte field_1_footer_len; private byte field_1_footer_len;
private String field_2_footer; private byte field_2_unicode_flag;
private String field_3_footer;
public FooterRecord() public FooterRecord()
{ {
@ -82,10 +83,45 @@ public class FooterRecord
if (size > 0) if (size > 0)
{ {
field_1_footer_len = data[ 0 + offset ]; field_1_footer_len = data[ 0 + offset ];
field_2_footer = StringUtil.getFromCompressedUnicode(data, 3 + offset, // [Shawn] Changed 1 to 3 for offset of string 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) ); 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 * set the length of the footer string
@ -108,7 +144,9 @@ public class FooterRecord
public void setFooter(String footer) 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() public String getFooter()
{ {
return field_2_footer; return field_3_footer;
} }
public String toString() public String toString()
@ -156,14 +194,24 @@ public class FooterRecord
{ {
len+=3; // [Shawn] Fixed for two null bytes in the length 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, 0 + offset, sid);
LittleEndian.putShort(data, 2 + offset, LittleEndian.putShort(data, 2 + offset,
( short ) ((len - 4) + getFooterLength())); ( short ) ((len - 4) + bytelen ));
if (getFooterLength() > 0) if (getFooterLength() > 0)
{ {
data[ 4 + offset ] = (byte)getFooterLength(); data[ 4 + offset ] = (byte)getFooterLength();
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 StringUtil.putCompressedUnicode(getFooter(), data, 7 + offset); // [Shawn] Place the string in the correct offset
} }
}
return getRecordSize(); return getRecordSize();
} }
@ -175,7 +223,8 @@ public class FooterRecord
{ {
retval+=3; // [Shawn] Fixed for two null bytes in the length retval+=3; // [Shawn] Fixed for two null bytes in the length
} }
return retval + getFooterLength(); return (isMultibyte() ?
(retval + getFooterLength()*2) : (retval + getFooterLength()));
} }
public short getSid() public short getSid()
@ -186,7 +235,8 @@ public class FooterRecord
public Object clone() { public Object clone() {
FooterRecord rec = new FooterRecord(); FooterRecord rec = new FooterRecord();
rec.field_1_footer_len = field_1_footer_len; 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; return rec;
} }
} }

View File

@ -36,7 +36,8 @@ public class HeaderRecord
{ {
public final static short sid = 0x14; public final static short sid = 0x14;
private byte field_1_header_len; private byte field_1_header_len;
private String field_2_header; private byte field_2_unicode_flag;
private String field_3_header;
public HeaderRecord() public HeaderRecord()
{ {
@ -82,10 +83,45 @@ public class HeaderRecord
if (size > 0) if (size > 0)
{ {
field_1_header_len = data[ 0 + offset ]; field_1_header_len = data[ 0 + offset ];
field_2_header = StringUtil.getFromCompressedUnicode(data, 3 + offset, // [Shawn] Changed 1 to 3 for offset of string 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) ); 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 * set the length of the header string
@ -108,7 +144,9 @@ public class HeaderRecord
public void setHeader(String header) 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() public String getHeader()
{ {
return field_2_header; return field_3_header;
} }
public String toString() public String toString()
@ -156,15 +194,25 @@ public class HeaderRecord
{ {
len+=3; // [Shawn] Fixed for two null bytes in the length 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, 0 + offset, sid);
LittleEndian.putShort(data, 2 + offset, LittleEndian.putShort(data, 2 + offset,
( short ) ((len - 4) + getHeaderLength())); ( short ) ((len - 4) + bytelen));
if (getHeaderLength() > 0) if (getHeaderLength() > 0)
{ {
data[ 4 + offset ] = (byte)getHeaderLength(); data[ 4 + offset ] = (byte)getHeaderLength();
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 StringUtil.putCompressedUnicode(getHeader(), data, 7 + offset); // [Shawn] Place the string in the correct offset
} }
}
return getRecordSize(); return getRecordSize();
} }
@ -176,8 +224,8 @@ public class HeaderRecord
{ {
retval+=3; // [Shawn] Fixed for two null bytes in the length retval+=3; // [Shawn] Fixed for two null bytes in the length
} }
retval += getHeaderLength(); return (isMultibyte() ?
return retval; (retval + getHeaderLength()*2) : (retval + getHeaderLength()));
} }
public short getSid() public short getSid()
@ -188,7 +236,8 @@ public class HeaderRecord
public Object clone() { public Object clone() {
HeaderRecord rec = new HeaderRecord(); HeaderRecord rec = new HeaderRecord();
rec.field_1_header_len = field_1_header_len; 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; return rec;
} }
} }

Binary file not shown.

View 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.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -86,5 +88,65 @@ public class TestHSSFHeaderFooter extends TestCase {
assertEquals("Bottom Center", foot.getCenter()); assertEquals("Bottom Center", foot.getCenter());
assertEquals("Bottom Right", foot.getRight()); 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");
}
} }