From d22525f10e5c18fc6350ac3bbbdedbf9cc368779 Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Wed, 24 Nov 2010 16:50:47 +0000 Subject: [PATCH] moved ptg classes to org.apache.poi.ss.formula.ptg git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1038688 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/ss/formula/EvaluationName.java | 4 +- .../poi/ss/formula/EvaluationWorkbook.java | 6 +- .../ss/formula/ExternSheetReferenceToken.java | 2 +- .../org/apache/poi/ss/formula/Formula.java | 8 +- .../apache/poi/ss/formula/FormulaParser.java | 4 +- .../ss/formula/FormulaParsingWorkbook.java | 2 +- .../poi/ss/formula/FormulaRenderer.java | 14 +- .../ss/formula/FormulaRenderingWorkbook.java | 4 +- .../apache/poi/ss/formula/FormulaShifter.java | 2 +- .../ss/formula/FormulaUsedBlankCellSet.java | 2 +- .../apache/poi/ss/formula/LazyAreaEval.java | 6 +- .../apache/poi/ss/formula/LazyRefEval.java | 6 +- .../ss/formula/OperandClassTransformer.java | 20 +- .../formula/OperationEvaluationContext.java | 8 +- .../ss/formula/OperationEvaluatorFactory.java | 38 +-- .../org/apache/poi/ss/formula/ParseNode.java | 12 +- .../apache/poi/ss/formula/SharedFormula.java | 4 +- .../ss/formula/WorkbookDependentFormula.java | 2 +- .../poi/ss/formula/WorkbookEvaluator.java | 56 +-- .../formula/constant/ConstantValueParser.java | 157 +++++++++ .../ss/formula/constant/ErrorConstant.java | 77 +++++ .../poi/ss/formula/eval/AreaEvalBase.java | 2 +- .../apache/poi/ss/formula/eval/NameXEval.java | 2 +- .../poi/ss/formula/eval/NumberEval.java | 6 +- .../poi/ss/formula/eval/StringEval.java | 4 +- .../eval/forked/ForkedEvaluationWorkbook.java | 6 +- .../function/FunctionMetadataReader.java | 2 +- .../ss/formula/ptg/AbstractFunctionPtg.java | 164 +++++++++ .../org/apache/poi/ss/formula/ptg/AddPtg.java | 54 +++ .../poi/ss/formula/ptg/Area2DPtgBase.java | 64 ++++ .../apache/poi/ss/formula/ptg/Area3DPtg.java | 105 ++++++ .../apache/poi/ss/formula/ptg/AreaErrPtg.java | 63 ++++ .../org/apache/poi/ss/formula/ptg/AreaI.java | 75 ++++ .../apache/poi/ss/formula/ptg/AreaNPtg.java | 36 ++ .../apache/poi/ss/formula/ptg/AreaPtg.java | 45 +++ .../poi/ss/formula/ptg/AreaPtgBase.java | 272 +++++++++++++++ .../apache/poi/ss/formula/ptg/ArrayPtg.java | 268 +++++++++++++++ .../apache/poi/ss/formula/ptg/AttrPtg.java | 263 ++++++++++++++ .../apache/poi/ss/formula/ptg/BoolPtg.java | 66 ++++ .../apache/poi/ss/formula/ptg/ConcatPtg.java | 52 +++ .../apache/poi/ss/formula/ptg/ControlPtg.java | 38 +++ .../poi/ss/formula/ptg/DeletedArea3DPtg.java | 69 ++++ .../poi/ss/formula/ptg/DeletedRef3DPtg.java | 68 ++++ .../apache/poi/ss/formula/ptg/DividePtg.java | 50 +++ .../apache/poi/ss/formula/ptg/EqualPtg.java | 50 +++ .../org/apache/poi/ss/formula/ptg/ErrPtg.java | 94 +++++ .../org/apache/poi/ss/formula/ptg/ExpPtg.java | 73 ++++ .../formula/ptg/ExternSheetNameResolver.java | 55 +++ .../apache/poi/ss/formula/ptg/FuncPtg.java | 60 ++++ .../apache/poi/ss/formula/ptg/FuncVarPtg.java | 73 ++++ .../poi/ss/formula/ptg/GreaterEqualPtg.java | 54 +++ .../poi/ss/formula/ptg/GreaterThanPtg.java | 61 ++++ .../org/apache/poi/ss/formula/ptg/IntPtg.java | 76 +++++ .../poi/ss/formula/ptg/IntersectionPtg.java | 62 ++++ .../poi/ss/formula/ptg/LessEqualPtg.java | 53 +++ .../poi/ss/formula/ptg/LessThanPtg.java | 64 ++++ .../apache/poi/ss/formula/ptg/MemAreaPtg.java | 74 ++++ .../apache/poi/ss/formula/ptg/MemErrPtg.java | 57 ++++ .../apache/poi/ss/formula/ptg/MemFuncPtg.java | 75 ++++ .../poi/ss/formula/ptg/MissingArgPtg.java | 51 +++ .../poi/ss/formula/ptg/MultiplyPtg.java | 50 +++ .../apache/poi/ss/formula/ptg/NamePtg.java | 79 +++++ .../apache/poi/ss/formula/ptg/NameXPtg.java | 93 +++++ .../poi/ss/formula/ptg/NotEqualPtg.java | 52 +++ .../apache/poi/ss/formula/ptg/NumberPtg.java | 71 ++++ .../apache/poi/ss/formula/ptg/OperandPtg.java | 38 +++ .../poi/ss/formula/ptg/OperationPtg.java | 45 +++ .../poi/ss/formula/ptg/ParenthesisPtg.java | 58 ++++ .../apache/poi/ss/formula/ptg/PercentPtg.java | 52 +++ .../apache/poi/ss/formula/ptg/PowerPtg.java | 51 +++ .../org/apache/poi/ss/formula/ptg/Ptg.java | 321 ++++++++++++++++++ .../apache/poi/ss/formula/ptg/RangePtg.java | 71 ++++ .../poi/ss/formula/ptg/Ref2DPtgBase.java | 69 ++++ .../apache/poi/ss/formula/ptg/Ref3DPtg.java | 96 ++++++ .../poi/ss/formula/ptg/RefErrorPtg.java | 62 ++++ .../apache/poi/ss/formula/ptg/RefNPtg.java | 36 ++ .../org/apache/poi/ss/formula/ptg/RefPtg.java | 54 +++ .../apache/poi/ss/formula/ptg/RefPtgBase.java | 117 +++++++ .../poi/ss/formula/ptg/ScalarConstantPtg.java | 42 +++ .../apache/poi/ss/formula/ptg/StringPtg.java | 108 ++++++ .../poi/ss/formula/ptg/SubtractPtg.java | 50 +++ .../org/apache/poi/ss/formula/ptg/TblPtg.java | 80 +++++ .../poi/ss/formula/ptg/UnaryMinusPtg.java | 51 +++ .../poi/ss/formula/ptg/UnaryPlusPtg.java | 51 +++ .../apache/poi/ss/formula/ptg/UnionPtg.java | 70 ++++ .../apache/poi/ss/formula/ptg/UnknownPtg.java | 50 +++ .../poi/ss/formula/ptg/ValueOperatorPtg.java | 56 +++ .../apache/poi/ss/formula/ptg/package.html | 38 +++ .../org/apache/poi/ss/usermodel/Footer.java | 2 +- .../org/apache/poi/ss/usermodel/Header.java | 2 +- 90 files changed, 5142 insertions(+), 113 deletions(-) create mode 100644 src/java/org/apache/poi/ss/formula/constant/ConstantValueParser.java create mode 100644 src/java/org/apache/poi/ss/formula/constant/ErrorConstant.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/AddPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/Area2DPtgBase.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/Area3DPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/AreaErrPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/AreaI.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/AreaNPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/AreaPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/AttrPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/BoolPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/ConcatPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/ControlPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/DeletedArea3DPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/DeletedRef3DPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/DividePtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/EqualPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/ErrPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/ExpPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/FuncPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/FuncVarPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/GreaterEqualPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/GreaterThanPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/IntPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/IntersectionPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/LessEqualPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/LessThanPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/MemAreaPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/MemErrPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/MemFuncPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/MissingArgPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/MultiplyPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/NamePtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/NameXPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/NotEqualPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/NumberPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/OperandPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/OperationPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/ParenthesisPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/PercentPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/PowerPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/Ptg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/RangePtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/Ref2DPtgBase.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/Ref3DPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/RefErrorPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/RefNPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/RefPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/RefPtgBase.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/ScalarConstantPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/StringPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/SubtractPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/TblPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/UnaryMinusPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/UnaryPlusPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/UnionPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/UnknownPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/ValueOperatorPtg.java create mode 100644 src/java/org/apache/poi/ss/formula/ptg/package.html diff --git a/src/java/org/apache/poi/ss/formula/EvaluationName.java b/src/java/org/apache/poi/ss/formula/EvaluationName.java index 7d6688bb82..2d1fbf5e27 100644 --- a/src/java/org/apache/poi/ss/formula/EvaluationName.java +++ b/src/java/org/apache/poi/ss/formula/EvaluationName.java @@ -17,8 +17,8 @@ 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.
* diff --git a/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java b/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java index 1f42aa8930..0a40bf0ca9 100644 --- a/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java +++ b/src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java @@ -17,9 +17,9 @@ 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.
diff --git a/src/java/org/apache/poi/ss/formula/ExternSheetReferenceToken.java b/src/java/org/apache/poi/ss/formula/ExternSheetReferenceToken.java index c3f9bc2e56..ce67dadc16 100644 --- a/src/java/org/apache/poi/ss/formula/ExternSheetReferenceToken.java +++ b/src/java/org/apache/poi/ss/formula/ExternSheetReferenceToken.java @@ -18,7 +18,7 @@ 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
+ * Should be implemented by any {@link org.apache.poi.ss.formula.ptg.Ptg} subclass that needs has an extern sheet index
* * For POI internal use only * diff --git a/src/java/org/apache/poi/ss/formula/Formula.java b/src/java/org/apache/poi/ss/formula/Formula.java index da1ef1af71..52b92ec4b1 100644 --- a/src/java/org/apache/poi/ss/formula/Formula.java +++ b/src/java/org/apache/poi/ss/formula/Formula.java @@ -19,10 +19,10 @@ package org.apache.poi.ss.formula; 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; diff --git a/src/java/org/apache/poi/ss/formula/FormulaParser.java b/src/java/org/apache/poi/ss/formula/FormulaParser.java index 4399045832..f9f3ca0c77 100644 --- a/src/java/org/apache/poi/ss/formula/FormulaParser.java +++ b/src/java/org/apache/poi/ss/formula/FormulaParser.java @@ -21,8 +21,8 @@ import java.util.ArrayList; 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; diff --git a/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java b/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java index 83f7c99a96..5bafa57e54 100644 --- a/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java +++ b/src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java @@ -17,7 +17,7 @@ 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; /** diff --git a/src/java/org/apache/poi/ss/formula/FormulaRenderer.java b/src/java/org/apache/poi/ss/formula/FormulaRenderer.java index d37e843596..13c1eef56f 100644 --- a/src/java/org/apache/poi/ss/formula/FormulaRenderer.java +++ b/src/java/org/apache/poi/ss/formula/FormulaRenderer.java @@ -19,13 +19,13 @@ package org.apache.poi.ss.formula; 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.
diff --git a/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java b/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java index b0dcb38512..0234ae65b4 100644 --- a/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java +++ b/src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java @@ -17,8 +17,8 @@ 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; /** diff --git a/src/java/org/apache/poi/ss/formula/FormulaShifter.java b/src/java/org/apache/poi/ss/formula/FormulaShifter.java index 750eecc373..e735496d7a 100644 --- a/src/java/org/apache/poi/ss/formula/FormulaShifter.java +++ b/src/java/org/apache/poi/ss/formula/FormulaShifter.java @@ -17,7 +17,7 @@ package org.apache.poi.ss.formula; -import org.apache.poi.hssf.record.formula.*; +import org.apache.poi.ss.formula.ptg.*; /** diff --git a/src/java/org/apache/poi/ss/formula/FormulaUsedBlankCellSet.java b/src/java/org/apache/poi/ss/formula/FormulaUsedBlankCellSet.java index 91b2336e87..e054f125da 100644 --- a/src/java/org/apache/poi/ss/formula/FormulaUsedBlankCellSet.java +++ b/src/java/org/apache/poi/ss/formula/FormulaUsedBlankCellSet.java @@ -22,7 +22,7 @@ import java.util.HashMap; 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. diff --git a/src/java/org/apache/poi/ss/formula/LazyAreaEval.java b/src/java/org/apache/poi/ss/formula/LazyAreaEval.java index 65eaa0a5cc..f66d6b1961 100644 --- a/src/java/org/apache/poi/ss/formula/LazyAreaEval.java +++ b/src/java/org/apache/poi/ss/formula/LazyAreaEval.java @@ -17,12 +17,12 @@ 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; /** * diff --git a/src/java/org/apache/poi/ss/formula/LazyRefEval.java b/src/java/org/apache/poi/ss/formula/LazyRefEval.java index 63dffdeb18..167fd102e5 100644 --- a/src/java/org/apache/poi/ss/formula/LazyRefEval.java +++ b/src/java/org/apache/poi/ss/formula/LazyRefEval.java @@ -17,12 +17,12 @@ 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; /** * diff --git a/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java b/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java index 46f5c71f0c..05b7d56d71 100644 --- a/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java +++ b/src/java/org/apache/poi/ss/formula/OperandClassTransformer.java @@ -17,16 +17,16 @@ 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 diff --git a/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java b/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java index e7355a49ff..a154089253 100644 --- a/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java +++ b/src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java @@ -17,10 +17,10 @@ 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; diff --git a/src/java/org/apache/poi/ss/formula/OperationEvaluatorFactory.java b/src/java/org/apache/poi/ss/formula/OperationEvaluatorFactory.java index d1ca78fc67..d85b6feae5 100644 --- a/src/java/org/apache/poi/ss/formula/OperationEvaluatorFactory.java +++ b/src/java/org/apache/poi/ss/formula/OperationEvaluatorFactory.java @@ -22,25 +22,25 @@ import java.lang.reflect.Modifier; 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; diff --git a/src/java/org/apache/poi/ss/formula/ParseNode.java b/src/java/org/apache/poi/ss/formula/ParseNode.java index ebe30d40aa..a671ede597 100644 --- a/src/java/org/apache/poi/ss/formula/ParseNode.java +++ b/src/java/org/apache/poi/ss/formula/ParseNode.java @@ -17,12 +17,12 @@ 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 Ptg diff --git a/src/java/org/apache/poi/ss/formula/SharedFormula.java b/src/java/org/apache/poi/ss/formula/SharedFormula.java index 70cbeffe27..0cf492e9cd 100644 --- a/src/java/org/apache/poi/ss/formula/SharedFormula.java +++ b/src/java/org/apache/poi/ss/formula/SharedFormula.java @@ -16,7 +16,7 @@ ==================================================================== */ package org.apache.poi.ss.formula; -import org.apache.poi.hssf.record.formula.*; +import org.apache.poi.ss.formula.ptg.*; import org.apache.poi.ss.SpreadsheetVersion; /** @@ -34,7 +34,7 @@ public class SharedFormula { /** * Creates a non shared formula from the shared formula counterpart, i.e. - * Converts the shared formula into the equivalent {@link org.apache.poi.hssf.record.formula.Ptg} array that it would have, + * Converts the shared formula into the equivalent {@link org.apache.poi.ss.formula.ptg.Ptg} array that it would have, * were it not shared. * * @param ptgs parsed tokens of the shared formula diff --git a/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java b/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java index 4beaaa3b08..47dc952f7c 100644 --- a/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java +++ b/src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java @@ -18,7 +18,7 @@ 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. *
* * For POI internal use only diff --git a/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java b/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java index 5717be22b0..cd635898f8 100644 --- a/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java +++ b/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java @@ -21,33 +21,33 @@ import java.util.IdentityHashMap; 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; @@ -63,7 +63,7 @@ import org.apache.poi.ss.formula.functions.FreeRefFunction; 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; diff --git a/src/java/org/apache/poi/ss/formula/constant/ConstantValueParser.java b/src/java/org/apache/poi/ss/formula/constant/ConstantValueParser.java new file mode 100644 index 0000000000..cf664ebc2d --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/constant/ConstantValueParser.java @@ -0,0 +1,157 @@ +/* ==================================================================== + 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.

+ * + * @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() + "'"); + } +} diff --git a/src/java/org/apache/poi/ss/formula/constant/ErrorConstant.java b/src/java/org/apache/poi/ss/formula/constant/ErrorConstant.java new file mode 100644 index 0000000000..5a58db9278 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/constant/ErrorConstant.java @@ -0,0 +1,77 @@ +/* ==================================================================== + 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.

+ * + * This class is a type-safe wrapper for a 16-bit int value performing a similar job to + * ErrorEval. + * + * @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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/eval/AreaEvalBase.java b/src/java/org/apache/poi/ss/formula/eval/AreaEvalBase.java index 8f09e6e07a..6b81636e8d 100644 --- a/src/java/org/apache/poi/ss/formula/eval/AreaEvalBase.java +++ b/src/java/org/apache/poi/ss/formula/eval/AreaEvalBase.java @@ -17,7 +17,7 @@ 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 diff --git a/src/java/org/apache/poi/ss/formula/eval/NameXEval.java b/src/java/org/apache/poi/ss/formula/eval/NameXEval.java index 951d4619be..32831bc258 100644 --- a/src/java/org/apache/poi/ss/formula/eval/NameXEval.java +++ b/src/java/org/apache/poi/ss/formula/eval/NameXEval.java @@ -17,7 +17,7 @@ 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 diff --git a/src/java/org/apache/poi/ss/formula/eval/NumberEval.java b/src/java/org/apache/poi/ss/formula/eval/NumberEval.java index e500f707ce..1233cea7fe 100644 --- a/src/java/org/apache/poi/ss/formula/eval/NumberEval.java +++ b/src/java/org/apache/poi/ss/formula/eval/NumberEval.java @@ -20,9 +20,9 @@ */ 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; /** diff --git a/src/java/org/apache/poi/ss/formula/eval/StringEval.java b/src/java/org/apache/poi/ss/formula/eval/StringEval.java index b2596fa105..5d3976137b 100644 --- a/src/java/org/apache/poi/ss/formula/eval/StringEval.java +++ b/src/java/org/apache/poi/ss/formula/eval/StringEval.java @@ -17,8 +17,8 @@ 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 > diff --git a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java index 8742b92143..74e4a182bb 100644 --- a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java +++ b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java @@ -20,9 +20,9 @@ package org.apache.poi.ss.formula.eval.forked; 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; diff --git a/src/java/org/apache/poi/ss/formula/function/FunctionMetadataReader.java b/src/java/org/apache/poi/ss/formula/function/FunctionMetadataReader.java index 53ba79c5da..d7ebb5262e 100644 --- a/src/java/org/apache/poi/ss/formula/function/FunctionMetadataReader.java +++ b/src/java/org/apache/poi/ss/formula/function/FunctionMetadataReader.java @@ -27,7 +27,7 @@ import java.util.HashSet; 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 FunctionMetadataRegistry diff --git a/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java b/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java new file mode 100644 index 0000000000..9e413c5fe2 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/AbstractFunctionPtg.java @@ -0,0 +1,164 @@ +/* ==================================================================== + 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 true 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;ifirstArgIx) { + 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 + *

+ * The name matching is case insensitive. + * @return true if the name specifies a standard worksheet function, + * false 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. + *

+ * The name matching is case insensitive. + * @return the standard worksheet function index if found, otherwise FUNCTION_INDEX_EXTERNAL + */ + 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]; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/AddPtg.java b/src/java/org/apache/poi/ss/formula/ptg/AddPtg.java new file mode 100644 index 0000000000..e275d8c439 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/AddPtg.java @@ -0,0 +1,54 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/Area2DPtgBase.java b/src/java/org/apache/poi/ss/formula/ptg/Area2DPtgBase.java new file mode 100644 index 0000000000..59324f8097 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/Area2DPtgBase.java @@ -0,0 +1,64 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/Area3DPtg.java b/src/java/org/apache/poi/ss/formula/ptg/Area3DPtg.java new file mode 100644 index 0000000000..2bee023b6e --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/Area3DPtg.java @@ -0,0 +1,105 @@ +/* ==================================================================== + 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)

+ * Description: Defined a area in Extern Sheet.

+ * REFERENCE:

+ * @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"); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/AreaErrPtg.java b/src/java/org/apache/poi/ss/formula/ptg/AreaErrPtg.java new file mode 100644 index 0000000000..3697425886 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/AreaErrPtg.java @@ -0,0 +1,63 @@ +/* ==================================================================== + 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; + } +} + diff --git a/src/java/org/apache/poi/ss/formula/ptg/AreaI.java b/src/java/org/apache/poi/ss/formula/ptg/AreaI.java new file mode 100644 index 0000000000..96ffe70053 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/AreaI.java @@ -0,0 +1,75 @@ +/* ==================================================================== + 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 diff --git a/src/java/org/apache/poi/ss/formula/ptg/AreaNPtg.java b/src/java/org/apache/poi/ss/formula/ptg/AreaNPtg.java new file mode 100644 index 0000000000..bc8f76e3db --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/AreaNPtg.java @@ -0,0 +1,36 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/AreaPtg.java b/src/java/org/apache/poi/ss/formula/ptg/AreaPtg.java new file mode 100644 index 0000000000..4499319b62 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/AreaPtg.java @@ -0,0 +1,45 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java b/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java new file mode 100644 index 0000000000..4df3314440 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/AreaPtgBase.java @@ -0,0 +1,272 @@ +/* ==================================================================== + 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 true if the last row relative, else + * false + */ + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java b/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java new file mode 100644 index 0000000000..b21936bec4 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/ArrayPtg.java @@ -0,0 +1,268 @@ +/* ==================================================================== + 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= _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 0) { + b.append(";"); + } + for (int x=0;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; + } + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/AttrPtg.java b/src/java/org/apache/poi/ss/formula/ptg/AttrPtg.java new file mode 100644 index 0000000000..96da294451 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/AttrPtg.java @@ -0,0 +1,263 @@ +/* ==================================================================== + 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 SpaceType + * @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

+ */ + 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"; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/BoolPtg.java b/src/java/org/apache/poi/ss/formula/ptg/BoolPtg.java new file mode 100644 index 0000000000..28b5619052 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/BoolPtg.java @@ -0,0 +1,66 @@ +/* ==================================================================== + 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"; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/ConcatPtg.java b/src/java/org/apache/poi/ss/formula/ptg/ConcatPtg.java new file mode 100644 index 0000000000..eb11f8fc3b --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/ConcatPtg.java @@ -0,0 +1,52 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/ControlPtg.java b/src/java/org/apache/poi/ss/formula/ptg/ControlPtg.java new file mode 100644 index 0000000000..6e819daab7 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/ControlPtg.java @@ -0,0 +1,38 @@ +/* ==================================================================== + 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"); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/DeletedArea3DPtg.java b/src/java/org/apache/poi/ss/formula/ptg/DeletedArea3DPtg.java new file mode 100644 index 0000000000..1ddfd019d7 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/DeletedArea3DPtg.java @@ -0,0 +1,69 @@ +/* ==================================================================== + 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)

+ * Description: Defined a area in Extern Sheet.

+ * REFERENCE:

+ * @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); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/DeletedRef3DPtg.java b/src/java/org/apache/poi/ss/formula/ptg/DeletedRef3DPtg.java new file mode 100644 index 0000000000..9f6aaf342e --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/DeletedRef3DPtg.java @@ -0,0 +1,68 @@ +/* ==================================================================== + 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

+ * Description: Defined a cell in extern sheet.

+ * REFERENCE:

+ * @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); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/DividePtg.java b/src/java/org/apache/poi/ss/formula/ptg/DividePtg.java new file mode 100644 index 0000000000..66e6913bcb --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/DividePtg.java @@ -0,0 +1,50 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/EqualPtg.java b/src/java/org/apache/poi/ss/formula/ptg/EqualPtg.java new file mode 100644 index 0000000000..164ce981c1 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/EqualPtg.java @@ -0,0 +1,50 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/ErrPtg.java b/src/java/org/apache/poi/ss/formula/ptg/ErrPtg.java new file mode 100644 index 0000000000..2e38c33083 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/ErrPtg.java @@ -0,0 +1,94 @@ +/* ==================================================================== + 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; + + /** #NULL! - Intersection of two cell ranges is empty */ + public static final ErrPtg NULL_INTERSECTION = new ErrPtg(EC.ERROR_NULL); + /** #DIV/0! - Division by zero */ + public static final ErrPtg DIV_ZERO = new ErrPtg(EC.ERROR_DIV_0); + /** #VALUE! - Wrong type of operand */ + public static final ErrPtg VALUE_INVALID = new ErrPtg(EC.ERROR_VALUE); + /** #REF! - Illegal or deleted cell reference */ + public static final ErrPtg REF_INVALID = new ErrPtg(EC.ERROR_REF); + /** #NAME? - Wrong function or range name */ + public static final ErrPtg NAME_INVALID = new ErrPtg(EC.ERROR_NAME); + /** #NUM! - Value range overflow */ + public static final ErrPtg NUM_ERROR = new ErrPtg(EC.ERROR_NUM); + /** #N/A - 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 + ")"); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/ExpPtg.java b/src/java/org/apache/poi/ss/formula/ptg/ExpPtg.java new file mode 100644 index 0000000000..a82625f5eb --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/ExpPtg.java @@ -0,0 +1,73 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java b/src/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java new file mode 100644 index 0000000000..150bd99e79 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java @@ -0,0 +1,55 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/FuncPtg.java b/src/java/org/apache/poi/ss/formula/ptg/FuncPtg.java new file mode 100644 index 0000000000..ecfccb67b2 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/FuncPtg.java @@ -0,0 +1,60 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/FuncVarPtg.java b/src/java/org/apache/poi/ss/formula/ptg/FuncVarPtg.java new file mode 100644 index 0000000000..3392d04a76 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/FuncVarPtg.java @@ -0,0 +1,73 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/GreaterEqualPtg.java b/src/java/org/apache/poi/ss/formula/ptg/GreaterEqualPtg.java new file mode 100644 index 0000000000..eafbeba6fd --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/GreaterEqualPtg.java @@ -0,0 +1,54 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/GreaterThanPtg.java b/src/java/org/apache/poi/ss/formula/ptg/GreaterThanPtg.java new file mode 100644 index 0000000000..dabdab6655 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/GreaterThanPtg.java @@ -0,0 +1,61 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/IntPtg.java b/src/java/org/apache/poi/ss/formula/ptg/IntPtg.java new file mode 100644 index 0000000000..b91784edb2 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/IntPtg.java @@ -0,0 +1,76 @@ +/* ==================================================================== + 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 true if the specified value is within the range of values + * IntPtg 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()); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/IntersectionPtg.java b/src/java/org/apache/poi/ss/formula/ptg/IntersectionPtg.java new file mode 100644 index 0000000000..ed2f327bae --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/IntersectionPtg.java @@ -0,0 +1,62 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/LessEqualPtg.java b/src/java/org/apache/poi/ss/formula/ptg/LessEqualPtg.java new file mode 100644 index 0000000000..ce70ae79db --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/LessEqualPtg.java @@ -0,0 +1,53 @@ + +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/LessThanPtg.java b/src/java/org/apache/poi/ss/formula/ptg/LessThanPtg.java new file mode 100644 index 0000000000..51455c5204 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/LessThanPtg.java @@ -0,0 +1,64 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/MemAreaPtg.java b/src/java/org/apache/poi/ss/formula/ptg/MemAreaPtg.java new file mode 100644 index 0000000000..6c4568e664 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/MemAreaPtg.java @@ -0,0 +1,74 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/MemErrPtg.java b/src/java/org/apache/poi/ss/formula/ptg/MemErrPtg.java new file mode 100644 index 0000000000..44f541da99 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/MemErrPtg.java @@ -0,0 +1,57 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/MemFuncPtg.java b/src/java/org/apache/poi/ss/formula/ptg/MemFuncPtg.java new file mode 100644 index 0000000000..1837382f18 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/MemFuncPtg.java @@ -0,0 +1,75 @@ +/* ==================================================================== + 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 diff --git a/src/java/org/apache/poi/ss/formula/ptg/MissingArgPtg.java b/src/java/org/apache/poi/ss/formula/ptg/MissingArgPtg.java new file mode 100644 index 0000000000..84e4412873 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/MissingArgPtg.java @@ -0,0 +1,51 @@ +/* ==================================================================== + 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 " "; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/MultiplyPtg.java b/src/java/org/apache/poi/ss/formula/ptg/MultiplyPtg.java new file mode 100644 index 0000000000..ce251c82b0 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/MultiplyPtg.java @@ -0,0 +1,50 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/NamePtg.java b/src/java/org/apache/poi/ss/formula/ptg/NamePtg.java new file mode 100644 index 0000000000..8218cbe9eb --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/NamePtg.java @@ -0,0 +1,79 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/NameXPtg.java b/src/java/org/apache/poi/ss/formula/ptg/NameXPtg.java new file mode 100644 index 0000000000..e604fbe102 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/NameXPtg.java @@ -0,0 +1,93 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/NotEqualPtg.java b/src/java/org/apache/poi/ss/formula/ptg/NotEqualPtg.java new file mode 100644 index 0000000000..2c91b9cd82 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/NotEqualPtg.java @@ -0,0 +1,52 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/NumberPtg.java b/src/java/org/apache/poi/ss/formula/ptg/NumberPtg.java new file mode 100644 index 0000000000..6cec23604b --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/NumberPtg.java @@ -0,0 +1,71 @@ +/* ==================================================================== + 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); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/OperandPtg.java b/src/java/org/apache/poi/ss/formula/ptg/OperandPtg.java new file mode 100644 index 0000000000..0c36a84437 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/OperandPtg.java @@ -0,0 +1,38 @@ +/* ==================================================================== + 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); + } + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/OperationPtg.java b/src/java/org/apache/poi/ss/formula/ptg/OperationPtg.java new file mode 100644 index 0000000000..089d3c7368 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/OperationPtg.java @@ -0,0 +1,45 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/ParenthesisPtg.java b/src/java/org/apache/poi/ss/formula/ptg/ParenthesisPtg.java new file mode 100644 index 0000000000..1ea30abe20 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/ParenthesisPtg.java @@ -0,0 +1,58 @@ +/* ==================================================================== + 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] + ")"; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/PercentPtg.java b/src/java/org/apache/poi/ss/formula/ptg/PercentPtg.java new file mode 100644 index 0000000000..12eabcaa6d --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/PercentPtg.java @@ -0,0 +1,52 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/PowerPtg.java b/src/java/org/apache/poi/ss/formula/ptg/PowerPtg.java new file mode 100644 index 0000000000..3f240f40c4 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/PowerPtg.java @@ -0,0 +1,51 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/Ptg.java b/src/java/org/apache/poi/ss/formula/ptg/Ptg.java new file mode 100644 index 0000000000..93397fa85f --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/Ptg.java @@ -0,0 +1,321 @@ +/* ==================================================================== + 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; + +/** + * Ptg represents a syntactic token in a formula. 'PTG' is an acronym for + * 'parse thing'. Originally, the name referred to the single + * byte identifier at the start of the token, but in POI, Ptg encapsulates + * the whole formula token (initial byte + value data). + *

+ * + * Ptgs are logically arranged in a tree representing the structure of the + * parsed formula. However, in BIFF files Ptgs are written/read in + * Reverse-Polish Notation order. The RPN ordering also simplifies formula + * evaluation logic, so POI mostly accesses Ptgs 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 size bytes of the input stream, to create an array of Ptgs. + * Extra data (beyond size) may be read if and ArrayPtgs are present. + */ + public static Ptg[] readTokens(int size, LittleEndianInput in) { + List temp = new ArrayList(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= 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 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 Ptgs + */ + 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. + * + *
+ * The 2 byte encode length field is not 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 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(5); + } + arrayPtgs.add(ptg); + } + } + if (arrayPtgs != null) { + for (int i=0;ifalse 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/RangePtg.java b/src/java/org/apache/poi/ss/formula/ptg/RangePtg.java new file mode 100644 index 0000000000..1ab4cf1b8c --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/RangePtg.java @@ -0,0 +1,71 @@ +/* ==================================================================== + 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; + } + +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/Ref2DPtgBase.java b/src/java/org/apache/poi/ss/formula/ptg/Ref2DPtgBase.java new file mode 100644 index 0000000000..585b7d73c9 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/Ref2DPtgBase.java @@ -0,0 +1,69 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/Ref3DPtg.java b/src/java/org/apache/poi/ss/formula/ptg/Ref3DPtg.java new file mode 100644 index 0000000000..a75521bac0 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/Ref3DPtg.java @@ -0,0 +1,96 @@ +/* ==================================================================== + 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

+ * Description: Defined a cell in extern sheet.

+ * REFERENCE:

+ * @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"); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/RefErrorPtg.java b/src/java/org/apache/poi/ss/formula/ptg/RefErrorPtg.java new file mode 100644 index 0000000000..730f139ea6 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/RefErrorPtg.java @@ -0,0 +1,62 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/RefNPtg.java b/src/java/org/apache/poi/ss/formula/ptg/RefNPtg.java new file mode 100644 index 0000000000..715836f8d6 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/RefNPtg.java @@ -0,0 +1,36 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/RefPtg.java b/src/java/org/apache/poi/ss/formula/ptg/RefPtg.java new file mode 100644 index 0000000000..297c0e7d89 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/RefPtg.java @@ -0,0 +1,54 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/RefPtgBase.java b/src/java/org/apache/poi/ss/formula/ptg/RefPtgBase.java new file mode 100644 index 0000000000..4cf5192a01 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/RefPtgBase.java @@ -0,0 +1,117 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/ScalarConstantPtg.java b/src/java/org/apache/poi/ss/formula/ptg/ScalarConstantPtg.java new file mode 100644 index 0000000000..f916c38720 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/ScalarConstantPtg.java @@ -0,0 +1,42 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/StringPtg.java b/src/java/org/apache/poi/ss/formula/ptg/StringPtg.java new file mode 100644 index 0000000000..836ca0feac --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/StringPtg.java @@ -0,0 +1,108 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/SubtractPtg.java b/src/java/org/apache/poi/ss/formula/ptg/SubtractPtg.java new file mode 100644 index 0000000000..f06e60496d --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/SubtractPtg.java @@ -0,0 +1,50 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/TblPtg.java b/src/java/org/apache/poi/ss/formula/ptg/TblPtg.java new file mode 100644 index 0000000000..5ab5558ff2 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/TblPtg.java @@ -0,0 +1,80 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/UnaryMinusPtg.java b/src/java/org/apache/poi/ss/formula/ptg/UnaryMinusPtg.java new file mode 100644 index 0000000000..9079150eb0 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/UnaryMinusPtg.java @@ -0,0 +1,51 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/UnaryPlusPtg.java b/src/java/org/apache/poi/ss/formula/ptg/UnaryPlusPtg.java new file mode 100644 index 0000000000..1596c67355 --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/UnaryPlusPtg.java @@ -0,0 +1,51 @@ +/* ==================================================================== + 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(); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/UnionPtg.java b/src/java/org/apache/poi/ss/formula/ptg/UnionPtg.java new file mode 100644 index 0000000000..fcc2ae5a2d --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/UnionPtg.java @@ -0,0 +1,70 @@ +/* ==================================================================== + 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; + } + +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/UnknownPtg.java b/src/java/org/apache/poi/ss/formula/ptg/UnknownPtg.java new file mode 100644 index 0000000000..8eac21208e --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/UnknownPtg.java @@ -0,0 +1,50 @@ +/* ==================================================================== + 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; + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/ValueOperatorPtg.java b/src/java/org/apache/poi/ss/formula/ptg/ValueOperatorPtg.java new file mode 100644 index 0000000000..1194adfd2a --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/ValueOperatorPtg.java @@ -0,0 +1,56 @@ +/* ==================================================================== + 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 Ptgs 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"); + } +} diff --git a/src/java/org/apache/poi/ss/formula/ptg/package.html b/src/java/org/apache/poi/ss/formula/ptg/package.html new file mode 100644 index 0000000000..b0e899c1ba --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/ptg/package.html @@ -0,0 +1,38 @@ + + + + + + + +formula package contains binary PTG structures used in Formulas + +

Related Documentation

+ +For overviews, tutorials, examples, guides, and tool documentation, please see: + + + +@see org.apache.poi.hssf.record +@see org.apache.poi.hssf.record.FormulaRecord + + diff --git a/src/java/org/apache/poi/ss/usermodel/Footer.java b/src/java/org/apache/poi/ss/usermodel/Footer.java index 4a1bbfbb06..f982b71e6e 100644 --- a/src/java/org/apache/poi/ss/usermodel/Footer.java +++ b/src/java/org/apache/poi/ss/usermodel/Footer.java @@ -22,7 +22,7 @@ package org.apache.poi.ss.usermodel; * 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 { /** diff --git a/src/java/org/apache/poi/ss/usermodel/Header.java b/src/java/org/apache/poi/ss/usermodel/Header.java index e06345c9f5..22f38a665c 100644 --- a/src/java/org/apache/poi/ss/usermodel/Header.java +++ b/src/java/org/apache/poi/ss/usermodel/Header.java @@ -22,7 +22,7 @@ package org.apache.poi.ss.usermodel; * 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 { /** -- 2.39.5