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
c38fc6e7a0
commit
2072902e33
@ -124,5 +124,7 @@ public class AddPtg
|
||||
buffer.append(operands[ 1 ]);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ public class Area3DPtg extends Ptg
|
||||
{
|
||||
public final static short sid = 0x3b;
|
||||
private final static int SIZE = 11; // 10 + 1 for Ptg
|
||||
private short field_1_index_extern_sheet;
|
||||
private short field_1_index_extern_sheet;
|
||||
private short field_2_first_row;
|
||||
private short field_3_last_row;
|
||||
private short field_4_first_column;
|
||||
@ -116,20 +116,20 @@ public class Area3DPtg extends Ptg
|
||||
array[ 0 + offset ] = sid;
|
||||
LittleEndian.putShort(array, 1 + offset , getExternSheetIndex());
|
||||
LittleEndian.putShort(array, 3 + offset , getFirstRow());
|
||||
LittleEndian.putShort(array, 5 + offset , getLastRow());
|
||||
LittleEndian.putShort(array, 7 + offset , getFirstColumnRaw());
|
||||
LittleEndian.putShort(array, 9 + offset , getLastColumnRaw());
|
||||
LittleEndian.putShort(array, 5 + offset , getLastRow());
|
||||
LittleEndian.putShort(array, 7 + offset , getFirstColumnRaw());
|
||||
LittleEndian.putShort(array, 9 + offset , getLastColumnRaw());
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
|
||||
public short getExternSheetIndex(){
|
||||
return field_1_index_extern_sheet;
|
||||
}
|
||||
|
||||
|
||||
public void setExternSheetIndex(short index){
|
||||
field_1_index_extern_sheet = index;
|
||||
}
|
||||
@ -177,17 +177,17 @@ public class Area3DPtg extends Ptg
|
||||
public void setFirstColumn(short column)
|
||||
{
|
||||
field_4_first_column &= 0xFF00;
|
||||
field_4_first_column |= column & 0xFF;
|
||||
field_4_first_column |= column & 0xFF;
|
||||
}
|
||||
|
||||
public void setFirstColumnRaw(short column)
|
||||
{
|
||||
field_4_first_column = column;
|
||||
field_4_first_column = column;
|
||||
}
|
||||
|
||||
public short getLastColumn()
|
||||
{
|
||||
return ( short ) (field_5_last_column & 0xFF);
|
||||
return ( short ) (field_5_last_column & 0xFF);
|
||||
}
|
||||
|
||||
public short getLastColumnRaw()
|
||||
@ -208,32 +208,32 @@ public class Area3DPtg extends Ptg
|
||||
public void setLastColumn(short column)
|
||||
{
|
||||
field_5_last_column &= 0xFF00;
|
||||
field_5_last_column |= column & 0xFF;
|
||||
field_5_last_column |= column & 0xFF;
|
||||
}
|
||||
|
||||
public void setLastColumnRaw(short column)
|
||||
{
|
||||
field_5_last_column = column;
|
||||
}
|
||||
|
||||
|
||||
public String getArea(){
|
||||
RangeAddress ra = new RangeAddress( getFirstColumn(),getFirstRow() + 1, getLastColumn(), getLastRow() + 1);
|
||||
RangeAddress ra = new RangeAddress( getFirstColumn(),getFirstRow() + 1, getLastColumn(), getLastRow() + 1);
|
||||
String result = ra.getAddress();
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public void setArea(String ref){
|
||||
RangeAddress ra = new RangeAddress(ref);
|
||||
|
||||
|
||||
String from = ra.getFromCell();
|
||||
String to = ra.getToCell();
|
||||
|
||||
|
||||
setFirstColumn((short) (ra.getXPosition(from) -1));
|
||||
setFirstRow((short) (ra.getYPosition(from) -1));
|
||||
setLastColumn((short) (ra.getXPosition(to) -1));
|
||||
setLastRow((short) (ra.getYPosition(to) -1));
|
||||
|
||||
|
||||
}
|
||||
|
||||
public String toFormulaString()
|
||||
@ -243,5 +243,8 @@ public class Area3DPtg extends Ptg
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public byte getDefaultOperandClass() {
|
||||
return Ptg.CLASS_VALUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ public class AreaPtg
|
||||
}
|
||||
|
||||
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+3,field_2_last_row);
|
||||
LittleEndian.putShort(array,offset+5,field_3_first_column);
|
||||
@ -309,4 +309,8 @@ public class AreaPtg
|
||||
(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";
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||
|
||||
}
|
||||
|
@ -79,6 +79,12 @@ import java.io.File;
|
||||
*/
|
||||
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 int pointer=0;
|
||||
|
||||
@ -193,18 +199,16 @@ public class FormulaParser {
|
||||
|
||||
/** Get an Identifier */
|
||||
private String GetName() {
|
||||
String Token;
|
||||
Token = "";
|
||||
StringBuffer Token = new StringBuffer();
|
||||
if (!IsAlpha(Look)) {
|
||||
Expected("Name");
|
||||
}
|
||||
while (IsAlNum(Look)) {
|
||||
Token = Token + Character.toUpperCase(Look);
|
||||
Token = Token.append(Character.toUpperCase(Look));
|
||||
GetChar();
|
||||
}
|
||||
|
||||
SkipWhite();
|
||||
return Token;
|
||||
return Token.toString();
|
||||
}
|
||||
|
||||
|
||||
@ -304,7 +308,10 @@ public class FormulaParser {
|
||||
return;
|
||||
} else if (IsAlpha(Look)){
|
||||
Ident();
|
||||
}else{
|
||||
} else if(Look == '"') {
|
||||
StringLiteral();
|
||||
} else {
|
||||
|
||||
String number = GetNum();
|
||||
if (Look=='.') {
|
||||
Match('.');
|
||||
@ -316,7 +323,13 @@ public class FormulaParser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void StringLiteral() {
|
||||
Match('"');
|
||||
String name= GetName();
|
||||
Match('"');
|
||||
tokens.add(new StringPtg(name));
|
||||
}
|
||||
|
||||
/** Recognize and Translate a Multiply */
|
||||
private void Multiply(){
|
||||
@ -429,13 +442,89 @@ end;
|
||||
* a result of the parsing
|
||||
*/
|
||||
public Ptg[] getRPNPtg() {
|
||||
synchronized (tokens) {
|
||||
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);
|
||||
}
|
||||
return getRPNPtg(FORMULA_TYPE_CELL);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
* signature
|
||||
@ -459,6 +548,7 @@ end;
|
||||
String[] operands;
|
||||
for (int i=0;i<numPtgs;i++) {
|
||||
if (ptgs[i] instanceof OperationPtg) {
|
||||
|
||||
// Excel allows to have AttrPtg at position 0 (such as Blanks) which
|
||||
// do not have any operands. Skip them.
|
||||
if(i > 0) {
|
||||
@ -478,6 +568,31 @@ end;
|
||||
}
|
||||
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
|
||||
* Useful for testing
|
||||
@ -491,5 +606,17 @@ end;
|
||||
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.
|
||||
* @author Avik Sengupta
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @version
|
||||
*/
|
||||
public class FunctionPtg extends OperationPtg {
|
||||
public final static short sid = 0x22;
|
||||
private final static int SIZE = 4;
|
||||
|
||||
private static BinaryTree map = produceHash();
|
||||
|
||||
static { map=produceHash();}
|
||||
private static Object[][] functionData = produceFunctionData();
|
||||
private byte returnClass;
|
||||
private byte[] paramClass;
|
||||
|
||||
private byte field_1_num_args;
|
||||
private short field_2_fnc_index;
|
||||
@ -30,7 +30,6 @@ public class FunctionPtg extends OperationPtg {
|
||||
offset++;
|
||||
field_1_num_args = data[ offset + 0 ];
|
||||
field_2_fnc_index = LittleEndian.getShort(data,offset + 1 );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -39,7 +38,13 @@ public class FunctionPtg extends OperationPtg {
|
||||
protected FunctionPtg(String pName, byte pNumOperands) {
|
||||
field_1_num_args = pNumOperands;
|
||||
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() {
|
||||
@ -89,7 +94,7 @@ public class FunctionPtg extends OperationPtg {
|
||||
|
||||
|
||||
public void writeBytes(byte[] array, int offset) {
|
||||
array[offset+0]=sid;
|
||||
array[offset+0]=(byte) (sid + ptgClass);
|
||||
array[offset+1]=field_1_num_args;
|
||||
LittleEndian.putShort(array,offset+2,field_2_fnc_index);
|
||||
}
|
||||
@ -99,11 +104,11 @@ public class FunctionPtg extends OperationPtg {
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||
}
|
||||
|
@ -120,4 +120,5 @@ public class MemErrPtg
|
||||
{
|
||||
return "ERR#";
|
||||
}
|
||||
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||
}
|
||||
|
@ -106,4 +106,6 @@ public class NamePtg
|
||||
{
|
||||
return "NO IDEA - NAME";
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||
}
|
||||
|
@ -113,6 +113,6 @@ public class NumberPtg
|
||||
{
|
||||
return "" + getValue();
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||
}
|
||||
|
||||
|
@ -88,4 +88,6 @@ public abstract class OperationPtg extends Ptg
|
||||
*/
|
||||
public abstract int getNumberOfOperands();
|
||||
|
||||
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||
|
||||
}
|
||||
|
@ -112,7 +112,9 @@ public class ParenthesisPtg
|
||||
|
||||
public String toFormulaString(String[] operands) {
|
||||
return "("+operands[0]+")";
|
||||
}
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||
|
||||
}
|
||||
|
||||
|
@ -109,9 +109,7 @@ public class PowerPtg
|
||||
{
|
||||
return "^";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public String toFormulaString(String[] operands) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
|
@ -66,6 +66,7 @@ import java.util.ArrayList;
|
||||
/**
|
||||
*
|
||||
* @author andy
|
||||
* @author avik
|
||||
*/
|
||||
|
||||
public abstract class Ptg
|
||||
@ -124,54 +125,18 @@ public abstract class Ptg
|
||||
return retval;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
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)
|
||||
{
|
||||
byte id = data[ offset + 0 ];
|
||||
Ptg retval = null;
|
||||
|
||||
final int refRef = ReferencePtg.sid - 0x20;
|
||||
final int arrayRef = ReferencePtg.sid + 0x20;
|
||||
|
||||
|
||||
final int valueFunc = FunctionPtg.sid + 0x20;
|
||||
final int arrayFunc = FunctionPtg.sid + 0x40;
|
||||
|
||||
|
||||
final int refArea = AreaPtg.sid-0x20;
|
||||
final int arrayArea = AreaPtg.sid+0x20;
|
||||
|
||||
final byte valueRef = ReferencePtg.sid + 0x20;
|
||||
final byte arrayRef = ReferencePtg.sid + 0x40;
|
||||
final byte valueFunc = FunctionPtg.sid + 0x20;
|
||||
final byte arrayFunc = FunctionPtg.sid + 0x40;
|
||||
final byte valueArea = AreaPtg.sid + 0x20;
|
||||
final byte arrayArea = AreaPtg.sid + 0x40;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -207,7 +172,12 @@ public abstract class Ptg
|
||||
case AreaPtg.sid :
|
||||
retval = new AreaPtg(data, offset);
|
||||
break;
|
||||
|
||||
case valueArea:
|
||||
retval = new AreaPtg(data, offset);
|
||||
break;
|
||||
case arrayArea:
|
||||
retval = new AreaPtg(data, offset);
|
||||
break;
|
||||
case MemErrPtg.sid :
|
||||
retval = new MemErrPtg(data, offset);
|
||||
break;
|
||||
@ -215,18 +185,16 @@ public abstract class Ptg
|
||||
case AttrPtg.sid :
|
||||
retval = new AttrPtg(data, offset);
|
||||
break;
|
||||
|
||||
|
||||
case ReferencePtg.sid :
|
||||
retval = new ReferencePtg(data, offset);
|
||||
break;
|
||||
|
||||
case refRef :
|
||||
break;
|
||||
case valueRef :
|
||||
retval = new ReferencePtg(data, offset);
|
||||
break;
|
||||
|
||||
break;
|
||||
case arrayRef :
|
||||
retval = new ReferencePtg(data, offset);
|
||||
break;
|
||||
break;
|
||||
|
||||
case ParenthesisPtg.sid :
|
||||
retval = new ParenthesisPtg(data, offset);
|
||||
@ -239,7 +207,6 @@ public abstract class Ptg
|
||||
case valueFunc :
|
||||
retval = new FunctionPtg(data, offset);
|
||||
break;
|
||||
|
||||
case arrayFunc :
|
||||
retval = new FunctionPtg(data, offset);
|
||||
break;
|
||||
@ -275,7 +242,15 @@ public abstract class Ptg
|
||||
+ Integer.toHexString(( 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();
|
||||
@ -310,5 +285,19 @@ public abstract class Ptg
|
||||
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
|
||||
*
|
||||
@ -72,22 +73,22 @@ public class Ref3DPtg extends Ptg {
|
||||
private short field_1_index_extern_sheet;
|
||||
private short field_2_row;
|
||||
private short field_3_column;
|
||||
|
||||
|
||||
/** Creates new AreaPtg */
|
||||
|
||||
|
||||
public Ref3DPtg() {
|
||||
}
|
||||
|
||||
|
||||
public Ref3DPtg(byte[] data, int offset) {
|
||||
offset++;
|
||||
field_1_index_extern_sheet = LittleEndian.getShort(data, 0 + offset);
|
||||
field_2_row = LittleEndian.getShort(data, 2 + offset);
|
||||
field_3_column = LittleEndian.getShort(data, 4 + offset);
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
|
||||
buffer.append("Ref3dPrg\n");
|
||||
buffer.append("Index to Extern Sheet = " + getExternSheetIndex()).append("\n");
|
||||
buffer.append("Row = " + getRow()).append("\n");
|
||||
@ -97,81 +98,83 @@ public class Ref3DPtg extends Ptg {
|
||||
buffer.append("ColRel = " + isColRelative()).append("\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
|
||||
public void writeBytes(byte [] array, int offset) {
|
||||
array[ 0 + offset ] = sid;
|
||||
LittleEndian.putShort(array, 1 + offset , getExternSheetIndex());
|
||||
LittleEndian.putShort(array, 3 + offset , getRow());
|
||||
LittleEndian.putShort(array, 5 + offset , getColumnRaw());
|
||||
LittleEndian.putShort(array, 5 + offset , getColumnRaw());
|
||||
}
|
||||
|
||||
|
||||
public int getSize() {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
|
||||
public short getExternSheetIndex(){
|
||||
return field_1_index_extern_sheet;
|
||||
}
|
||||
|
||||
|
||||
public void setExternSheetIndex(short index){
|
||||
field_1_index_extern_sheet = index;
|
||||
}
|
||||
|
||||
|
||||
public short getRow() {
|
||||
return field_2_row;
|
||||
}
|
||||
|
||||
|
||||
public void setRow(short row) {
|
||||
field_2_row = row;
|
||||
}
|
||||
|
||||
|
||||
public short getColumn() {
|
||||
return ( short ) (field_3_column & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
public short getColumnRaw() {
|
||||
return field_3_column;
|
||||
}
|
||||
|
||||
|
||||
public boolean isColRowRelative() {
|
||||
return (((getColumnRaw()) & 0x8000) == 0x8000);
|
||||
}
|
||||
|
||||
|
||||
public boolean isColRelative() {
|
||||
return (((getColumnRaw()) & 0x4000) == 0x4000);
|
||||
}
|
||||
|
||||
|
||||
public void setColumn(short column) {
|
||||
field_3_column &= 0xFF00;
|
||||
field_3_column |= column & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
public void setColumnRaw(short column) {
|
||||
field_3_column = column;
|
||||
}
|
||||
|
||||
|
||||
public String getArea(){
|
||||
RangeAddress ra = new RangeAddress("");
|
||||
|
||||
|
||||
String result = (ra.numTo26Sys(getColumn()) + (getRow() + 1));
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setArea(String ref){
|
||||
RangeAddress ra = new RangeAddress(ref);
|
||||
|
||||
|
||||
String from = ra.getFromCell();
|
||||
|
||||
|
||||
setColumn((short) (ra.getXPosition(from) -1));
|
||||
setRow((short) (ra.getYPosition(from) -1));
|
||||
|
||||
|
||||
}
|
||||
|
||||
public String toFormulaString() {
|
||||
String result = getArea();
|
||||
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* ValueReferencePtg - handles references (such as A1, A2, IA4) - Should also
|
||||
* 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
|
||||
* ReferencePtg - handles references (such as A1, A2, IA4)
|
||||
* @author Andrew C. Oliver (acoliver@apache.org)
|
||||
*/
|
||||
|
||||
public class ReferencePtg extends Ptg
|
||||
{
|
||||
private final static int SIZE = 5;
|
||||
//public final static byte sid = 0x24;
|
||||
public final static byte sid = 0x44;
|
||||
public final static byte sid = 0x24;
|
||||
//public final static byte sid = 0x44;
|
||||
private short field_1_row;
|
||||
private short field_2_col;
|
||||
private BitField rowRelative = new BitField(0x8000);
|
||||
@ -120,7 +117,7 @@ public class ReferencePtg extends Ptg
|
||||
|
||||
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+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!
|
||||
return (new CellReference(getRow(),getColumn(),!isRowRelative(),!isColRelative())).toString();
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {
|
||||
return Ptg.CLASS_REF;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -69,29 +69,29 @@ public class StringPtg
|
||||
public final static byte sid = 0x17;
|
||||
private String field_1_value;
|
||||
|
||||
|
||||
|
||||
/** Create a StringPtg from a byte array read from disk */
|
||||
public StringPtg(byte [] data, int offset)
|
||||
{
|
||||
setValue(new String(data, offset+3, data[offset+1] + 256*data[offset+2]));
|
||||
}
|
||||
|
||||
|
||||
/** Create a StringPtg from a string representation of the number
|
||||
* Number format is not checked, it is expected to be validated in the parser
|
||||
* that calls this method.
|
||||
* that calls this method.
|
||||
* @param value : String representation of a floating point number
|
||||
*/
|
||||
protected StringPtg(String value) {
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void setValue(String value)
|
||||
{
|
||||
field_1_value = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
return field_1_value;
|
||||
@ -114,6 +114,9 @@ public class StringPtg
|
||||
{
|
||||
return getValue();
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {
|
||||
return Ptg.CLASS_VALUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -95,4 +95,7 @@ public class UnknownPtg
|
||||
{
|
||||
return "UNKNOWN";
|
||||
}
|
||||
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
|
||||
|
||||
|
||||
}
|
||||
|
@ -768,6 +768,8 @@ extends TestCase {
|
||||
c.setCellFormula("AVERAGE(A2:A3)");
|
||||
c=r.createCell( (short) 4);
|
||||
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) 2);c=r.createCell( (short) 0); c.setCellValue(3.0);
|
||||
|
Loading…
Reference in New Issue
Block a user