Bugzilla 46776 - Added clone() method to MulBlankRecord to fix crash in Sheet.cloneSheet()
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@782177 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3f7db41945
commit
190684164a
@ -35,6 +35,7 @@
|
|||||||
<release version="3.5-beta7" date="2009-??-??">
|
<release version="3.5-beta7" date="2009-??-??">
|
||||||
</release>
|
</release>
|
||||||
<release version="3.5-beta6" date="2009-06-11">
|
<release version="3.5-beta6" date="2009-06-11">
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">46776 - Added clone() method to MulBlankRecord to fix crash in Sheet.cloneSheet()</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">47244 - Fixed HSSFSheet to handle missing header / footer records</action>
|
<action dev="POI-DEVELOPERS" type="fix">47244 - Fixed HSSFSheet to handle missing header / footer records</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">47312 - Fixed formula parser to properly reject cell references with a '0' row component</action>
|
<action dev="POI-DEVELOPERS" type="fix">47312 - Fixed formula parser to properly reject cell references with a '0' row component</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">47199 - Fixed PageSettingsBlock/Sheet to tolerate margin records after other non-PSB records</action>
|
<action dev="POI-DEVELOPERS" type="fix">47199 - Fixed PageSettingsBlock/Sheet to tolerate margin records after other non-PSB records</action>
|
||||||
|
@ -22,128 +22,114 @@ import org.apache.poi.util.LittleEndianOutput;
|
|||||||
/**
|
/**
|
||||||
* Title: Multiple Blank cell record(0x00BE) <P/>
|
* Title: Multiple Blank cell record(0x00BE) <P/>
|
||||||
* Description: Represents a set of columns in a row with no value but with styling.
|
* Description: Represents a set of columns in a row with no value but with styling.
|
||||||
* In this release we have read-only support for this record type.
|
* <p/>
|
||||||
* The RecordFactory converts this to a set of BlankRecord objects.<P/>
|
|
||||||
* REFERENCE: PG 329 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P/>
|
* REFERENCE: PG 329 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P/>
|
||||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||||
* @author Glen Stampoultzis (glens at apache.org)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
* @see BlankRecord
|
* @see BlankRecord
|
||||||
*/
|
*/
|
||||||
public final class MulBlankRecord extends StandardRecord {
|
public final class MulBlankRecord extends StandardRecord {
|
||||||
public final static short sid = 0x00BE;
|
public final static short sid = 0x00BE;
|
||||||
|
|
||||||
private int field_1_row;
|
private final int _row;
|
||||||
private short field_2_first_col;
|
private final int _firstCol;
|
||||||
private short[] field_3_xfs;
|
private final short[] _xfs;
|
||||||
private short field_4_last_col;
|
private final int _lastCol;
|
||||||
|
|
||||||
public MulBlankRecord(int row, int firstCol, short[] xfs) {
|
public MulBlankRecord(int row, int firstCol, short[] xfs) {
|
||||||
field_1_row = row;
|
_row = row;
|
||||||
field_2_first_col = (short)firstCol;
|
_firstCol = firstCol;
|
||||||
field_3_xfs = xfs;
|
_xfs = xfs;
|
||||||
field_4_last_col = (short) (firstCol + xfs.length - 1);
|
_lastCol = firstCol + xfs.length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the row number of the cells this represents
|
* @return the row number of the cells this represents
|
||||||
*
|
*/
|
||||||
* @return row number
|
public int getRow() {
|
||||||
*/
|
return _row;
|
||||||
public int getRow()
|
}
|
||||||
{
|
|
||||||
return field_1_row;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* starting column (first cell this holds in the row)
|
* @return starting column (first cell this holds in the row). Zero based
|
||||||
* @return first column number
|
*/
|
||||||
*/
|
public int getFirstColumn() {
|
||||||
public short getFirstColumn()
|
return _firstCol;
|
||||||
{
|
}
|
||||||
return field_2_first_col;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ending column (last cell this holds in the row)
|
* get the number of columns this contains (last-first +1)
|
||||||
* @return first column number
|
* @return number of columns (last - first +1)
|
||||||
*/
|
*/
|
||||||
public short getLastColumn()
|
public int getNumColumns() {
|
||||||
{
|
return _lastCol - _firstCol + 1;
|
||||||
return field_4_last_col;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the number of columns this contains (last-first +1)
|
* returns the xf index for column (coffset = column - field_2_first_col)
|
||||||
* @return number of columns (last - first +1)
|
* @param coffset the column (coffset = column - field_2_first_col)
|
||||||
*/
|
* @return the XF index for the column
|
||||||
public int getNumColumns()
|
*/
|
||||||
{
|
public short getXFAt(int coffset) {
|
||||||
return field_4_last_col - field_2_first_col + 1;
|
return _xfs[coffset];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the xf index for column (coffset = column - field_2_first_col)
|
* @param in the RecordInputstream to read the record from
|
||||||
* @param coffset the column (coffset = column - field_2_first_col)
|
*/
|
||||||
* @return the XF index for the column
|
public MulBlankRecord(RecordInputStream in) {
|
||||||
*/
|
_row = in.readUShort();
|
||||||
public short getXFAt(int coffset)
|
_firstCol = in.readShort();
|
||||||
{
|
_xfs = parseXFs(in);
|
||||||
return field_3_xfs[ coffset ];
|
_lastCol = in.readShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static short [] parseXFs(RecordInputStream in) {
|
||||||
* @param in the RecordInputstream to read the record from
|
short[] retval = new short[(in.remaining() - 2) / 2];
|
||||||
*/
|
|
||||||
public MulBlankRecord(RecordInputStream in) {
|
|
||||||
field_1_row = in.readUShort();
|
|
||||||
field_2_first_col = in.readShort();
|
|
||||||
field_3_xfs = parseXFs(in);
|
|
||||||
field_4_last_col = in.readShort();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static short [] parseXFs(RecordInputStream in)
|
for (int idx = 0; idx < retval.length;idx++) {
|
||||||
{
|
retval[idx] = in.readShort();
|
||||||
short[] retval = new short[ (in.remaining() - 2) / 2 ];
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
for (int idx = 0; idx < retval.length;idx++)
|
public String toString() {
|
||||||
{
|
StringBuffer buffer = new StringBuffer();
|
||||||
retval[idx] = in.readShort();
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
buffer.append("[MULBLANK]\n");
|
||||||
StringBuffer buffer = new StringBuffer();
|
buffer.append("row = ").append(Integer.toHexString(getRow())).append("\n");
|
||||||
|
buffer.append("firstcol = ").append(Integer.toHexString(getFirstColumn())).append("\n");
|
||||||
|
buffer.append(" lastcol = ").append(Integer.toHexString(_lastCol)).append("\n");
|
||||||
|
for (int k = 0; k < getNumColumns(); k++) {
|
||||||
|
buffer.append("xf").append(k).append(" = ").append(
|
||||||
|
Integer.toHexString(getXFAt(k))).append("\n");
|
||||||
|
}
|
||||||
|
buffer.append("[/MULBLANK]\n");
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
buffer.append("[MULBLANK]\n");
|
public short getSid() {
|
||||||
buffer.append("row = ").append(Integer.toHexString(getRow())).append("\n");
|
return sid;
|
||||||
buffer.append("firstcol = ").append(Integer.toHexString(getFirstColumn())).append("\n");
|
}
|
||||||
buffer.append(" lastcol = ").append(Integer.toHexString(getLastColumn())).append("\n");
|
|
||||||
for (int k = 0; k < getNumColumns(); k++) {
|
|
||||||
buffer.append("xf").append(k).append(" = ").append(
|
|
||||||
Integer.toHexString(getXFAt(k))).append("\n");
|
|
||||||
}
|
|
||||||
buffer.append("[/MULBLANK]\n");
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getSid()
|
public void serialize(LittleEndianOutput out) {
|
||||||
{
|
out.writeShort(_row);
|
||||||
return sid;
|
out.writeShort(_firstCol);
|
||||||
}
|
int nItems = _xfs.length;
|
||||||
|
for (int i = 0; i < nItems; i++) {
|
||||||
|
out.writeShort(_xfs[i]);
|
||||||
|
}
|
||||||
|
out.writeShort(_lastCol);
|
||||||
|
}
|
||||||
|
|
||||||
public void serialize(LittleEndianOutput out) {
|
protected int getDataSize() {
|
||||||
out.writeShort(field_1_row);
|
// 3 short fields + array of shorts
|
||||||
out.writeShort(field_2_first_col);
|
return 6 + _xfs.length * 2;
|
||||||
int nItems = field_3_xfs.length;
|
}
|
||||||
for (int i = 0; i < nItems; i++) {
|
|
||||||
out.writeShort(field_3_xfs[i]);
|
|
||||||
}
|
|
||||||
out.writeShort(field_4_last_col);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int getDataSize() {
|
@Override
|
||||||
// 3 short fields + array of shorts
|
public Object clone() {
|
||||||
return 6 + field_3_xfs.length * 2;
|
// immutable - so OK to return this
|
||||||
}
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package org.apache.poi.hssf.model;
|
package org.apache.poi.hssf.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
@ -34,6 +35,7 @@ import org.apache.poi.hssf.record.FormulaRecord;
|
|||||||
import org.apache.poi.hssf.record.GutsRecord;
|
import org.apache.poi.hssf.record.GutsRecord;
|
||||||
import org.apache.poi.hssf.record.IndexRecord;
|
import org.apache.poi.hssf.record.IndexRecord;
|
||||||
import org.apache.poi.hssf.record.MergeCellsRecord;
|
import org.apache.poi.hssf.record.MergeCellsRecord;
|
||||||
|
import org.apache.poi.hssf.record.MulBlankRecord;
|
||||||
import org.apache.poi.hssf.record.NumberRecord;
|
import org.apache.poi.hssf.record.NumberRecord;
|
||||||
import org.apache.poi.hssf.record.Record;
|
import org.apache.poi.hssf.record.Record;
|
||||||
import org.apache.poi.hssf.record.RecordBase;
|
import org.apache.poi.hssf.record.RecordBase;
|
||||||
@ -671,4 +673,33 @@ public final class TestSheet extends TestCase {
|
|||||||
}
|
}
|
||||||
assertNotNull(cft);
|
assertNotNull(cft);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCloneMulBlank_bug46776() {
|
||||||
|
Record[] recs = {
|
||||||
|
Sheet.createBOF(),
|
||||||
|
new DimensionsRecord(),
|
||||||
|
new RowRecord(1),
|
||||||
|
new MulBlankRecord(1, 3, new short[] { 0x0F, 0x0F, 0x0F, } ),
|
||||||
|
new RowRecord(2),
|
||||||
|
createWindow2Record(),
|
||||||
|
EOFRecord.instance,
|
||||||
|
};
|
||||||
|
|
||||||
|
Sheet sheet = createSheet(Arrays.asList(recs));
|
||||||
|
|
||||||
|
Sheet sheet2;
|
||||||
|
try {
|
||||||
|
sheet2 = sheet.cloneSheet();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
if (e.getMessage().equals("The class org.apache.poi.hssf.record.MulBlankRecord needs to define a clone method")) {
|
||||||
|
throw new AssertionFailedError("Identified bug 46776");
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
RecordCollector rc = new RecordCollector();
|
||||||
|
sheet2.visitContainedRecords(rc, 0);
|
||||||
|
Record[] clonedRecs = rc.getRecords();
|
||||||
|
assertEquals(recs.length+2, clonedRecs.length); // +2 for INDEX and DBCELL
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user