示例#1
0
        private static void ConfirmRefErr(Ptg ptg)
        {
            Ptg[] ptgs = { ptg };

            ValueEval result = EvaluateFormula(ptgs);
            Assert.AreEqual(ErrorEval.REF_INVALID, result);
        }
示例#2
0
 private static void ConfirmAttrData(Ptg[] ptgs, int i, int expectedData)
 {
     Ptg ptg = ptgs[i];
     if (!(ptg is AttrPtg))
     {
         throw new AssertionException("Token[" + i + "] was not AttrPtg as expected");
     }
     AttrPtg attrPtg = (AttrPtg)ptg;
     Assert.AreEqual(expectedData, attrPtg.Data);
 }
示例#3
0
 public NumberEval(Ptg ptg)
 {
     if (ptg is IntPtg)
     {
         this._value = ((IntPtg)ptg).Value;
     }
     else if (ptg is NumberPtg)
     {
         this._value = ((NumberPtg)ptg).Value;
     }
 }
示例#4
0
 public ParseNode(Ptg token, ParseNode[] children)
 {
     _token = token;
     _children = children;
     _isIf = IsIf(token);
     int tokenCount = 1;
     for (int i = 0; i < children.Length; i++)
     {
         tokenCount += children[i].TokenCount;
     }
     if (_isIf)
     {
         // there will be 2 or 3 extra tAttr Tokens according To whether the false param is present
         tokenCount += children.Length;
     }
     _tokenCount = tokenCount;
 }
示例#5
0
        /**
         * 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 is ArrayPtg)
                {
                    result += ArrayPtg.PLAIN_TOKEN_SIZE;
                }
                else
                {
                    result += ptg.Size;
                }
            }
            return(result);
        }
示例#6
0
文件: Ptg.cs 项目: zanhaipeng/npoi
 private static bool IsDeletedCellRef(Ptg ptg)
 {
     if (ptg == ErrPtg.REF_INVALID)
     {
         return(true);
     }
     if (ptg is DeletedArea3DPtg)
     {
         return(true);
     }
     if (ptg is DeletedRef3DPtg)
     {
         return(true);
     }
     if (ptg is AreaErrPtg)
     {
         return(true);
     }
     if (ptg is RefErrorPtg)
     {
         return(true);
     }
     return(false);
 }
示例#7
0
        /**
         * Generates the variable Function ptg for the formula.
         * 
         * For IF Formulas, Additional PTGs are Added To the Tokens
	 * @param name a {@link NamePtg} or {@link NameXPtg} or <code>null</code>
         * @return Ptg a null is returned if we're in an IF formula, it needs extreme manipulation and is handled in this Function
         */
        private ParseNode GetFunction(String name, Ptg namePtg, ParseNode[] args)
        {

            FunctionMetadata fm = FunctionMetadataRegistry.GetFunctionByName(name.ToUpper());
            int numArgs = args.Length;
            if (fm == null)
            {
                if (namePtg == null)
                {
                    throw new InvalidOperationException("NamePtg must be supplied for external Functions");
                }
                // must be external Function
                ParseNode[] allArgs = new ParseNode[numArgs + 1];
                allArgs[0] = new ParseNode(namePtg);
                System.Array.Copy(args, 0, allArgs, 1, numArgs);
                return new ParseNode(FuncVarPtg.Create(name, (byte)(numArgs + 1)), allArgs);
            }

            if (namePtg != null)
            {
                throw new InvalidOperationException("NamePtg no applicable To internal Functions");
            }
            bool IsVarArgs = !fm.HasFixedArgsLength;
            int funcIx = fm.Index;
		if (funcIx == FunctionMetadataRegistry.FUNCTION_INDEX_SUM && args.Length == 1) {
			// Excel encodes the sum of a single argument as tAttrSum
			// POI does the same for consistency, but this is not critical
			return new ParseNode(AttrPtg.GetSumSingle(), args);
			// The code below would encode tFuncVar(SUM) which seems to do no harm
		}
            ValidateNumArgs(args.Length, fm);

            AbstractFunctionPtg retval;
            if (IsVarArgs)
            {
                retval = FuncVarPtg.Create(name, (byte)numArgs);
            }
            else
            {
                retval = FuncPtg.Create(funcIx);
            }
            return new ParseNode(retval, args);
        }
        public void SetArrayFormula(CellRangeAddress r, Ptg[] ptgs)
        {

            ArrayRecord arr = new ArrayRecord(NPOI.SS.Formula.Formula.Create(ptgs), new CellRangeAddress8Bit(r.FirstRow, r.LastRow, r.FirstColumn, r.LastColumn));
            _sharedValueManager.AddArrayRecord(arr);
        }
 private static void ConfirmOperandClasses(Ptg[] originalPtgs, Ptg[] convertedPtg)
 {
     Assert.AreEqual(originalPtgs.Length, convertedPtg.Length);
     for (int i = 0; i < convertedPtg.Length; i++)
     {
         Ptg originalPtg = originalPtgs[i];
         Ptg ConvertedPtg = convertedPtg[i];
         if (originalPtg.PtgClass != ConvertedPtg.PtgClass)
         {
             throw new ComparisonFailure("Different operand class for token[" + i + "]",
                     originalPtg.PtgClass.ToString(), ConvertedPtg.PtgClass.ToString());
         }
     }
 }
示例#10
0
 public void SetParsedExpression(Ptg[] ptgs)
 {
     field_5_name_definition = Formula.Create(ptgs);
 }
示例#11
0
 public void SetPlaceholder(int index, Ptg token)
 {
     if (_ptgs[index] != null)
     {
         throw new InvalidOperationException("Invalid placeholder index (" + index + ")");
     }
     _ptgs[index] = token;
 }
        /**
         * Constructs an EmbeddedObjectRef record and Sets its fields appropriately.
         *
         * @param in the record input stream.
         */
        public EmbeddedObjectRefSubRecord(ILittleEndianInput in1, int size)
        {
            // Much guess-work going on here due to lack of any documentation.
            // See similar source code in OOO:
            // http://lxr.go-oo.org/source/sc/sc/source/filter/excel/xiescher.cxx
            // 1223 void XclImpOleObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nRecSize )

            int streamIdOffset = in1.ReadShort(); // OOO calls this 'nFmlaLen'
            int remaining = size - LittleEndianConsts.SHORT_SIZE;

            int dataLenAfterFormula = remaining - streamIdOffset;
            int formulaSize = in1.ReadUShort();

            remaining -= LittleEndianConsts.SHORT_SIZE;
            field_1_unknown_int = in1.ReadInt();
            remaining -= LittleEndianConsts.INT_SIZE;
            byte[] formulaRawBytes = ReadRawData(in1, formulaSize);
            remaining -= formulaSize;
            field_2_refPtg = ReadRefPtg(formulaRawBytes);
            if (field_2_refPtg == null)
            {
                // common case
                // field_2_n16 seems to be 5 here
                // The formula almost looks like tTbl but the row/column values seem like garbage.
                field_2_unknownFormulaData = formulaRawBytes;
            }
            else
            {
                field_2_unknownFormulaData = null;
            }


            int stringByteCount;
            if (remaining >= dataLenAfterFormula + 3)
            {
                int tag = in1.ReadByte();
                stringByteCount = LittleEndianConsts.BYTE_SIZE;
                if (tag != 0x03)
                {
                    throw new RecordFormatException("Expected byte 0x03 here");
                }
                int nChars = in1.ReadUShort();
                stringByteCount += LittleEndianConsts.SHORT_SIZE;
                if (nChars > 0)
                {
                    // OOO: the 4th way Xcl stores a unicode string: not even a Grbit byte present if Length 0
                    field_3_unicode_flag = (in1.ReadByte() & 0x01) != 0;
                    stringByteCount += LittleEndianConsts.BYTE_SIZE;
                    if (field_3_unicode_flag)
                    {
                        field_4_ole_classname = StringUtil.ReadUnicodeLE(in1,nChars);
                        stringByteCount += nChars * 2;
                    }
                    else
                    {
                        field_4_ole_classname = StringUtil.ReadCompressedUnicode(in1,nChars);
                        stringByteCount += nChars;
                    }
                }
                else
                {
                    field_4_ole_classname = "";
                }
            }
            else
            {
                field_4_ole_classname = null;
                stringByteCount = 0;
            }
            remaining -= stringByteCount;
            // Pad to next 2-byte boundary
            if (((stringByteCount + formulaSize) % 2) != 0)
            {
                int b = in1.ReadByte();
                remaining -= LittleEndianConsts.BYTE_SIZE;
                if (field_2_refPtg != null && field_4_ole_classname == null)
                {
                    field_4_unknownByte = (byte)b;
                }
            }
            int nUnexpectedPadding = remaining - dataLenAfterFormula;

            if (nUnexpectedPadding > 0)
            {
                logger.Log(POILogger.ERROR, "Discarding " + nUnexpectedPadding + " unexpected padding bytes ");
                ReadRawData(in1, nUnexpectedPadding);
                remaining -= nUnexpectedPadding;
            }

            // Fetch the stream ID
            if (dataLenAfterFormula >= 4)
            {
                field_5_stream_id = in1.ReadInt();
                remaining -= LittleEndianConsts.INT_SIZE;
            }
            else
            {
                field_5_stream_id = null;
            }

            field_6_unknown = ReadRawData(in1, remaining);
        }
 private void ConfirmTokenClass(Ptg[] ptgs, int i, byte operandClass)
 {
     Ptg ptg = ptgs[i];
     if (ptg.IsBaseToken)
     {
         throw new AssertionException("ptg[" + i + "] is a base token");
     }
     if (operandClass != ptg.PtgClass)
     {
         throw new AssertionException("Wrong operand class for ptg ("
                 + ptg.ToString() + "). Expected " + GetOperandClassName(operandClass)
                 + " but got " + GetOperandClassName(ptg.PtgClass));
     }
 }
 private void ConfirmFuncClass(Ptg[] ptgs, int i, String expectedFunctionName, byte operandClass)
 {
     ConfirmTokenClass(ptgs, i, operandClass);
     AbstractFunctionPtg afp = (AbstractFunctionPtg)ptgs[i];
     Assert.AreEqual(expectedFunctionName, afp.Name);
 }
示例#15
0
        public ParseNode(Ptg token, ParseNode child0, ParseNode child1)
            : this(token, new ParseNode[] { child0, child1, })
        {

        }
示例#16
0
        public ParseNode(Ptg token)
            : this(token, EMPTY_ARRAY)
        {

        }
示例#17
0
 private static Double ConvertArrayNumber(Ptg ptg, bool isPositive)
 {
     double value;
     if (ptg is IntPtg)
     {
         value = ((IntPtg)ptg).Value;
     }
     else if (ptg is NumberPtg)
     {
         value = ((NumberPtg)ptg).Value;
     }
     else
     {
         throw new Exception("Unexpected ptg (" + ptg.GetType().Name + ")");
     }
     if (!isPositive)
     {
         value = -value;
     }
     return value;
 }
示例#18
0
文件: TestRVA.cs 项目: ctddjyds/npoi
        private void ConfirmCell(ICell formulaCell, String formula, HSSFWorkbook wb)
        {
            Ptg[] excelPtgs = FormulaExtractor.GetPtgs(formulaCell);
            Ptg[] poiPtgs = HSSFFormulaParser.Parse(formula, wb);
            int nExcelTokens = excelPtgs.Length;
            int nPoiTokens = poiPtgs.Length;
            if (nExcelTokens != nPoiTokens)
            {
                if (nExcelTokens == nPoiTokens + 1 && excelPtgs[0].GetType() == typeof(AttrPtg))
                {
                    // compensate for missing tAttrVolatile, which belongs in any formula 
                    // involving OFFSET() et al. POI currently does not insert where required
                    Ptg[] temp = new Ptg[nExcelTokens];
                    temp[0] = excelPtgs[0];
                    Array.Copy(poiPtgs, 0, temp, 1, nPoiTokens);
                    poiPtgs = temp;
                }
                else
                {
                    throw new Exception("Expected " + nExcelTokens + " tokens but got "
                            + nPoiTokens);
                }
            }
            bool hasMismatch = false;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < nExcelTokens; i++)
            {
                Ptg poiPtg = poiPtgs[i];
                Ptg excelPtg = excelPtgs[i];
                if (excelPtg.GetType() != poiPtg.GetType())
                {
                    hasMismatch = true;
                    sb.Append("  mismatch token type[" + i + "] " + GetShortClassName(excelPtg) + " "
                            + excelPtg.RVAType + " - " + GetShortClassName(poiPtg) + " "
                            + poiPtg.RVAType);
                    sb.Append(Environment.NewLine);
                    continue;
                }
                if (poiPtg.IsBaseToken)
                {
                    continue;
                }
                sb.Append("  token[" + i + "] " + excelPtg.ToString() + " "
                        + excelPtg.RVAType);

                if (excelPtg.PtgClass != poiPtg.PtgClass)
                {
                    hasMismatch = true;
                    sb.Append(" - was " + poiPtg.RVAType);
                }
                sb.Append(Environment.NewLine);
            }
            //if (false)
            //{ // Set 'true' to see trace of RVA values
            //    Console.WriteLine(formula);
            //    Console.WriteLine(sb.ToString());
            //}
            if (hasMismatch)
            {
                throw new AssertionException(sb.ToString());
            }
        }
示例#19
0
        /**
         * 
         * "A1", "B3" -> "A1:B3"   
         * "sheet1!A1", "B3" -> "sheet1!A1:B3"
         * 
         * @return <c>null</c> if the range expression cannot / shouldn't be reduced.
         */
        private static Ptg ReduceRangeExpression(Ptg ptgA, Ptg ptgB)
        {
            if (!(ptgB is RefPtg))
            {
                // only when second ref is simple 2-D ref can the range 
                // expression be converted To an area ref
                return null;
            }
            RefPtg refB = (RefPtg)ptgB;

            if (ptgA is RefPtg)
            {
                RefPtg refA = (RefPtg)ptgA;
                return new AreaPtg(refA.Row, refB.Row, refA.Column, refB.Column,
                        refA.IsRowRelative, refB.IsRowRelative, refA.IsColRelative, refB.IsColRelative);
            }
            if (ptgA is Ref3DPtg)
            {
                Ref3DPtg refA = (Ref3DPtg)ptgA;
                return new Area3DPtg(refA.Row, refB.Row, refA.Column, refB.Column,
                        refA.IsRowRelative, refB.IsRowRelative, refA.IsColRelative, refB.IsColRelative,
                        refA.ExternSheetIndex);
            }
            // Note - other operand types (like AreaPtg) which probably can't evaluate 
            // do not cause validation errors at Parse time
            return null;
        }
示例#20
0
 private static void ConfirmSingle3DRef(Ptg[] ptgs, int expectedExternSheetIndex)
 {
     Assert.AreEqual(1, ptgs.Length);
     Ptg ptg0 = ptgs[0];
     Assert.IsTrue(ptg0 is Ref3DPtg);
     Assert.AreEqual(expectedExternSheetIndex, ((Ref3DPtg)ptg0).ExternSheetIndex);
 }
示例#21
0
        /**
	 * 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 <c>Ptg</c>s
	 */
        public static int GetEncodedSize(Ptg[] ptgs)
        {
            int result = 0;
            for (int i = 0; i < ptgs.Length; i++)
            {
                result += ptgs[i].Size;
            }
            return result;
        }
示例#22
0
 public void Add(Ptg token)
 {
     if (token == null)
     {
         throw new ArgumentException("token must not be null");
     }
     _ptgs[_offset] = token;
     _offset++;
 }
示例#23
0
 /* package */
 private static void ConfirmTokenClasses(Ptg[] ptgs, params Type[] expectedClasses)
 {
     Assert.AreEqual(expectedClasses.Length, ptgs.Length);
     for (int i = 0; i < expectedClasses.Length; i++)
     {
         if (expectedClasses[i] != ptgs[i].GetType())
         {
             Assert.Fail("difference at token[" + i + "]: expected ("
                 + expectedClasses[i].Name + ") but got ("
                 + ptgs[i].GetType().Name + ")");
         }
     }
 }
示例#24
0
        /**
 * 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 is ArrayPtg)
                {
                    result += ArrayPtg.PLAIN_TOKEN_SIZE;
                }
                else
                {
                    result += ptg.Size;
                }
            }
            return result;
        }
示例#25
0
        public void TestSpaceAtStartOfFormula()
        {
            // Simulating cell formula of "= 4" (note space)
            // The same Ptg array can be observed if an excel file is1 saved with that exact formula

            AttrPtg spacePtg = AttrPtg.CreateSpace(AttrPtg.SpaceType.SpaceBefore, 1);
            Ptg[] ptgs = { spacePtg, new IntPtg(4), };
            String formulaString;
            try
            {
                formulaString = HSSFFormulaParser.ToFormulaString(null, ptgs);
            }
            catch (InvalidOperationException e)
            {
                if (e.Message.Equals("too much stuff left on the stack", StringComparison.OrdinalIgnoreCase))
                {
                    throw new AssertionException("Identified bug 44609");
                }
                // else some unexpected error
                throw e;
            }
            // FormulaParser strips spaces anyway
            Assert.AreEqual("4", formulaString);

            ptgs = new Ptg[] { new IntPtg(3), spacePtg, new IntPtg(4), spacePtg, AddPtg.instance, };
            formulaString = HSSFFormulaParser.ToFormulaString(null, ptgs);
            Assert.AreEqual("3+4", formulaString);
        }
示例#26
0
        /**
         * Writes the ptgs to the data buffer, starting at the specified offset.  
         *
         * <br/>
         * The 2 byte encode Length field is <b>not</b> written by this method.
         * @return number of bytes written
         */
        public static int SerializePtgs(Ptg[] ptgs, byte[] array, int offset)
        {
            int size = ptgs.Length;

            LittleEndianByteArrayOutputStream out1 = new LittleEndianByteArrayOutputStream(array, offset);

            ArrayList arrayPtgs = null;

            for (int k = 0; k < size; k++)
            {
                Ptg ptg = ptgs[k];

                ptg.Write(out1);
                if (ptg is ArrayPtg)
                {
                    if (arrayPtgs == null)
                    {
                        arrayPtgs = new ArrayList(5);
                    }
                    arrayPtgs.Add(ptg);

                }
            }
            if (arrayPtgs != null)
            {
                for (int i = 0; i < arrayPtgs.Count; i++)
                {
                    ArrayPtg p = (ArrayPtg)arrayPtgs[i];
                    p.WriteTokenValueBytes(out1);
                }
            }
            return out1.WriteIndex - offset; ;
        }
示例#27
0
文件: FormulaRecord.cs 项目: WPG/npoi
 public void SetParsedExpression(Ptg[] ptgs)
 {
     field_8_parsed_expr = NPOI.SS.Formula.Formula.Create(ptgs);
 }
示例#28
0
 public static bool DoesFormulaReferToDeletedCell(Ptg[] ptgs)
 {
     for (int i = 0; i < ptgs.Length; i++)
     {
         if (IsDeletedCellRef(ptgs[i]))
         {
             return true;
         }
     }
     return false;
 }
        /**
 * Also checks for a related shared formula and unlinks it if found
 */
        public void SetParsedExpression(Ptg[] ptgs)
        {
            NotifyFormulaChanging();
            _formulaRecord.ParsedExpression=(ptgs);
        }
示例#30
0
 private static bool IsDeletedCellRef(Ptg ptg)
 {
     if (ptg == ErrPtg.REF_INVALID)
     {
         return true;
     }
     if (ptg is DeletedArea3DPtg)
     {
         return true;
     }
     if (ptg is DeletedRef3DPtg)
     {
         return true;
     }
     if (ptg is AreaErrPtg)
     {
         return true;
     }
     if (ptg is RefErrorPtg)
     {
         return true;
     }
     return false;
 }
示例#31
0
 private CFRuleRecord(byte conditionType, ComparisonOperator comparisonOperation, Ptg[] formula1, Ptg[] formula2)
     :this(conditionType, comparisonOperation)
 {
     
     //field_1_condition_type = CONDITION_TYPE_CELL_VALUE_IS;
     //field_2_comparison_operator = (byte)comparisonOperation;
     field_17_formula1 = FR.Formula.Create(formula1);
     field_18_formula2 = FR.Formula.Create(formula2);
 }
示例#32
0
文件: HSSFName.cs 项目: WPG/npoi
 //
 /// <summary>
 /// Sets the NameParsedFormula structure that specifies the formula for the defined name.
 /// </summary>
 /// <param name="ptgs">the sequence of {@link Ptg}s for the formula.</param>
 public void SetNameDefinition(Ptg[] ptgs)
 {
     _definedNameRec.NameDefinition = (ptgs);
 }