mirror of https://github.com/apache/poi.git
Fixed decoding of operand class for ArrayPtg
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@690461 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
55a6277bf2
commit
077c07f988
|
@ -43,58 +43,6 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
public abstract class Ptg implements Cloneable {
|
public abstract class Ptg implements Cloneable {
|
||||||
public static final Ptg[] EMPTY_PTG_ARRAY = { };
|
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 <tt>size</tt> bytes of the input stream, to create an array of <tt>Ptg</tt>s.
|
* Reads <tt>size</tt> bytes of the input stream, to create an array of <tt>Ptg</tt>s.
|
||||||
|
@ -145,15 +93,15 @@ public abstract class Ptg implements Cloneable {
|
||||||
|
|
||||||
Ptg retval = createClassifiedPtg(id, in);
|
Ptg retval = createClassifiedPtg(id, in);
|
||||||
|
|
||||||
if (id > 0x60) {
|
if (id >= 0x60) {
|
||||||
retval.setClass(CLASS_ARRAY);
|
retval.setClass(CLASS_ARRAY);
|
||||||
} else if (id > 0x40) {
|
} else if (id >= 0x40) {
|
||||||
retval.setClass(CLASS_VALUE);
|
retval.setClass(CLASS_VALUE);
|
||||||
} else {
|
} else {
|
||||||
retval.setClass(CLASS_REF);
|
retval.setClass(CLASS_REF);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Ptg createClassifiedPtg(byte id, RecordInputStream in) {
|
private static Ptg createClassifiedPtg(byte id, RecordInputStream in) {
|
||||||
|
@ -397,6 +345,22 @@ public abstract class Ptg implements Cloneable {
|
||||||
return ptgClass;
|
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();
|
public abstract byte getDefaultOperandClass();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.poi.hssf.record.formula;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
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.TestcaseRecordInputStream;
|
||||||
import org.apache.poi.hssf.record.UnicodeString;
|
import org.apache.poi.hssf.record.UnicodeString;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
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);
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue