Added ArrayRecord and CellRangeAddress8Bit
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@690411 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5cb7d5e0d1
commit
1c3cefbfdd
126
src/java/org/apache/poi/hssf/record/ArrayRecord.java
Normal file
126
src/java/org/apache/poi/hssf/record/ArrayRecord.java
Normal file
@ -0,0 +1,126 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.util.CellRangeAddress8Bit;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* ARRAY (0x0221)<p/>
|
||||
*
|
||||
* Treated in a similar way to SharedFormulaRecord
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public final class ArrayRecord extends Record {
|
||||
|
||||
public final static short sid = 0x0221;
|
||||
private static final int OPT_ALWAYS_RECALCULATE = 0x0001;
|
||||
private static final int OPT_CALCULATE_ON_OPEN = 0x0002;
|
||||
|
||||
private CellRangeAddress8Bit _range;
|
||||
|
||||
private int _options;
|
||||
private int _field3notUsed;
|
||||
private Ptg[] _formulaTokens;
|
||||
|
||||
public ArrayRecord(RecordInputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
public boolean isAlwaysRecalculate() {
|
||||
return (_options & OPT_ALWAYS_RECALCULATE) != 0;
|
||||
}
|
||||
public boolean isCalculateOnOpen() {
|
||||
return (_options & OPT_CALCULATE_ON_OPEN) != 0;
|
||||
}
|
||||
|
||||
protected void validateSid(short id) {
|
||||
if (id != sid) {
|
||||
throw new RecordFormatException("NOT A valid Array RECORD");
|
||||
}
|
||||
}
|
||||
|
||||
private int getDataSize(){
|
||||
return CellRangeAddress8Bit.ENCODED_SIZE
|
||||
+ 2 + 4
|
||||
+ getFormulaSize();
|
||||
}
|
||||
|
||||
public int serialize( int offset, byte[] data ) {
|
||||
int dataSize = getDataSize();
|
||||
|
||||
LittleEndian.putShort(data, 0 + offset, sid);
|
||||
LittleEndian.putUShort(data, 2 + offset, dataSize);
|
||||
|
||||
int pos = offset+4;
|
||||
_range.serialize(pos, data);
|
||||
pos += CellRangeAddress8Bit.ENCODED_SIZE;
|
||||
LittleEndian.putUShort(data, pos, _options);
|
||||
pos+=2;
|
||||
LittleEndian.putInt(data, pos, _field3notUsed);
|
||||
pos+=4;
|
||||
int tokenSize = Ptg.getEncodedSizeWithoutArrayData(_formulaTokens);
|
||||
LittleEndian.putUShort(data, pos, tokenSize);
|
||||
pos+=2;
|
||||
Ptg.serializePtgs(_formulaTokens, data, pos);
|
||||
return dataSize + 4;
|
||||
}
|
||||
|
||||
private int getFormulaSize() {
|
||||
int result = 0;
|
||||
for (int i = 0; i < _formulaTokens.length; i++) {
|
||||
result += _formulaTokens[i].getSize();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public int getRecordSize(){
|
||||
return 4 + getDataSize();
|
||||
}
|
||||
|
||||
|
||||
protected void fillFields(RecordInputStream in) {
|
||||
_range = new CellRangeAddress8Bit(in);
|
||||
_options = in.readUShort();
|
||||
_field3notUsed = in.readInt();
|
||||
int formulaLen = in.readUShort();
|
||||
_formulaTokens = Ptg.readTokens(formulaLen, in);
|
||||
}
|
||||
|
||||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(getClass().getName()).append(" [ARRAY]\n");
|
||||
sb.append(" range=").append(_range.toString()).append("\n");
|
||||
sb.append(" options=").append(HexDump.shortToHex(_options)).append("\n");
|
||||
sb.append(" notUsed=").append(HexDump.intToHex(_field3notUsed)).append("\n");
|
||||
sb.append(" formula:").append("\n");
|
||||
for (int i = 0; i < _formulaTokens.length; i++) {
|
||||
sb.append(_formulaTokens[i].toString());
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.hssf.util.CellRangeAddress8Bit;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
@ -35,66 +36,25 @@ public final class SelectionRecord extends Record {
|
||||
private int field_2_row_active_cell;
|
||||
private int field_3_col_active_cell;
|
||||
private int field_4_active_cell_ref_index;
|
||||
private Reference[] field_6_refs;
|
||||
|
||||
/**
|
||||
* Note - column values are 8-bit so cannot use <tt>CellRangeAddressList</tt>
|
||||
*/
|
||||
public class Reference {
|
||||
/* package */ static final int ENCODED_SIZE = 6;
|
||||
private int _firstRow;
|
||||
private int _lastRow;
|
||||
private int _firstCol;
|
||||
private int _lastCol;
|
||||
|
||||
/* package */ Reference(int firstRow, int lastRow, int firstColumn, int lastColumn) {
|
||||
_firstRow = firstRow;
|
||||
_lastRow = lastRow;
|
||||
_firstCol = firstColumn;
|
||||
_lastCol = lastColumn;
|
||||
}
|
||||
/* package */ Reference(RecordInputStream in) {
|
||||
this(in.readUShort(), in.readUShort(), in.readUByte(), in.readUByte());
|
||||
}
|
||||
public void serialize(int offset, byte[] data) {
|
||||
LittleEndian.putUShort(data, offset + 0, _firstRow);
|
||||
LittleEndian.putUShort(data, offset + 2, _lastRow);
|
||||
LittleEndian.putByte(data, offset + 4, _firstCol);
|
||||
LittleEndian.putByte(data, offset + 6, _lastCol);
|
||||
}
|
||||
|
||||
public int getFirstRow() {
|
||||
return _firstRow;
|
||||
}
|
||||
public int getLastRow() {
|
||||
return _lastRow;
|
||||
}
|
||||
public int getFirstColumn() {
|
||||
return _firstCol;
|
||||
}
|
||||
public int getLastColumn() {
|
||||
return _lastCol;
|
||||
}
|
||||
}
|
||||
private CellRangeAddress8Bit[] field_6_refs;
|
||||
|
||||
/**
|
||||
* Creates a default selection record (cell A1, in pane ID 3)
|
||||
*/
|
||||
public SelectionRecord(int activeCellRow, int activeCellCol) {
|
||||
field_1_pane = 3; // pane id 3 is always present. see OOO sec 5.75 'PANE'
|
||||
field_2_row_active_cell = activeCellRow;
|
||||
field_3_col_active_cell = activeCellCol;
|
||||
field_4_active_cell_ref_index = 0;
|
||||
field_6_refs = new Reference[] {
|
||||
new Reference(activeCellRow, activeCellRow, activeCellCol, activeCellCol),
|
||||
};
|
||||
field_1_pane = 3; // pane id 3 is always present. see OOO sec 5.75 'PANE'
|
||||
field_2_row_active_cell = activeCellRow;
|
||||
field_3_col_active_cell = activeCellCol;
|
||||
field_4_active_cell_ref_index = 0;
|
||||
field_6_refs = new CellRangeAddress8Bit[] {
|
||||
new CellRangeAddress8Bit(activeCellRow, activeCellRow, activeCellCol, activeCellCol),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Selection record and sets its fields appropriately.
|
||||
* @param in the RecordInputstream to read the record from
|
||||
*/
|
||||
|
||||
public SelectionRecord(RecordInputStream in) {
|
||||
super(in);
|
||||
}
|
||||
@ -112,10 +72,10 @@ public final class SelectionRecord extends Record {
|
||||
field_4_active_cell_ref_index = in.readShort();
|
||||
int field_5_num_refs = in.readUShort();
|
||||
|
||||
field_6_refs = new Reference[field_5_num_refs];
|
||||
field_6_refs = new CellRangeAddress8Bit[field_5_num_refs];
|
||||
for (int i = 0; i < field_6_refs.length; i++) {
|
||||
field_6_refs[i] = new Reference(in);
|
||||
}
|
||||
field_6_refs[i] = new CellRangeAddress8Bit(in);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -180,8 +140,7 @@ public final class SelectionRecord extends Record {
|
||||
return (short)field_4_active_cell_ref_index;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
buffer.append("[SELECTION]\n");
|
||||
@ -199,11 +158,11 @@ public final class SelectionRecord extends Record {
|
||||
return buffer.toString();
|
||||
}
|
||||
private int getDataSize() {
|
||||
return 9 // 1 byte + 4 shorts
|
||||
+ field_6_refs.length * Reference.ENCODED_SIZE;
|
||||
return 9 // 1 byte + 4 shorts
|
||||
+ CellRangeAddress8Bit.getEncodedSize(field_6_refs.length);
|
||||
}
|
||||
public int serialize(int offset, byte [] data) {
|
||||
int dataSize = getDataSize();
|
||||
int dataSize = getDataSize();
|
||||
LittleEndian.putUShort(data, 0 + offset, sid);
|
||||
LittleEndian.putUShort(data, 2 + offset, dataSize);
|
||||
LittleEndian.putByte(data, 4 + offset, getPane());
|
||||
@ -213,9 +172,9 @@ public final class SelectionRecord extends Record {
|
||||
int nRefs = field_6_refs.length;
|
||||
LittleEndian.putUShort(data, 11 + offset, nRefs);
|
||||
for (int i = 0; i < field_6_refs.length; i++) {
|
||||
Reference r = field_6_refs[i];
|
||||
r.serialize(offset + 13 + i * Reference.ENCODED_SIZE, data);
|
||||
}
|
||||
CellRangeAddress8Bit r = field_6_refs[i];
|
||||
r.serialize(offset + 13 + i * CellRangeAddress8Bit.ENCODED_SIZE, data);
|
||||
}
|
||||
return 4 + dataSize;
|
||||
}
|
||||
|
||||
|
@ -17,17 +17,16 @@
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.AreaNPtg;
|
||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.record.formula.RefNPtg;
|
||||
import org.apache.poi.hssf.record.formula.RefPtg;
|
||||
import org.apache.poi.hssf.util.CellRangeAddress8Bit;
|
||||
import org.apache.poi.util.HexDump;
|
||||
|
||||
/**
|
||||
* Title: SharedFormulaRecord
|
||||
* Title: SHAREDFMLA (0x04BC) SharedFormulaRecord
|
||||
* Description: Primarily used as an excel optimization so that multiple similar formulas
|
||||
* are not written out too many times. We should recognize this record and
|
||||
* serialize as is since this is used when reading templates.
|
||||
@ -40,58 +39,46 @@ import org.apache.poi.hssf.record.formula.RefPtg;
|
||||
public final class SharedFormulaRecord extends Record {
|
||||
public final static short sid = 0x04BC;
|
||||
|
||||
private int field_1_first_row;
|
||||
private int field_2_last_row;
|
||||
private short field_3_first_column;
|
||||
private short field_4_last_column;
|
||||
private int field_5_reserved;
|
||||
private short field_6_expression_len;
|
||||
private Stack field_7_parsed_expr;
|
||||
private CellRangeAddress8Bit _range;
|
||||
private int field_5_reserved;
|
||||
private Ptg[] field_7_parsed_expr;
|
||||
|
||||
public SharedFormulaRecord()
|
||||
{
|
||||
public SharedFormulaRecord() {
|
||||
_range = new CellRangeAddress8Bit(0, 0, 0, 0);
|
||||
field_7_parsed_expr = Ptg.EMPTY_PTG_ARRAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in the RecordInputstream to read the record from
|
||||
*/
|
||||
|
||||
public SharedFormulaRecord(RecordInputStream in)
|
||||
{
|
||||
public SharedFormulaRecord(RecordInputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
protected void validateSid(short id)
|
||||
{
|
||||
if (id != this.sid)
|
||||
{
|
||||
protected void validateSid(short id) {
|
||||
if (id != this.sid) {
|
||||
throw new RecordFormatException("Not a valid SharedFormula");
|
||||
}
|
||||
}
|
||||
|
||||
public int getFirstRow() {
|
||||
return field_1_first_row;
|
||||
return _range.getFirstRow();
|
||||
}
|
||||
|
||||
public int getLastRow() {
|
||||
return field_2_last_row;
|
||||
return _range.getLastRow();
|
||||
}
|
||||
|
||||
public short getFirstColumn() {
|
||||
return field_3_first_column;
|
||||
return (short) _range.getFirstColumn();
|
||||
}
|
||||
|
||||
public short getLastColumn() {
|
||||
return field_4_last_column;
|
||||
}
|
||||
|
||||
public short getExpressionLength()
|
||||
{
|
||||
return field_6_expression_len;
|
||||
return (short) _range.getLastColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
* spit the record out AS IS. no interperatation or identification
|
||||
* spit the record out AS IS. no interpretation or identification
|
||||
*/
|
||||
|
||||
public int serialize(int offset, byte [] data)
|
||||
@ -115,65 +102,28 @@ public final class SharedFormulaRecord extends Record {
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
buffer.append("[SHARED FORMULA RECORD:" + Integer.toHexString(sid) + "]\n");
|
||||
buffer.append(" .id = ").append(Integer.toHexString(sid))
|
||||
.append("\n");
|
||||
buffer.append(" .first_row = ")
|
||||
.append(Integer.toHexString(getFirstRow())).append("\n");
|
||||
buffer.append(" .last_row = ")
|
||||
.append(Integer.toHexString(getLastRow()))
|
||||
.append("\n");
|
||||
buffer.append(" .first_column = ")
|
||||
.append(Integer.toHexString(getFirstColumn())).append("\n");
|
||||
buffer.append(" .last_column = ")
|
||||
.append(Integer.toHexString(getLastColumn()))
|
||||
.append("\n");
|
||||
buffer.append(" .reserved = ")
|
||||
.append(Integer.toHexString(field_5_reserved))
|
||||
.append("\n");
|
||||
buffer.append(" .expressionlength= ").append(getExpressionLength())
|
||||
.append("\n");
|
||||
buffer.append("[SHARED FORMULA (").append(HexDump.intToHex(sid)).append("]\n");
|
||||
buffer.append(" .range = ").append(_range.toString()).append("\n");
|
||||
buffer.append(" .reserved = ").append(HexDump.shortToHex(field_5_reserved)).append("\n");
|
||||
|
||||
buffer.append(" .numptgsinarray = ").append(field_7_parsed_expr.size())
|
||||
.append("\n");
|
||||
|
||||
for (int k = 0; k < field_7_parsed_expr.size(); k++ ) {
|
||||
buffer.append("Formula ")
|
||||
.append(k)
|
||||
.append("\n")
|
||||
.append(field_7_parsed_expr.get(k).toString())
|
||||
.append("\n");
|
||||
for (int k = 0; k < field_7_parsed_expr.length; k++ ) {
|
||||
buffer.append("Formula[").append(k).append("]");
|
||||
buffer.append(field_7_parsed_expr[k].toString()).append("\n");
|
||||
}
|
||||
|
||||
buffer.append("[/SHARED FORMULA RECORD]\n");
|
||||
buffer.append("[/SHARED FORMULA]\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public short getSid()
|
||||
{
|
||||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
protected void fillFields(RecordInputStream in)
|
||||
{
|
||||
field_1_first_row = in.readUShort();
|
||||
field_2_last_row = in.readUShort();
|
||||
field_3_first_column = in.readUByte();
|
||||
field_4_last_column = in.readUByte();
|
||||
field_5_reserved = in.readShort();
|
||||
field_6_expression_len = in.readShort();
|
||||
field_7_parsed_expr = getParsedExpressionTokens(in);
|
||||
}
|
||||
|
||||
private Stack getParsedExpressionTokens(RecordInputStream in)
|
||||
{
|
||||
Stack stack = new Stack();
|
||||
|
||||
while (in.remaining() != 0) {
|
||||
Ptg ptg = Ptg.createPtg(in);
|
||||
stack.push(ptg);
|
||||
}
|
||||
return stack;
|
||||
protected void fillFields(RecordInputStream in) {
|
||||
_range = new CellRangeAddress8Bit(in);
|
||||
field_5_reserved = in.readShort();
|
||||
int field_6_expression_len = in.readShort();
|
||||
field_7_parsed_expr = Ptg.readTokens(field_6_expression_len, in);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,7 +140,7 @@ public final class SharedFormulaRecord extends Record {
|
||||
* Creates a non shared formula from the shared formula
|
||||
* counter part
|
||||
*/
|
||||
protected static Stack convertSharedFormulas(Stack ptgs, int formulaRow, int formulaColumn) {
|
||||
protected static Ptg[] convertSharedFormulas(Ptg[] ptgs, int formulaRow, int formulaColumn) {
|
||||
if(false) {
|
||||
/*
|
||||
* TODO - (May-2008) Stop converting relative ref Ptgs in shared formula records.
|
||||
@ -201,11 +151,10 @@ public final class SharedFormulaRecord extends Record {
|
||||
*/
|
||||
return ptgs;
|
||||
}
|
||||
Stack newPtgStack = new Stack();
|
||||
Ptg[] newPtgStack = new Ptg[ptgs.length];
|
||||
|
||||
if (ptgs != null)
|
||||
for (int k = 0; k < ptgs.size(); k++) {
|
||||
Ptg ptg = (Ptg) ptgs.get(k);
|
||||
for (int k = 0; k < ptgs.length; k++) {
|
||||
Ptg ptg = ptgs[k];
|
||||
byte originalOperandClass = -1;
|
||||
if (!ptg.isBaseToken()) {
|
||||
originalOperandClass = ptg.getPtgClass();
|
||||
@ -226,12 +175,16 @@ public final class SharedFormulaRecord extends Record {
|
||||
areaNPtg.isLastRowRelative(),
|
||||
areaNPtg.isFirstColRelative(),
|
||||
areaNPtg.isLastColRelative());
|
||||
} else {
|
||||
if (false) {// do we need a ptg clone here?
|
||||
ptg = ptg.copy();
|
||||
}
|
||||
}
|
||||
if (!ptg.isBaseToken()) {
|
||||
ptg.setClass(originalOperandClass);
|
||||
}
|
||||
|
||||
newPtgStack.add(ptg);
|
||||
newPtgStack[k] = ptg;
|
||||
}
|
||||
return newPtgStack;
|
||||
}
|
||||
@ -248,9 +201,7 @@ public final class SharedFormulaRecord extends Record {
|
||||
final int formulaRow = formula.getRow();
|
||||
final int formulaColumn = formula.getColumn();
|
||||
|
||||
List ptgList = convertSharedFormulas(field_7_parsed_expr, formulaRow, formulaColumn);
|
||||
Ptg[] ptgs = new Ptg[ptgList.size()];
|
||||
ptgList.toArray(ptgs);
|
||||
Ptg[] ptgs = convertSharedFormulas(field_7_parsed_expr, formulaRow, formulaColumn);
|
||||
formula.setParsedExpression(ptgs);
|
||||
//Now its not shared!
|
||||
formula.setSharedFormula(false);
|
||||
|
@ -18,47 +18,46 @@
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.TblPtg;
|
||||
import org.apache.poi.hssf.util.CellRangeAddress8Bit;
|
||||
import org.apache.poi.hssf.util.CellReference;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
/**
|
||||
* DATATABLE (0x0236)<p/>
|
||||
*
|
||||
* TableRecord - The record specifies a data table.
|
||||
* This record is preceded by a single Formula record that
|
||||
* defines the first cell in the data table, which should
|
||||
* only contain a single Ptg, {@link TblPtg}.
|
||||
*
|
||||
*
|
||||
* See p536 of the June 08 binary docs
|
||||
*/
|
||||
public final class TableRecord extends Record {
|
||||
public static final short sid = 566;
|
||||
|
||||
private static final BitField alwaysCalc = BitFieldFactory.getInstance(0x0001);
|
||||
private static final BitField reserved1 = BitFieldFactory.getInstance(0x0002);
|
||||
private static final BitField rowOrColInpCell = BitFieldFactory.getInstance(0x0004);
|
||||
private static final BitField oneOrTwoVar = BitFieldFactory.getInstance(0x0008);
|
||||
private static final BitField rowDeleted = BitFieldFactory.getInstance(0x0010);
|
||||
private static final BitField colDeleted = BitFieldFactory.getInstance(0x0020);
|
||||
private static final BitField reserved2 = BitFieldFactory.getInstance(0x0040);
|
||||
private static final BitField reserved3 = BitFieldFactory.getInstance(0x0080);
|
||||
|
||||
private short field_1_ref_rowFirst;
|
||||
private short field_2_ref_rowLast;
|
||||
private short field_3_ref_colFirst;
|
||||
private short field_4_ref_colLast;
|
||||
|
||||
private byte field_5_flags;
|
||||
private byte field_6_res;
|
||||
private short field_7_rowInputRow;
|
||||
private short field_8_colInputRow;
|
||||
private short field_9_rowInputCol;
|
||||
private short field_10_colInputCol;
|
||||
|
||||
public static final short sid = 0x0236;
|
||||
|
||||
private static final BitField alwaysCalc = BitFieldFactory.getInstance(0x0001);
|
||||
private static final BitField reserved1 = BitFieldFactory.getInstance(0x0002);
|
||||
private static final BitField rowOrColInpCell = BitFieldFactory.getInstance(0x0004);
|
||||
private static final BitField oneOrTwoVar = BitFieldFactory.getInstance(0x0008);
|
||||
private static final BitField rowDeleted = BitFieldFactory.getInstance(0x0010);
|
||||
private static final BitField colDeleted = BitFieldFactory.getInstance(0x0020);
|
||||
private static final BitField reserved2 = BitFieldFactory.getInstance(0x0040);
|
||||
private static final BitField reserved3 = BitFieldFactory.getInstance(0x0080);
|
||||
|
||||
private CellRangeAddress8Bit _range;
|
||||
|
||||
private int field_5_flags;
|
||||
private int field_6_res;
|
||||
private int field_7_rowInputRow;
|
||||
private int field_8_colInputRow;
|
||||
private int field_9_rowInputCol;
|
||||
private int field_10_colInputCol;
|
||||
|
||||
|
||||
protected void fillFields(RecordInputStream in) {
|
||||
field_1_ref_rowFirst = in.readShort();
|
||||
field_2_ref_rowLast = in.readShort();
|
||||
field_3_ref_colFirst = in.readUByte();
|
||||
field_4_ref_colLast = in.readUByte();
|
||||
_range = new CellRangeAddress8Bit(in);
|
||||
field_5_flags = in.readByte();
|
||||
field_6_res = in.readByte();
|
||||
field_7_rowInputRow = in.readShort();
|
||||
@ -66,183 +65,146 @@ public final class TableRecord extends Record {
|
||||
field_9_rowInputCol = in.readShort();
|
||||
field_10_colInputCol = in.readShort();
|
||||
}
|
||||
|
||||
public TableRecord(RecordInputStream in) {
|
||||
super(in);
|
||||
}
|
||||
public TableRecord() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public short getRowFirst() {
|
||||
return field_1_ref_rowFirst;
|
||||
public TableRecord(RecordInputStream in) {
|
||||
super(in);
|
||||
}
|
||||
public void setRowFirst(short field_1_ref_rowFirst) {
|
||||
this.field_1_ref_rowFirst = field_1_ref_rowFirst;
|
||||
public TableRecord(CellRangeAddress8Bit range) {
|
||||
_range = range;
|
||||
field_6_res = 0;
|
||||
}
|
||||
|
||||
public short getRowLast() {
|
||||
return field_2_ref_rowLast;
|
||||
}
|
||||
public void setRowLast(short field_2_ref_rowLast) {
|
||||
this.field_2_ref_rowLast = field_2_ref_rowLast;
|
||||
public CellRangeAddress8Bit getRange() {
|
||||
return _range;
|
||||
}
|
||||
|
||||
public short getColFirst() {
|
||||
return field_3_ref_colFirst;
|
||||
}
|
||||
public void setColFirst(short field_3_ref_colFirst) {
|
||||
this.field_3_ref_colFirst = field_3_ref_colFirst;
|
||||
}
|
||||
|
||||
public short getColLast() {
|
||||
return field_4_ref_colLast;
|
||||
}
|
||||
public void setColLast(short field_4_ref_colLast) {
|
||||
this.field_4_ref_colLast = field_4_ref_colLast;
|
||||
}
|
||||
|
||||
public byte getFlags() {
|
||||
public int getFlags() {
|
||||
return field_5_flags;
|
||||
}
|
||||
public void setFlags(byte field_5_flags) {
|
||||
this.field_5_flags = field_5_flags;
|
||||
public void setFlags(int flags) {
|
||||
field_5_flags = flags;
|
||||
}
|
||||
|
||||
public byte getReserved() {
|
||||
return field_6_res;
|
||||
}
|
||||
public void setReserved(byte field_6_res) {
|
||||
this.field_6_res = field_6_res;
|
||||
}
|
||||
|
||||
public short getRowInputRow() {
|
||||
public int getRowInputRow() {
|
||||
return field_7_rowInputRow;
|
||||
}
|
||||
public void setRowInputRow(short field_7_rowInputRow) {
|
||||
this.field_7_rowInputRow = field_7_rowInputRow;
|
||||
public void setRowInputRow(int rowInputRow) {
|
||||
field_7_rowInputRow = rowInputRow;
|
||||
}
|
||||
|
||||
public short getColInputRow() {
|
||||
public int getColInputRow() {
|
||||
return field_8_colInputRow;
|
||||
}
|
||||
public void setColInputRow(short field_8_colInputRow) {
|
||||
this.field_8_colInputRow = field_8_colInputRow;
|
||||
public void setColInputRow(int colInputRow) {
|
||||
field_8_colInputRow = colInputRow;
|
||||
}
|
||||
|
||||
public short getRowInputCol() {
|
||||
public int getRowInputCol() {
|
||||
return field_9_rowInputCol;
|
||||
}
|
||||
public void setRowInputCol(short field_9_rowInputCol) {
|
||||
this.field_9_rowInputCol = field_9_rowInputCol;
|
||||
public void setRowInputCol(int rowInputCol) {
|
||||
field_9_rowInputCol = rowInputCol;
|
||||
}
|
||||
|
||||
public short getColInputCol() {
|
||||
public int getColInputCol() {
|
||||
return field_10_colInputCol;
|
||||
}
|
||||
public void setColInputCol(short field_10_colInputCol) {
|
||||
this.field_10_colInputCol = field_10_colInputCol;
|
||||
public void setColInputCol(int colInputCol) {
|
||||
field_10_colInputCol = colInputCol;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public boolean isAlwaysCalc() {
|
||||
return alwaysCalc.isSet(field_5_flags);
|
||||
}
|
||||
public void setAlwaysCalc(boolean flag) {
|
||||
field_5_flags = alwaysCalc.setByteBoolean(field_5_flags, flag);
|
||||
field_5_flags = alwaysCalc.setBoolean(field_5_flags, flag);
|
||||
}
|
||||
|
||||
|
||||
public boolean isRowOrColInpCell() {
|
||||
return rowOrColInpCell.isSet(field_5_flags);
|
||||
}
|
||||
public void setRowOrColInpCell(boolean flag) {
|
||||
field_5_flags = rowOrColInpCell.setByteBoolean(field_5_flags, flag);
|
||||
field_5_flags = rowOrColInpCell.setBoolean(field_5_flags, flag);
|
||||
}
|
||||
|
||||
|
||||
public boolean isOneNotTwoVar() {
|
||||
return oneOrTwoVar.isSet(field_5_flags);
|
||||
}
|
||||
public void setOneNotTwoVar(boolean flag) {
|
||||
field_5_flags = oneOrTwoVar.setByteBoolean(field_5_flags, flag);
|
||||
field_5_flags = oneOrTwoVar.setBoolean(field_5_flags, flag);
|
||||
}
|
||||
|
||||
|
||||
public boolean isColDeleted() {
|
||||
return colDeleted.isSet(field_5_flags);
|
||||
}
|
||||
public void setColDeleted(boolean flag) {
|
||||
field_5_flags = colDeleted.setByteBoolean(field_5_flags, flag);
|
||||
field_5_flags = colDeleted.setBoolean(field_5_flags, flag);
|
||||
}
|
||||
|
||||
|
||||
public boolean isRowDeleted() {
|
||||
return rowDeleted.isSet(field_5_flags);
|
||||
}
|
||||
public void setRowDeleted(boolean flag) {
|
||||
field_5_flags = rowDeleted.setByteBoolean(field_5_flags, flag);
|
||||
field_5_flags = rowDeleted.setBoolean(field_5_flags, flag);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
public int serialize(int offset, byte[] data) {
|
||||
LittleEndian.putShort(data, 0 + offset, sid);
|
||||
LittleEndian.putShort(data, 2 + offset, ( short ) (16));
|
||||
|
||||
LittleEndian.putShort(data, 4 + offset, field_1_ref_rowFirst);
|
||||
LittleEndian.putShort(data, 6 + offset, field_2_ref_rowLast);
|
||||
LittleEndian.putByte(data, 8 + offset, field_3_ref_colFirst);
|
||||
LittleEndian.putByte(data, 9 + offset, field_4_ref_colLast);
|
||||
LittleEndian.putByte(data, 10 + offset, field_5_flags);
|
||||
LittleEndian.putByte(data, 11 + offset, field_6_res);
|
||||
LittleEndian.putShort(data, 12 + offset, field_7_rowInputRow);
|
||||
LittleEndian.putShort(data, 14 + offset, field_8_colInputRow);
|
||||
LittleEndian.putShort(data, 16 + offset, field_9_rowInputCol);
|
||||
LittleEndian.putShort(data, 18 + offset, field_10_colInputCol);
|
||||
|
||||
return getRecordSize();
|
||||
int dataSize = getDataSize();
|
||||
LittleEndian.putShort(data, 0 + offset, sid);
|
||||
LittleEndian.putUShort(data, 2 + offset, dataSize);
|
||||
|
||||
_range.serialize(4 + offset, data);
|
||||
LittleEndian.putByte(data, 10 + offset, field_5_flags);
|
||||
LittleEndian.putByte(data, 11 + offset, field_6_res);
|
||||
LittleEndian.putUShort(data, 12 + offset, field_7_rowInputRow);
|
||||
LittleEndian.putUShort(data, 14 + offset, field_8_colInputRow);
|
||||
LittleEndian.putUShort(data, 16 + offset, field_9_rowInputCol);
|
||||
LittleEndian.putUShort(data, 18 + offset, field_10_colInputCol);
|
||||
|
||||
return 4 + dataSize;
|
||||
}
|
||||
private int getDataSize() {
|
||||
return CellRangeAddress8Bit.ENCODED_SIZE
|
||||
+ 2 // 2 byte fields
|
||||
+ 8; // 4 short fields
|
||||
}
|
||||
|
||||
public int getRecordSize() {
|
||||
return 4+16;
|
||||
return 4+getDataSize();
|
||||
}
|
||||
|
||||
|
||||
protected void validateSid(short id) {
|
||||
if (id != sid)
|
||||
{
|
||||
throw new RecordFormatException("NOT A TABLE RECORD");
|
||||
}
|
||||
if (id != sid)
|
||||
{
|
||||
throw new RecordFormatException("NOT A TABLE RECORD");
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("[TABLE]\n");
|
||||
buffer.append(" .range = ").append(_range.toString()).append("\n");
|
||||
buffer.append(" .flags = ") .append(HexDump.byteToHex(field_5_flags)).append("\n");
|
||||
buffer.append(" .alwaysClc= ").append(isAlwaysCalc()).append("\n");
|
||||
buffer.append(" .reserved = ").append(HexDump.intToHex(field_6_res)).append("\n");
|
||||
CellReference crRowInput = cr(field_7_rowInputRow, field_8_colInputRow);
|
||||
CellReference crColInput = cr(field_9_rowInputCol, field_10_colInputCol);
|
||||
buffer.append(" .rowInput = ").append(crRowInput.formatAsString()).append("\n");
|
||||
buffer.append(" .colInput = ").append(crColInput.formatAsString()).append("\n");
|
||||
buffer.append("[/TABLE]\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private static CellReference cr(int rowIx, int colIxAndFlags) {
|
||||
int colIx = colIxAndFlags & 0x00FF;
|
||||
boolean isRowAbs = (colIxAndFlags & 0x8000) == 0;
|
||||
boolean isColAbs = (colIxAndFlags & 0x4000) == 0;
|
||||
return new CellReference(rowIx, colIx, isRowAbs, isColAbs);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("[TABLE]\n");
|
||||
buffer.append(" .row from = ")
|
||||
.append(Integer.toHexString(field_1_ref_rowFirst)).append("\n");
|
||||
buffer.append(" .row to = ")
|
||||
.append(Integer.toHexString(field_2_ref_rowLast)).append("\n");
|
||||
buffer.append(" .column from = ")
|
||||
.append(Integer.toHexString(field_3_ref_colFirst)).append("\n");
|
||||
buffer.append(" .column to = ")
|
||||
.append(Integer.toHexString(field_4_ref_colLast)).append("\n");
|
||||
|
||||
buffer.append(" .flags = ")
|
||||
.append(Integer.toHexString(field_5_flags)).append("\n");
|
||||
buffer.append(" .always calc =")
|
||||
.append(isAlwaysCalc()).append("\n");
|
||||
|
||||
buffer.append(" .reserved = ")
|
||||
.append(Integer.toHexString(field_6_res)).append("\n");
|
||||
buffer.append(" .row input row = ")
|
||||
.append(Integer.toHexString(field_7_rowInputRow)).append("\n");
|
||||
buffer.append(" .col input row = ")
|
||||
.append(Integer.toHexString(field_8_colInputRow)).append("\n");
|
||||
buffer.append(" .row input col = ")
|
||||
.append(Integer.toHexString(field_9_rowInputCol)).append("\n");
|
||||
buffer.append(" .col input col = ")
|
||||
.append(Integer.toHexString(field_10_colInputCol)).append("\n");
|
||||
buffer.append("[/TABLE]\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
@ -26,153 +26,41 @@ import org.apache.poi.util.LittleEndian;
|
||||
* Note - {@link SelectionRecord} uses the BIFF5 version of this structure
|
||||
* @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
|
||||
*/
|
||||
public final class CellRangeAddress {
|
||||
public final class CellRangeAddress extends CellRangeAddressBase {
|
||||
/*
|
||||
* TODO - replace org.apache.poi.hssf.util.Region
|
||||
*/
|
||||
public static final int ENCODED_SIZE = 8;
|
||||
|
||||
/** max 65536 rows in BIFF8 */
|
||||
private static final int LAST_ROW_INDEX = 0x00FFFF;
|
||||
/** max 256 columns in BIFF8 */
|
||||
private static final int LAST_COLUMN_INDEX = 0x00FF;
|
||||
|
||||
|
||||
private int _firstRow;
|
||||
private int _firstCol;
|
||||
private int _lastRow;
|
||||
private int _lastCol;
|
||||
|
||||
public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) {
|
||||
if(!isValid(firstRow, lastRow, firstCol, lastCol)) {
|
||||
throw new IllegalArgumentException("invalid cell range (" + firstRow + ", " + lastRow
|
||||
+ ", " + firstCol + ", " + lastCol + ")");
|
||||
}
|
||||
_firstRow = firstRow;
|
||||
_lastRow = convertM1ToMax(lastRow, LAST_ROW_INDEX);
|
||||
_firstCol = firstCol;
|
||||
_lastCol = convertM1ToMax(lastCol, LAST_COLUMN_INDEX);
|
||||
super(firstRow, lastRow, firstCol, lastCol);
|
||||
}
|
||||
private static boolean isValid(int firstRow, int lastRow, int firstColumn, int lastColumn)
|
||||
{
|
||||
if(lastRow < 0 || lastRow > LAST_ROW_INDEX) {
|
||||
return false;
|
||||
}
|
||||
if(firstRow < 0 || firstRow > LAST_ROW_INDEX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(lastColumn < 0 || lastColumn > LAST_COLUMN_INDEX) {
|
||||
return false;
|
||||
}
|
||||
if(firstColumn < 0 || firstColumn > LAST_COLUMN_INDEX) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Range arithmetic is easier when using a large positive number for 'max row or column'
|
||||
* instead of <tt>-1</tt>.
|
||||
*/
|
||||
private static int convertM1ToMax(int lastIx, int maxIndex) {
|
||||
if(lastIx < 0) {
|
||||
return maxIndex;
|
||||
}
|
||||
return lastIx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public CellRangeAddress(RecordInputStream in) {
|
||||
super(readUShortAndCheck(in), in.readUShort(), in.readUShort(), in.readUShort());
|
||||
}
|
||||
|
||||
private static int readUShortAndCheck(RecordInputStream in) {
|
||||
if (in.remaining() < ENCODED_SIZE) {
|
||||
// Ran out of data
|
||||
throw new RuntimeException("Ran out of data reading CellRangeAddress");
|
||||
}
|
||||
_firstRow = in.readUShort();
|
||||
_lastRow = in.readUShort();
|
||||
_firstCol = in.readUShort();
|
||||
_lastCol = in.readUShort();
|
||||
}
|
||||
public boolean isFullColumnRange() {
|
||||
return _firstRow == 0 && _lastRow == LAST_ROW_INDEX;
|
||||
}
|
||||
public boolean isFullRowRange() {
|
||||
return _firstCol == 0 && _lastCol == LAST_COLUMN_INDEX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return column number for the upper left hand corner
|
||||
*/
|
||||
public int getFirstColumn() {
|
||||
return _firstCol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return row number for the upper left hand corner
|
||||
*/
|
||||
public int getFirstRow() {
|
||||
return _firstRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return column number for the lower right hand corner
|
||||
*/
|
||||
public int getLastColumn() {
|
||||
return _lastCol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return row number for the lower right hand corner
|
||||
*/
|
||||
public int getLastRow() {
|
||||
return _lastRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param _firstCol column number for the upper left hand corner
|
||||
*/
|
||||
public void setFirstColumn(int firstCol) {
|
||||
_firstCol = firstCol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rowFrom row number for the upper left hand corner
|
||||
*/
|
||||
public void setFirstRow(int firstRow) {
|
||||
_firstRow = firstRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param colTo column number for the lower right hand corner
|
||||
*/
|
||||
public void setLastColumn(int lastCol) {
|
||||
_lastCol = lastCol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rowTo row number for the lower right hand corner
|
||||
*/
|
||||
public void setLastRow(int lastRow) {
|
||||
_lastRow = lastRow;
|
||||
}
|
||||
return in.readUShort();
|
||||
}
|
||||
|
||||
public int serialize(int offset, byte[] data) {
|
||||
LittleEndian.putUShort(data, offset + 0, _firstRow);
|
||||
LittleEndian.putUShort(data, offset + 2, _lastRow);
|
||||
LittleEndian.putUShort(data, offset + 4, _firstCol);
|
||||
LittleEndian.putUShort(data, offset + 6, _lastCol);
|
||||
LittleEndian.putUShort(data, offset + 0, getFirstRow());
|
||||
LittleEndian.putUShort(data, offset + 2, getLastRow());
|
||||
LittleEndian.putUShort(data, offset + 4, getFirstColumn());
|
||||
LittleEndian.putUShort(data, offset + 6, getLastColumn());
|
||||
return ENCODED_SIZE;
|
||||
}
|
||||
|
||||
public CellRangeAddress copy() {
|
||||
return new CellRangeAddress(_firstRow, _lastRow, _firstCol, _lastCol);
|
||||
return new CellRangeAddress(getFirstRow(), getLastRow(), getFirstColumn(), getLastColumn());
|
||||
}
|
||||
|
||||
public static int getEncodedSize(int numberOfItems) {
|
||||
return numberOfItems * ENCODED_SIZE;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getClass().getName() + " ["+_firstRow+", "+_lastRow+", "+_firstCol+", "+_lastCol+"]";
|
||||
}
|
||||
}
|
64
src/java/org/apache/poi/hssf/util/CellRangeAddress8Bit.java
Normal file
64
src/java/org/apache/poi/hssf/util/CellRangeAddress8Bit.java
Normal file
@ -0,0 +1,64 @@
|
||||
/* ====================================================================
|
||||
Copyright 2002-2004 Apache Software Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.util;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
|
||||
*
|
||||
* Like {@link CellRangeAddress} except column fields are 8-bit.
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public final class CellRangeAddress8Bit extends CellRangeAddressBase {
|
||||
|
||||
public static final int ENCODED_SIZE = 6;
|
||||
|
||||
public CellRangeAddress8Bit(int firstRow, int lastRow, int firstCol, int lastCol) {
|
||||
super(firstRow, lastRow, firstCol, lastCol);
|
||||
}
|
||||
|
||||
public CellRangeAddress8Bit(RecordInputStream in) {
|
||||
super(readUShortAndCheck(in), in.readUShort(), in.readUByte(), in.readUByte());
|
||||
}
|
||||
|
||||
private static int readUShortAndCheck(RecordInputStream in) {
|
||||
if (in.remaining() < ENCODED_SIZE) {
|
||||
// Ran out of data
|
||||
throw new RuntimeException("Ran out of data reading CellRangeAddress");
|
||||
}
|
||||
return in.readUShort();
|
||||
}
|
||||
|
||||
public int serialize(int offset, byte[] data) {
|
||||
LittleEndian.putUShort(data, offset + 0, getFirstRow());
|
||||
LittleEndian.putUShort(data, offset + 2, getLastRow());
|
||||
LittleEndian.putByte(data, offset + 4, getFirstColumn());
|
||||
LittleEndian.putByte(data, offset + 5, getLastColumn());
|
||||
return ENCODED_SIZE;
|
||||
}
|
||||
|
||||
public CellRangeAddress8Bit copy() {
|
||||
return new CellRangeAddress8Bit(getFirstRow(), getLastRow(), getFirstColumn(), getLastColumn());
|
||||
}
|
||||
|
||||
public static int getEncodedSize(int numberOfItems) {
|
||||
return numberOfItems * ENCODED_SIZE;
|
||||
}
|
||||
}
|
134
src/java/org/apache/poi/hssf/util/CellRangeAddressBase.java
Normal file
134
src/java/org/apache/poi/hssf/util/CellRangeAddressBase.java
Normal file
@ -0,0 +1,134 @@
|
||||
/* ====================================================================
|
||||
Copyright 2002-2004 Apache Software Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.hssf.util;
|
||||
|
||||
|
||||
/**
|
||||
* See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
|
||||
*
|
||||
* Common subclass of 8-bit and 16-bit versions
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
abstract class CellRangeAddressBase {
|
||||
|
||||
/** max 65536 rows in BIFF8 */
|
||||
private static final int LAST_ROW_INDEX = 0x00FFFF;
|
||||
/** max 256 columns in BIFF8 */
|
||||
private static final int LAST_COLUMN_INDEX = 0x00FF;
|
||||
|
||||
private int _firstRow;
|
||||
private int _firstCol;
|
||||
private int _lastRow;
|
||||
private int _lastCol;
|
||||
|
||||
protected CellRangeAddressBase(int firstRow, int lastRow, int firstCol, int lastCol) {
|
||||
if(!isValid(firstRow, lastRow, firstCol, lastCol)) {
|
||||
throw new IllegalArgumentException("invalid cell range (" + firstRow + ", " + lastRow
|
||||
+ ", " + firstCol + ", " + lastCol + ")");
|
||||
}
|
||||
_firstRow = firstRow;
|
||||
_lastRow =lastRow;
|
||||
_firstCol = firstCol;
|
||||
_lastCol = lastCol;
|
||||
}
|
||||
private static boolean isValid(int firstRow, int lastRow, int firstColumn, int lastColumn)
|
||||
{
|
||||
if(lastRow < 0 || lastRow > LAST_ROW_INDEX) {
|
||||
return false;
|
||||
}
|
||||
if(firstRow < 0 || firstRow > LAST_ROW_INDEX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(lastColumn < 0 || lastColumn > LAST_COLUMN_INDEX) {
|
||||
return false;
|
||||
}
|
||||
if(firstColumn < 0 || firstColumn > LAST_COLUMN_INDEX) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public final boolean isFullColumnRange() {
|
||||
return _firstRow == 0 && _lastRow == LAST_ROW_INDEX;
|
||||
}
|
||||
public final boolean isFullRowRange() {
|
||||
return _firstCol == 0 && _lastCol == LAST_COLUMN_INDEX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return column number for the upper left hand corner
|
||||
*/
|
||||
public final int getFirstColumn() {
|
||||
return _firstCol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return row number for the upper left hand corner
|
||||
*/
|
||||
public final int getFirstRow() {
|
||||
return _firstRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return column number for the lower right hand corner
|
||||
*/
|
||||
public final int getLastColumn() {
|
||||
return _lastCol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return row number for the lower right hand corner
|
||||
*/
|
||||
public final int getLastRow() {
|
||||
return _lastRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param _firstCol column number for the upper left hand corner
|
||||
*/
|
||||
public final void setFirstColumn(int firstCol) {
|
||||
_firstCol = firstCol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rowFrom row number for the upper left hand corner
|
||||
*/
|
||||
public final void setFirstRow(int firstRow) {
|
||||
_firstRow = firstRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param colTo column number for the lower right hand corner
|
||||
*/
|
||||
public final void setLastColumn(int lastCol) {
|
||||
_lastCol = lastCol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rowTo row number for the lower right hand corner
|
||||
*/
|
||||
public final void setLastRow(int lastRow) {
|
||||
_lastRow = lastRow;
|
||||
}
|
||||
|
||||
public final String toString() {
|
||||
return getClass().getName() + " ["+_firstRow+", "+_lastRow+", "+_firstCol+", "+_lastCol+"]";
|
||||
}
|
||||
}
|
@ -17,9 +17,6 @@
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
import junit.framework.ComparisonFailure;
|
||||
import junit.framework.TestCase;
|
||||
@ -63,18 +60,18 @@ public final class TestSharedFormulaRecord extends TestCase {
|
||||
public void testConvertSharedFormulasOperandClasses_bug45123() {
|
||||
|
||||
TestcaseRecordInputStream in = new TestcaseRecordInputStream(0, SHARED_FORMULA_WITH_REF_ARRAYS_DATA);
|
||||
short encodedLen = in.readShort();
|
||||
Stack sharedFormula = Ptg.createParsedExpressionTokens(encodedLen, in);
|
||||
int encodedLen = in.readUShort();
|
||||
Ptg[] sharedFormula = Ptg.readTokens(encodedLen, in);
|
||||
|
||||
Stack convertedFormula = SharedFormulaRecord.convertSharedFormulas(sharedFormula, 100, 200);
|
||||
Ptg[] convertedFormula = SharedFormulaRecord.convertSharedFormulas(sharedFormula, 100, 200);
|
||||
|
||||
RefPtg refPtg = (RefPtg) convertedFormula.get(1);
|
||||
RefPtg refPtg = (RefPtg) convertedFormula[1];
|
||||
assertEquals("$C101", refPtg.toFormulaString(null));
|
||||
if (refPtg.getPtgClass() == Ptg.CLASS_REF) {
|
||||
throw new AssertionFailedError("Identified bug 45123");
|
||||
}
|
||||
|
||||
confirmOperandClasses(toPtgArray(sharedFormula), toPtgArray(convertedFormula));
|
||||
confirmOperandClasses(sharedFormula, convertedFormula);
|
||||
}
|
||||
|
||||
private static void confirmOperandClasses(Ptg[] originalPtgs, Ptg[] convertedPtgs) {
|
||||
@ -88,10 +85,4 @@ public final class TestSharedFormulaRecord extends TestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Ptg[] toPtgArray(List list) {
|
||||
Ptg[] result = new Ptg[list.size()];
|
||||
list.toArray(result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -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,9 +14,10 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.hssf.util.CellRangeAddress8Bit;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@ -26,48 +26,40 @@ import junit.framework.TestCase;
|
||||
* class works correctly. Test data taken directly from a real
|
||||
* Excel file.
|
||||
*/
|
||||
public class TestTableRecord
|
||||
extends TestCase
|
||||
{
|
||||
public final class TestTableRecord extends TestCase {
|
||||
byte[] header = new byte[] {
|
||||
0x36, 02, 0x10, 00, // sid=x236, 16 bytes long
|
||||
0x36, 02, 0x10, 00, // sid=x236, 16 bytes long
|
||||
};
|
||||
byte[] data = new byte[] {
|
||||
03, 00, // from row 3
|
||||
8, 00, // to row 8
|
||||
04, // from col 4
|
||||
06, // to col 6
|
||||
00, 00, // no flags set
|
||||
04, 00, // row inp row 4
|
||||
01, 00, // col inp row 1
|
||||
0x76, 0x40, // row inp col 0x4076 (!)
|
||||
00, 00 // col inp col 0
|
||||
};
|
||||
byte[] data = new byte[] {
|
||||
03, 00, // from row 3
|
||||
8, 00, // to row 8
|
||||
04, // from col 4
|
||||
06, // to col 6
|
||||
00, 00, // no flags set
|
||||
04, 00, // row inp row 4
|
||||
01, 00, // col inp row 1
|
||||
0x76, 0x40, // row inp col 0x4076 (!)
|
||||
00, 00 // col inp col 0
|
||||
};
|
||||
|
||||
public TestTableRecord(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
public void testLoad() {
|
||||
|
||||
public void testLoad()
|
||||
throws Exception
|
||||
{
|
||||
TableRecord record = new TableRecord(new TestcaseRecordInputStream((short)0x236, (short)data.length, data));
|
||||
|
||||
TableRecord record = new TableRecord(new TestcaseRecordInputStream((short)0x236, (short)data.length, data));
|
||||
CellRangeAddress8Bit range = record.getRange();
|
||||
assertEquals(3, range.getFirstRow());
|
||||
assertEquals(8, range.getLastRow());
|
||||
assertEquals(4, range.getFirstColumn());
|
||||
assertEquals(6, range.getLastColumn());
|
||||
assertEquals(0, record.getFlags());
|
||||
assertEquals(4, record.getRowInputRow());
|
||||
assertEquals(1, record.getColInputRow());
|
||||
assertEquals(0x4076, record.getRowInputCol());
|
||||
assertEquals(0, record.getColInputCol());
|
||||
|
||||
assertEquals(3, record.getRowFirst());
|
||||
assertEquals(8, record.getRowLast());
|
||||
assertEquals(4, record.getColFirst());
|
||||
assertEquals(6, record.getColLast());
|
||||
assertEquals(0, record.getFlags());
|
||||
assertEquals(4, record.getRowInputRow());
|
||||
assertEquals(1, record.getColInputRow());
|
||||
assertEquals(0x4076, record.getRowInputCol());
|
||||
assertEquals(0, record.getColInputCol());
|
||||
|
||||
assertEquals( 16 + 4, record.getRecordSize() );
|
||||
record.validateSid((short)0x236);
|
||||
}
|
||||
assertEquals( 16 + 4, record.getRecordSize() );
|
||||
record.validateSid((short)0x236);
|
||||
}
|
||||
|
||||
public void testStore()
|
||||
{
|
||||
@ -87,21 +79,17 @@ public class TestTableRecord
|
||||
// .col input col = 0
|
||||
// [/TABLE]
|
||||
|
||||
TableRecord record = new TableRecord();
|
||||
record.setRowFirst((short)3);
|
||||
record.setRowLast((short)8);
|
||||
record.setColFirst((short)4);
|
||||
record.setColLast((short)6);
|
||||
record.setFlags((byte)0);
|
||||
record.setReserved((byte)0);
|
||||
record.setRowInputRow((short)4);
|
||||
record.setColInputRow((short)1);
|
||||
record.setRowInputCol((short)0x4076);
|
||||
record.setColInputCol((short)0);
|
||||
CellRangeAddress8Bit crab = new CellRangeAddress8Bit(3, 8, 4, 6);
|
||||
TableRecord record = new TableRecord(crab);
|
||||
record.setFlags((byte)0);
|
||||
record.setRowInputRow(4);
|
||||
record.setColInputRow(1);
|
||||
record.setRowInputCol(0x4076);
|
||||
record.setColInputCol(0);
|
||||
|
||||
byte [] recordBytes = record.serialize();
|
||||
assertEquals(recordBytes.length - 4, data.length);
|
||||
for (int i = 0; i < data.length; i++)
|
||||
assertEquals("At offset " + i, data[i], recordBytes[i+4]);
|
||||
}
|
||||
byte [] recordBytes = record.serialize();
|
||||
assertEquals(recordBytes.length - 4, data.length);
|
||||
for (int i = 0; i < data.length; i++)
|
||||
assertEquals("At offset " + i, data[i], recordBytes[i+4]);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user