Cleaned up AttrPtg - made immutable, fixed property accessors.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@835982 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2009-11-13 20:46:02 +00:00
parent a8da0c422e
commit a76bd88d9b
4 changed files with 78 additions and 87 deletions

View File

@ -33,8 +33,8 @@ import org.apache.poi.util.LittleEndianOutput;
public final class AttrPtg extends ControlPtg {
public final static byte sid = 0x19;
private final static int SIZE = 4;
private byte field_1_options;
private short field_2_data;
private final byte _options;
private final short _data;
/** only used for tAttrChoose: table of offsets to starts of args */
private final int[] _jumpTable;
@ -46,8 +46,8 @@ public final class AttrPtg extends ControlPtg {
private static final BitField semiVolatile = BitFieldFactory.getInstance(0x01);
private static final BitField optiIf = BitFieldFactory.getInstance(0x02);
private static final BitField optiChoose = BitFieldFactory.getInstance(0x04);
private static final BitField optGoto = BitFieldFactory.getInstance(0x08); // skip
private static final BitField sum = BitFieldFactory.getInstance(0x10);
private static final BitField optiSkip = BitFieldFactory.getInstance(0x08);
private static final BitField optiSum = BitFieldFactory.getInstance(0x10);
private static final BitField baxcel = BitFieldFactory.getInstance(0x20); // 'assignment-style formula in a macro sheet'
private static final BitField space = BitFieldFactory.getInstance(0x40);
@ -74,16 +74,11 @@ public final class AttrPtg extends ControlPtg {
public static final int SPACE_AFTER_EQUALITY = 0x06;
}
public AttrPtg() {
_jumpTable = null;
_chooseFuncOffset = -1;
}
public AttrPtg(LittleEndianInput in) {
field_1_options = in.readByte();
field_2_data = in.readShort();
_options = in.readByte();
_data = in.readShort();
if (isOptimizedChoose()) {
int nCases = field_2_data;
int nCases = _data;
int[] jumpTable = new int[nCases];
for (int i = 0; i < jumpTable.length; i++) {
jumpTable[i] = in.readUShort();
@ -97,8 +92,8 @@ public final class AttrPtg extends ControlPtg {
}
private AttrPtg(int options, int data, int[] jt, int chooseFuncOffset) {
field_1_options = (byte) options;
field_2_data = (short) data;
_options = (byte) options;
_data = (short) data;
_jumpTable = jt;
_chooseFuncOffset = chooseFuncOffset;
}
@ -112,60 +107,65 @@ public final class AttrPtg extends ControlPtg {
return new AttrPtg(space.set(0), data, null, -1);
}
/**
* @param dist distance (in bytes) to start of either <ul><li>false parameter</li>
* <li>tFuncVar(IF) token (when false parameter is not present)</li></ul>
*/
public static AttrPtg createIf(int dist) {
return new AttrPtg(optiIf.set(0), dist, null, -1);
}
/**
* @param dist distance (in bytes) to position behind tFuncVar(IF) token (minus 1)
*/
public static AttrPtg createSkip(int dist) {
return new AttrPtg(optiSkip.set(0), dist, null, -1);
}
public static AttrPtg getSumSingle() {
return new AttrPtg(sum.set(0), 0, null, -1);
return new AttrPtg(optiSum.set(0), 0, null, -1);
}
public boolean isSemiVolatile() {
return semiVolatile.isSet(field_1_options);
return semiVolatile.isSet(_options);
}
public boolean isOptimizedIf() {
return optiIf.isSet(field_1_options);
return optiIf.isSet(_options);
}
public boolean isOptimizedChoose() {
return optiChoose.isSet(field_1_options);
}
// lets hope no one uses this anymore
public boolean isGoto() {
return optGoto.isSet(field_1_options);
return optiChoose.isSet(_options);
}
public boolean isSum() {
return sum.isSet(field_1_options);
return optiSum.isSet(_options);
}
public void setOptimizedIf(boolean bif) {
field_1_options=optiIf.setByteBoolean(field_1_options,bif);
}
/**
* Flags this ptg as a goto/jump
* @param isGoto
*/
public void setGoto(boolean isGoto) {
field_1_options=optGoto.setByteBoolean(field_1_options, isGoto);
public boolean isSkip() {
return optiSkip.isSet(_options);
}
// lets hope no one uses this anymore
private boolean isBaxcel() {
return baxcel.isSet(field_1_options);
return baxcel.isSet(_options);
}
// biff3&4 only shouldn't happen anymore
public boolean isSpace() {
return space.isSet(field_1_options);
}
public void setData(short data) {
field_2_data = data;
return space.isSet(_options);
}
public short getData() {
return field_2_data;
return _data;
}
public int[] getJumpTable() {
return _jumpTable.clone();
}
public int getChooseFuncOffset() {
if (_jumpTable == null) {
throw new IllegalStateException("Not tAttrChoose");
}
return _chooseFuncOffset;
}
public String toString() {
@ -176,16 +176,16 @@ public final class AttrPtg extends ControlPtg {
sb.append("volatile ");
}
if(isSpace()) {
sb.append("space count=").append((field_2_data >> 8) & 0x00FF);
sb.append(" type=").append(field_2_data & 0x00FF).append(" ");
sb.append("space count=").append((_data >> 8) & 0x00FF);
sb.append(" type=").append(_data & 0x00FF).append(" ");
}
// the rest seem to be mutually exclusive
if(isOptimizedIf()) {
sb.append("if dist=").append(getData());
sb.append("if dist=").append(_data);
} else if(isOptimizedChoose()) {
sb.append("choose nCases=").append(getData());
} else if(isGoto()) {
sb.append("skip dist=").append(getData());
sb.append("choose nCases=").append(_data);
} else if(isSkip()) {
sb.append("skip dist=").append(_data);
} else if(isSum()) {
sb.append("sum ");
} else if(isBaxcel()) {
@ -197,8 +197,8 @@ public final class AttrPtg extends ControlPtg {
public void write(LittleEndianOutput out) {
out.writeByte(sid + getPtgClass());
out.writeByte(field_1_options);
out.writeShort(field_2_data);
out.writeByte(_options);
out.writeShort(_data);
int[] jt = _jumpTable;
if (jt != null) {
for (int i = 0; i < jt.length; i++) {
@ -216,11 +216,11 @@ public final class AttrPtg extends ControlPtg {
}
public String toFormulaString(String[] operands) {
if(space.isSet(field_1_options)) {
if(space.isSet(_options)) {
return operands[ 0 ];
} else if (optiIf.isSet(field_1_options)) {
} else if (optiIf.isSet(_options)) {
return toFormulaString() + "(" + operands[0] + ")";
} else if (optGoto.isSet(field_1_options)) {
} else if (optiSkip.isSet(_options)) {
return toFormulaString() + operands[0]; //goto isn't a real formula element should not show up
} else {
return toFormulaString() + "(" + operands[0] + ")";
@ -237,25 +237,25 @@ public final class AttrPtg extends ControlPtg {
}
public String toFormulaString() {
if(semiVolatile.isSet(field_1_options)) {
if(semiVolatile.isSet(_options)) {
return "ATTR(semiVolatile)";
}
if(optiIf.isSet(field_1_options)) {
if(optiIf.isSet(_options)) {
return "IF";
}
if( optiChoose.isSet(field_1_options)) {
if( optiChoose.isSet(_options)) {
return "CHOOSE";
}
if(optGoto.isSet(field_1_options)) {
if(optiSkip.isSet(_options)) {
return "";
}
if(sum.isSet(field_1_options)) {
if(optiSum.isSet(_options)) {
return "SUM";
}
if(baxcel.isSet(field_1_options)) {
if(baxcel.isSet(_options)) {
return "ATTR(baxcel)";
}
if(space.isSet(field_1_options)) {
if(space.isSet(_options)) {
return "";
}
return "UNKNOWN ATTRIBUTE";
@ -268,6 +268,6 @@ public final class AttrPtg extends ControlPtg {
} else {
jt = _jumpTable.clone();
}
return new AttrPtg(field_1_options, field_2_data, jt, _chooseFuncOffset);
return new AttrPtg(_options, _data, jt, _chooseFuncOffset);
}
}

View File

@ -65,7 +65,7 @@ public class FormulaRenderer {
}
if (ptg instanceof AttrPtg) {
AttrPtg attrPtg = ((AttrPtg) ptg);
if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isGoto()) {
if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isSkip()) {
continue;
}
if (attrPtg.isSpace()) {

View File

@ -28,7 +28,7 @@ import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
* Represents a syntactic element from a formula by encapsulating the corresponding <tt>Ptg</tt>
* token. Each <tt>ParseNode</tt> may have child <tt>ParseNode</tt>s in the case when the wrapped
* <tt>Ptg</tt> is non-atomic.
*
*
* @author Josh Micich
*/
final class ParseNode {
@ -103,58 +103,49 @@ final class ParseNode {
/**
* The IF() function gets marked up with two or three tAttr tokens.
* Similar logic will be required for CHOOSE() when it is supported
*
*
* See excelfileformat.pdf sec 3.10.5 "tAttr (19H)
*/
private void collectIfPtgs(TokenCollector temp) {
// condition goes first
getChildren()[0].collectPtgs(temp);
// placeholder for tAttrIf
int ifAttrIndex = temp.createPlaceholder();
// true parameter
getChildren()[1].collectPtgs(temp);
// placeholder for first skip attr
int skipAfterTrueParamIndex = temp.createPlaceholder();
int trueParamSize = temp.sumTokenSizes(ifAttrIndex+1, skipAfterTrueParamIndex);
AttrPtg attrIf = new AttrPtg();
attrIf.setOptimizedIf(true);
AttrPtg attrSkipAfterTrue = new AttrPtg();
attrSkipAfterTrue.setGoto(true);
AttrPtg attrIf = AttrPtg.createIf(trueParamSize + 4); // distance to start of false parameter/tFuncVar. +4 for tAttrSkip after true
if (getChildren().length > 2) {
// false param present
// false parameter
getChildren()[2].collectPtgs(temp);
int skipAfterFalseParamIndex = temp.createPlaceholder();
AttrPtg attrSkipAfterFalse = new AttrPtg();
attrSkipAfterFalse.setGoto(true);
int falseParamSize = temp.sumTokenSizes(skipAfterTrueParamIndex+1, skipAfterFalseParamIndex);
attrIf.setData((short)(trueParamSize + 4)); // distance to start of false parameter. +4 for skip after true
attrSkipAfterTrue.setData((short)(falseParamSize + 4 + 4 - 1)); // 1 less than distance to end of if FuncVar(size=4). +4 for attr skip before
attrSkipAfterFalse.setData((short)(4 - 1)); // 1 less than distance to end of if FuncVar(size=4).
AttrPtg attrSkipAfterTrue = AttrPtg.createSkip(falseParamSize + 4 + 4 - 1); // 1 less than distance to end of if FuncVar(size=4). +4 for attr skip before
AttrPtg attrSkipAfterFalse = AttrPtg.createSkip(4 - 1); // 1 less than distance to end of if FuncVar(size=4).
temp.setPlaceholder(ifAttrIndex, attrIf);
temp.setPlaceholder(skipAfterTrueParamIndex, attrSkipAfterTrue);
temp.setPlaceholder(skipAfterFalseParamIndex, attrSkipAfterFalse);
} else {
// false parameter not present
attrIf.setData((short)(trueParamSize + 4)); // distance to start of FuncVar. +4 for skip after true
attrSkipAfterTrue.setData((short)(4 - 1)); // 1 less than distance to end of if FuncVar(size=4).
AttrPtg attrSkipAfterTrue = AttrPtg.createSkip(4 - 1); // 1 less than distance to end of if FuncVar(size=4).
temp.setPlaceholder(ifAttrIndex, attrIf);
temp.setPlaceholder(skipAfterTrueParamIndex, attrSkipAfterTrue);
}
temp.add(_token);
}

View File

@ -202,7 +202,7 @@ public final class TestFormulaParserIf extends TestCase {
assertEquals("Y", y.getValue());
assertEquals("N", n.getValue());
assertEquals("IF", funif.toFormulaString());
assertTrue("Goto ptg exists", goto1.isGoto());
assertTrue("tAttrSkip ptg exists", goto1.isSkip());
}
/**
* Make sure the ptgs are generated properly with two functions embedded