44914 - Fix/suppress warning message - WARN. Unread n bytes of record 0xNN

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@652446 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2008-05-01 07:42:18 +00:00
parent 993bf57633
commit 63a52cf21d
6 changed files with 207 additions and 225 deletions

View File

@ -37,6 +37,7 @@
<!-- Don't forget to update status.xml too! -->
<release version="3.1-beta2" date="2008-05-??">
<action dev="POI-DEVELOPERS" type="fix">44914 - Fix/suppress warning message "WARN. Unread n bytes of record 0xNN"</action>
<action dev="POI-DEVELOPERS" type="fix">44892 - made HSSFWorkbook.getSheet(String) case insensitive</action>
<action dev="POI-DEVELOPERS" type="fix">44886] - Correctly process PICT metafile in EscherMetafileBlip</action>
<action dev="POI-DEVELOPERS" type="fix">44893 - Correctly handle merged regions in HSSFSheet.autoSizeColumn</action>

View File

@ -34,6 +34,7 @@
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.1-beta2" date="2008-05-??">
<action dev="POI-DEVELOPERS" type="fix">44914 - Fix/suppress warning message "WARN. Unread n bytes of record 0xNN"</action>
<action dev="POI-DEVELOPERS" type="fix">44892 - made HSSFWorkbook.getSheet(String) case insensitive</action>
<action dev="POI-DEVELOPERS" type="fix">44886] - Correctly process PICT metafile in EscherMetafileBlip</action>
<action dev="POI-DEVELOPERS" type="fix">44893 - Correctly handle merged regions in HSSFSheet.autoSizeColumn</action>

View File

@ -1,4 +1,3 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@ -15,13 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
/*
* ColumnInfoRecord.java
*
* Created on December 8, 2001, 8:44 AM
*/
package org.apache.poi.hssf.record;
import org.apache.poi.util.LittleEndian;
@ -29,29 +22,28 @@ import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
/**
* Title: ColumnInfo Record<P>
* Description: Defines with width and formatting for a range of columns<P>
* REFERENCE: PG 293 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
* Title: COLINFO Record<p/>
* Description: Defines with width and formatting for a range of columns<p/>
* REFERENCE: PG 293 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
* @author Andrew C. Oliver (acoliver at apache dot org)
* @version 2.0-pre
*/
public class ColumnInfoRecord
extends Record
{
public final class ColumnInfoRecord extends Record {
public static final short sid = 0x7d;
private short field_1_first_col;
private short field_2_last_col;
private short field_3_col_width;
private short field_4_xf_index;
private short field_5_options;
static final private BitField hidden = BitFieldFactory.getInstance(0x01);
static final private BitField outlevel = BitFieldFactory.getInstance(0x0700);
static final private BitField collapsed = BitFieldFactory.getInstance(0x1000);
private static final BitField hidden = BitFieldFactory.getInstance(0x01);
private static final BitField outlevel = BitFieldFactory.getInstance(0x0700);
private static final BitField collapsed = BitFieldFactory.getInstance(0x1000);
// Excel seems write values 2, 10, and 260, even though spec says "must be zero"
private short field_6_reserved;
public ColumnInfoRecord()
{
field_6_reserved = 2; // seems to be the most common value
}
/**
@ -71,7 +63,18 @@ public class ColumnInfoRecord
field_3_col_width = in.readShort();
field_4_xf_index = in.readShort();
field_5_options = in.readShort();
field_6_reserved = in.readShort();
switch(in.remaining()) {
case 2: // usual case
field_6_reserved = in.readShort();
break;
case 1:
// often COLINFO gets encoded 1 byte short
// shouldn't matter because this field is unused
field_6_reserved = in.readByte();
break;
default:
throw new RuntimeException("Unusual record size remaining=(" + in.remaining() + ")");
}
}
protected void validateSid(short id)

View File

@ -14,31 +14,26 @@
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.hssf.record;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.StringUtil;
/**
* Title: FileSharing<P>
* Title: FILESHARING<P>
* Description: stores the encrypted readonly for a workbook (write protect)
* REFERENCE: PG 314 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
* This functionality is accessed from the options dialog box available when performing 'Save As'.<p/>
* REFERENCE: PG 314 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<p/>
* @author Andrew C. Oliver (acoliver at apache dot org)
*/
public final class FileSharingRecord extends Record {
public class FileSharingRecord extends Record {
private static POILogger logger = POILogFactory.getLogger(FileSharingRecord.class);
public final static short sid = 0x5b;
private short field_1_readonly;
private short field_2_password;
private byte field_3_username_length;
private short field_4_unknown; // not documented
private String field_5_username;
private byte field_3_username_unicode_options;
private String field_3_username_value;
public FileSharingRecord() {}
@ -61,23 +56,15 @@ public class FileSharingRecord extends Record {
protected void fillFields(RecordInputStream in) {
field_1_readonly = in.readShort();
field_2_password = in.readShort();
field_3_username_length = in.readByte();
// Is this really correct? The latest docs
// seem to hint there's nothing between the
// username length and the username string
field_4_unknown = in.readShort();
int nameLen = in.readShort();
// Ensure we don't try to read more data than
// there actually is
if(field_3_username_length > in.remaining()) {
logger.log(POILogger.WARN, "FileSharingRecord defined a username of length " + field_3_username_length + ", but only " + in.remaining() + " bytes were left, truncating");
field_3_username_length = (byte)in.remaining();
}
if(field_3_username_length > 0) {
field_5_username = in.readCompressedUnicode(field_3_username_length);
if(nameLen > 0) {
// TODO - Current examples(3) from junits only have zero length username.
field_3_username_unicode_options = in.readByte();
field_3_username_value = in.readCompressedUnicode(nameLen);
} else {
field_5_username = "";
field_3_username_value = "";
}
}
@ -135,45 +122,24 @@ public class FileSharingRecord extends Record {
/**
* @returns byte representing the length of the username field
*/
public byte getUsernameLength() {
return field_3_username_length ;
}
/**
* @param byte representing the length of the username field
*/
public void setUsernameLength(byte length) {
this.field_3_username_length = length;
public short getUsernameLength() {
return (short) field_3_username_value.length();
}
/**
* @returns username of the user that created the file
*/
public String getUsername() {
return this.field_5_username;
return field_3_username_value;
}
/**
* @param username of the user that created the file
*/
public void setUsername(String username) {
this.field_5_username = username;
this.field_3_username_length = (byte)username.length();
field_3_username_value = username;
}
/**
* @return short value of a "bonus field" in Excel that was not doc'd
*/
public short getUnknown() {
return field_4_unknown;
}
/**
* @param unknown field value to set (bonus field that is not doc'd)
*/
public void setUnknown(short unk) {
field_4_unknown = unk;
}
public String toString() {
StringBuffer buffer = new StringBuffer();
@ -183,10 +149,6 @@ public class FileSharingRecord extends Record {
.append(getReadOnly() == 1 ? "true" : "false").append("\n");
buffer.append(" .password = ")
.append(Integer.toHexString(getPassword())).append("\n");
buffer.append(" .userlen = ")
.append(Integer.toHexString(getUsernameLength())).append("\n");
buffer.append(" .unknown = ")
.append(Integer.toHexString(getUnknown())).append("\n");
buffer.append(" .username = ")
.append(getUsername()).append("\n");
buffer.append("[/FILESHARING]\n");
@ -194,18 +156,25 @@ public class FileSharingRecord extends Record {
}
public int serialize(int offset, byte [] data) {
// TODO - junit
LittleEndian.putShort(data, 0 + offset, sid);
LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize()-4));
LittleEndian.putShort(data, 4 + offset, getReadOnly());
LittleEndian.putShort(data, 6 + offset, getPassword());
data[ 8 + offset ] = getUsernameLength();
LittleEndian.putShort(data, 9 + offset, getUnknown());
StringUtil.putCompressedUnicode( getUsername(), data, 11 + offset );
LittleEndian.putShort(data, 8 + offset, getUsernameLength());
if(getUsernameLength() > 0) {
LittleEndian.putByte(data, 10 + offset, field_3_username_unicode_options);
StringUtil.putCompressedUnicode( getUsername(), data, 11 + offset );
}
return getRecordSize();
}
public int getRecordSize() {
return 11+getUsernameLength();
short nameLen = getUsernameLength();
if (nameLen < 1) {
return 10;
}
return 11+nameLen;
}
public short getSid() {
@ -219,10 +188,7 @@ public class FileSharingRecord extends Record {
FileSharingRecord clone = new FileSharingRecord();
clone.setReadOnly(field_1_readonly);
clone.setPassword(field_2_password);
clone.setUsernameLength(field_3_username_length);
clone.setUnknown(field_4_unknown);
clone.setUsername(field_5_username);
clone.setUsername(field_3_username_value);
return clone;
}
}

View File

@ -40,7 +40,7 @@ import org.apache.poi.util.LittleEndian;
* @version 2.0-pre
*/
public class FormulaRecord
public final class FormulaRecord
extends Record
implements CellValueRecordInterface, Comparable
{
@ -108,6 +108,11 @@ public class FormulaRecord
} catch (java.lang.UnsupportedOperationException uoe) {
throw new RecordFormatException(uoe);
}
if (in.remaining() == 10) {
// TODO - this seems to occur when IntersectionPtg is present
// 10 extra bytes are just 0x01 and 0x00
// This causes POI stderr: "WARN. Unread 10 bytes of record 0x6"
}
}
//public void setRow(short row)

View File

@ -30,24 +30,23 @@ import org.apache.poi.hssf.record.RecordInputStream;
* @author avik
* @author Jason Height (jheight at chariot dot net dot au)
*/
public abstract class Ptg
{
/* convert infix order ptg list to rpn order ptg list
* @return List ptgs in RPN order
* @param infixPtgs List of ptgs in infix order
*/
/* DO NOT REMOVE
*we keep this method in case we wish to change the way we parse
*It needs a getPrecedence in OperationsPtg
public static List ptgsToRpn(List infixPtgs) {
java.util.Stack operands = new java.util.Stack();
java.util.List retval = new java.util.Stack();
java.util.ListIterator i = infixPtgs.listIterator();
Object p;
OperationPtg o ;
@ -61,13 +60,13 @@ public abstract class Ptg
weHaveABracket = true;
} else {
o = (OperationPtg) operands.pop();
while (!(o instanceof ParenthesisPtg)) {
while (!(o instanceof ParenthesisPtg)) {
retval.add(o);
}
weHaveABracket = false;
}
} else {
while (!operands.isEmpty() && ((OperationPtg) operands.peek()).getPrecedence() >= ((OperationPtg) p).getPrecedence() ) { //TODO handle ^ since it is right associative
retval.add(operands.pop());
}
@ -82,12 +81,16 @@ public abstract class Ptg
//throw some error
} else {
retval.add(operands.pop());
}
}
}
return retval;
}
*/
/**
* Reads <tt>size</tt> bytes of the input stream, to create an array of <tt>Ptg</tt>s.
* Extra data (beyond <tt>size</tt>) may be read if and <tt>ArrayPtg</tt>s are present.
*/
public static Stack createParsedExpressionTokens(short size, RecordInputStream in )
{
Stack stack = new Stack();
@ -97,22 +100,25 @@ public abstract class Ptg
{
Ptg ptg = Ptg.createPtg( in );
if (ptg instanceof ArrayPtg) {
if (arrayPtgs == null)
arrayPtgs = new ArrayList(5);
arrayPtgs.add(ptg);
pos += 8;
if (arrayPtgs == null)
arrayPtgs = new ArrayList(5);
arrayPtgs.add(ptg);
pos += 8;
} else pos += ptg.getSize();
stack.push( ptg );
}
if(pos != size) {
throw new RuntimeException("Ptg array size mismatch");
}
if (arrayPtgs != null) {
for (int i=0;i<arrayPtgs.size();i++) {
ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
p.readTokenValues(in);
}
for (int i=0;i<arrayPtgs.size();i++) {
ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
p.readTokenValues(in);
}
}
return stack;
}
public static Ptg createPtg(RecordInputStream in)
{
byte id = in.readByte();
@ -123,142 +129,142 @@ public abstract class Ptg
case ExpPtg.sid : // 0x01
retval = new ExpPtg(in);
break;
case AddPtg.sid : // 0x03
retval = new AddPtg(in);
break;
case SubtractPtg.sid : // 0x04
retval = new SubtractPtg(in);
break;
case MultiplyPtg.sid : // 0x05
retval = new MultiplyPtg(in);
break;
case DividePtg.sid : // 0x06
retval = new DividePtg(in);
break;
retval = new DividePtg(in);
break;
case PowerPtg.sid : // 0x07
retval = new PowerPtg(in);
break;
case ConcatPtg.sid : // 0x08
retval = new ConcatPtg(in);
break;
break;
case LessThanPtg.sid: // 0x09
retval = new LessThanPtg(in);
break;
break;
case LessEqualPtg.sid : // 0x0a
retval = new LessEqualPtg(in);
break;
break;
case EqualPtg.sid : // 0x0b
retval = new EqualPtg(in);
break;
break;
case GreaterEqualPtg.sid : // 0x0c
retval = new GreaterEqualPtg(in);
break;
break;
case GreaterThanPtg.sid : // 0x0d
retval = new GreaterThanPtg(in);
break;
break;
case NotEqualPtg.sid : // 0x0e
retval = new NotEqualPtg(in);
break;
break;
case IntersectionPtg.sid : // 0x0f
retval = new IntersectionPtg(in);
break;
break;
case UnionPtg.sid : // 0x10
retval = new UnionPtg(in);
break;
break;
case RangePtg.sid : // 0x11
retval = new RangePtg(in);
break;
break;
case UnaryPlusPtg.sid : // 0x12
retval = new UnaryPlusPtg(in);
break;
break;
case UnaryMinusPtg.sid : // 0x13
retval = new UnaryMinusPtg(in);
break;
break;
case PercentPtg.sid : // 0x14
retval = new PercentPtg(in);
break;
break;
case ParenthesisPtg.sid : // 0x15
retval = new ParenthesisPtg(in);
break;
break;
case MissingArgPtg.sid : // 0x16
retval = new MissingArgPtg(in);
break;
break;
case StringPtg.sid : // 0x17
retval = new StringPtg(in);
break;
case AttrPtg.sid : // 0x19
case 0x1a :
retval = new AttrPtg(in);
break;
break;
case ErrPtg.sid : // 0x1c
retval = new ErrPtg(in);
break;
break;
case BoolPtg.sid : // 0x1d
retval = new BoolPtg(in);
break;
case IntPtg.sid : // 0x1e
retval = new IntPtg(in);
break;
break;
case NumberPtg.sid : // 0x1f
retval = new NumberPtg(in);
break;
retval = new NumberPtg(in);
break;
case ArrayPtg.sid : // 0x20
retval = new ArrayPtg(in);
break;
retval = new ArrayPtg(in);
break;
case ArrayPtgV.sid : // 0x40
retval = new ArrayPtgV(in);
break;
retval = new ArrayPtgV(in);
break;
case ArrayPtgA.sid : // 0x60
retval = new ArrayPtgA(in);
break;
retval = new ArrayPtgA(in);
break;
case FuncPtg.sid : // 0x21
case FuncPtg.sid + 0x20 : // 0x41
case FuncPtg.sid + 0x40 : // 0x61
retval = new FuncPtg(in);
break;
case FuncVarPtg.sid : // 0x22
case FuncVarPtg.sid + 0x20 : // 0x42
case FuncVarPtg.sid + 0x40 : // 0x62
retval = new FuncVarPtg(in);
break;
case ReferencePtg.sid : // 0x24
break;
case ReferencePtg.sid : // 0x24
retval = new ReferencePtg(in);
break;
break;
case RefAPtg.sid : // 0x64
retval = new RefAPtg(in);
break;
break;
case RefVPtg.sid : // 0x44
retval = new RefVPtg(in);
break;
break;
case RefNAPtg.sid : // 0x6C
retval = new RefNAPtg(in);
break;
@ -267,11 +273,11 @@ public abstract class Ptg
break;
case RefNVPtg.sid : // 0x4C
retval = new RefNVPtg(in);
break;
case AreaPtg.sid : // 0x25
break;
case AreaPtg.sid : // 0x25
retval = new AreaPtg(in);
break;
break;
case AreaVPtg.sid: // 0x45
retval = new AreaVPtg(in);
break;
@ -287,81 +293,81 @@ public abstract class Ptg
case AreaNVPtg.sid : // 0x4D
retval = new AreaNVPtg(in);
break;
case MemAreaPtg.sid : // 0x26
case MemAreaPtg.sid + 0x40 : // 0x46
case MemAreaPtg.sid + 0x20 : // 0x66
retval = new MemAreaPtg(in);
break;
case MemErrPtg.sid : // 0x27
case MemErrPtg.sid + 0x20 : // 0x47
case MemErrPtg.sid + 0x40 : // 0x67
retval = new MemErrPtg(in);
break;
break;
case MemFuncPtg.sid : // 0x29
retval = new MemFuncPtg(in);
break;
case RefErrorPtg.sid : // 0x2a
case RefErrorPtg.sid + 0x20 : // 0x4a
case RefErrorPtg.sid + 0x40 : // 0x6a
retval = new RefErrorPtg(in);
break;
break;
case AreaErrPtg.sid : // 0x2b
case AreaErrPtg.sid + 0x20 : // 0x4b
case AreaErrPtg.sid + 0x40 : // 0x6b
retval = new AreaErrPtg(in);
break;
break;
case NamePtg.sid : // 0x23
case NamePtg.sid + 0x20 : // 0x43
case NamePtg.sid + 0x40 : // 0x63
retval = new NamePtg(in);
break;
case NameXPtg.sid : // 0x39
case NameXPtg.sid + 0x20 : // 0x45
case NameXPtg.sid + 0x40 : // 0x79
retval = new NameXPtg(in);
break;
break;
case Area3DPtg.sid : // 0x3b
case Area3DPtg.sid + 0x20 : // 0x5b
case Area3DPtg.sid + 0x40 : // 0x7b
retval = new Area3DPtg(in);
break;
break;
case Ref3DPtg.sid : // 0x3a
case Ref3DPtg.sid + 0x20: // 0x5a
case Ref3DPtg.sid + 0x40: // 0x7a
retval = new Ref3DPtg(in);
break;
break;
case DeletedRef3DPtg.sid: // 0x3c
case DeletedRef3DPtg.sid + 0x20: // 0x5c
case DeletedRef3DPtg.sid + 0x40: // 0x7c
retval = new DeletedRef3DPtg(in);
break;
break;
case DeletedArea3DPtg.sid : // 0x3d
case DeletedArea3DPtg.sid + 0x20 : // 0x5d
case DeletedArea3DPtg.sid + 0x40 : // 0x7d
retval = new DeletedArea3DPtg(in);
break;
case 0x00:
retval = new UnknownPtg();
break;
retval = new UnknownPtg();
break;
default :
//retval = new UnknownPtg();
throw new java.lang.UnsupportedOperationException(" Unknown Ptg in Formula: 0x"+
Integer.toHexString(( int ) id) + " (" + ( int ) id + ")");
}
if (id > 0x60) {
retval.setClass(CLASS_ARRAY);
} else if (id > 0x40) {
@ -371,35 +377,35 @@ public abstract class Ptg
}
return retval;
}
public static int serializePtgStack(Stack expression, byte[] array, int offset) {
int pos = 0;
int size = 0;
if (expression != null)
size = expression.size();
List arrayPtgs = null;
for (int k = 0; k < size; k++) {
Ptg ptg = ( Ptg ) expression.get(k);
ptg.writeBytes(array, pos + offset);
if (ptg instanceof ArrayPtg) {
if (arrayPtgs == null)
arrayPtgs = new ArrayList(5);
arrayPtgs.add(ptg);
pos += 8;
} else pos += ptg.getSize();
}
if (arrayPtgs != null) {
for (int i=0;i<arrayPtgs.size();i++) {
ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
pos += p.writeTokenValueBytes(array, pos + offset);
}
}
return pos;
}
public static int serializePtgStack(Stack expression, byte[] array, int offset) {
int pos = 0;
int size = 0;
if (expression != null)
size = expression.size();
List arrayPtgs = null;
for (int k = 0; k < size; k++) {
Ptg ptg = ( Ptg ) expression.get(k);
ptg.writeBytes(array, pos + offset);
if (ptg instanceof ArrayPtg) {
if (arrayPtgs == null)
arrayPtgs = new ArrayList(5);
arrayPtgs.add(ptg);
pos += 8;
} else pos += ptg.getSize();
}
if (arrayPtgs != null) {
for (int i=0;i<arrayPtgs.size();i++) {
ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
pos += p.writeTokenValueBytes(array, pos + offset);
}
}
return pos;
}
public abstract int getSize();
@ -414,7 +420,7 @@ public abstract class Ptg
}
/** write this Ptg to a byte array*/
public abstract void writeBytes(byte [] array, int offset);
/**
* return a string representation of this token alone
*/
@ -425,7 +431,7 @@ public abstract class Ptg
public String toDebugString() {
byte[] ba = new byte[getSize()];
String retval=null;
writeBytes(ba,0);
writeBytes(ba,0);
try {
retval = org.apache.poi.util.HexDump.dump(ba,0,0);
} catch (Exception e) {
@ -433,7 +439,7 @@ public abstract class Ptg
}
return retval;
}
/** Overridden toString method to ensure object hash is not printed.
* This helps get rid of gratuitous diffs when comparing two dumps
* Subclasses may output more relevant information by overriding this method
@ -441,26 +447,26 @@ public abstract class Ptg
public String toString(){
return this.getClass().toString();
}
public static final byte CLASS_REF = 0x00;
public static final byte CLASS_VALUE = 0x20;
public static final byte CLASS_ARRAY = 0x40;
protected byte ptgClass = CLASS_REF; //base ptg
public void setClass(byte thePtgClass) {
ptgClass = thePtgClass;
}
/** returns the class (REF/VALUE/ARRAY) for this Ptg */
public byte getPtgClass() {
return ptgClass;
}
public abstract byte getDefaultOperandClass();
public abstract Object clone();
}