package org.apache.poi.ss.formula;
-import org.apache.poi.hssf.record.formula.NamePtg;
-import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.formula.ptg.NamePtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
/**
* Abstracts a name record for formula evaluation.<br/>
*
package org.apache.poi.ss.formula;
-import org.apache.poi.hssf.record.formula.NamePtg;
-import org.apache.poi.hssf.record.formula.NameXPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.formula.ptg.NamePtg;
+import org.apache.poi.ss.formula.ptg.NameXPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
/**
* Abstracts a workbook for the purpose of formula evaluation.<br/>
package org.apache.poi.ss.formula;
/**
- * Should be implemented by any {@link org.apache.poi.hssf.record.formula.Ptg} subclass that needs has an extern sheet index <br/>
+ * Should be implemented by any {@link org.apache.poi.ss.formula.ptg.Ptg} subclass that needs has an extern sheet index <br/>
*
* For POI internal use only
*
import java.util.Arrays;
-import org.apache.poi.hssf.record.formula.ExpPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.TblPtg;
-import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.ss.formula.ptg.ExpPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.formula.ptg.TblPtg;
+import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianByteArrayInputStream;
import org.apache.poi.util.LittleEndianInput;
import java.util.List;
import java.util.regex.Pattern;
-import org.apache.poi.hssf.record.constant.ErrorConstant;
-import org.apache.poi.hssf.record.formula.*;
+import org.apache.poi.ss.formula.constant.ErrorConstant;
+import org.apache.poi.ss.formula.ptg.*;
import org.apache.poi.ss.formula.function.FunctionMetadata;
import org.apache.poi.ss.formula.function.FunctionMetadataRegistry;
import org.apache.poi.ss.usermodel.ErrorConstants;
package org.apache.poi.ss.formula;
-import org.apache.poi.hssf.record.formula.NameXPtg;
+import org.apache.poi.ss.formula.ptg.NameXPtg;
import org.apache.poi.ss.SpreadsheetVersion;
/**
import java.util.Stack;
-import org.apache.poi.hssf.record.formula.AttrPtg;
-import org.apache.poi.hssf.record.formula.MemAreaPtg;
-import org.apache.poi.hssf.record.formula.MemErrPtg;
-import org.apache.poi.hssf.record.formula.MemFuncPtg;
-import org.apache.poi.hssf.record.formula.OperationPtg;
-import org.apache.poi.hssf.record.formula.ParenthesisPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.formula.ptg.AttrPtg;
+import org.apache.poi.ss.formula.ptg.MemAreaPtg;
+import org.apache.poi.ss.formula.ptg.MemErrPtg;
+import org.apache.poi.ss.formula.ptg.MemFuncPtg;
+import org.apache.poi.ss.formula.ptg.OperationPtg;
+import org.apache.poi.ss.formula.ptg.ParenthesisPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
/**
* Common logic for rendering formulas.<br/>
package org.apache.poi.ss.formula;
-import org.apache.poi.hssf.record.formula.NamePtg;
-import org.apache.poi.hssf.record.formula.NameXPtg;
+import org.apache.poi.ss.formula.ptg.NamePtg;
+import org.apache.poi.ss.formula.ptg.NameXPtg;
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
/**
package org.apache.poi.ss.formula;
-import org.apache.poi.hssf.record.formula.*;
+import org.apache.poi.ss.formula.ptg.*;
/**
import java.util.List;
import java.util.Map;
-import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.ss.util.CellReference;
/**
* Optimisation - compacts many blank cell references used by a single formula.
package org.apache.poi.ss.formula;
-import org.apache.poi.hssf.record.formula.AreaI;
-import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
+import org.apache.poi.ss.formula.ptg.AreaI;
+import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea;
import org.apache.poi.ss.formula.eval.AreaEval;
import org.apache.poi.ss.formula.eval.AreaEvalBase;
import org.apache.poi.ss.formula.eval.ValueEval;
-import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.ss.util.CellReference;
/**
*
package org.apache.poi.ss.formula;
-import org.apache.poi.hssf.record.formula.AreaI;
-import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
+import org.apache.poi.ss.formula.ptg.AreaI;
+import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea;
import org.apache.poi.ss.formula.eval.AreaEval;
import org.apache.poi.ss.formula.eval.RefEvalBase;
import org.apache.poi.ss.formula.eval.ValueEval;
-import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.ss.util.CellReference;
/**
*
package org.apache.poi.ss.formula;
-import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
-import org.apache.poi.hssf.record.formula.AttrPtg;
-import org.apache.poi.hssf.record.formula.ControlPtg;
-import org.apache.poi.hssf.record.formula.FuncVarPtg;
-import org.apache.poi.hssf.record.formula.MemAreaPtg;
-import org.apache.poi.hssf.record.formula.MemFuncPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.RangePtg;
-import org.apache.poi.hssf.record.formula.UnionPtg;
-import org.apache.poi.hssf.record.formula.ValueOperatorPtg;
+import org.apache.poi.ss.formula.ptg.AbstractFunctionPtg;
+import org.apache.poi.ss.formula.ptg.AttrPtg;
+import org.apache.poi.ss.formula.ptg.ControlPtg;
+import org.apache.poi.ss.formula.ptg.FuncVarPtg;
+import org.apache.poi.ss.formula.ptg.MemAreaPtg;
+import org.apache.poi.ss.formula.ptg.MemFuncPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.formula.ptg.RangePtg;
+import org.apache.poi.ss.formula.ptg.UnionPtg;
+import org.apache.poi.ss.formula.ptg.ValueOperatorPtg;
/**
* This class performs 'operand class' transformation. Non-base tokens are classified into three
package org.apache.poi.ss.formula;
-import org.apache.poi.hssf.record.formula.Area3DPtg;
-import org.apache.poi.hssf.record.formula.NameXPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.Ref3DPtg;
+import org.apache.poi.ss.formula.ptg.Area3DPtg;
+import org.apache.poi.ss.formula.ptg.NameXPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.formula.ptg.Ref3DPtg;
import org.apache.poi.ss.formula.eval.*;
import org.apache.poi.ss.formula.functions.FreeRefFunction;
import org.apache.poi.ss.SpreadsheetVersion;
import java.util.HashMap;
import java.util.Map;
-import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
-import org.apache.poi.hssf.record.formula.AddPtg;
-import org.apache.poi.hssf.record.formula.ConcatPtg;
-import org.apache.poi.hssf.record.formula.DividePtg;
-import org.apache.poi.hssf.record.formula.EqualPtg;
-import org.apache.poi.hssf.record.formula.GreaterEqualPtg;
-import org.apache.poi.hssf.record.formula.GreaterThanPtg;
-import org.apache.poi.hssf.record.formula.IntersectionPtg;
-import org.apache.poi.hssf.record.formula.LessEqualPtg;
-import org.apache.poi.hssf.record.formula.LessThanPtg;
-import org.apache.poi.hssf.record.formula.MultiplyPtg;
-import org.apache.poi.hssf.record.formula.NotEqualPtg;
-import org.apache.poi.hssf.record.formula.OperationPtg;
-import org.apache.poi.hssf.record.formula.PercentPtg;
-import org.apache.poi.hssf.record.formula.PowerPtg;
-import org.apache.poi.hssf.record.formula.RangePtg;
-import org.apache.poi.hssf.record.formula.SubtractPtg;
-import org.apache.poi.hssf.record.formula.UnaryMinusPtg;
-import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
+import org.apache.poi.ss.formula.ptg.AbstractFunctionPtg;
+import org.apache.poi.ss.formula.ptg.AddPtg;
+import org.apache.poi.ss.formula.ptg.ConcatPtg;
+import org.apache.poi.ss.formula.ptg.DividePtg;
+import org.apache.poi.ss.formula.ptg.EqualPtg;
+import org.apache.poi.ss.formula.ptg.GreaterEqualPtg;
+import org.apache.poi.ss.formula.ptg.GreaterThanPtg;
+import org.apache.poi.ss.formula.ptg.IntersectionPtg;
+import org.apache.poi.ss.formula.ptg.LessEqualPtg;
+import org.apache.poi.ss.formula.ptg.LessThanPtg;
+import org.apache.poi.ss.formula.ptg.MultiplyPtg;
+import org.apache.poi.ss.formula.ptg.NotEqualPtg;
+import org.apache.poi.ss.formula.ptg.OperationPtg;
+import org.apache.poi.ss.formula.ptg.PercentPtg;
+import org.apache.poi.ss.formula.ptg.PowerPtg;
+import org.apache.poi.ss.formula.ptg.RangePtg;
+import org.apache.poi.ss.formula.ptg.SubtractPtg;
+import org.apache.poi.ss.formula.ptg.UnaryMinusPtg;
+import org.apache.poi.ss.formula.ptg.UnaryPlusPtg;
import org.apache.poi.ss.formula.eval.ConcatEval;
import org.apache.poi.ss.formula.eval.FunctionEval;
import org.apache.poi.ss.formula.eval.IntersectionEval;
package org.apache.poi.ss.formula;
-import org.apache.poi.hssf.record.formula.ArrayPtg;
-import org.apache.poi.hssf.record.formula.AttrPtg;
-import org.apache.poi.hssf.record.formula.FuncVarPtg;
-import org.apache.poi.hssf.record.formula.MemAreaPtg;
-import org.apache.poi.hssf.record.formula.MemFuncPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.formula.ptg.ArrayPtg;
+import org.apache.poi.ss.formula.ptg.AttrPtg;
+import org.apache.poi.ss.formula.ptg.FuncVarPtg;
+import org.apache.poi.ss.formula.ptg.MemAreaPtg;
+import org.apache.poi.ss.formula.ptg.MemFuncPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.function.FunctionMetadataRegistry;
/**
* Represents a syntactic element from a formula by encapsulating the corresponding <tt>Ptg</tt>
==================================================================== */\r
package org.apache.poi.ss.formula;\r
\r
-import org.apache.poi.hssf.record.formula.*;\r
+import org.apache.poi.ss.formula.ptg.*;\r
import org.apache.poi.ss.SpreadsheetVersion;\r
\r
/**\r
\r
/**\r
* Creates a non shared formula from the shared formula counterpart, i.e.\r
- * Converts the shared formula into the equivalent {@link org.apache.poi.hssf.record.formula.Ptg} array that it would have,\r
+ * Converts the shared formula into the equivalent {@link org.apache.poi.ss.formula.ptg.Ptg} array that it would have,\r
* were it not shared.\r
*\r
* @param ptgs parsed tokens of the shared formula\r
package org.apache.poi.ss.formula;
/**
- * Should be implemented by any {@link org.apache.poi.hssf.record.formula.Ptg} subclass that needs a workbook to render its formula.
+ * Should be implemented by any {@link org.apache.poi.ss.formula.ptg.Ptg} subclass that needs a workbook to render its formula.
* <br/>
*
* For POI internal use only
import java.util.Map;
import java.util.Stack;
-import org.apache.poi.hssf.record.formula.Area3DPtg;
-import org.apache.poi.hssf.record.formula.AreaErrPtg;
-import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.AttrPtg;
-import org.apache.poi.hssf.record.formula.BoolPtg;
-import org.apache.poi.hssf.record.formula.ControlPtg;
-import org.apache.poi.hssf.record.formula.DeletedArea3DPtg;
-import org.apache.poi.hssf.record.formula.DeletedRef3DPtg;
-import org.apache.poi.hssf.record.formula.ErrPtg;
-import org.apache.poi.hssf.record.formula.ExpPtg;
-import org.apache.poi.hssf.record.formula.FuncVarPtg;
-import org.apache.poi.hssf.record.formula.IntPtg;
-import org.apache.poi.hssf.record.formula.MemAreaPtg;
-import org.apache.poi.hssf.record.formula.MemErrPtg;
-import org.apache.poi.hssf.record.formula.MemFuncPtg;
-import org.apache.poi.hssf.record.formula.MissingArgPtg;
-import org.apache.poi.hssf.record.formula.NamePtg;
-import org.apache.poi.hssf.record.formula.NameXPtg;
-import org.apache.poi.hssf.record.formula.NumberPtg;
-import org.apache.poi.hssf.record.formula.OperationPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.Ref3DPtg;
-import org.apache.poi.hssf.record.formula.RefErrorPtg;
-import org.apache.poi.hssf.record.formula.RefPtg;
-import org.apache.poi.hssf.record.formula.StringPtg;
-import org.apache.poi.hssf.record.formula.UnionPtg;
-import org.apache.poi.hssf.record.formula.UnknownPtg;
+import org.apache.poi.ss.formula.ptg.Area3DPtg;
+import org.apache.poi.ss.formula.ptg.AreaErrPtg;
+import org.apache.poi.ss.formula.ptg.AreaPtg;
+import org.apache.poi.ss.formula.ptg.AttrPtg;
+import org.apache.poi.ss.formula.ptg.BoolPtg;
+import org.apache.poi.ss.formula.ptg.ControlPtg;
+import org.apache.poi.ss.formula.ptg.DeletedArea3DPtg;
+import org.apache.poi.ss.formula.ptg.DeletedRef3DPtg;
+import org.apache.poi.ss.formula.ptg.ErrPtg;
+import org.apache.poi.ss.formula.ptg.ExpPtg;
+import org.apache.poi.ss.formula.ptg.FuncVarPtg;
+import org.apache.poi.ss.formula.ptg.IntPtg;
+import org.apache.poi.ss.formula.ptg.MemAreaPtg;
+import org.apache.poi.ss.formula.ptg.MemErrPtg;
+import org.apache.poi.ss.formula.ptg.MemFuncPtg;
+import org.apache.poi.ss.formula.ptg.MissingArgPtg;
+import org.apache.poi.ss.formula.ptg.NamePtg;
+import org.apache.poi.ss.formula.ptg.NameXPtg;
+import org.apache.poi.ss.formula.ptg.NumberPtg;
+import org.apache.poi.ss.formula.ptg.OperationPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.formula.ptg.Ref3DPtg;
+import org.apache.poi.ss.formula.ptg.RefErrorPtg;
+import org.apache.poi.ss.formula.ptg.RefPtg;
+import org.apache.poi.ss.formula.ptg.StringPtg;
+import org.apache.poi.ss.formula.ptg.UnionPtg;
+import org.apache.poi.ss.formula.ptg.UnknownPtg;
import org.apache.poi.ss.formula.eval.BlankEval;
import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.functions.IfFunc;
import org.apache.poi.ss.formula.udf.UDFFinder;
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
-import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException;
import org.apache.poi.ss.formula.eval.NotImplementedException;
import org.apache.poi.ss.usermodel.Cell;
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.constant;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * To support Constant Values (2.5.7) as required by the CRN record.
+ * This class is also used for two dimensional arrays which are encoded by
+ * EXTERNALNAME (5.39) records and Array tokens.<p/>
+ *
+ * @author Josh Micich
+ */
+public final class ConstantValueParser {
+ // note - these (non-combinable) enum values are sparse.
+ private static final int TYPE_EMPTY = 0;
+ private static final int TYPE_NUMBER = 1;
+ private static final int TYPE_STRING = 2;
+ private static final int TYPE_BOOLEAN = 4;
+ private static final int TYPE_ERROR_CODE = 16; // TODO - update OOO document to include this value
+
+ private static final int TRUE_ENCODING = 1;
+ private static final int FALSE_ENCODING = 0;
+
+ // TODO - is this the best way to represent 'EMPTY'?
+ private static final Object EMPTY_REPRESENTATION = null;
+
+ private ConstantValueParser() {
+ // no instances of this class
+ }
+
+ public static Object[] parse(LittleEndianInput in, int nValues) {
+ Object[] result = new Object[nValues];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = readAConstantValue(in);
+ }
+ return result;
+ }
+
+ private static Object readAConstantValue(LittleEndianInput in) {
+ byte grbit = in.readByte();
+ switch(grbit) {
+ case TYPE_EMPTY:
+ in.readLong(); // 8 byte 'not used' field
+ return EMPTY_REPRESENTATION;
+ case TYPE_NUMBER:
+ return new Double(in.readDouble());
+ case TYPE_STRING:
+ return StringUtil.readUnicodeString(in);
+ case TYPE_BOOLEAN:
+ return readBoolean(in);
+ case TYPE_ERROR_CODE:
+ int errCode = in.readUShort();
+ // next 6 bytes are unused
+ in.readUShort();
+ in.readInt();
+ return ErrorConstant.valueOf(errCode);
+ }
+ throw new RuntimeException("Unknown grbit value (" + grbit + ")");
+ }
+
+ private static Object readBoolean(LittleEndianInput in) {
+ byte val = (byte)in.readLong(); // 7 bytes 'not used'
+ switch(val) {
+ case FALSE_ENCODING:
+ return Boolean.FALSE;
+ case TRUE_ENCODING:
+ return Boolean.TRUE;
+ }
+ // Don't tolerate unusual boolean encoded values (unless it becomes evident that they occur)
+ throw new RuntimeException("unexpected boolean encoding (" + val + ")");
+ }
+
+ public static int getEncodedSize(Object[] values) {
+ // start with one byte 'type' code for each value
+ int result = values.length * 1;
+ for (int i = 0; i < values.length; i++) {
+ result += getEncodedSize(values[i]);
+ }
+ return result;
+ }
+
+ /**
+ * @return encoded size without the 'type' code byte
+ */
+ private static int getEncodedSize(Object object) {
+ if(object == EMPTY_REPRESENTATION) {
+ return 8;
+ }
+ Class cls = object.getClass();
+
+ if(cls == Boolean.class || cls == Double.class || cls == ErrorConstant.class) {
+ return 8;
+ }
+ String strVal = (String)object;
+ return StringUtil.getEncodedSize(strVal);
+ }
+
+ public static void encode(LittleEndianOutput out, Object[] values) {
+ for (int i = 0; i < values.length; i++) {
+ encodeSingleValue(out, values[i]);
+ }
+ }
+
+ private static void encodeSingleValue(LittleEndianOutput out, Object value) {
+ if (value == EMPTY_REPRESENTATION) {
+ out.writeByte(TYPE_EMPTY);
+ out.writeLong(0L);
+ return;
+ }
+ if (value instanceof Boolean) {
+ Boolean bVal = ((Boolean)value);
+ out.writeByte(TYPE_BOOLEAN);
+ long longVal = bVal.booleanValue() ? 1L : 0L;
+ out.writeLong(longVal);
+ return;
+ }
+ if (value instanceof Double) {
+ Double dVal = (Double) value;
+ out.writeByte(TYPE_NUMBER);
+ out.writeDouble(dVal.doubleValue());
+ return;
+ }
+ if (value instanceof String) {
+ String val = (String) value;
+ out.writeByte(TYPE_STRING);
+ StringUtil.writeUnicodeString(out, val);
+ return;
+ }
+ if (value instanceof ErrorConstant) {
+ ErrorConstant ecVal = (ErrorConstant) value;
+ out.writeByte(TYPE_ERROR_CODE);
+ long longVal = ecVal.getErrorCode();
+ out.writeLong(longVal);
+ return;
+ }
+
+ throw new IllegalStateException("Unexpected value type (" + value.getClass().getName() + "'");
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.constant;
+
+import org.apache.poi.ss.usermodel.ErrorConstants;
+/**
+ * Represents a constant error code value as encoded in a constant values array. <p/>
+ *
+ * This class is a type-safe wrapper for a 16-bit int value performing a similar job to
+ * <tt>ErrorEval</tt>.
+ *
+ * @author Josh Micich
+ */
+public class ErrorConstant {
+ // convenient access to name space
+ private static final ErrorConstants EC = null;
+
+ private static final ErrorConstant NULL = new ErrorConstant(EC.ERROR_NULL);
+ private static final ErrorConstant DIV_0 = new ErrorConstant(EC.ERROR_DIV_0);
+ private static final ErrorConstant VALUE = new ErrorConstant(EC.ERROR_VALUE);
+ private static final ErrorConstant REF = new ErrorConstant(EC.ERROR_REF);
+ private static final ErrorConstant NAME = new ErrorConstant(EC.ERROR_NAME);
+ private static final ErrorConstant NUM = new ErrorConstant(EC.ERROR_NUM);
+ private static final ErrorConstant NA = new ErrorConstant(EC.ERROR_NA);
+
+ private final int _errorCode;
+
+ private ErrorConstant(int errorCode) {
+ _errorCode = errorCode;
+ }
+
+ public int getErrorCode() {
+ return _errorCode;
+ }
+ public String getText() {
+ if(ErrorConstants.isValidCode(_errorCode)) {
+ return ErrorConstants.getText(_errorCode);
+ }
+ return "unknown error code (" + _errorCode + ")";
+ }
+
+ public static ErrorConstant valueOf(int errorCode) {
+ switch (errorCode) {
+ case ErrorConstants.ERROR_NULL: return NULL;
+ case ErrorConstants.ERROR_DIV_0: return DIV_0;
+ case ErrorConstants.ERROR_VALUE: return VALUE;
+ case ErrorConstants.ERROR_REF: return REF;
+ case ErrorConstants.ERROR_NAME: return NAME;
+ case ErrorConstants.ERROR_NUM: return NUM;
+ case ErrorConstants.ERROR_NA: return NA;
+ }
+ System.err.println("Warning - unexpected error code (" + errorCode + ")");
+ return new ErrorConstant(errorCode);
+ }
+ public String toString() {
+ StringBuffer sb = new StringBuffer(64);
+ sb.append(getClass().getName()).append(" [");
+ sb.append(getText());
+ sb.append("]");
+ return sb.toString();
+ }
+}
package org.apache.poi.ss.formula.eval;
-import org.apache.poi.hssf.record.formula.AreaI;
+import org.apache.poi.ss.formula.ptg.AreaI;
/**
* @author Josh Micich
package org.apache.poi.ss.formula.eval;
-import org.apache.poi.hssf.record.formula.NameXPtg;
+import org.apache.poi.ss.formula.ptg.NameXPtg;
/**
* @author Josh Micich
*/
package org.apache.poi.ss.formula.eval;
-import org.apache.poi.hssf.record.formula.IntPtg;
-import org.apache.poi.hssf.record.formula.NumberPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.formula.ptg.IntPtg;
+import org.apache.poi.ss.formula.ptg.NumberPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.util.NumberToTextConverter;
/**
package org.apache.poi.ss.formula.eval;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.StringPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.formula.ptg.StringPtg;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
import java.util.HashMap;
import java.util.Map;
-import org.apache.poi.hssf.record.formula.NamePtg;
-import org.apache.poi.hssf.record.formula.NameXPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.formula.ptg.NamePtg;
+import org.apache.poi.ss.formula.ptg.NameXPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.EvaluationCell;
import org.apache.poi.ss.formula.EvaluationName;
import org.apache.poi.ss.formula.EvaluationSheet;
import java.util.Set;
import java.util.regex.Pattern;
-import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.ss.formula.ptg.Ptg;
/**
* Converts the text meta-data file into a <tt>FunctionMetadataRegistry</tt>
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.formula.function.FunctionMetadata;
+import org.apache.poi.ss.formula.function.FunctionMetadataRegistry;
+
+
+/**
+ * This class provides the base functionality for Excel sheet functions
+ * There are two kinds of function Ptgs - tFunc and tFuncVar
+ * Therefore, this class will have ONLY two subclasses
+ * @author Avik Sengupta
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ */
+public abstract class AbstractFunctionPtg extends OperationPtg {
+
+ /**
+ * The name of the IF function (i.e. "IF"). Extracted as a constant for clarity.
+ */
+ public static final String FUNCTION_NAME_IF = "IF";
+ /** All external functions have function index 255 */
+ private static final short FUNCTION_INDEX_EXTERNAL = 255;
+
+ private final byte returnClass;
+ private final byte[] paramClass;
+
+ private final byte _numberOfArgs;
+ private final short _functionIndex;
+
+ protected AbstractFunctionPtg(int functionIndex, int pReturnClass, byte[] paramTypes, int nParams) {
+ _numberOfArgs = (byte) nParams;
+ _functionIndex = (short) functionIndex;
+ returnClass = (byte) pReturnClass;
+ paramClass = paramTypes;
+ }
+ public final boolean isBaseToken() {
+ return false;
+ }
+
+ public final String toString() {
+ StringBuilder sb = new StringBuilder(64);
+ sb.append(getClass().getName()).append(" [");
+ sb.append(lookupName(_functionIndex));
+ sb.append(" nArgs=").append(_numberOfArgs);
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public final short getFunctionIndex() {
+ return _functionIndex;
+ }
+ public final int getNumberOfOperands() {
+ return _numberOfArgs;
+ }
+
+ public final String getName() {
+ return lookupName(_functionIndex);
+ }
+ /**
+ * external functions get some special processing
+ * @return <code>true</code> if this is an external function
+ */
+ public final boolean isExternalFunction() {
+ return _functionIndex == FUNCTION_INDEX_EXTERNAL;
+ }
+
+ public final String toFormulaString() {
+ return getName();
+ }
+
+ public String toFormulaString(String[] operands) {
+ StringBuilder buf = new StringBuilder();
+
+ if(isExternalFunction()) {
+ buf.append(operands[0]); // first operand is actually the function name
+ appendArgs(buf, 1, operands);
+ } else {
+ buf.append(getName());
+ appendArgs(buf, 0, operands);
+ }
+ return buf.toString();
+ }
+
+ private static void appendArgs(StringBuilder buf, int firstArgIx, String[] operands) {
+ buf.append('(');
+ for (int i=firstArgIx;i<operands.length;i++) {
+ if (i>firstArgIx) {
+ buf.append(',');
+ }
+ buf.append(operands[i]);
+ }
+ buf.append(")");
+ }
+
+ public abstract int getSize();
+
+
+ /**
+ * Used to detect whether a function name found in a formula is one of the standard excel functions
+ * <p>
+ * The name matching is case insensitive.
+ * @return <code>true</code> if the name specifies a standard worksheet function,
+ * <code>false</code> if the name should be assumed to be an external function.
+ */
+ public static final boolean isBuiltInFunctionName(String name) {
+ short ix = FunctionMetadataRegistry.lookupIndexByName(name.toUpperCase());
+ return ix >= 0;
+ }
+
+ protected final String lookupName(short index) {
+ if(index == FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL) {
+ return "#external#";
+ }
+ FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(index);
+ if(fm == null) {
+ throw new RuntimeException("bad function index (" + index + ")");
+ }
+ return fm.getName();
+ }
+
+ /**
+ * Resolves internal function names into function indexes.
+ * <p>
+ * The name matching is case insensitive.
+ * @return the standard worksheet function index if found, otherwise <tt>FUNCTION_INDEX_EXTERNAL</tt>
+ */
+ protected static short lookupIndex(String name) {
+ short ix = FunctionMetadataRegistry.lookupIndexByName(name.toUpperCase());
+ if (ix < 0) {
+ return FUNCTION_INDEX_EXTERNAL;
+ }
+ return ix;
+ }
+
+ public byte getDefaultOperandClass() {
+ return returnClass;
+ }
+
+ public final byte getParameterClass(int index) {
+ if (index >= paramClass.length) {
+ // For var-arg (and other?) functions, the metadata does not list all the parameter
+ // operand classes. In these cases, all extra parameters are assumed to have the
+ // same operand class as the last one specified.
+ return paramClass[paramClass.length - 1];
+ }
+ return paramClass[index];
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * Addition operator PTG the "+" binomial operator. If you need more
+ * explanation than that then well...We really can't help you here.
+ * @author Andrew C. Oliver (acoliver@apache.org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class AddPtg extends ValueOperatorPtg {
+ public final static byte sid = 0x03;
+
+ private final static String ADD = "+";
+
+ public static final ValueOperatorPtg instance = new AddPtg();
+
+ private AddPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 2;
+ }
+
+ /** implementation of method from OperationsPtg*/
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(operands[ 0 ]);
+ buffer.append(ADD);
+ buffer.append(operands[ 1 ]);
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Common superclass of 2-D area refs
+ */
+public abstract class Area2DPtgBase extends AreaPtgBase {
+ private final static int SIZE = 9;
+
+ protected Area2DPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+ super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
+ }
+ protected Area2DPtgBase(AreaReference ar) {
+ super(ar);
+ }
+
+ protected Area2DPtgBase(LittleEndianInput in) {
+ readCoordinates(in);
+ }
+
+ protected abstract byte getSid();
+
+ public final void write(LittleEndianOutput out) {
+ out.writeByte(getSid() + getPtgClass());
+ writeCoordinates(out);
+ }
+
+ public final int getSize() {
+ return SIZE;
+ }
+
+ public final String toFormulaString() {
+ return formatReferenceAsString();
+ }
+
+ public final String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append(" [");
+ sb.append(formatReferenceAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.ss.formula.ExternSheetReferenceToken;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: Area 3D Ptg - 3D reference (Sheet + Area)<P>
+ * Description: Defined a area in Extern Sheet. <P>
+ * REFERENCE: <P>
+ * @author Libin Roman (Vista Portal LDT. Developer)
+ * @author avik
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class Area3DPtg extends AreaPtgBase implements WorkbookDependentFormula, ExternSheetReferenceToken {
+ public final static byte sid = 0x3b;
+ private final static int SIZE = 11; // 10 + 1 for Ptg
+
+ private int field_1_index_extern_sheet;
+
+
+ public Area3DPtg(String arearef, int externIdx) {
+ super(new AreaReference(arearef));
+ setExternSheetIndex(externIdx);
+ }
+
+ public Area3DPtg(LittleEndianInput in) {
+ field_1_index_extern_sheet = in.readShort();
+ readCoordinates(in);
+ }
+
+ public Area3DPtg(int firstRow, int lastRow, int firstColumn, int lastColumn,
+ boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative,
+ int externalSheetIndex) {
+ super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
+ setExternSheetIndex(externalSheetIndex);
+ }
+
+ public Area3DPtg(AreaReference arearef, int externIdx) {
+ super(arearef);
+ setExternSheetIndex(externIdx);
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append(" [");
+ sb.append("sheetIx=").append(getExternSheetIndex());
+ sb.append(" ! ");
+ sb.append(formatReferenceAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeShort(field_1_index_extern_sheet);
+ writeCoordinates(out);
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public int getExternSheetIndex() {
+ return field_1_index_extern_sheet;
+ }
+
+ public void setExternSheetIndex(int index) {
+ field_1_index_extern_sheet = index;
+ }
+ public String format2DRefAsString() {
+ return formatReferenceAsString();
+ }
+ /**
+ * @return text representation of this area reference that can be used in text
+ * formulas. The sheet name will get properly delimited if required.
+ */
+ public String toFormulaString(FormulaRenderingWorkbook book) {
+ return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, formatReferenceAsString());
+ }
+ public String toFormulaString() {
+ throw new RuntimeException("3D references need a workbook to determine formula text");
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.usermodel.ErrorConstants;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * AreaErr - handles deleted cell area references.
+ *
+ * @author Daniel Noll (daniel at nuix dot com dot au)
+ */
+public final class AreaErrPtg extends OperandPtg {
+ public final static byte sid = 0x2B;
+ private final int unused1;
+ private final int unused2;
+
+ public AreaErrPtg() {
+ unused1 = 0;
+ unused2 = 0;
+ }
+
+ public AreaErrPtg(LittleEndianInput in) {
+ // 8 bytes unused:
+ unused1 = in.readInt();
+ unused2 = in.readInt();
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeInt(unused1);
+ out.writeInt(unused2);
+ }
+
+ public String toFormulaString() {
+ return ErrorConstants.getText(ErrorConstants.ERROR_REF);
+ }
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
+
+ public int getSize() {
+ return 9;
+ }
+}
+
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * Common interface for AreaPtg and Area3DPtg, and their child classes.
+ */
+public interface AreaI {
+ /**
+ * @return the first row in the area
+ */
+ public int getFirstRow();
+
+ /**
+ * @return last row in the range (x2 in x1,y1-x2,y2)
+ */
+ public int getLastRow();
+
+ /**
+ * @return the first column number in the area.
+ */
+ public int getFirstColumn();
+
+ /**
+ * @return lastcolumn in the area
+ */
+ public int getLastColumn();
+
+ class OffsetArea implements AreaI {
+
+ private final int _firstColumn;
+ private final int _firstRow;
+ private final int _lastColumn;
+ private final int _lastRow;
+
+ public OffsetArea(int baseRow, int baseColumn, int relFirstRowIx, int relLastRowIx,
+ int relFirstColIx, int relLastColIx) {
+ _firstRow = baseRow + Math.min(relFirstRowIx, relLastRowIx);
+ _lastRow = baseRow + Math.max(relFirstRowIx, relLastRowIx);
+ _firstColumn = baseColumn + Math.min(relFirstColIx, relLastColIx);
+ _lastColumn = baseColumn + Math.max(relFirstColIx, relLastColIx);
+ }
+
+ public int getFirstColumn() {
+ return _firstColumn;
+ }
+
+ public int getFirstRow() {
+ return _firstRow;
+ }
+
+ public int getLastColumn() {
+ return _lastColumn;
+ }
+
+ public int getLastRow() {
+ return _lastRow;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianInput;
+
+/**
+ * Specifies a rectangular area of cells A1:A4 for instance.
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class AreaNPtg extends Area2DPtgBase {
+ public final static short sid = 0x2D;
+
+ public AreaNPtg(LittleEndianInput in) {
+ super(in);
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.util.LittleEndianInput;
+
+/**
+ * Specifies a rectangular area of cells A1:A4 for instance.
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class AreaPtg extends Area2DPtgBase {
+ public final static short sid = 0x25;
+
+ public AreaPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+ super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
+ }
+ public AreaPtg(LittleEndianInput in) {
+ super(in);
+ }
+ public AreaPtg(String arearef) {
+ super(new AreaReference(arearef));
+ }
+ public AreaPtg(AreaReference areaRef) {
+ super(areaRef);
+ }
+ protected byte getSid() {
+ return sid;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Specifies a rectangular area of cells A1:A4 for instance.
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public abstract class AreaPtgBase extends OperandPtg implements AreaI {
+ /**
+ * TODO - (May-2008) fix subclasses of AreaPtg 'AreaN~' which are used in shared formulas.
+ * see similar comment in ReferencePtg
+ */
+ protected final RuntimeException notImplemented() {
+ return new RuntimeException("Coding Error: This method should never be called. This ptg should be converted");
+ }
+
+ /** zero based, unsigned 16 bit */
+ private int field_1_first_row;
+ /** zero based, unsigned 16 bit */
+ private int field_2_last_row;
+ /** zero based, unsigned 8 bit */
+ private int field_3_first_column;
+ /** zero based, unsigned 8 bit */
+ private int field_4_last_column;
+
+ private final static BitField rowRelative = BitFieldFactory.getInstance(0x8000);
+ private final static BitField colRelative = BitFieldFactory.getInstance(0x4000);
+ private final static BitField columnMask = BitFieldFactory.getInstance(0x3FFF);
+
+ protected AreaPtgBase() {
+ // do nothing
+ }
+
+ protected AreaPtgBase(AreaReference ar) {
+ CellReference firstCell = ar.getFirstCell();
+ CellReference lastCell = ar.getLastCell();
+ setFirstRow(firstCell.getRow());
+ setFirstColumn(firstCell.getCol() == -1 ? 0 : firstCell.getCol());
+ setLastRow(lastCell.getRow());
+ setLastColumn(lastCell.getCol() == -1 ? 0xFF : lastCell.getCol());
+ setFirstColRelative(!firstCell.isColAbsolute());
+ setLastColRelative(!lastCell.isColAbsolute());
+ setFirstRowRelative(!firstCell.isRowAbsolute());
+ setLastRowRelative(!lastCell.isRowAbsolute());
+ }
+
+ protected AreaPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn,
+ boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
+
+ if (lastRow > firstRow) {
+ setFirstRow(firstRow);
+ setLastRow(lastRow);
+ setFirstRowRelative(firstRowRelative);
+ setLastRowRelative(lastRowRelative);
+ } else {
+ setFirstRow(lastRow);
+ setLastRow(firstRow);
+ setFirstRowRelative(lastRowRelative);
+ setLastRowRelative(firstRowRelative);
+ }
+
+ if (lastColumn > firstColumn) {
+ setFirstColumn(firstColumn);
+ setLastColumn(lastColumn);
+ setFirstColRelative(firstColRelative);
+ setLastColRelative(lastColRelative);
+ } else {
+ setFirstColumn(lastColumn);
+ setLastColumn(firstColumn);
+ setFirstColRelative(lastColRelative);
+ setLastColRelative(firstColRelative);
+ }
+ }
+
+ protected final void readCoordinates(LittleEndianInput in) {
+ field_1_first_row = in.readUShort();
+ field_2_last_row = in.readUShort();
+ field_3_first_column = in.readUShort();
+ field_4_last_column = in.readUShort();
+ }
+ protected final void writeCoordinates(LittleEndianOutput out) {
+ out.writeShort(field_1_first_row);
+ out.writeShort(field_2_last_row);
+ out.writeShort(field_3_first_column);
+ out.writeShort(field_4_last_column);
+ }
+
+ /**
+ * @return the first row in the area
+ */
+ public final int getFirstRow() {
+ return field_1_first_row;
+ }
+
+ /**
+ * sets the first row
+ * @param rowIx number (0-based)
+ */
+ public final void setFirstRow(int rowIx) {
+ field_1_first_row = rowIx;
+ }
+
+ /**
+ * @return last row in the range (x2 in x1,y1-x2,y2)
+ */
+ public final int getLastRow() {
+ return field_2_last_row;
+ }
+
+ /**
+ * @param rowIx last row number in the area
+ */
+ public final void setLastRow(int rowIx) {
+ field_2_last_row = rowIx;
+ }
+
+ /**
+ * @return the first column number in the area.
+ */
+ public final int getFirstColumn() {
+ return columnMask.getValue(field_3_first_column);
+ }
+
+ /**
+ * @return the first column number + the options bit settings unstripped
+ */
+ public final short getFirstColumnRaw() {
+ return (short) field_3_first_column; // TODO
+ }
+
+ /**
+ * @return whether or not the first row is a relative reference or not.
+ */
+ public final boolean isFirstRowRelative() {
+ return rowRelative.isSet(field_3_first_column);
+ }
+
+ /**
+ * sets the first row to relative or not
+ * @param rel is relative or not.
+ */
+ public final void setFirstRowRelative(boolean rel) {
+ field_3_first_column=rowRelative.setBoolean(field_3_first_column,rel);
+ }
+
+ /**
+ * @return isrelative first column to relative or not
+ */
+ public final boolean isFirstColRelative() {
+ return colRelative.isSet(field_3_first_column);
+ }
+
+ /**
+ * set whether the first column is relative
+ */
+ public final void setFirstColRelative(boolean rel) {
+ field_3_first_column=colRelative.setBoolean(field_3_first_column,rel);
+ }
+
+ /**
+ * set the first column in the area
+ */
+ public final void setFirstColumn(int colIx) {
+ field_3_first_column=columnMask.setValue(field_3_first_column, colIx);
+ }
+
+ /**
+ * set the first column irrespective of the bitmasks
+ */
+ public final void setFirstColumnRaw(int column) {
+ field_3_first_column = column;
+ }
+
+ /**
+ * @return lastcolumn in the area
+ */
+ public final int getLastColumn() {
+ return columnMask.getValue(field_4_last_column);
+ }
+
+ /**
+ * @return last column and bitmask (the raw field)
+ */
+ public final short getLastColumnRaw() {
+ return (short) field_4_last_column;
+ }
+
+ /**
+ * @return last row relative or not
+ */
+ public final boolean isLastRowRelative() {
+ return rowRelative.isSet(field_4_last_column);
+ }
+
+ /**
+ * set whether the last row is relative or not
+ * @param rel <code>true</code> if the last row relative, else
+ * <code>false</code>
+ */
+ public final void setLastRowRelative(boolean rel) {
+ field_4_last_column=rowRelative.setBoolean(field_4_last_column,rel);
+ }
+
+ /**
+ * @return lastcol relative or not
+ */
+ public final boolean isLastColRelative() {
+ return colRelative.isSet(field_4_last_column);
+ }
+
+ /**
+ * set whether the last column should be relative or not
+ */
+ public final void setLastColRelative(boolean rel) {
+ field_4_last_column=colRelative.setBoolean(field_4_last_column,rel);
+ }
+
+ /**
+ * set the last column in the area
+ */
+ public final void setLastColumn(int colIx) {
+ field_4_last_column=columnMask.setValue(field_4_last_column, colIx);
+ }
+
+ /**
+ * set the last column irrespective of the bitmasks
+ */
+ public final void setLastColumnRaw(short column) {
+ field_4_last_column = column;
+ }
+ protected final String formatReferenceAsString() {
+ CellReference topLeft = new CellReference(getFirstRow(),getFirstColumn(),!isFirstRowRelative(),!isFirstColRelative());
+ CellReference botRight = new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative());
+
+ if(AreaReference.isWholeColumnReference(topLeft, botRight)) {
+ return (new AreaReference(topLeft, botRight)).formatAsString();
+ }
+ return topLeft.formatAsString() + ":" + botRight.formatAsString();
+ }
+
+ public String toFormulaString() {
+ return formatReferenceAsString();
+ }
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.formula.constant.ConstantValueParser;
+import org.apache.poi.ss.formula.constant.ErrorConstant;
+import org.apache.poi.ss.util.NumberToTextConverter;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * ArrayPtg - handles arrays
+ *
+ * The ArrayPtg is a little weird, the size of the Ptg when parsing initially only
+ * includes the Ptg sid and the reserved bytes. The next Ptg in the expression then follows.
+ * It is only after the "size" of all the Ptgs is met, that the ArrayPtg data is actually
+ * held after this. So Ptg.createParsedExpression keeps track of the number of
+ * ArrayPtg elements and need to parse the data upto the FORMULA record size.
+ *
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class ArrayPtg extends Ptg {
+ public static final byte sid = 0x20;
+
+ private static final int RESERVED_FIELD_LEN = 7;
+ /**
+ * The size of the plain tArray token written within the standard formula tokens
+ * (not including the data which comes after all formula tokens)
+ */
+ public static final int PLAIN_TOKEN_SIZE = 1+RESERVED_FIELD_LEN;
+
+ // 7 bytes of data (stored as an int, short and byte here)
+ private final int _reserved0Int;
+ private final int _reserved1Short;
+ private final int _reserved2Byte;
+
+ // data from these fields comes after the Ptg data of all tokens in current formula
+ private final int _nColumns;
+ private final int _nRows;
+ private final Object[] _arrayValues;
+
+ ArrayPtg(int reserved0, int reserved1, int reserved2, int nColumns, int nRows, Object[] arrayValues) {
+ _reserved0Int = reserved0;
+ _reserved1Short = reserved1;
+ _reserved2Byte = reserved2;
+ _nColumns = nColumns;
+ _nRows = nRows;
+ _arrayValues = arrayValues;
+ }
+ /**
+ * @param values2d array values arranged in rows
+ */
+ public ArrayPtg(Object[][] values2d) {
+ int nColumns = values2d[0].length;
+ int nRows = values2d.length;
+ // convert 2-d to 1-d array (row by row according to getValueIndex())
+ _nColumns = (short) nColumns;
+ _nRows = (short) nRows;
+
+ Object[] vv = new Object[_nColumns * _nRows];
+ for (int r=0; r<nRows; r++) {
+ Object[] rowData = values2d[r];
+ for (int c=0; c<nColumns; c++) {
+ vv[getValueIndex(c, r)] = rowData[c];
+ }
+ }
+
+ _arrayValues = vv;
+ _reserved0Int = 0;
+ _reserved1Short = 0;
+ _reserved2Byte = 0;
+ }
+ /**
+ * @return 2-d array (inner index is rowIx, outer index is colIx)
+ */
+ public Object[][] getTokenArrayValues() {
+ if (_arrayValues == null) {
+ throw new IllegalStateException("array values not read yet");
+ }
+ Object[][] result = new Object[_nRows][_nColumns];
+ for (int r = 0; r < _nRows; r++) {
+ Object[] rowData = result[r];
+ for (int c = 0; c < _nColumns; c++) {
+ rowData[c] = _arrayValues[getValueIndex(c, r)];
+ }
+ }
+ return result;
+ }
+
+ public boolean isBaseToken() {
+ return false;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer("[ArrayPtg]\n");
+
+ sb.append("nRows = ").append(getRowCount()).append("\n");
+ sb.append("nCols = ").append(getColumnCount()).append("\n");
+ if (_arrayValues == null) {
+ sb.append(" #values#uninitialised#\n");
+ } else {
+ sb.append(" ").append(toFormulaString());
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Note - (2D) array elements are stored row by row
+ * @return the index into the internal 1D array for the specified column and row
+ */
+ /* package */ int getValueIndex(int colIx, int rowIx) {
+ if(colIx < 0 || colIx >= _nColumns) {
+ throw new IllegalArgumentException("Specified colIx (" + colIx
+ + ") is outside the allowed range (0.." + (_nColumns-1) + ")");
+ }
+ if(rowIx < 0 || rowIx >= _nRows) {
+ throw new IllegalArgumentException("Specified rowIx (" + rowIx
+ + ") is outside the allowed range (0.." + (_nRows-1) + ")");
+ }
+ return rowIx * _nColumns + colIx;
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeInt(_reserved0Int);
+ out.writeShort(_reserved1Short);
+ out.writeByte(_reserved2Byte);
+ }
+
+ public int writeTokenValueBytes(LittleEndianOutput out) {
+
+ out.writeByte(_nColumns-1);
+ out.writeShort(_nRows-1);
+ ConstantValueParser.encode(out, _arrayValues);
+ return 3 + ConstantValueParser.getEncodedSize(_arrayValues);
+ }
+
+ public int getRowCount() {
+ return _nRows;
+ }
+
+ public int getColumnCount() {
+ return _nColumns;
+ }
+
+ /** This size includes the size of the array Ptg plus the Array Ptg Token value size*/
+ public int getSize() {
+ return PLAIN_TOKEN_SIZE
+ // data written after the all tokens:
+ + 1 + 2 // column, row
+ + ConstantValueParser.getEncodedSize(_arrayValues);
+ }
+
+ public String toFormulaString() {
+ StringBuffer b = new StringBuffer();
+ b.append("{");
+ for (int y=0;y<getRowCount();y++) {
+ if (y > 0) {
+ b.append(";");
+ }
+ for (int x=0;x<getColumnCount();x++) {
+ if (x > 0) {
+ b.append(",");
+ }
+ Object o = _arrayValues[getValueIndex(x, y)];
+ b.append(getConstantText(o));
+ }
+ }
+ b.append("}");
+ return b.toString();
+ }
+
+ private static String getConstantText(Object o) {
+
+ if (o == null) {
+ throw new RuntimeException("Array item cannot be null");
+ }
+ if (o instanceof String) {
+ return "\"" + (String)o + "\"";
+ }
+ if (o instanceof Double) {
+ return NumberToTextConverter.toText(((Double)o).doubleValue());
+ }
+ if (o instanceof Boolean) {
+ return ((Boolean)o).booleanValue() ? "TRUE" : "FALSE";
+ }
+ if (o instanceof ErrorConstant) {
+ return ((ErrorConstant)o).getText();
+ }
+ throw new IllegalArgumentException("Unexpected constant class (" + o.getClass().getName() + ")");
+ }
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_ARRAY;
+ }
+
+ /**
+ * Represents the initial plain tArray token (without the constant data that trails the whole
+ * formula). Objects of this class are only temporary and cannot be used as {@link Ptg}s.
+ * These temporary objects get converted to {@link ArrayPtg} by the
+ * {@link #finishReading(LittleEndianInput)} method.
+ */
+ static final class Initial extends Ptg {
+ private final int _reserved0;
+ private final int _reserved1;
+ private final int _reserved2;
+
+ public Initial(LittleEndianInput in) {
+ _reserved0 = in.readInt();
+ _reserved1 = in.readUShort();
+ _reserved2 = in.readUByte();
+ }
+ private static RuntimeException invalid() {
+ throw new IllegalStateException("This object is a partially initialised tArray, and cannot be used as a Ptg");
+ }
+ public byte getDefaultOperandClass() {
+ throw invalid();
+ }
+ public int getSize() {
+ return PLAIN_TOKEN_SIZE;
+ }
+ public boolean isBaseToken() {
+ return false;
+ }
+ public String toFormulaString() {
+ throw invalid();
+ }
+ public void write(LittleEndianOutput out) {
+ throw invalid();
+ }
+ /**
+ * Read in the actual token (array) values. This occurs
+ * AFTER the last Ptg in the expression.
+ * See page 304-305 of Excel97-2007BinaryFileFormat(xls)Specification.pdf
+ */
+ public ArrayPtg finishReading(LittleEndianInput in) {
+ int nColumns = in.readUByte();
+ short nRows = in.readShort();
+ //The token_1_columns and token_2_rows do not follow the documentation.
+ //The number of physical rows and columns is actually +1 of these values.
+ //Which is not explicitly documented.
+ nColumns++;
+ nRows++;
+
+ int totalCount = nRows * nColumns;
+ Object[] arrayValues = ConstantValueParser.parse(in, totalCount);
+
+ ArrayPtg result = new ArrayPtg(_reserved0, _reserved1, _reserved2, nColumns, nRows, arrayValues);
+ result.setClass(getPtgClass());
+ return result;
+ }
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * "Special Attributes"
+ * This seems to be a Misc Stuff and Junk record. One function it serves is
+ * in SUM functions (i.e. SUM(A1:A3) causes an area PTG then an ATTR with the SUM option set)
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class AttrPtg extends ControlPtg {
+ public final static byte sid = 0x19;
+ private final static int SIZE = 4;
+ private final byte _options;
+ private final short _data;
+
+ /** only used for tAttrChoose: table of offsets to starts of args */
+ private final int[] _jumpTable;
+ /** only used for tAttrChoose: offset to the tFuncVar for CHOOSE() */
+ private final int _chooseFuncOffset;
+
+ // flags 'volatile' and 'space', can be combined.
+ // OOO spec says other combinations are theoretically possible but not likely to occur.
+ 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 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);
+
+ public static final AttrPtg SUM = new AttrPtg(0x0010, 0, null, -1);
+
+ public static final class SpaceType {
+ private SpaceType() {
+ // no instances of this class
+ }
+
+ /** 00H = Spaces before the next token (not allowed before tParen token) */
+ public static final int SPACE_BEFORE = 0x00;
+ /** 01H = Carriage returns before the next token (not allowed before tParen token) */
+ public static final int CR_BEFORE = 0x01;
+ /** 02H = Spaces before opening parenthesis (only allowed before tParen token) */
+ public static final int SPACE_BEFORE_OPEN_PAREN = 0x02;
+ /** 03H = Carriage returns before opening parenthesis (only allowed before tParen token) */
+ public static final int CR_BEFORE_OPEN_PAREN = 0x03;
+ /** 04H = Spaces before closing parenthesis (only allowed before tParen, tFunc, and tFuncVar tokens) */
+ public static final int SPACE_BEFORE_CLOSE_PAREN = 0x04;
+ /** 05H = Carriage returns before closing parenthesis (only allowed before tParen, tFunc, and tFuncVar tokens) */
+ public static final int CR_BEFORE_CLOSE_PAREN = 0x05;
+ /** 06H = Spaces following the equality sign (only in macro sheets) */
+ public static final int SPACE_AFTER_EQUALITY = 0x06;
+ }
+
+ public AttrPtg(LittleEndianInput in) {
+ _options = in.readByte();
+ _data = in.readShort();
+ if (isOptimizedChoose()) {
+ int nCases = _data;
+ int[] jumpTable = new int[nCases];
+ for (int i = 0; i < jumpTable.length; i++) {
+ jumpTable[i] = in.readUShort();
+ }
+ _jumpTable = jumpTable;
+ _chooseFuncOffset = in.readUShort();
+ } else {
+ _jumpTable = null;
+ _chooseFuncOffset = -1;
+ }
+
+ }
+ private AttrPtg(int options, int data, int[] jt, int chooseFuncOffset) {
+ _options = (byte) options;
+ _data = (short) data;
+ _jumpTable = jt;
+ _chooseFuncOffset = chooseFuncOffset;
+ }
+
+ /**
+ * @param type a constant from <tt>SpaceType</tt>
+ * @param count the number of space characters
+ */
+ public static AttrPtg createSpace(int type, int count) {
+ int data = type & 0x00FF | (count << 8) & 0x00FFFF;
+ 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(optiSum.set(0), 0, null, -1);
+ }
+
+
+ public boolean isSemiVolatile() {
+ return semiVolatile.isSet(_options);
+ }
+
+ public boolean isOptimizedIf() {
+ return optiIf.isSet(_options);
+ }
+
+ public boolean isOptimizedChoose() {
+ return optiChoose.isSet(_options);
+ }
+
+ public boolean isSum() {
+ return optiSum.isSet(_options);
+ }
+ public boolean isSkip() {
+ return optiSkip.isSet(_options);
+ }
+
+ // lets hope no one uses this anymore
+ private boolean isBaxcel() {
+ return baxcel.isSet(_options);
+ }
+
+ public boolean isSpace() {
+ return space.isSet(_options);
+ }
+
+ public short getData() {
+ return _data;
+ }
+ public int[] getJumpTable() {
+ return _jumpTable.clone();
+ }
+ public int getChooseFuncOffset() {
+ if (_jumpTable == null) {
+ throw new IllegalStateException("Not tAttrChoose");
+ }
+ return _chooseFuncOffset;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer(64);
+ sb.append(getClass().getName()).append(" [");
+
+ if(isSemiVolatile()) {
+ sb.append("volatile ");
+ }
+ if(isSpace()) {
+ 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(_data);
+ } else if(isOptimizedChoose()) {
+ sb.append("choose nCases=").append(_data);
+ } else if(isSkip()) {
+ sb.append("skip dist=").append(_data);
+ } else if(isSum()) {
+ sb.append("sum ");
+ } else if(isBaxcel()) {
+ sb.append("assign ");
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeByte(_options);
+ out.writeShort(_data);
+ int[] jt = _jumpTable;
+ if (jt != null) {
+ for (int i = 0; i < jt.length; i++) {
+ out.writeShort(jt[i]);
+ }
+ out.writeShort(_chooseFuncOffset);
+ }
+ }
+
+ public int getSize() {
+ if (_jumpTable != null) {
+ return SIZE + (_jumpTable.length + 1) * LittleEndian.SHORT_SIZE;
+ }
+ return SIZE;
+ }
+
+ public String toFormulaString(String[] operands) {
+ if(space.isSet(_options)) {
+ return operands[ 0 ];
+ } else if (optiIf.isSet(_options)) {
+ return toFormulaString() + "(" + operands[0] + ")";
+ } 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] + ")";
+ }
+ }
+
+
+ public int getNumberOfOperands() {
+ return 1;
+ }
+
+ public int getType() {
+ return -1;
+ }
+
+ public String toFormulaString() {
+ if(semiVolatile.isSet(_options)) {
+ return "ATTR(semiVolatile)";
+ }
+ if(optiIf.isSet(_options)) {
+ return "IF";
+ }
+ if( optiChoose.isSet(_options)) {
+ return "CHOOSE";
+ }
+ if(optiSkip.isSet(_options)) {
+ return "";
+ }
+ if(optiSum.isSet(_options)) {
+ return "SUM";
+ }
+ if(baxcel.isSet(_options)) {
+ return "ATTR(baxcel)";
+ }
+ if(space.isSet(_options)) {
+ return "";
+ }
+ return "UNKNOWN ATTRIBUTE";
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Boolean (boolean) Stores a (java) boolean value in a formula.
+ *
+ * @author Paul Krause (pkrause at soundbite dot com)
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class BoolPtg extends ScalarConstantPtg {
+ public static final int SIZE = 2;
+ public static final byte sid = 0x1D;
+
+ private static final BoolPtg FALSE = new BoolPtg(false);
+ private static final BoolPtg TRUE = new BoolPtg(true);
+
+ private final boolean _value;
+
+ private BoolPtg(boolean b) {
+ _value = b;
+ }
+
+ public static BoolPtg valueOf(boolean b) {
+ return b ? TRUE : FALSE;
+ }
+ public static BoolPtg read(LittleEndianInput in) {
+ return valueOf(in.readByte() == 1);
+ }
+
+ public boolean getValue() {
+ return _value;
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeByte(_value ? 1 : 0);
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public String toFormulaString() {
+ return _value ? "TRUE" : "FALSE";
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ *
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class ConcatPtg extends ValueOperatorPtg {
+ public final static byte sid = 0x08;
+
+ private final static String CONCAT = "&";
+
+ public static final ValueOperatorPtg instance = new ConcatPtg();
+
+ private ConcatPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 2;
+ }
+
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(operands[ 0 ]);
+ buffer.append(CONCAT);
+ buffer.append(operands[ 1 ]);
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * Common superclass for
+ * tExp
+ * tTbl
+ * tParen
+ * tNlr
+ * tAttr
+ * tSheet
+ * tEndSheet
+ */
+public abstract class ControlPtg extends Ptg {
+
+ public boolean isBaseToken() {
+ return true;
+ }
+ public final byte getDefaultOperandClass() {
+ throw new IllegalStateException("Control tokens are not classified");
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.usermodel.ErrorConstants;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: Deleted Area 3D Ptg - 3D referecnce (Sheet + Area)<P>
+ * Description: Defined a area in Extern Sheet. <P>
+ * REFERENCE: <P>
+ * @author Patrick Luby
+ * @version 1.0-pre
+ */
+public final class DeletedArea3DPtg extends OperandPtg implements WorkbookDependentFormula {
+ public final static byte sid = 0x3d;
+ private final int field_1_index_extern_sheet;
+ private final int unused1;
+ private final int unused2;
+
+ public DeletedArea3DPtg(int externSheetIndex) {
+ field_1_index_extern_sheet = externSheetIndex;
+ unused1 = 0;
+ unused2 = 0;
+ }
+
+ public DeletedArea3DPtg(LittleEndianInput in) {
+ field_1_index_extern_sheet = in.readUShort();
+ unused1 = in.readInt();
+ unused2 = in.readInt();
+ }
+ public String toFormulaString(FormulaRenderingWorkbook book) {
+ return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet,
+ ErrorConstants.getText(ErrorConstants.ERROR_REF));
+ }
+ public String toFormulaString() {
+ throw new RuntimeException("3D references need a workbook to determine formula text");
+ }
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
+ public int getSize() {
+ return 11;
+ }
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeShort(field_1_index_extern_sheet);
+ out.writeInt(unused1);
+ out.writeInt(unused2);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+
+import org.apache.poi.ss.usermodel.ErrorConstants;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: Deleted Reference 3D Ptg <P>
+ * Description: Defined a cell in extern sheet. <P>
+ * REFERENCE: <P>
+ * @author Patrick Luby
+ * @version 1.0-pre
+ */
+public final class DeletedRef3DPtg extends OperandPtg implements WorkbookDependentFormula {
+ public final static byte sid = 0x3c;
+ private final int field_1_index_extern_sheet;
+ private final int unused1;
+
+ /** Creates new DeletedRef3DPtg */
+ public DeletedRef3DPtg(LittleEndianInput in) {
+ field_1_index_extern_sheet = in.readUShort();
+ unused1 = in.readInt();
+ }
+
+ public DeletedRef3DPtg(int externSheetIndex) {
+ field_1_index_extern_sheet = externSheetIndex;
+ unused1 = 0;
+ }
+
+ public String toFormulaString(FormulaRenderingWorkbook book) {
+ return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet,
+ ErrorConstants.getText(ErrorConstants.ERROR_REF));
+ }
+ public String toFormulaString() {
+ throw new RuntimeException("3D references need a workbook to determine formula text");
+ }
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
+ public int getSize() {
+ return 7;
+ }
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeShort(field_1_index_extern_sheet);
+ out.writeInt(unused1);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * This PTG implements the standard binomial divide "/"
+ * @author Andrew C. Oliver acoliver at apache dot org
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class DividePtg extends ValueOperatorPtg {
+ public final static byte sid = 0x06;
+
+ public static final ValueOperatorPtg instance = new DividePtg();
+
+ private DividePtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 2;
+ }
+
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(operands[ 0 ]);
+ buffer.append("/");
+ buffer.append(operands[ 1 ]);
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ *
+ * @author andy
+ */
+public final class EqualPtg extends ValueOperatorPtg {
+ public final static byte sid = 0x0b;
+
+ public static final ValueOperatorPtg instance = new EqualPtg();
+
+ private EqualPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 2;
+ }
+
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+
+
+ buffer.append(operands[ 0 ]);
+ buffer.append("=");
+ buffer.append(operands[ 1 ]);
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.usermodel.ErrorConstants;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author Daniel Noll (daniel at nuix dot com dot au)
+ */
+public final class ErrPtg extends ScalarConstantPtg {
+
+ // convenient access to namespace
+ private static final ErrorConstants EC = null;
+
+ /** <b>#NULL!</b> - Intersection of two cell ranges is empty */
+ public static final ErrPtg NULL_INTERSECTION = new ErrPtg(EC.ERROR_NULL);
+ /** <b>#DIV/0!</b> - Division by zero */
+ public static final ErrPtg DIV_ZERO = new ErrPtg(EC.ERROR_DIV_0);
+ /** <b>#VALUE!</b> - Wrong type of operand */
+ public static final ErrPtg VALUE_INVALID = new ErrPtg(EC.ERROR_VALUE);
+ /** <b>#REF!</b> - Illegal or deleted cell reference */
+ public static final ErrPtg REF_INVALID = new ErrPtg(EC.ERROR_REF);
+ /** <b>#NAME?</b> - Wrong function or range name */
+ public static final ErrPtg NAME_INVALID = new ErrPtg(EC.ERROR_NAME);
+ /** <b>#NUM!</b> - Value range overflow */
+ public static final ErrPtg NUM_ERROR = new ErrPtg(EC.ERROR_NUM);
+ /** <b>#N/A</b> - Argument or function not available */
+ public static final ErrPtg N_A = new ErrPtg(EC.ERROR_NA);
+
+
+ public static final short sid = 0x1c;
+ private static final int SIZE = 2;
+ private final int field_1_error_code;
+
+ /** Creates new ErrPtg */
+
+ private ErrPtg(int errorCode) {
+ if(!ErrorConstants.isValidCode(errorCode)) {
+ throw new IllegalArgumentException("Invalid error code (" + errorCode + ")");
+ }
+ field_1_error_code = errorCode;
+ }
+
+ public static ErrPtg read(LittleEndianInput in) {
+ return valueOf(in.readByte());
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeByte(field_1_error_code);
+ }
+
+ public String toFormulaString() {
+ return ErrorConstants.getText(field_1_error_code);
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public int getErrorCode() {
+ return field_1_error_code;
+ }
+
+ public static ErrPtg valueOf(int code) {
+ switch(code) {
+ case ErrorConstants.ERROR_DIV_0: return DIV_ZERO;
+ case ErrorConstants.ERROR_NA: return N_A;
+ case ErrorConstants.ERROR_NAME: return NAME_INVALID;
+ case ErrorConstants.ERROR_NULL: return NULL_INTERSECTION;
+ case ErrorConstants.ERROR_NUM: return NUM_ERROR;
+ case ErrorConstants.ERROR_REF: return REF_INVALID;
+ case ErrorConstants.ERROR_VALUE: return VALUE_INVALID;
+ }
+ throw new RuntimeException("Unexpected error code (" + code + ")");
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ *
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @author dmui (save existing implementation)
+ */
+public final class ExpPtg extends ControlPtg {
+ private final static int SIZE = 5;
+ public final static short sid = 0x1;
+ private final int field_1_first_row;
+ private final int field_2_first_col;
+
+ public ExpPtg(LittleEndianInput in) {
+ field_1_first_row = in.readShort();
+ field_2_first_col = in.readShort();
+ }
+
+ public ExpPtg(int firstRow, int firstCol) {
+ this.field_1_first_row = firstRow;
+ this.field_2_first_col = firstCol;
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeShort(field_1_first_row);
+ out.writeShort(field_2_first_col);
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public int getRow() {
+ return field_1_first_row;
+ }
+
+ public int getColumn() {
+ return field_2_first_col;
+ }
+
+ public String toFormulaString() {
+ throw new RuntimeException("Coding Error: Expected ExpPtg to be converted from Shared to Non-Shared Formula by ValueRecordsAggregate, but it wasn't");
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer("[Array Formula or Shared Formula]\n");
+ buffer.append("row = ").append(getRow()).append("\n");
+ buffer.append("col = ").append(getColumn()).append("\n");
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
+import org.apache.poi.ss.formula.SheetNameFormatter;
+
+/**
+ * @author Josh Micich
+ */
+final class ExternSheetNameResolver {
+
+ private ExternSheetNameResolver() {
+ // no instances of this class
+ }
+
+ public static String prependSheetName(FormulaRenderingWorkbook book, int field_1_index_extern_sheet, String cellRefText) {
+ ExternalSheet externalSheet = book.getExternalSheet(field_1_index_extern_sheet);
+ StringBuffer sb;
+ if (externalSheet != null) {
+ String wbName = externalSheet.getWorkbookName();
+ String sheetName = externalSheet.getSheetName();
+ sb = new StringBuffer(wbName.length() + sheetName.length() + cellRefText.length() + 4);
+ SheetNameFormatter.appendFormat(sb, wbName, sheetName);
+ } else {
+ String sheetName = book.getSheetNameByExternSheet(field_1_index_extern_sheet);
+ sb = new StringBuffer(sheetName.length() + cellRefText.length() + 4);
+ if (sheetName.length() < 1) {
+ // What excel does if sheet has been deleted
+ sb.append("#REF"); // note - '!' added just once below
+ } else {
+ SheetNameFormatter.appendFormat(sb, sheetName);
+ }
+ }
+ sb.append('!');
+ sb.append(cellRefText);
+ return sb.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.formula.function.FunctionMetadata;
+import org.apache.poi.ss.formula.function.FunctionMetadataRegistry;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author aviks
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @author Danny Mui (dmui at apache dot org) (Leftover handling)
+ */
+public final class FuncPtg extends AbstractFunctionPtg {
+
+ public final static byte sid = 0x21;
+ public final static int SIZE = 3;
+
+ public static FuncPtg create(LittleEndianInput in) {
+ return create(in.readUShort());
+ }
+
+ private FuncPtg(int funcIndex, FunctionMetadata fm) {
+ super(funcIndex, fm.getReturnClassCode(), fm.getParameterClassCodes(), fm.getMinParams()); // minParams same as max since these are not var-arg funcs
+ }
+
+ public static FuncPtg create(int functionIndex) {
+ FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(functionIndex);
+ if(fm == null) {
+ throw new RuntimeException("Invalid built-in function index (" + functionIndex + ")");
+ }
+ return new FuncPtg(functionIndex, fm);
+ }
+
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeShort(getFunctionIndex());
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+import org.apache.poi.ss.formula.function.FunctionMetadata;
+import org.apache.poi.ss.formula.function.FunctionMetadataRegistry;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class FuncVarPtg extends AbstractFunctionPtg{
+
+ public final static byte sid = 0x22;
+ private final static int SIZE = 4;
+
+ /**
+ * Single instance of this token for 'sum() taking a single argument'
+ */
+ public static final OperationPtg SUM = FuncVarPtg.create("SUM", 1);
+
+ private FuncVarPtg(int functionIndex, int returnClass, byte[] paramClasses, int numArgs) {
+ super(functionIndex, returnClass, paramClasses, numArgs);
+ }
+
+ /**Creates new function pointer from a byte array
+ * usually called while reading an excel file.
+ */
+ public static FuncVarPtg create(LittleEndianInput in) {
+ return create(in.readByte(), in.readShort());
+ }
+
+ /**
+ * Create a function ptg from a string tokenised by the parser
+ */
+ public static FuncVarPtg create(String pName, int numArgs) {
+ return create(numArgs, lookupIndex(pName));
+ }
+
+ private static FuncVarPtg create(int numArgs, int functionIndex) {
+ FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(functionIndex);
+ if(fm == null) {
+ // Happens only as a result of a call to FormulaParser.parse(), with a non-built-in function name
+ return new FuncVarPtg(functionIndex, Ptg.CLASS_VALUE, new byte[] {Ptg.CLASS_VALUE}, numArgs);
+ }
+ return new FuncVarPtg(functionIndex, fm.getReturnClassCode(), fm.getParameterClassCodes(), numArgs);
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeByte(getNumberOfOperands());
+ out.writeShort(getFunctionIndex());
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+
+/**
+ * PTG class to implement greater or equal to
+ *
+ * @author fred at stsci dot edu
+ */
+public final class GreaterEqualPtg extends ValueOperatorPtg {
+ public final static int SIZE = 1;
+ public final static byte sid = 0x0c;
+
+ public static final ValueOperatorPtg instance = new GreaterEqualPtg();
+
+ private GreaterEqualPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 2;
+ }
+
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(operands[ 0 ]);
+
+ buffer.append(">=");
+ buffer.append(operands[ 1 ]);
+
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+
+/**
+ * Greater than operator PTG ">"
+ * @author Cameron Riley (criley at ekmail.com)
+ */
+public final class GreaterThanPtg extends ValueOperatorPtg {
+ public final static byte sid = 0x0D;
+ private final static String GREATERTHAN = ">";
+
+ public static final ValueOperatorPtg instance = new GreaterThanPtg();
+
+ private GreaterThanPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ /**
+ * Get the number of operands for the Less than operator
+ * @return int the number of operands
+ */
+ public int getNumberOfOperands() {
+ return 2;
+ }
+
+ /**
+ * Implementation of method from OperationsPtg
+ * @param operands a String array of operands
+ * @return String the Formula as a String
+ */
+ public String toFormulaString(String[] operands)
+ {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(operands[ 0 ]);
+ buffer.append(GREATERTHAN);
+ buffer.append(operands[ 1 ]);
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Integer (unsigned short integer) Stores an unsigned short value (java int) in
+ * a formula
+ *
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class IntPtg extends ScalarConstantPtg {
+ // 16 bit unsigned integer
+ private static final int MIN_VALUE = 0x0000;
+ private static final int MAX_VALUE = 0xFFFF;
+
+ /**
+ * Excel represents integers 0..65535 with the tInt token.
+ *
+ * @return <code>true</code> if the specified value is within the range of values
+ * <tt>IntPtg</tt> can represent.
+ */
+ public static boolean isInRange(int i) {
+ return i >= MIN_VALUE && i <= MAX_VALUE;
+ }
+
+ public final static int SIZE = 3;
+ public final static byte sid = 0x1e;
+ private final int field_1_value;
+
+ public IntPtg(LittleEndianInput in) {
+ this(in.readUShort());
+ }
+
+ public IntPtg(int value) {
+ if (!isInRange(value)) {
+ throw new IllegalArgumentException("value is out of range: " + value);
+ }
+ field_1_value = value;
+ }
+
+ public int getValue() {
+ return field_1_value;
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeShort(getValue());
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public String toFormulaString() {
+ return String.valueOf(getValue());
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author Daniel Noll (daniel at nuix dot com dot au)
+ */
+public final class IntersectionPtg extends OperationPtg {
+ public final static byte sid = 0x0f;
+
+ public static final OperationPtg instance = new IntersectionPtg();
+
+ private IntersectionPtg() {
+ // enforce singleton
+ }
+
+ public final boolean isBaseToken() {
+ return true;
+ }
+
+ public int getSize() {
+ return 1;
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ }
+
+ public String toFormulaString() {
+ return " ";
+ }
+
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(operands[0]);
+ buffer.append(" ");
+ buffer.append(operands[1]);
+ return buffer.toString();
+ }
+
+ public int getNumberOfOperands() {
+ return 2;
+ }
+}
--- /dev/null
+
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+
+
+
+/**
+ * Ptg class to implement less than or equal
+ *
+ * @author fred at stsci dot edu
+ */
+public final class LessEqualPtg extends ValueOperatorPtg {
+ public final static byte sid = 0x0a;
+
+ public static final ValueOperatorPtg instance = new LessEqualPtg();
+
+ private LessEqualPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 2;
+ }
+
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append( operands[0] );
+ buffer.append("<=");
+ buffer.append( operands[1] );
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * Less than operator PTG "<". The SID is taken from the
+ * Openoffice.orgs Documentation of the Excel File Format,
+ * Table 3.5.7
+ * @author Cameron Riley (criley at ekmail.com)
+ */
+public final class LessThanPtg extends ValueOperatorPtg {
+ /** the sid for the less than operator as hex */
+ public final static byte sid = 0x09;
+
+ /** identifier for LESS THAN char */
+ private final static String LESSTHAN = "<";
+
+ public static final ValueOperatorPtg instance = new LessThanPtg();
+
+ private LessThanPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ /**
+ * Get the number of operands for the Less than operator
+ * @return int the number of operands
+ */
+ public int getNumberOfOperands() {
+ return 2;
+ }
+
+ /**
+ * Implementation of method from OperationsPtg
+ * @param operands a String array of operands
+ * @return String the Formula as a String
+ */
+ public String toFormulaString(String[] operands)
+ {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(operands[ 0 ]);
+ buffer.append(LESSTHAN);
+ buffer.append(operands[ 1 ]);
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author Daniel Noll (daniel at nuix dot com dot au)
+ */
+public final class MemAreaPtg extends OperandPtg {
+ public final static short sid = 0x26;
+ private final static int SIZE = 7;
+ private final int field_1_reserved;
+ private final int field_2_subex_len;
+
+ /** Creates new MemAreaPtg */
+
+ public MemAreaPtg(int subexLen) {
+ field_1_reserved = 0;
+ field_2_subex_len = subexLen;
+ }
+
+ public MemAreaPtg(LittleEndianInput in) {
+ field_1_reserved = in.readInt();
+ field_2_subex_len = in.readShort();
+ }
+
+ public int getLenRefSubexpression() {
+ return field_2_subex_len;
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeInt(field_1_reserved);
+ out.writeShort(field_2_subex_len);
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public String toFormulaString() {
+ return ""; // TODO: Not sure how to format this. -- DN
+ }
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_VALUE;
+ }
+
+ @Override
+ public final String toString() {
+ StringBuffer sb = new StringBuffer(64);
+ sb.append(getClass().getName()).append(" [len=");
+ sb.append(field_2_subex_len);
+ sb.append("]");
+ return sb.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ *
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @author Daniel Noll (daniel at nuix dot com dot au)
+ */
+public final class MemErrPtg extends OperandPtg {
+ public final static short sid = 0x27;
+ private final static int SIZE = 7;
+ private int field_1_reserved;
+ private short field_2_subex_len;
+
+ public MemErrPtg(LittleEndianInput in) {
+ field_1_reserved = in.readInt();
+ field_2_subex_len = in.readShort();
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeInt(field_1_reserved);
+ out.writeShort(field_2_subex_len);
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public String toFormulaString() {
+ return "ERR#";
+ }
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_VALUE;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class MemFuncPtg extends OperandPtg {
+
+ public final static byte sid = 0x29;
+ private final int field_1_len_ref_subexpression;
+
+ /**
+ * Creates new function pointer from a byte array usually called while
+ * reading an excel file.
+ */
+ public MemFuncPtg(LittleEndianInput in) {
+ this(in.readUShort());
+ }
+
+ public MemFuncPtg(int subExprLen) {
+ field_1_len_ref_subexpression = subExprLen;
+ }
+
+ public int getSize() {
+ return 3;
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeShort(field_1_len_ref_subexpression);
+ }
+
+ public String toFormulaString() {
+ return "";
+ }
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
+
+ public int getNumberOfOperands() {
+ return field_1_len_ref_subexpression;
+ }
+
+ public int getLenRefSubexpression() {
+ return field_1_len_ref_subexpression;
+ }
+ @Override
+ public final String toString() {
+ StringBuffer sb = new StringBuffer(64);
+ sb.append(getClass().getName()).append(" [len=");
+ sb.append(field_1_len_ref_subexpression);
+ sb.append("]");
+ return sb.toString();
+ }
+}
\ No newline at end of file
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Missing Function Arguments
+ *
+ * Avik Sengupta <avik at apache.org>
+ *
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class MissingArgPtg extends ScalarConstantPtg {
+
+ private final static int SIZE = 1;
+ public final static byte sid = 0x16;
+
+ public static final Ptg instance = new MissingArgPtg();
+
+ private MissingArgPtg() {
+ // enforce singleton
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public String toFormulaString() {
+ return " ";
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * Implements the standard mathmatical multiplication - *
+ * @author Andrew C. Oliver (acoliver at apache dot org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class MultiplyPtg extends ValueOperatorPtg {
+ public final static byte sid = 0x05;
+
+ public static final ValueOperatorPtg instance = new MultiplyPtg();
+
+ private MultiplyPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 2;
+ }
+
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(operands[ 0 ]);
+ buffer.append("*");
+ buffer.append(operands[ 1 ]);
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ *
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class NamePtg extends OperandPtg implements WorkbookDependentFormula {
+ public final static short sid = 0x23;
+ private final static int SIZE = 5;
+ /** one-based index to defined name record */
+ private int field_1_label_index;
+ private short field_2_zero; // reserved must be 0
+
+ /**
+ * @param nameIndex zero-based index to name within workbook
+ */
+ public NamePtg(int nameIndex) {
+ field_1_label_index = 1 + nameIndex; // convert to 1-based
+ }
+
+ /** Creates new NamePtg */
+
+ public NamePtg(LittleEndianInput in) {
+ field_1_label_index = in.readShort();
+ field_2_zero = in.readShort();
+ }
+
+ /**
+ * @return zero based index to a defined name record in the LinkTable
+ */
+ public int getIndex() {
+ return field_1_label_index - 1; // convert to zero based
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeShort(field_1_label_index);
+ out.writeShort(field_2_zero);
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public String toFormulaString(FormulaRenderingWorkbook book) {
+ return book.getNameText(this);
+ }
+
+ public String toFormulaString() {
+ throw new RuntimeException("3D references need a workbook to determine formula text");
+ }
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ *
+ * @author aviks
+ */
+public final class NameXPtg extends OperandPtg implements WorkbookDependentFormula {
+ public final static short sid = 0x39;
+ private final static int SIZE = 7;
+
+ /** index to REF entry in externsheet record */
+ private final int _sheetRefIndex;
+ /** index to defined name or externname table(1 based) */
+ private final int _nameNumber;
+ /** reserved must be 0 */
+ private final int _reserved;
+
+ private NameXPtg(int sheetRefIndex, int nameNumber, int reserved) {
+ _sheetRefIndex = sheetRefIndex;
+ _nameNumber = nameNumber;
+ _reserved = reserved;
+ }
+
+ /**
+ * @param sheetRefIndex index to REF entry in externsheet record
+ * @param nameIndex index to defined name or externname table
+ */
+ public NameXPtg(int sheetRefIndex, int nameIndex) {
+ this(sheetRefIndex, nameIndex + 1, 0);
+ }
+
+ public NameXPtg(LittleEndianInput in) {
+ this(in.readUShort(), in.readUShort(), in.readUShort());
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeShort(_sheetRefIndex);
+ out.writeShort(_nameNumber);
+ out.writeShort(_reserved);
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public String toFormulaString(FormulaRenderingWorkbook book) {
+ // -1 to convert definedNameIndex from 1-based to zero-based
+ return book.resolveNameXText(this);
+ }
+ public String toFormulaString() {
+ throw new RuntimeException("3D references need a workbook to determine formula text");
+ }
+
+ public String toString(){
+ String retValue = "NameXPtg:[sheetRefIndex:" + _sheetRefIndex +
+ " , nameNumber:" + _nameNumber + "]" ;
+ return retValue;
+ }
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_VALUE;
+ }
+
+ public int getSheetRefIndex() {
+ return _sheetRefIndex;
+ }
+ public int getNameIndex() {
+ return _nameNumber - 1;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * Ptg class to implement not equal
+ *
+ * @author fred at stsci dot edu
+ */
+public final class NotEqualPtg extends ValueOperatorPtg {
+ public final static byte sid = 0x0e;
+
+ public static final ValueOperatorPtg instance = new NotEqualPtg();
+
+ private NotEqualPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 2;
+ }
+
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append( operands[0] );
+
+ buffer.append("<>");
+ buffer.append( operands[1] );
+
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.util.NumberToTextConverter;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Number Stores a floating point value in a formula value stored in a 8 byte
+ * field using IEEE notation
+ *
+ * @author Avik Sengupta
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class NumberPtg extends ScalarConstantPtg {
+ public final static int SIZE = 9;
+ public final static byte sid = 0x1f;
+ private final double field_1_value;
+
+ public NumberPtg(LittleEndianInput in) {
+ this(in.readDouble());
+ }
+
+ /**
+ * Create a NumberPtg 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.
+ *
+ * @param value String representation of a floating point number
+ */
+ public NumberPtg(String value) {
+ this(Double.parseDouble(value));
+ }
+
+ public NumberPtg(double value) {
+ field_1_value = value;
+ }
+
+ public double getValue() {
+ return field_1_value;
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeDouble(getValue());
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public String toFormulaString() {
+ return NumberToTextConverter.toText(field_1_value);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * @author Josh Micich
+ */
+public abstract class OperandPtg extends Ptg implements Cloneable {
+
+ /**
+ * All Operand {@link Ptg}s are classified ('relative', 'value', 'array')
+ */
+ public final boolean isBaseToken() {
+ return false;
+ }
+ public final OperandPtg copy() {
+ try {
+ return (OperandPtg) clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * defines a Ptg that is an operation instead of an operand
+ * @author andy
+ */
+public abstract class OperationPtg extends Ptg {
+ public final static int TYPE_UNARY = 0;
+ public final static int TYPE_BINARY = 1;
+ public final static int TYPE_FUNCTION = 2;
+
+ /**
+ * returns a string representation of the operations
+ * the length of the input array should equal the number returned by
+ * @see #getNumberOfOperands
+ *
+ */
+ public abstract String toFormulaString(String[] operands);
+
+ /**
+ * The number of operands expected by the operations
+ */
+ public abstract int getNumberOfOperands();
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_VALUE;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * While formula tokens are stored in RPN order and thus do not need parenthesis
+ * for precedence reasons, Parenthesis tokens ARE written to ensure that user
+ * entered parenthesis are displayed as-is on reading back
+ *
+ * Avik Sengupta <lists@aviksengupta.com> Andrew C. Oliver (acoliver at
+ * apache dot org)
+ *
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class ParenthesisPtg extends ControlPtg {
+
+ private final static int SIZE = 1;
+ public final static byte sid = 0x15;
+
+ public static final ControlPtg instance = new ParenthesisPtg();
+
+ private ParenthesisPtg() {
+ // enforce singleton
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public String toFormulaString() {
+ return "()";
+ }
+
+ public String toFormulaString(String[] operands) {
+ return "(" + operands[0] + ")";
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * Percent PTG.
+ *
+ * @author Daniel Noll (daniel at nuix.com.au)
+ */
+public final class PercentPtg extends ValueOperatorPtg {
+ public final static int SIZE = 1;
+ public final static byte sid = 0x14;
+
+ private final static String PERCENT = "%";
+
+ public static final ValueOperatorPtg instance = new PercentPtg();
+
+ private PercentPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 1;
+ }
+
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(operands[ 0 ]);
+ buffer.append(PERCENT);
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ *
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class PowerPtg extends ValueOperatorPtg {
+ public final static byte sid = 0x07;
+
+ public static final ValueOperatorPtg instance = new PowerPtg();
+
+ private PowerPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 2; // TODO - 2 seems wrong (Jun 2008). Maybe this method is not relevant
+ }
+
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+
+
+ buffer.append(operands[ 0 ]);
+ buffer.append("^");
+ buffer.append(operands[ 1 ]);
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.util.LittleEndianByteArrayOutputStream;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * <tt>Ptg</tt> represents a syntactic token in a formula. 'PTG' is an acronym for
+ * '<b>p</b>arse <b>t</b>hin<b>g</b>'. Originally, the name referred to the single
+ * byte identifier at the start of the token, but in POI, <tt>Ptg</tt> encapsulates
+ * the whole formula token (initial byte + value data).
+ * <p/>
+ *
+ * <tt>Ptg</tt>s are logically arranged in a tree representing the structure of the
+ * parsed formula. However, in BIFF files <tt>Ptg</tt>s are written/read in
+ * <em>Reverse-Polish Notation</em> order. The RPN ordering also simplifies formula
+ * evaluation logic, so POI mostly accesses <tt>Ptg</tt>s in the same way.
+ *
+ * @author andy
+ * @author avik
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public abstract class Ptg {
+ public static final Ptg[] EMPTY_PTG_ARRAY = { };
+
+
+ /**
+ * Reads <tt>size</tt> bytes of the input stream, to create an array of <tt>Ptg</tt>s.
+ * Extra data (beyond <tt>size</tt>) may be read if and <tt>ArrayPtg</tt>s are present.
+ */
+ public static Ptg[] readTokens(int size, LittleEndianInput in) {
+ List<Ptg> temp = new ArrayList<Ptg>(4 + size / 2);
+ int pos = 0;
+ boolean hasArrayPtgs = false;
+ while (pos < size) {
+ Ptg ptg = Ptg.createPtg(in);
+ if (ptg instanceof ArrayPtg.Initial) {
+ hasArrayPtgs = true;
+ }
+ pos += ptg.getSize();
+ temp.add(ptg);
+ }
+ if(pos != size) {
+ throw new RuntimeException("Ptg array size mismatch");
+ }
+ if (hasArrayPtgs) {
+ Ptg[] result = toPtgArray(temp);
+ for (int i=0;i<result.length;i++) {
+ if (result[i] instanceof ArrayPtg.Initial) {
+ result[i] = ((ArrayPtg.Initial) result[i]).finishReading(in);
+ }
+ }
+ return result;
+ }
+ return toPtgArray(temp);
+ }
+
+ public static Ptg createPtg(LittleEndianInput in) {
+ byte id = in.readByte();
+
+ if (id < 0x20) {
+ return createBasePtg(id, in);
+ }
+
+ Ptg retval = createClassifiedPtg(id, in);
+
+ if (id >= 0x60) {
+ retval.setClass(CLASS_ARRAY);
+ } else if (id >= 0x40) {
+ retval.setClass(CLASS_VALUE);
+ } else {
+ retval.setClass(CLASS_REF);
+ }
+ return retval;
+ }
+
+ private static Ptg createClassifiedPtg(byte id, LittleEndianInput in) {
+
+ int baseId = id & 0x1F | 0x20;
+
+ switch (baseId) {
+ case ArrayPtg.sid: return new ArrayPtg.Initial(in);//0x20, 0x40, 0x60
+ case FuncPtg.sid: return FuncPtg.create(in); // 0x21, 0x41, 0x61
+ case FuncVarPtg.sid: return FuncVarPtg.create(in);//0x22, 0x42, 0x62
+ case NamePtg.sid: return new NamePtg(in); // 0x23, 0x43, 0x63
+ case RefPtg.sid: return new RefPtg(in); // 0x24, 0x44, 0x64
+ case AreaPtg.sid: return new AreaPtg(in); // 0x25, 0x45, 0x65
+ case MemAreaPtg.sid: return new MemAreaPtg(in); // 0x26, 0x46, 0x66
+ case MemErrPtg.sid: return new MemErrPtg(in); // 0x27, 0x47, 0x67
+ case MemFuncPtg.sid: return new MemFuncPtg(in); // 0x29, 0x49, 0x69
+ case RefErrorPtg.sid: return new RefErrorPtg(in); // 0x2a, 0x4a, 0x6a
+ case AreaErrPtg.sid: return new AreaErrPtg(in); // 0x2b, 0x4b, 0x6b
+ case RefNPtg.sid: return new RefNPtg(in); // 0x2c, 0x4c, 0x6c
+ case AreaNPtg.sid: return new AreaNPtg(in); // 0x2d, 0x4d, 0x6d
+
+ case NameXPtg.sid: return new NameXPtg(in); // 0x39, 0x49, 0x79
+ case Ref3DPtg.sid: return new Ref3DPtg(in); // 0x3a, 0x5a, 0x7a
+ case Area3DPtg.sid: return new Area3DPtg(in); // 0x3b, 0x5b, 0x7b
+ case DeletedRef3DPtg.sid: return new DeletedRef3DPtg(in); // 0x3c, 0x5c, 0x7c
+ case DeletedArea3DPtg.sid: return new DeletedArea3DPtg(in); // 0x3d, 0x5d, 0x7d
+ }
+ throw new UnsupportedOperationException(" Unknown Ptg in Formula: 0x"+
+ Integer.toHexString(id) + " (" + ( int ) id + ")");
+ }
+
+ private static Ptg createBasePtg(byte id, LittleEndianInput in) {
+ switch(id) {
+ case 0x00: return new UnknownPtg(id); // TODO - not a real Ptg
+ case ExpPtg.sid: return new ExpPtg(in); // 0x01
+ case TblPtg.sid: return new TblPtg(in); // 0x02
+ case AddPtg.sid: return AddPtg.instance; // 0x03
+ case SubtractPtg.sid: return SubtractPtg.instance; // 0x04
+ case MultiplyPtg.sid: return MultiplyPtg.instance; // 0x05
+ case DividePtg.sid: return DividePtg.instance; // 0x06
+ case PowerPtg.sid: return PowerPtg.instance; // 0x07
+ case ConcatPtg.sid: return ConcatPtg.instance; // 0x08
+ case LessThanPtg.sid: return LessThanPtg.instance; // 0x09
+ case LessEqualPtg.sid: return LessEqualPtg.instance; // 0x0a
+ case EqualPtg.sid: return EqualPtg.instance; // 0x0b
+ case GreaterEqualPtg.sid: return GreaterEqualPtg.instance;// 0x0c
+ case GreaterThanPtg.sid: return GreaterThanPtg.instance; // 0x0d
+ case NotEqualPtg.sid: return NotEqualPtg.instance; // 0x0e
+ case IntersectionPtg.sid: return IntersectionPtg.instance;// 0x0f
+ case UnionPtg.sid: return UnionPtg.instance; // 0x10
+ case RangePtg.sid: return RangePtg.instance; // 0x11
+ case UnaryPlusPtg.sid: return UnaryPlusPtg.instance; // 0x12
+ case UnaryMinusPtg.sid: return UnaryMinusPtg.instance; // 0x13
+ case PercentPtg.sid: return PercentPtg.instance; // 0x14
+ case ParenthesisPtg.sid: return ParenthesisPtg.instance; // 0x15
+ case MissingArgPtg.sid: return MissingArgPtg.instance; // 0x16
+
+ case StringPtg.sid: return new StringPtg(in); // 0x17
+ case AttrPtg.sid: return new AttrPtg(in); // 0x19
+ case ErrPtg.sid: return ErrPtg.read(in); // 0x1c
+ case BoolPtg.sid: return BoolPtg.read(in); // 0x1d
+ case IntPtg.sid: return new IntPtg(in); // 0x1e
+ case NumberPtg.sid: return new NumberPtg(in); // 0x1f
+ }
+ throw new RuntimeException("Unexpected base token id (" + id + ")");
+ }
+
+ private static Ptg[] toPtgArray(List<Ptg> l) {
+ if (l.isEmpty()) {
+ return EMPTY_PTG_ARRAY;
+ }
+ Ptg[] result = new Ptg[l.size()];
+ l.toArray(result);
+ return result;
+ }
+ /**
+ * This method will return the same result as {@link #getEncodedSizeWithoutArrayData(Ptg[])}
+ * if there are no array tokens present.
+ * @return the full size taken to encode the specified <tt>Ptg</tt>s
+ */
+ public static int getEncodedSize(Ptg[] ptgs) {
+ int result = 0;
+ for (int i = 0; i < ptgs.length; i++) {
+ result += ptgs[i].getSize();
+ }
+ return result;
+ }
+ /**
+ * Used to calculate value that should be encoded at the start of the encoded Ptg token array;
+ * @return the size of the encoded Ptg tokens not including any trailing array data.
+ */
+ public static int getEncodedSizeWithoutArrayData(Ptg[] ptgs) {
+ int result = 0;
+ for (int i = 0; i < ptgs.length; i++) {
+ Ptg ptg = ptgs[i];
+ if (ptg instanceof ArrayPtg) {
+ result += ArrayPtg.PLAIN_TOKEN_SIZE;
+ } else {
+ result += ptg.getSize();
+ }
+ }
+ return result;
+ }
+ /**
+ * Writes the ptgs to the data buffer, starting at the specified offset.
+ *
+ * <br/>
+ * The 2 byte encode length field is <b>not</b> written by this method.
+ * @return number of bytes written
+ */
+ public static int serializePtgs(Ptg[] ptgs, byte[] array, int offset) {
+ int nTokens = ptgs.length;
+
+ LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(array, offset);
+
+ List<Ptg> arrayPtgs = null;
+
+ for (int k = 0; k < nTokens; k++) {
+ Ptg ptg = ptgs[k];
+
+ ptg.write(out);
+ if (ptg instanceof ArrayPtg) {
+ if (arrayPtgs == null) {
+ arrayPtgs = new ArrayList<Ptg>(5);
+ }
+ arrayPtgs.add(ptg);
+ }
+ }
+ if (arrayPtgs != null) {
+ for (int i=0;i<arrayPtgs.size();i++) {
+ ArrayPtg p = (ArrayPtg)arrayPtgs.get(i);
+ p.writeTokenValueBytes(out);
+ }
+ }
+ return out.getWriteIndex() - offset;
+ }
+
+ /**
+ * @return the encoded length of this Ptg, including the initial Ptg type identifier byte.
+ */
+ public abstract int getSize();
+
+ public abstract void write(LittleEndianOutput out);
+
+ /**
+ * return a string representation of this token alone
+ */
+ public abstract String toFormulaString();
+
+ /** Overridden toString method to ensure object hash is not printed.
+ * This helps get rid of gratuitous diffs when comparing two dumps
+ * Subclasses may output more relevant information by overriding this method
+ **/
+ public String toString(){
+ return this.getClass().toString();
+ }
+
+ public static final byte CLASS_REF = 0x00;
+ public static final byte CLASS_VALUE = 0x20;
+ public static final byte CLASS_ARRAY = 0x40;
+
+ private byte ptgClass = CLASS_REF; //base ptg
+
+ public final void setClass(byte thePtgClass) {
+ if (isBaseToken()) {
+ throw new RuntimeException("setClass should not be called on a base token");
+ }
+ ptgClass = thePtgClass;
+ }
+
+ /**
+ * @return the 'operand class' (REF/VALUE/ARRAY) for this Ptg
+ */
+ 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();
+
+ /**
+ * @return <code>false</code> if this token is classified as 'reference', 'value', or 'array'
+ */
+ public abstract boolean isBaseToken();
+
+ public static boolean doesFormulaReferToDeletedCell(Ptg[] ptgs) {
+ for (int i = 0; i < ptgs.length; i++) {
+ if (isDeletedCellRef(ptgs[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+ private static boolean isDeletedCellRef(Ptg ptg) {
+ if (ptg == ErrPtg.REF_INVALID) {
+ return true;
+ }
+ if (ptg instanceof DeletedArea3DPtg) {
+ return true;
+ }
+ if (ptg instanceof DeletedRef3DPtg) {
+ return true;
+ }
+ if (ptg instanceof AreaErrPtg) {
+ return true;
+ }
+ if (ptg instanceof RefErrorPtg) {
+ return true;
+ }
+ return false;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+
+/**
+ * @author Daniel Noll (daniel at nuix dot com dot au)
+ */
+public final class RangePtg extends OperationPtg {
+ public final static int SIZE = 1;
+ public final static byte sid = 0x11;
+
+ public static final OperationPtg instance = new RangePtg();
+
+ private RangePtg() {
+ // enforce singleton
+ }
+
+ public final boolean isBaseToken() {
+ return true;
+ }
+
+ public int getSize()
+ {
+ return SIZE;
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ }
+
+ public String toFormulaString()
+ {
+ return ":";
+ }
+
+
+ /** implementation of method from OperationsPtg*/
+ public String toFormulaString(String[] operands)
+ {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(operands[ 0 ]);
+ buffer.append(":");
+ buffer.append(operands[ 1 ]);
+ return buffer.toString();
+ }
+
+ public int getNumberOfOperands()
+ {
+ return 2;
+ }
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author Josh Micich
+ */
+abstract class Ref2DPtgBase extends RefPtgBase {
+ private final static int SIZE = 5;
+
+
+ protected Ref2DPtgBase(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
+ setRow(row);
+ setColumn(column);
+ setRowRelative(isRowRelative);
+ setColRelative(isColumnRelative);
+ }
+
+ protected Ref2DPtgBase(LittleEndianInput in) {
+ readCoordinates(in);
+ }
+
+ protected Ref2DPtgBase(CellReference cr) {
+ super(cr);
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(getSid() + getPtgClass());
+ writeCoordinates(out);
+ }
+
+ public final String toFormulaString() {
+ return formatReferenceAsString();
+ }
+
+ protected abstract byte getSid();
+
+ public final int getSize() {
+ return SIZE;
+ }
+
+ public final String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append(" [");
+ sb.append(formatReferenceAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.ss.formula.ExternSheetReferenceToken;
+import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
+import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Title: Reference 3D Ptg <P>
+ * Description: Defined a cell in extern sheet. <P>
+ * REFERENCE: <P>
+ * @author Libin Roman (Vista Portal LDT. Developer)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class Ref3DPtg extends RefPtgBase implements WorkbookDependentFormula, ExternSheetReferenceToken {
+ public final static byte sid = 0x3a;
+
+ private final static int SIZE = 7; // 6 + 1 for Ptg
+ private int field_1_index_extern_sheet;
+
+
+ public Ref3DPtg(LittleEndianInput in) {
+ field_1_index_extern_sheet = in.readShort();
+ readCoordinates(in);
+ }
+
+ public Ref3DPtg(String cellref, int externIdx ) {
+ this(new CellReference(cellref), externIdx);
+ }
+
+ public Ref3DPtg(CellReference c, int externIdx) {
+ super(c);
+ setExternSheetIndex(externIdx);
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append(" [");
+ sb.append("sheetIx=").append(getExternSheetIndex());
+ sb.append(" ! ");
+ sb.append(formatReferenceAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeShort(getExternSheetIndex());
+ writeCoordinates(out);
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public int getExternSheetIndex() {
+ return field_1_index_extern_sheet;
+ }
+
+ public void setExternSheetIndex(int index) {
+ field_1_index_extern_sheet = index;
+ }
+ public String format2DRefAsString() {
+ return formatReferenceAsString();
+ }
+ /**
+ * @return text representation of this cell reference that can be used in text
+ * formulas. The sheet name will get properly delimited if required.
+ */
+ public String toFormulaString(FormulaRenderingWorkbook book) {
+ return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, formatReferenceAsString());
+ }
+ public String toFormulaString() {
+ throw new RuntimeException("3D references need a workbook to determine formula text");
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.usermodel.ErrorConstants;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * RefError - handles deleted cell reference
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class RefErrorPtg extends OperandPtg {
+
+ private final static int SIZE = 5;
+ public final static byte sid = 0x2A;
+ private int field_1_reserved;
+
+ public RefErrorPtg() {
+ field_1_reserved = 0;
+ }
+ public RefErrorPtg(LittleEndianInput in) {
+ field_1_reserved = in.readInt();
+ }
+
+ public String toString() {
+ return getClass().getName();
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeInt(field_1_reserved);
+ }
+
+ public int getSize()
+ {
+ return SIZE;
+ }
+
+ public String toFormulaString() {
+ return ErrorConstants.getText(ErrorConstants.ERROR_REF);
+ }
+
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianInput;
+
+/**
+ * RefNPtg
+ * @author Jason Height (jheight at apache dot com)
+ */
+public final class RefNPtg extends Ref2DPtgBase {
+ public final static byte sid = 0x2C;
+
+ public RefNPtg(LittleEndianInput in) {
+ super(in);
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.util.LittleEndianInput;
+
+/**
+ * ReferencePtg - handles references (such as A1, A2, IA4)
+ * @author Andrew C. Oliver (acoliver@apache.org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class RefPtg extends Ref2DPtgBase {
+ public final static byte sid = 0x24;
+
+ /**
+ * Takes in a String representation of a cell reference and fills out the
+ * numeric fields.
+ */
+ public RefPtg(String cellref) {
+ super(new CellReference(cellref));
+ }
+
+ public RefPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
+ super(row, column, isRowRelative, isColumnRelative);
+ }
+
+ public RefPtg(LittleEndianInput in) {
+ super(in);
+ }
+
+ public RefPtg(CellReference cr) {
+ super(cr);
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * ReferencePtgBase - handles references (such as A1, A2, IA4)
+ *
+ * @author Andrew C. Oliver (acoliver@apache.org)
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public abstract class RefPtgBase extends OperandPtg {
+
+ /** The row index - zero based unsigned 16 bit value */
+ private int field_1_row;
+ /**
+ * Field 2 - lower 8 bits is the zero based unsigned byte column index - bit
+ * 16 - isRowRelative - bit 15 - isColumnRelative
+ */
+ private int field_2_col;
+ private static final BitField rowRelative = BitFieldFactory.getInstance(0x8000);
+ private static final BitField colRelative = BitFieldFactory.getInstance(0x4000);
+
+ /**
+ * YK: subclasses of RefPtgBase are used by the FormulaParser and FormulaEvaluator accross HSSF and XSSF.
+ * The bit mask should accomodate the maximum number of avaiable columns, i.e. 0x3FFF.
+ *
+ * @see org.apache.poi.ss.SpreadsheetVersion
+ */
+ private static final BitField column = BitFieldFactory.getInstance(0x3FFF);
+
+ protected RefPtgBase() {
+ // Required for clone methods
+ }
+
+ protected RefPtgBase(CellReference c) {
+ setRow(c.getRow());
+ setColumn(c.getCol());
+ setColRelative(!c.isColAbsolute());
+ setRowRelative(!c.isRowAbsolute());
+ }
+
+ protected final void readCoordinates(LittleEndianInput in) {
+ field_1_row = in.readUShort();
+ field_2_col = in.readUShort();
+ }
+
+ protected final void writeCoordinates(LittleEndianOutput out) {
+ out.writeShort(field_1_row);
+ out.writeShort(field_2_col);
+ }
+
+ public final void setRow(int rowIndex) {
+ field_1_row = rowIndex;
+ }
+
+ /**
+ * @return the row number as an int
+ */
+ public final int getRow() {
+ return field_1_row;
+ }
+
+ public final boolean isRowRelative() {
+ return rowRelative.isSet(field_2_col);
+ }
+
+ public final void setRowRelative(boolean rel) {
+ field_2_col = rowRelative.setBoolean(field_2_col, rel);
+ }
+
+ public final boolean isColRelative() {
+ return colRelative.isSet(field_2_col);
+ }
+
+ public final void setColRelative(boolean rel) {
+ field_2_col = colRelative.setBoolean(field_2_col, rel);
+ }
+
+ public final void setColumn(int col) {
+ field_2_col = column.setValue(field_2_col, col);
+ }
+
+ public final int getColumn() {
+ return column.getValue(field_2_col);
+ }
+
+ protected final String formatReferenceAsString() {
+ // Only make cell references as needed. Memory is an issue
+ CellReference cr = new CellReference(getRow(), getColumn(), !isRowRelative(), !isColRelative());
+ return cr.formatAsString();
+ }
+
+ public final byte getDefaultOperandClass() {
+ return Ptg.CLASS_REF;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+
+/**
+ * Common superclass of all {@link Ptg}s that represent simple constant values.
+ *
+ * @author Josh Micich
+ */
+public abstract class ScalarConstantPtg extends Ptg {
+ public final boolean isBaseToken() {
+ return true;
+ }
+
+ public final byte getDefaultOperandClass() {
+ return Ptg.CLASS_VALUE;
+ }
+
+ public final String toString() {
+ StringBuffer sb = new StringBuffer(64);
+ sb.append(getClass().getName()).append(" [");
+ sb.append(toFormulaString());
+ sb.append("]");
+ return sb.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * String Stores a String value in a formula value stored in the format
+ * <length 2 bytes>char[]
+ *
+ * @author Werner Froidevaux
+ * @author Jason Height (jheight at chariot dot net dot au)
+ * @author Bernard Chesnoy
+ */
+public final class StringPtg extends ScalarConstantPtg {
+ public final static byte sid = 0x17;
+ /** the character (") used in formulas to delimit string literals */
+ private static final char FORMULA_DELIMITER = '"';
+
+ private final boolean _is16bitUnicode;
+ /**
+ * NOTE: OO doc says 16bit length, but BiffViewer says 8 Book says something
+ * totally different, so don't look there!
+ */
+ private final String field_3_string;
+
+ /** Create a StringPtg from a stream */
+ public StringPtg(LittleEndianInput in) {
+ int nChars = in.readUByte(); // Note - nChars is 8-bit
+ _is16bitUnicode = (in.readByte() & 0x01) != 0;
+ if (_is16bitUnicode) {
+ field_3_string = StringUtil.readUnicodeLE(in, nChars);
+ } else {
+ field_3_string = StringUtil.readCompressedUnicode(in, nChars);
+ }
+ }
+
+ /**
+ * 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.
+ *
+ * @param value :
+ * String representation of a floating point number
+ */
+ public StringPtg(String value) {
+ if (value.length() > 255) {
+ throw new IllegalArgumentException(
+ "String literals in formulas can't be bigger than 255 characters ASCII");
+ }
+ _is16bitUnicode = StringUtil.hasMultibyte(value);
+ field_3_string = value;
+ }
+
+ public String getValue() {
+ return field_3_string;
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeByte(field_3_string.length()); // Note - nChars is 8-bit
+ out.writeByte(_is16bitUnicode ? 0x01 : 0x00);
+ if (_is16bitUnicode) {
+ StringUtil.putUnicodeLE(field_3_string, out);
+ } else {
+ StringUtil.putCompressedUnicode(field_3_string, out);
+ }
+ }
+
+ public int getSize() {
+ return 3 + field_3_string.length() * (_is16bitUnicode ? 2 : 1);
+ }
+
+ public String toFormulaString() {
+ String value = field_3_string;
+ int len = value.length();
+ StringBuffer sb = new StringBuffer(len + 4);
+ sb.append(FORMULA_DELIMITER);
+
+ for (int i = 0; i < len; i++) {
+ char c = value.charAt(i);
+ if (c == FORMULA_DELIMITER) {
+ sb.append(FORMULA_DELIMITER);
+ }
+ sb.append(c);
+ }
+
+ sb.append(FORMULA_DELIMITER);
+ return sb.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ *
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public final class SubtractPtg extends ValueOperatorPtg {
+ public final static byte sid = 0x04;
+
+ public static final ValueOperatorPtg instance = new SubtractPtg();
+
+ private SubtractPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 2;
+ }
+
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(operands[ 0 ]);
+ buffer.append("-");
+ buffer.append(operands[ 1 ]);
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * This ptg indicates a data table.
+ * It only occurs in a FORMULA record, never in an
+ * ARRAY or NAME record. When ptgTbl occurs in a
+ * formula, it is the only token in the formula.
+ *
+ * This indicates that the cell containing the
+ * formula is an interior cell in a data table;
+ * the table description is found in a TABLE
+ * record. Rows and columns which contain input
+ * values to be substituted in the table do
+ * not contain ptgTbl.
+ * See page 811 of the june 08 binary docs.
+ */
+public final class TblPtg extends ControlPtg {
+ private final static int SIZE = 5;
+ public final static short sid = 0x02;
+ /** The row number of the upper left corner */
+ private final int field_1_first_row;
+ /** The column number of the upper left corner */
+ private final int field_2_first_col;
+
+ public TblPtg(LittleEndianInput in) {
+ field_1_first_row = in.readUShort();
+ field_2_first_col = in.readUShort();
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ out.writeShort(field_1_first_row);
+ out.writeShort(field_2_first_col);
+ }
+
+ public int getSize() {
+ return SIZE;
+ }
+
+ public int getRow() {
+ return field_1_first_row;
+ }
+
+ public int getColumn() {
+ return field_2_first_col;
+ }
+
+ public String toFormulaString()
+ {
+ // table(....)[][]
+ throw new RuntimeException("Table and Arrays are not yet supported");
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer("[Data Table - Parent cell is an interior cell in a data table]\n");
+ buffer.append("top left row = ").append(getRow()).append("\n");
+ buffer.append("top left col = ").append(getColumn()).append("\n");
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * Unary Plus operator
+ * does not have any effect on the operand
+ * @author Avik Sengupta
+ */
+public final class UnaryMinusPtg extends ValueOperatorPtg {
+ public final static byte sid = 0x13;
+
+ private final static String MINUS = "-";
+
+ public static final ValueOperatorPtg instance = new UnaryMinusPtg();
+
+ private UnaryMinusPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 1;
+ }
+
+ /** implementation of method from OperationsPtg*/
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(MINUS);
+ buffer.append(operands[ 0]);
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+/**
+ * Unary Plus operator
+ * does not have any effect on the operand
+ * @author Avik Sengupta
+ */
+public final class UnaryPlusPtg extends ValueOperatorPtg {
+ public final static byte sid = 0x12;
+
+ private final static String ADD = "+";
+
+ public static final ValueOperatorPtg instance = new UnaryPlusPtg();
+
+ private UnaryPlusPtg() {
+ // enforce singleton
+ }
+
+ protected byte getSid() {
+ return sid;
+ }
+
+ public int getNumberOfOperands() {
+ return 1;
+ }
+
+ /** implementation of method from OperationsPtg*/
+ public String toFormulaString(String[] operands) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(ADD);
+ buffer.append(operands[ 0]);
+ return buffer.toString();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+
+/**
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public final class UnionPtg extends OperationPtg {
+ public final static byte sid = 0x10;
+
+ public static final OperationPtg instance = new UnionPtg();
+
+ private UnionPtg() {
+ // enforce singleton
+ }
+
+ public final boolean isBaseToken() {
+ return true;
+ }
+
+ public int getSize()
+ {
+ return 1;
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(sid + getPtgClass());
+ }
+
+ public String toFormulaString()
+ {
+ return ",";
+ }
+
+
+ /** implementation of method from OperationsPtg*/
+ public String toFormulaString(String[] operands)
+ {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(operands[ 0 ]);
+ buffer.append(",");
+ buffer.append(operands[ 1 ]);
+ return buffer.toString();
+ }
+
+ public int getNumberOfOperands()
+ {
+ return 2;
+ }
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * @author andy
+ * @author Jason Height (jheight at chariot dot net dot au)
+ */
+public class UnknownPtg extends Ptg {
+ private short size = 1;
+ private final int _sid;
+
+ public UnknownPtg(int sid) {
+ _sid = sid;
+ }
+
+ public boolean isBaseToken() {
+ return true;
+ }
+ public void write(LittleEndianOutput out) {
+ out.writeByte(_sid);
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ public String toFormulaString() {
+ return "UNKNOWN";
+ }
+ public byte getDefaultOperandClass() {
+ return Ptg.CLASS_VALUE;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Common superclass of all value operators. Subclasses include all unary and
+ * binary operators except for the reference operators (IntersectionPtg,
+ * RangePtg, UnionPtg)
+ *
+ * @author Josh Micich
+ */
+public abstract class ValueOperatorPtg extends OperationPtg {
+
+ /**
+ * All Operator <tt>Ptg</tt>s are base tokens (i.e. are not RVA classified)
+ */
+ public final boolean isBaseToken() {
+ return true;
+ }
+
+ public final byte getDefaultOperandClass() {
+ return Ptg.CLASS_VALUE;
+ }
+
+ public void write(LittleEndianOutput out) {
+ out.writeByte(getSid());
+ }
+
+ protected abstract byte getSid();
+
+ public final int getSize() {
+ return 1;
+ }
+
+ public final String toFormulaString() {
+ // TODO - prune this method out of the hierarchy
+ throw new RuntimeException("toFormulaString(String[] operands) should be used for subclasses of OperationPtgs");
+ }
+}
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+ ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ====================================================================
+-->
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+formula package contains binary PTG structures used in Formulas
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+<li><a href="http://poi.apache.org">Apache POI Project</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+@see org.apache.poi.hssf.record
+@see org.apache.poi.hssf.record.FormulaRecord
+</body>
+</html>
* For a list of all the different fields that can be
* placed into a footer, such as page number,
* bold, underline etc, see
- * {@link org.apache.poi.hssf.usermodel.HeaderFooter}.
+ * {@link org.apache.poi.ss.usermodel.HeaderFooter}.
*/
public interface Footer extends HeaderFooter {
/**
* For a list of all the different fields that can be
* placed into a header, such as page number,
* bold, underline etc, see
- * {@link org.apache.poi.hssf.usermodel.HeaderFooter}.
+ * {@link org.apache.poi.ss.usermodel.HeaderFooter}.
*/
public interface Header extends HeaderFooter {
/**