mirror of https://github.com/apache/poi.git
Framework to set the class of a token
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352651 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d52ae71cde
commit
b35ab14e42
|
@ -125,4 +125,6 @@ public class AddPtg
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,5 +243,8 @@ public class Area3DPtg extends Ptg
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte getDefaultOperandClass() {
|
||||||
|
return Ptg.CLASS_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ public class AreaPtg
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeBytes(byte [] array, int offset) {
|
public void writeBytes(byte [] array, int offset) {
|
||||||
array[offset] = sid;
|
array[offset] = (byte) (sid + ptgClass);
|
||||||
LittleEndian.putShort(array,offset+1,field_1_first_row);
|
LittleEndian.putShort(array,offset+1,field_1_first_row);
|
||||||
LittleEndian.putShort(array,offset+3,field_2_last_row);
|
LittleEndian.putShort(array,offset+3,field_2_last_row);
|
||||||
LittleEndian.putShort(array,offset+5,field_3_first_column);
|
LittleEndian.putShort(array,offset+5,field_3_first_column);
|
||||||
|
@ -309,4 +309,8 @@ public class AreaPtg
|
||||||
(new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative())).toString();
|
(new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative())).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte getDefaultOperandClass() {
|
||||||
|
return Ptg.CLASS_REF;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,5 +211,5 @@ public class AttrPtg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,4 +96,7 @@ public class ExpPtg
|
||||||
{
|
{
|
||||||
return "NO IDEA SHARED FORMULA EXP PTG";
|
return "NO IDEA SHARED FORMULA EXP PTG";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,12 @@ import java.io.File;
|
||||||
*/
|
*/
|
||||||
public class FormulaParser {
|
public class FormulaParser {
|
||||||
|
|
||||||
|
public static int FORMULA_TYPE_CELL = 0;
|
||||||
|
public static int FORMULA_TYPE_SHARED = 1;
|
||||||
|
public static int FORMULA_TYPE_ARRAY =2;
|
||||||
|
public static int FORMULA_TYPE_CONDFOMRAT = 3;
|
||||||
|
public static int FORMULA_TYPE_NAMEDRANGE = 4;
|
||||||
|
|
||||||
private String formulaString;
|
private String formulaString;
|
||||||
private int pointer=0;
|
private int pointer=0;
|
||||||
|
|
||||||
|
@ -193,18 +199,16 @@ public class FormulaParser {
|
||||||
|
|
||||||
/** Get an Identifier */
|
/** Get an Identifier */
|
||||||
private String GetName() {
|
private String GetName() {
|
||||||
String Token;
|
StringBuffer Token = new StringBuffer();
|
||||||
Token = "";
|
|
||||||
if (!IsAlpha(Look)) {
|
if (!IsAlpha(Look)) {
|
||||||
Expected("Name");
|
Expected("Name");
|
||||||
}
|
}
|
||||||
while (IsAlNum(Look)) {
|
while (IsAlNum(Look)) {
|
||||||
Token = Token + Character.toUpperCase(Look);
|
Token = Token.append(Character.toUpperCase(Look));
|
||||||
GetChar();
|
GetChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
SkipWhite();
|
SkipWhite();
|
||||||
return Token;
|
return Token.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -304,7 +308,10 @@ public class FormulaParser {
|
||||||
return;
|
return;
|
||||||
} else if (IsAlpha(Look)){
|
} else if (IsAlpha(Look)){
|
||||||
Ident();
|
Ident();
|
||||||
}else{
|
} else if(Look == '"') {
|
||||||
|
StringLiteral();
|
||||||
|
} else {
|
||||||
|
|
||||||
String number = GetNum();
|
String number = GetNum();
|
||||||
if (Look=='.') {
|
if (Look=='.') {
|
||||||
Match('.');
|
Match('.');
|
||||||
|
@ -317,6 +324,12 @@ public class FormulaParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void StringLiteral() {
|
||||||
|
Match('"');
|
||||||
|
String name= GetName();
|
||||||
|
Match('"');
|
||||||
|
tokens.add(new StringPtg(name));
|
||||||
|
}
|
||||||
|
|
||||||
/** Recognize and Translate a Multiply */
|
/** Recognize and Translate a Multiply */
|
||||||
private void Multiply(){
|
private void Multiply(){
|
||||||
|
@ -429,13 +442,89 @@ end;
|
||||||
* a result of the parsing
|
* a result of the parsing
|
||||||
*/
|
*/
|
||||||
public Ptg[] getRPNPtg() {
|
public Ptg[] getRPNPtg() {
|
||||||
synchronized (tokens) {
|
return getRPNPtg(FORMULA_TYPE_CELL);
|
||||||
if (tokens == null) throw new IllegalStateException("Please parse a string before trying to access the parse result");
|
|
||||||
Ptg[] retval = new Ptg[tokens.size()];
|
|
||||||
return (Ptg[]) tokens.toArray(retval);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Ptg[] getRPNPtg(int formulaType) {
|
||||||
|
Node node = createTree();
|
||||||
|
setRootLevelRVA(node, formulaType);
|
||||||
|
setParameterRVA(node,formulaType);
|
||||||
|
return (Ptg[]) tokens.toArray(new Ptg[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setRootLevelRVA(Node n, int formulaType) {
|
||||||
|
//Pg 16, excelfileformat.pdf @ openoffice.org
|
||||||
|
Ptg p = (Ptg) n.getValue();
|
||||||
|
if (formulaType == this.FORMULA_TYPE_NAMEDRANGE) {
|
||||||
|
if (p.getDefaultOperandClass() == Ptg.CLASS_REF) {
|
||||||
|
setClass(n,Ptg.CLASS_REF);
|
||||||
|
} else {
|
||||||
|
setClass(n,Ptg.CLASS_ARRAY);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setClass(n,Ptg.CLASS_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setParameterRVA(Node n, int formulaType) {
|
||||||
|
Ptg p = (Ptg) n.getValue();
|
||||||
|
if (p instanceof FunctionPtg) {
|
||||||
|
int numOperands = n.getNumChildren();
|
||||||
|
for (int i =0;i<n.getNumChildren();i++) {
|
||||||
|
setParameterRVA(n.getChild(i),((FunctionPtg)p).getParameterClass(i),formulaType);
|
||||||
|
if (n.getChild(i).getValue() instanceof FunctionPtg) {
|
||||||
|
setParameterRVA(n.getChild(i),formulaType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i =0;i<n.getNumChildren();i++) {
|
||||||
|
setParameterRVA(n.getChild(i),formulaType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void setParameterRVA(Node n, int expectedClass,int formulaType) {
|
||||||
|
Ptg p = (Ptg) n.getValue();
|
||||||
|
if (expectedClass == Ptg.CLASS_REF) { //pg 15, table 1
|
||||||
|
if (p.getDefaultOperandClass() == Ptg.CLASS_REF ) {
|
||||||
|
setClass(n, Ptg.CLASS_REF);
|
||||||
|
}
|
||||||
|
if (p.getDefaultOperandClass() == Ptg.CLASS_VALUE) {
|
||||||
|
if (formulaType==FORMULA_TYPE_CELL || formulaType == FORMULA_TYPE_SHARED) {
|
||||||
|
setClass(n,Ptg.CLASS_VALUE);
|
||||||
|
} else {
|
||||||
|
setClass(n,Ptg.CLASS_ARRAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p.getDefaultOperandClass() == Ptg.CLASS_ARRAY ) {
|
||||||
|
setClass(n, Ptg.CLASS_ARRAY);
|
||||||
|
}
|
||||||
|
} else if (expectedClass == Ptg.CLASS_VALUE) { //pg 15, table 2
|
||||||
|
if (formulaType == FORMULA_TYPE_NAMEDRANGE) {
|
||||||
|
setClass(n,Ptg.CLASS_ARRAY) ;
|
||||||
|
} else {
|
||||||
|
setClass(n,Ptg.CLASS_VALUE);
|
||||||
|
}
|
||||||
|
} else { //Array class, pg 16.
|
||||||
|
if (p.getDefaultOperandClass() == Ptg.CLASS_VALUE &&
|
||||||
|
(formulaType==FORMULA_TYPE_CELL || formulaType == FORMULA_TYPE_SHARED)) {
|
||||||
|
setClass(n,Ptg.CLASS_VALUE);
|
||||||
|
} else {
|
||||||
|
setClass(n,Ptg.CLASS_ARRAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setClass(Node n, byte theClass) {
|
||||||
|
Ptg p = (Ptg) n.getValue();
|
||||||
|
if (p instanceof FunctionPtg || !(p instanceof OperationPtg)) {
|
||||||
|
p.setClass(theClass);
|
||||||
|
} else {
|
||||||
|
for (int i =0;i<n.getNumChildren();i++) {
|
||||||
|
setClass(n.getChild(i),theClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Convience method which takes in a list then passes it to the other toFormulaString
|
* Convience method which takes in a list then passes it to the other toFormulaString
|
||||||
* signature
|
* signature
|
||||||
|
@ -459,6 +548,7 @@ end;
|
||||||
String[] operands;
|
String[] operands;
|
||||||
for (int i=0;i<numPtgs;i++) {
|
for (int i=0;i<numPtgs;i++) {
|
||||||
if (ptgs[i] instanceof OperationPtg) {
|
if (ptgs[i] instanceof OperationPtg) {
|
||||||
|
|
||||||
// Excel allows to have AttrPtg at position 0 (such as Blanks) which
|
// Excel allows to have AttrPtg at position 0 (such as Blanks) which
|
||||||
// do not have any operands. Skip them.
|
// do not have any operands. Skip them.
|
||||||
if(i > 0) {
|
if(i > 0) {
|
||||||
|
@ -479,6 +569,31 @@ end;
|
||||||
return (String) stack.pop(); //TODO: catch stack underflow and throw parse exception.
|
return (String) stack.pop(); //TODO: catch stack underflow and throw parse exception.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Node createTree() {
|
||||||
|
java.util.Stack stack = new java.util.Stack();
|
||||||
|
int numPtgs = tokens.size();
|
||||||
|
OperationPtg o;
|
||||||
|
int numOperands;
|
||||||
|
Node[] operands;
|
||||||
|
for (int i=0;i<numPtgs;i++) {
|
||||||
|
if (tokens.get(i) instanceof OperationPtg) {
|
||||||
|
|
||||||
|
o = (OperationPtg) tokens.get(i);
|
||||||
|
numOperands = o.getNumberOfOperands();
|
||||||
|
operands = new Node[numOperands];
|
||||||
|
for (int j=0;j<numOperands;j++) {
|
||||||
|
operands[numOperands-j-1] = (Node) stack.pop();
|
||||||
|
}
|
||||||
|
Node result = new Node(o);
|
||||||
|
result.setChildren(operands);
|
||||||
|
stack.push(result);
|
||||||
|
} else {
|
||||||
|
stack.push(new Node((Ptg)tokens.get(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (Node) stack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
/** toString on the parser instance returns the RPN ordered list of tokens
|
/** toString on the parser instance returns the RPN ordered list of tokens
|
||||||
* Useful for testing
|
* Useful for testing
|
||||||
*/
|
*/
|
||||||
|
@ -491,5 +606,17 @@ end;
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
class Node {
|
||||||
|
private Ptg value=null;
|
||||||
|
private Node[] children=new Node[0];
|
||||||
|
private int numChild=0;
|
||||||
|
public Node(Ptg val) {
|
||||||
|
value = val;
|
||||||
|
}
|
||||||
|
public void setChildren(Node[] child) {children = child;numChild=child.length;}
|
||||||
|
public int getNumChildren() {return numChild;}
|
||||||
|
public Node getChild(int number) {return children[number];}
|
||||||
|
public Ptg getValue() {return value;}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,15 +9,15 @@ import org.apache.poi.util.BinaryTree;
|
||||||
* This class provides functions with variable arguments.
|
* This class provides functions with variable arguments.
|
||||||
* @author Avik Sengupta
|
* @author Avik Sengupta
|
||||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||||
* @version
|
|
||||||
*/
|
*/
|
||||||
public class FunctionPtg extends OperationPtg {
|
public class FunctionPtg extends OperationPtg {
|
||||||
public final static short sid = 0x22;
|
public final static short sid = 0x22;
|
||||||
private final static int SIZE = 4;
|
private final static int SIZE = 4;
|
||||||
|
|
||||||
private static BinaryTree map = produceHash();
|
private static BinaryTree map = produceHash();
|
||||||
|
private static Object[][] functionData = produceFunctionData();
|
||||||
static { map=produceHash();}
|
private byte returnClass;
|
||||||
|
private byte[] paramClass;
|
||||||
|
|
||||||
private byte field_1_num_args;
|
private byte field_1_num_args;
|
||||||
private short field_2_fnc_index;
|
private short field_2_fnc_index;
|
||||||
|
@ -30,7 +30,6 @@ public class FunctionPtg extends OperationPtg {
|
||||||
offset++;
|
offset++;
|
||||||
field_1_num_args = data[ offset + 0 ];
|
field_1_num_args = data[ offset + 0 ];
|
||||||
field_2_fnc_index = LittleEndian.getShort(data,offset + 1 );
|
field_2_fnc_index = LittleEndian.getShort(data,offset + 1 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,7 +38,13 @@ public class FunctionPtg extends OperationPtg {
|
||||||
protected FunctionPtg(String pName, byte pNumOperands) {
|
protected FunctionPtg(String pName, byte pNumOperands) {
|
||||||
field_1_num_args = pNumOperands;
|
field_1_num_args = pNumOperands;
|
||||||
field_2_fnc_index = lookupIndex(pName);
|
field_2_fnc_index = lookupIndex(pName);
|
||||||
|
try{
|
||||||
|
returnClass = ( (Byte) functionData[field_2_fnc_index][0]).byteValue();
|
||||||
|
paramClass = (byte[]) functionData[field_2_fnc_index][1];
|
||||||
|
} catch (NullPointerException npe ) {
|
||||||
|
returnClass = Ptg.CLASS_VALUE;
|
||||||
|
paramClass = new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -89,7 +94,7 @@ public class FunctionPtg extends OperationPtg {
|
||||||
|
|
||||||
|
|
||||||
public void writeBytes(byte[] array, int offset) {
|
public void writeBytes(byte[] array, int offset) {
|
||||||
array[offset+0]=sid;
|
array[offset+0]=(byte) (sid + ptgClass);
|
||||||
array[offset+1]=field_1_num_args;
|
array[offset+1]=field_1_num_args;
|
||||||
LittleEndian.putShort(array,offset+2,field_2_fnc_index);
|
LittleEndian.putShort(array,offset+2,field_2_fnc_index);
|
||||||
}
|
}
|
||||||
|
@ -99,11 +104,11 @@ public class FunctionPtg extends OperationPtg {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String lookupName(short index) {
|
private String lookupName(short index) {
|
||||||
return ((String)map.get(new Integer(index))); //for now always return "SUM"
|
return ((String)map.get(new Integer(index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private short lookupIndex(String name) {
|
private short lookupIndex(String name) {
|
||||||
return (short)((Integer)map.getKeyForValue(name)).intValue(); //for now just return SUM everytime...
|
return (short)((Integer)map.getKeyForValue(name)).intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -465,4 +470,50 @@ public class FunctionPtg extends OperationPtg {
|
||||||
|
|
||||||
return dmap;
|
return dmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Object[][] produceFunctionData() {
|
||||||
|
Object [][] functionData = new Object[368][2];
|
||||||
|
|
||||||
|
functionData[0][0]=new Byte(Ptg.CLASS_VALUE);functionData[0][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[2][0]=new Byte(Ptg.CLASS_VALUE);functionData[2][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[3][0]=new Byte(Ptg.CLASS_VALUE);functionData[3][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[4][0]=new Byte(Ptg.CLASS_VALUE);functionData[4][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[5][0]=new Byte(Ptg.CLASS_VALUE);functionData[5][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[6][0]=new Byte(Ptg.CLASS_VALUE);functionData[6][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[7][0]=new Byte(Ptg.CLASS_VALUE);functionData[7][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[8][0]=new Byte(Ptg.CLASS_VALUE);functionData[8][1]=new byte[] {Ptg.CLASS_REF};
|
||||||
|
functionData[9][0]=new Byte(Ptg.CLASS_VALUE);functionData[9][1]=new byte[] {Ptg.CLASS_REF};
|
||||||
|
functionData[10][0]=new Byte(Ptg.CLASS_VALUE);functionData[10][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[11][0]=new Byte(Ptg.CLASS_VALUE);functionData[11][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[12][0]=new Byte(Ptg.CLASS_VALUE);functionData[12][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[13][0]=new Byte(Ptg.CLASS_VALUE);functionData[13][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[14][0]=new Byte(Ptg.CLASS_VALUE);functionData[14][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[15][0]=new Byte(Ptg.CLASS_VALUE);functionData[15][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[16][0]=new Byte(Ptg.CLASS_VALUE);functionData[16][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[17][0]=new Byte(Ptg.CLASS_VALUE);functionData[17][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[18][0]=new Byte(Ptg.CLASS_VALUE);functionData[18][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[19][0]=new Byte(Ptg.CLASS_VALUE);functionData[19][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[20][0]=new Byte(Ptg.CLASS_VALUE);functionData[20][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[21][0]=new Byte(Ptg.CLASS_VALUE);functionData[21][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[22][0]=new Byte(Ptg.CLASS_VALUE);functionData[22][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[23][0]=new Byte(Ptg.CLASS_VALUE);functionData[23][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[24][0]=new Byte(Ptg.CLASS_VALUE);functionData[24][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[25][0]=new Byte(Ptg.CLASS_VALUE);functionData[25][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[26][0]=new Byte(Ptg.CLASS_VALUE);functionData[26][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
functionData[27][0]=new Byte(Ptg.CLASS_VALUE);functionData[27][1]=new byte[] {Ptg.CLASS_VALUE};
|
||||||
|
|
||||||
|
return functionData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getDefaultOperandClass() {
|
||||||
|
return returnClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected byte getParameterClass(int index) {
|
||||||
|
try {
|
||||||
|
return paramClass[index];
|
||||||
|
} catch (ArrayIndexOutOfBoundsException aioobe) {
|
||||||
|
return paramClass[paramClass.length - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,5 +114,5 @@ public class IntPtg
|
||||||
{
|
{
|
||||||
return "" + getValue();
|
return "" + getValue();
|
||||||
}
|
}
|
||||||
|
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,4 +120,5 @@ public class MemErrPtg
|
||||||
{
|
{
|
||||||
return "ERR#";
|
return "ERR#";
|
||||||
}
|
}
|
||||||
|
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,4 +106,6 @@ public class NamePtg
|
||||||
{
|
{
|
||||||
return "NO IDEA - NAME";
|
return "NO IDEA - NAME";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,6 @@ public class NumberPtg
|
||||||
{
|
{
|
||||||
return "" + getValue();
|
return "" + getValue();
|
||||||
}
|
}
|
||||||
|
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,4 +88,6 @@ public abstract class OperationPtg extends Ptg
|
||||||
*/
|
*/
|
||||||
public abstract int getNumberOfOperands();
|
public abstract int getNumberOfOperands();
|
||||||
|
|
||||||
|
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,5 +114,7 @@ public class ParenthesisPtg
|
||||||
return "("+operands[0]+")";
|
return "("+operands[0]+")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,8 +110,6 @@ public class PowerPtg
|
||||||
return "^";
|
return "^";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String toFormulaString(String[] operands) {
|
public String toFormulaString(String[] operands) {
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ import java.util.ArrayList;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author andy
|
* @author andy
|
||||||
|
* @author avik
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class Ptg
|
public abstract class Ptg
|
||||||
|
@ -125,53 +126,17 @@ public abstract class Ptg
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
private static List ptgsToList(Class [] ptgs)
|
|
||||||
{
|
|
||||||
List result = new ArrayList();
|
|
||||||
Constructor constructor;
|
|
||||||
|
|
||||||
for (int i = 0; i < ptgs.length; i++)
|
|
||||||
{
|
|
||||||
Class ptg = null;
|
|
||||||
|
|
||||||
ptg = ptgs[ i ];
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
constructor = ptg.getConstructor(new Class[]
|
|
||||||
{
|
|
||||||
byte [].class, int.class
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (Exception illegalArgumentException)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(
|
|
||||||
"Now that didn't work nicely at all (couldn't do that there list of ptgs)");
|
|
||||||
}
|
|
||||||
result.add(constructor);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
public static Ptg createPtg(byte [] data, int offset)
|
public static Ptg createPtg(byte [] data, int offset)
|
||||||
{
|
{
|
||||||
byte id = data[ offset + 0 ];
|
byte id = data[ offset + 0 ];
|
||||||
Ptg retval = null;
|
Ptg retval = null;
|
||||||
|
|
||||||
final int refRef = ReferencePtg.sid - 0x20;
|
final byte valueRef = ReferencePtg.sid + 0x20;
|
||||||
final int arrayRef = ReferencePtg.sid + 0x20;
|
final byte arrayRef = ReferencePtg.sid + 0x40;
|
||||||
|
final byte valueFunc = FunctionPtg.sid + 0x20;
|
||||||
|
final byte arrayFunc = FunctionPtg.sid + 0x40;
|
||||||
final int valueFunc = FunctionPtg.sid + 0x20;
|
final byte valueArea = AreaPtg.sid + 0x20;
|
||||||
final int arrayFunc = FunctionPtg.sid + 0x40;
|
final byte arrayArea = AreaPtg.sid + 0x40;
|
||||||
|
|
||||||
|
|
||||||
final int refArea = AreaPtg.sid-0x20;
|
|
||||||
final int arrayArea = AreaPtg.sid+0x20;
|
|
||||||
|
|
||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
|
@ -207,7 +172,12 @@ public abstract class Ptg
|
||||||
case AreaPtg.sid :
|
case AreaPtg.sid :
|
||||||
retval = new AreaPtg(data, offset);
|
retval = new AreaPtg(data, offset);
|
||||||
break;
|
break;
|
||||||
|
case valueArea:
|
||||||
|
retval = new AreaPtg(data, offset);
|
||||||
|
break;
|
||||||
|
case arrayArea:
|
||||||
|
retval = new AreaPtg(data, offset);
|
||||||
|
break;
|
||||||
case MemErrPtg.sid :
|
case MemErrPtg.sid :
|
||||||
retval = new MemErrPtg(data, offset);
|
retval = new MemErrPtg(data, offset);
|
||||||
break;
|
break;
|
||||||
|
@ -219,11 +189,9 @@ public abstract class Ptg
|
||||||
case ReferencePtg.sid :
|
case ReferencePtg.sid :
|
||||||
retval = new ReferencePtg(data, offset);
|
retval = new ReferencePtg(data, offset);
|
||||||
break;
|
break;
|
||||||
|
case valueRef :
|
||||||
case refRef :
|
|
||||||
retval = new ReferencePtg(data, offset);
|
retval = new ReferencePtg(data, offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case arrayRef :
|
case arrayRef :
|
||||||
retval = new ReferencePtg(data, offset);
|
retval = new ReferencePtg(data, offset);
|
||||||
break;
|
break;
|
||||||
|
@ -239,7 +207,6 @@ public abstract class Ptg
|
||||||
case valueFunc :
|
case valueFunc :
|
||||||
retval = new FunctionPtg(data, offset);
|
retval = new FunctionPtg(data, offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case arrayFunc :
|
case arrayFunc :
|
||||||
retval = new FunctionPtg(data, offset);
|
retval = new FunctionPtg(data, offset);
|
||||||
break;
|
break;
|
||||||
|
@ -275,7 +242,15 @@ public abstract class Ptg
|
||||||
+ Integer.toHexString(( int ) id)
|
+ Integer.toHexString(( int ) id)
|
||||||
+ " (" + ( int ) id + ")");
|
+ " (" + ( int ) id + ")");
|
||||||
}
|
}
|
||||||
return retval;
|
|
||||||
|
if (id > 0x60) {
|
||||||
|
retval.setClass(CLASS_ARRAY);
|
||||||
|
} else if (id > 0x40) {
|
||||||
|
retval.setClass(CLASS_VALUE);
|
||||||
|
} else
|
||||||
|
retval.setClass(CLASS_REF);
|
||||||
|
return retval;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract int getSize();
|
public abstract int getSize();
|
||||||
|
@ -310,5 +285,19 @@ public abstract class Ptg
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final byte CLASS_REF = 0x00;
|
||||||
|
public static final byte CLASS_VALUE = 0x20;
|
||||||
|
public static final byte CLASS_ARRAY = 0x40;
|
||||||
|
|
||||||
|
protected byte ptgClass = CLASS_REF; //base ptg
|
||||||
|
|
||||||
|
public void setClass(byte thePtgClass) {
|
||||||
|
ptgClass = thePtgClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public abstract byte getDefaultOperandClass();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================================
|
/* ====================================================================
|
||||||
* The Apache Software License, Version 1.1
|
* The Apache Software License, Version 1.1
|
||||||
*
|
*
|
||||||
|
@ -174,4 +175,6 @@ public class Ref3DPtg extends Ptg {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,18 +66,15 @@ import org.apache.poi.util.BitField;
|
||||||
import org.apache.poi.hssf.util.CellReference;
|
import org.apache.poi.hssf.util.CellReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ValueReferencePtg - handles references (such as A1, A2, IA4) - Should also
|
* ReferencePtg - handles references (such as A1, A2, IA4)
|
||||||
* be made to handle relative versus absolute references but I don't know enough
|
|
||||||
* about using them in excel to know if its correct. Seems inverted to me.
|
|
||||||
* FIXME = correct abs vs relative references
|
|
||||||
* @author Andrew C. Oliver (acoliver@apache.org)
|
* @author Andrew C. Oliver (acoliver@apache.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ReferencePtg extends Ptg
|
public class ReferencePtg extends Ptg
|
||||||
{
|
{
|
||||||
private final static int SIZE = 5;
|
private final static int SIZE = 5;
|
||||||
//public final static byte sid = 0x24;
|
public final static byte sid = 0x24;
|
||||||
public final static byte sid = 0x44;
|
//public final static byte sid = 0x44;
|
||||||
private short field_1_row;
|
private short field_1_row;
|
||||||
private short field_2_col;
|
private short field_2_col;
|
||||||
private BitField rowRelative = new BitField(0x8000);
|
private BitField rowRelative = new BitField(0x8000);
|
||||||
|
@ -120,7 +117,7 @@ public class ReferencePtg extends Ptg
|
||||||
|
|
||||||
public void writeBytes(byte [] array, int offset)
|
public void writeBytes(byte [] array, int offset)
|
||||||
{
|
{
|
||||||
array[offset] = sid;
|
array[offset] = (byte) (sid + ptgClass);
|
||||||
LittleEndian.putShort(array,offset+1,field_1_row);
|
LittleEndian.putShort(array,offset+1,field_1_row);
|
||||||
LittleEndian.putShort(array,offset+3,field_2_col);
|
LittleEndian.putShort(array,offset+3,field_2_col);
|
||||||
}
|
}
|
||||||
|
@ -183,4 +180,9 @@ public class ReferencePtg extends Ptg
|
||||||
//TODO -- should we store a cellreference instance in this ptg?? but .. memory is an issue, i believe!
|
//TODO -- should we store a cellreference instance in this ptg?? but .. memory is an issue, i believe!
|
||||||
return (new CellReference(getRow(),getColumn(),!isRowRelative(),!isColRelative())).toString();
|
return (new CellReference(getRow(),getColumn(),!isRowRelative(),!isColRelative())).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte getDefaultOperandClass() {
|
||||||
|
return Ptg.CLASS_REF;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,9 @@ public class StringPtg
|
||||||
{
|
{
|
||||||
return getValue();
|
return getValue();
|
||||||
}
|
}
|
||||||
|
public byte getDefaultOperandClass() {
|
||||||
|
return Ptg.CLASS_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,4 +95,7 @@ public class UnknownPtg
|
||||||
{
|
{
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
|
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -768,6 +768,8 @@ extends TestCase {
|
||||||
c.setCellFormula("AVERAGE(A2:A3)");
|
c.setCellFormula("AVERAGE(A2:A3)");
|
||||||
c=r.createCell( (short) 4);
|
c=r.createCell( (short) 4);
|
||||||
c.setCellFormula("POWER(A2,A3)");
|
c.setCellFormula("POWER(A2,A3)");
|
||||||
|
c=r.createCell( (short) 5);
|
||||||
|
c.setCellFormula("SIN(A2)");
|
||||||
|
|
||||||
r = s.createRow((short) 1);c=r.createCell( (short) 0); c.setCellValue(2.0);
|
r = s.createRow((short) 1);c=r.createCell( (short) 0); c.setCellValue(2.0);
|
||||||
r = s.createRow((short) 2);c=r.createCell( (short) 0); c.setCellValue(3.0);
|
r = s.createRow((short) 2);c=r.createCell( (short) 0); c.setCellValue(3.0);
|
||||||
|
|
Loading…
Reference in New Issue