diff --git a/src/java/org/apache/poi/hssf/record/formula/Ptg.java b/src/java/org/apache/poi/hssf/record/formula/Ptg.java
index 3af4991d4..e16ae178e 100644
--- a/src/java/org/apache/poi/hssf/record/formula/Ptg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/Ptg.java
@@ -43,58 +43,6 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public abstract class Ptg implements Cloneable {
public static final Ptg[] EMPTY_PTG_ARRAY = { };
- /* 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 ;
- boolean weHaveABracket = false;
- while (i.hasNext()) {
- p=i.next();
- if (p instanceof OperationPtg) {
- if (p instanceof ParenthesisPtg) {
- if (!weHaveABracket) {
- operands.push(p);
- weHaveABracket = true;
- } else {
- o = (OperationPtg) operands.pop();
- 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());
- }
- operands.push(p);
- }
- } else {
- retval.add(p);
- }
- }
- while (!operands.isEmpty()) {
- if (operands.peek() instanceof ParenthesisPtg ){
- //throw some error
- } else {
- retval.add(operands.pop());
- }
- }
- return retval;
- }
- */
/**
* Reads size bytes of the input stream, to create an array of Ptgs.
@@ -145,15 +93,15 @@ public abstract class Ptg implements Cloneable {
Ptg retval = createClassifiedPtg(id, in);
- if (id > 0x60) {
+ if (id >= 0x60) {
retval.setClass(CLASS_ARRAY);
- } else if (id > 0x40) {
+ } else if (id >= 0x40) {
retval.setClass(CLASS_VALUE);
} else {
retval.setClass(CLASS_REF);
}
- return retval;
+ return retval;
}
private static Ptg createClassifiedPtg(byte id, RecordInputStream in) {
@@ -396,6 +344,22 @@ public abstract class Ptg implements Cloneable {
public final byte getPtgClass() {
return ptgClass;
}
+
+ /**
+ * Debug / diagnostic method to get this token's 'operand class' type.
+ * @return 'R' for 'reference', 'V' for 'value', 'A' for 'array' and '.' for base tokens
+ */
+ public final char getRVAType() {
+ if (isBaseToken()) {
+ return '.';
+ }
+ switch (ptgClass) {
+ case Ptg.CLASS_REF: return 'R';
+ case Ptg.CLASS_VALUE: return 'V';
+ case Ptg.CLASS_ARRAY: return 'A';
+ }
+ throw new RuntimeException("Unknown operand class (" + ptgClass + ")");
+ }
public abstract byte getDefaultOperandClass();
diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java b/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java
index 2906f5e02..9e5a34004 100644
--- a/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java
+++ b/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java
@@ -20,6 +20,7 @@ package org.apache.poi.hssf.record.formula;
import java.util.Arrays;
import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.record.TestcaseRecordInputStream;
import org.apache.poi.hssf.record.UnicodeString;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@@ -128,4 +129,28 @@ public final class TestArrayPtg extends TestCase {
}
assertEquals("{TRUE,\"ABCD\";\"E\",0.0;FALSE,\"FG\"}", actualFormula);
}
+
+ /**
+ * worth checking since AttrPtg.sid=0x20 and Ptg.CLASS_* = (0x00, 0x20, and 0x40)
+ */
+ public void testOperandClassDecoding() {
+ confirmOperandClassDecoding(Ptg.CLASS_REF);
+ confirmOperandClassDecoding(Ptg.CLASS_VALUE);
+ confirmOperandClassDecoding(Ptg.CLASS_ARRAY);
+ }
+
+ private static void confirmOperandClassDecoding(byte operandClass) {
+ byte[] fullData = new byte[ENCODED_PTG_DATA.length + ENCODED_CONSTANT_DATA.length];
+ System.arraycopy(ENCODED_PTG_DATA, 0, fullData, 0, ENCODED_PTG_DATA.length);
+ System.arraycopy(ENCODED_CONSTANT_DATA, 0, fullData, ENCODED_PTG_DATA.length, ENCODED_CONSTANT_DATA.length);
+
+ // Force encoded operand class for tArray
+ fullData[0] = (byte) (ArrayPtg.sid + operandClass);
+
+ RecordInputStream in = new TestcaseRecordInputStream(ArrayPtg.sid, fullData);
+
+ Ptg[] ptgs = Ptg.readTokens(ENCODED_PTG_DATA.length, in);
+ ArrayPtg aPtg = (ArrayPtg) ptgs[0];
+ assertEquals(operandClass, aPtg.getPtgClass());
+ }
}