avik 2003/07/25 11:22:20
Modified: src/java/org/apache/poi/hssf/model Tag: REL_2_BRANCH
Workbook.java
src/java/org/apache/poi/hssf/record Tag: REL_2_BRANCH
NameRecord.java StyleRecord.java
src/java/org/apache/poi/hssf/record/aggregates Tag:
REL_2_BRANCH FormulaRecordAggregate.java
src/java/org/apache/poi/hssf/record/formula Tag:
REL_2_BRANCH NamePtg.java StringPtg.java
Added: src/testcases/org/apache/poi/hssf/data Tag: REL_2_BRANCH
15228.xls
src/testcases/org/apache/poi/hssf/usermodel Tag:
REL_2_BRANCH TestBugs.java
Log:
bug 15228 and related fixes:
1. Correct structure of NamePtg
2. Correct Unicode handling of strings in StyleRecord and StringPtg
3. Workaround for SheetReferences
4. Ensure correct handling in NameRecord if we cant parse PTGs
5. Ensure correct order of String and SharFormula records
6. Testcase!
Revision Changes Path
No revision
No revision
1.29.2.3 +15 -11 jakarta-poi/src/java/org/apache/poi/hssf/model/Workbook.java
Index: Workbook.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/model/Workbook.java,v
retrieving revision 1.29.2.2
retrieving revision 1.29.2.3
diff -u -r1.29.2.2 -r1.29.2.3
--- Workbook.java 1 Jul 2003 14:52:15 -0000 1.29.2.2
+++ Workbook.java 25 Jul 2003 18:22:19 -0000 1.29.2.3
@@ -1729,15 +1729,17 @@
}
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
@@ -1745,10 +1747,12 @@
* @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;
}
No revision
No revision
1.12.2.1 +4 -1 jakarta-poi/src/java/org/apache/poi/hssf/record/NameRecord.java
Index: NameRecord.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/NameRecord.java,v
retrieving revision 1.12
retrieving revision 1.12.2.1
diff -u -r1.12 -r1.12.2.1
--- NameRecord.java 17 May 2003 18:32:41 -0000 1.12
+++ NameRecord.java 25 Jul 2003 18:22:19 -0000 1.12.2.1
@@ -794,6 +794,8 @@
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 @@
.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 @@
.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();
1.6.2.1 +31 -14 jakarta-poi/src/java/org/apache/poi/hssf/record/StyleRecord.java
Index: StyleRecord.java
===================================================================
RCS file:
/home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/StyleRecord.java,v
retrieving revision 1.6
retrieving revision 1.6.2.1
diff -u -r1.6 -r1.6.2.1
--- StyleRecord.java 30 Apr 2003 04:38:47 -0000 1.6
+++ StyleRecord.java 25 Jul 2003 18:22:19 -0000 1.6.2.1
@@ -57,12 +57,14 @@
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 @@
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 @@
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 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 @@
* @see #getName()
*/
- public byte getNameLength()
+ public short getNameLength()
{
return field_2_name_length;
}
@@ -286,7 +298,7 @@
public String getName()
{
- return field_3_name;
+ return field_4_name;
}
// end user defined
@@ -361,7 +373,7 @@
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 @@
}
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 @@
}
else
{
- retval = 7 + getNameLength();
+ if (fHighByte.isSet(field_3_string_options)) {
+ retval= 9+2*getNameLength();
+ }else {
+ retval = 9 + getNameLength();
+ }
}
return retval;
}
No revision
No revision
1.4.2.2 +4 -4
jakarta-poi/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java
Index: FormulaRecordAggregate.java
===================================================================
RCS file:
/home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/aggregates/FormulaRecordAggregate.java,v
retrieving revision 1.4.2.1
retrieving revision 1.4.2.2
diff -u -r1.4.2.1 -r1.4.2.2
--- FormulaRecordAggregate.java 28 Jun 2003 00:21:47 -0000 1.4.2.1
+++ FormulaRecordAggregate.java 25 Jul 2003 18:22:19 -0000 1.4.2.2
@@ -119,14 +119,14 @@
{
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;
}
No revision
No revision
1.6.2.2 +14 -12
jakarta-poi/src/java/org/apache/poi/hssf/record/formula/NamePtg.java
Index: NamePtg.java
===================================================================
RCS file:
/home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/formula/NamePtg.java,v
retrieving revision 1.6.2.1
retrieving revision 1.6.2.2
diff -u -r1.6.2.1 -r1.6.2.2
--- NamePtg.java 1 Jul 2003 14:47:34 -0000 1.6.2.1
+++ NamePtg.java 25 Jul 2003 18:22:19 -0000 1.6.2.2
@@ -73,10 +73,10 @@
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 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 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;
}
}
1.6.2.1 +43 -12
jakarta-poi/src/java/org/apache/poi/hssf/record/formula/StringPtg.java
Index: StringPtg.java
===================================================================
RCS file:
/home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/formula/StringPtg.java,v
retrieving revision 1.6
retrieving revision 1.6.2.1
diff -u -r1.6 -r1.6.2.1
--- StringPtg.java 30 Apr 2003 04:39:02 -0000 1.6
+++ StringPtg.java 25 Jul 2003 18:22:19 -0000 1.6.2.1
@@ -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 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 @@
/** 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 @@
* @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 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;
}
No revision
No revision
1.1.2.1 +3730 -0
jakarta-poi/src/testcases/org/apache/poi/hssf/data/Attic/15228.xls
<<Binary file>>
No revision
No revision
1.1.2.1 +98 -0
jakarta-poi/src/testcases/org/apache/poi/hssf/usermodel/Attic/TestBugs.java
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]