Esempio n. 1
0
        /// <summary>
        /// FmlaWithoutArrayLen might be less than the total array len
        /// </summary>
        internal static byte[] GetTokenData(TNameRecordList Names, TParsedTokenList Tokens, TFormulaType FmlaType, out int FmlaLenWithoutArray)
        {
            // Remember to ungrow maxrow and maxcol from 2007 too biff8
            // Tokens that grow are ptgref, area, 3dref and 3darea. All of them (and nothing else) should ungrow.

            using (MemoryStream Data = new MemoryStream())
            {
                using (MemoryStream ArrayData = new MemoryStream())
                {
                    int[]        TokenOffset = new int[Tokens.Count + 1];
                    TTokenOffset StreamPos   = new TTokenOffset();
                    Int32List    FuturePos   = new Int32List();

                    Tokens.ResetPositionToStart();
                    while (!Tokens.Eof())
                    {
                        TBaseParsedToken Token = Tokens.ForwardPop();
                        TokenOffset[Tokens.SavePosition()] = (int)Data.Position;
                        ptg BaseToken = Token.GetBaseId;
                        Add(Data, ArrayData, Token, BaseToken, Tokens, StreamPos, FmlaType, FuturePos);
                    } //while

                    TokenOffset[Tokens.Count] = (int)Data.Position;
                    FixFutureFunctions(Names, FuturePos, Tokens, Data, TokenOffset, ref StreamPos);
                    FixGotoAndMemTokens(Tokens, Data, TokenOffset, StreamPos);
                    ArrayData.Position  = 0;
                    Data.Position       = Data.Length;               //FixGoto will change this.
                    FmlaLenWithoutArray = (int)Data.Length;
                    ArrayData.WriteTo(Data);
                    return(Data.ToArray());
                }
            }
        }
Esempio n. 2
0
        protected static void AddParsedRefN(TParsedTokenListBuilder TokenBuilder, ptg aId, int Rw1, int grBit1)
        {
            bool RowAbs; bool ColAbs; int Row; int Col;

            GetRelativeRowAndCol(Rw1, grBit1, out RowAbs, out ColAbs, out Row, out Col);
            Push(TokenBuilder, new TRefNToken(aId, Row, Col, RowAbs, ColAbs, true));
        }
Esempio n. 3
0
        internal static string AsString(TParsedTokenList Tokens, int CellRow, int CellCol,
                                        ICellList CellList, TWorkbookGlobals Globals, int MaxStringConstantLen, bool WritingXlsx, bool SkipEqual)
        {
            string        StartFormula = fts(TFormulaToken.fmStartFormula); //Formulas do not always begin with "=". Array formulas begin with "{", and they override this var to empty.
            TFormulaStack ParsedStack  = new TFormulaStack();

            bool R1C1 = false;

            if (Globals != null && !WritingXlsx)
            {
                R1C1 = Globals.Workbook.FormulaReferenceStyle == TReferenceStyle.R1C1;
            }

            Tokens.ResetPositionToStart();
            while (!Tokens.Eof())
            {
                TBaseParsedToken Token = Tokens.ForwardPop();
                ptg BaseToken          = Token.GetBaseId;
                Evaluate(Token, R1C1, CellRow, CellCol, BaseToken, Tokens, CellList, Globals, ParsedStack, ref StartFormula, MaxStringConstantLen, WritingXlsx);
            }             //while


            if (WritingXlsx || SkipEqual)
            {
                StartFormula = String.Empty;
            }

            if (ParsedStack.Count == 0)
            {
                return(String.Empty);                         //StartFormula + TFormulaMessages.ErrString(TFlxFormulaErrorValue.ErrRef);  This is needed for deleted named ranges.
            }
            return(StartFormula + ParsedStack.Pop());
        }
Esempio n. 4
0
        private bool DoRPN(TParsedTokenListBuilder TokenBuilder, TNameRecordList Names, byte[] RPN, int atPos, int afPos, ref bool HasSubtotal, ref bool HasAggregate)
        {
            int tPos     = atPos;
            int fPos     = afPos;
            int ArrayPos = fPos;

            TTokenOffset TokenOffset = new TTokenOffset();

            while (tPos < fPos)
            {
                TokenOffset.Add(tPos, TokenBuilder.Count);
                byte RealToken = RPN[tPos];
                ptg  BaseToken = TBaseParsedToken.CalcBaseToken((ptg)RealToken);
                TUnsupportedFormulaErrorType ErrType = TUnsupportedFormulaErrorType.FormulaTooComplex;
                string ErrName = null;
                if (!Evaluate(TokenBuilder, TokenOffset, Names, BaseToken, (ptg)RealToken, RPN, ref tPos, ref ArrayPos, ref ErrType, ref ErrName, ref HasSubtotal, ref HasAggregate))
                {
                    TokenBuilder.Clear();
                    return(false);
                }
                tPos++;
            }                                          //while

            TokenOffset.Add(tPos, TokenBuilder.Count); //eof

            FixGotosAndMemTokens(TokenBuilder, TokenOffset);
            return(true);
        }
Esempio n. 5
0
        private static bool IsError(ptg BaseToken, TFormulaType FmlaType)
        {
            switch (FmlaType)
            {
            case TFormulaType.Normal:
                return(false);

            case TFormulaType.Name:
                return(BaseToken == ptg.Tbl || BaseToken == ptg.Exp ||
                       BaseToken == ptg.Ref || BaseToken == ptg.RefN || BaseToken == ptg.RefErr ||
                       BaseToken == ptg.Area || BaseToken == ptg.AreaN || BaseToken == ptg.AreaErr);

            case TFormulaType.DataValidation:
                return(BaseToken == ptg.Tbl || BaseToken == ptg.Exp ||
                       BaseToken == ptg.Isect || BaseToken == ptg.Union || BaseToken == ptg.Array ||
                       BaseToken == ptg.Ref3d || BaseToken == ptg.Area3d || BaseToken == ptg.Ref3dErr || BaseToken == ptg.Area3dErr ||
                       BaseToken == ptg.NameX || BaseToken == ptg.MemArea || BaseToken == ptg.MemNoMem
                       );

            case TFormulaType.CondFmt:
                return(BaseToken == ptg.Tbl || BaseToken == ptg.Exp ||
                       BaseToken == ptg.Isect || BaseToken == ptg.Union || BaseToken == ptg.Array ||
                       BaseToken == ptg.Ref3d || BaseToken == ptg.Ref3dErr ||
                       BaseToken == ptg.NameX || BaseToken == ptg.MemArea || BaseToken == ptg.MemNoMem
                       );

            case TFormulaType.Chart:
                return(BaseToken != ptg.Paren && BaseToken != ptg.Union && BaseToken != ptg.Ref3d && BaseToken != ptg.Ref3dErr &&
                       BaseToken != ptg.Area3d && BaseToken != ptg.Area3dErr && BaseToken != ptg.NameX && BaseToken != ptg.MemFunc
                       );
            }

            return(false);
        }
Esempio n. 6
0
 internal static void Add(int Index, ptg PtgId, int ArgCount, TBaseFunctionToken ResultValue)
 {
     EnsureFList();
     if (FList.Count > 1024)
     {
         FList.Clear();                     //Shouldn't happen, but just in case avoid this growing ad infinitum.
     }
     FList.Add(new TFunctionKey(Index, PtgId, ArgCount), ResultValue);
 }
Esempio n. 7
0
        internal static bool TryGetValue(int Index, ptg PtgId, int ArgCount, out TBaseFunctionToken ResultValue)
        {
            EnsureFList();
#if (FRAMEWORK20)
            return(FList.TryGetValue(new TFunctionKey(Index, PtgId, ArgCount), out ResultValue));
#else
            ResultValue = FList[GetHash(Index, PtgId, ArgCount)] as TBaseFunctionToken;
            return(ResultValue != null);
#endif
        }
Esempio n. 8
0
        protected static void AddParsedAreaN(TParsedTokenListBuilder TokenBuilder, ptg aId, int Rw1, int Rw2, int grBit1, int grBit2)
        {
            bool RowAbs1; bool ColAbs1; int Row1; int Col1;

            GetRelativeRowAndCol(Rw1, grBit1, out RowAbs1, out ColAbs1, out Row1, out Col1);
            bool RowAbs2; bool ColAbs2; int Row2; int Col2;

            GetRelativeRowAndCol(Rw2, grBit2, out RowAbs2, out ColAbs2, out Row2, out Col2);

            Push(TokenBuilder, new TAreaNToken(aId, Row1, Col1, RowAbs1, ColAbs1, Row2, Col2, RowAbs2, ColAbs2, true));
        }
Esempio n. 9
0
        protected override bool LastIsReference()
        {
            if (LastRefOp < 0)
            {
                return(false);
            }
            ptg           aptg    = GetLastRefOp();
            TFmReturnType PtgMode = GetPtgMode(aptg);

            return(PtgMode == TFmReturnType.Ref);
        }
Esempio n. 10
0
        private static ptg GetRealPtg(ptg PtgBase, TFmReturnType ReturnType)
        {
            switch (ReturnType)
            {
            case TFmReturnType.Array: return((ptg)(PtgBase + 0x40));

            case TFmReturnType.Ref: return((ptg)PtgBase);

            default: return((ptg)(PtgBase + 0x20));
            } //case
        }
Esempio n. 11
0
        protected static void AddParsedSep(TParsedTokenListBuilder TokenBuilder, ptg b)
        {
            switch (b)
            {
            case ptg.Isect: Push(TokenBuilder, TISectToken.Instance); break;

            case ptg.Union: Push(TokenBuilder, TUnionToken.Instance); break;

            case ptg.Range: Push(TokenBuilder, TRangeToken.Instance); break;

            default: Push(TokenBuilder, new TUnsupportedToken(2, b)); break;
            }
        }
Esempio n. 12
0
 private void AddParsed3dRef(TParsedTokenListBuilder TokenBuilder, ptg RealToken, int ExternSheet, int Rw1, int grBit1)
 {
     if (Relative3dRanges)
     {
         bool RowAbs1; bool ColAbs1; int Row1; int Col1;
         GetRelativeRowAndCol(Rw1, grBit1, out RowAbs1, out ColAbs1, out Row1, out Col1);
         Push(TokenBuilder, new TRef3dNToken(RealToken, ExternSheet, Row1, Col1, RowAbs1, ColAbs1, true));
     }
     else
     {
         Push(TokenBuilder, new TRef3dToken(RealToken, ExternSheet, Biff8Utils.ExpandBiff8Row(Rw1),
                                            Biff8Utils.ExpandBiff8Col(grBit1 & ColMask), (grBit1 & 0x8000) == 0, (grBit1 & 0x4000) == 0));
     }
 }
Esempio n. 13
0
        private static TArrayDataToken GetArrayDataToken(ptg aId, byte[] RPN, ref int ArrayPos)
        {
            int Columns = RPN[ArrayPos] + 1;
            int Rows    = BitOps.GetWord(RPN, ArrayPos + 1) + 1;

            ArrayPos        += 3;
            object[,] Result = new object[Rows, Columns];

            for (int r = 0; r < Rows; r++)
            {
                for (int c = 0; c < Columns; c++)
                {
                    Result[r, c] = GetArrayObject(RPN, ref ArrayPos);
                }
            }
            return(new TArrayDataToken(aId, Result));
        }
Esempio n. 14
0
        internal static bool HasExternRefs(TParsedTokenList Data)
        {
            Data.ResetPositionToLast();
            while (!Data.Bof())
            {
                TBaseParsedToken r = Data.LightPop();
                ptg id             = r.GetBaseId;
                // This check is a little simplistic because an Area3d or Ref3d might in fact refer to the same sheet. But then, the externsheet is not copied so
                // the reference will be invalid anyway. The "right" thing to do would be to convert external refs to the same sheet to external refs on the new sheet.
                if (id == ptg.Area3d || id == ptg.Ref3d || id == ptg.NameX)
                {
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 15
0
        protected override void ConvertLastRefValueType(TFmReturnType RefMode, TParseState ParseState, bool IgnoreArray)
        {
            if (LastRefOp < 0)              //we should always call this when an operand has been added.
            {
                char c = ' ';
                if (ParsePos - 1 >= 0 && ParsePos - 1 < FormulaText.Length)
                {
                    c = FormulaText[ParsePos - 1];
                }
                FlxMessages.ThrowException(FlxErr.ErrUnexpectedChar, c, ParsePos, FormulaText);
            }

            ptg           aptg    = GetLastRefOp();
            TFmReturnType PtgMode = GetPtgMode(aptg);

            switch (RefMode)
            {
            case TFmReturnType.Ref:
                if (ParseState.ForcedArrayClass && ParseState.Level > 0 && PtgMode == TFmReturnType.Value)
                {
                    SetLastRefOp(aptg, TFmReturnType.Array);
                }
                break;

            case TFmReturnType.Value:
                if (ParseState.ForcedArrayClass && ParseState.Level > 0)
                {
                    SetLastRefOp(aptg, TFmReturnType.Array);
                }
                else
                if (!IgnoreArray || PtgMode != TFmReturnType.Array)
                {
                    SetLastRefOp(aptg, TFmReturnType.Value);
                }
                break;

            case TFmReturnType.Array:
                SetLastRefOp(aptg, TFmReturnType.Array);
                break;
            }
        }
Esempio n. 16
0
        private static TFmReturnType GetPtgMode(ptg aptg)
        {
            TFmReturnType PtgMode = TFmReturnType.Value;

            if (aptg == ptg.Range || aptg == ptg.Isect || aptg == ptg.Union)             //binary operators with ref results.
            {
                PtgMode = TFmReturnType.Ref;
            }

            switch (((byte)aptg) & 0x60)
            {
            case 0x20:
                PtgMode = TFmReturnType.Ref;
                break;

            case 0x60:
                PtgMode = TFmReturnType.Array;
                break;
            }
            return(PtgMode);
        }
Esempio n. 17
0
        internal static bool HasExternLinks(TParsedTokenList Data, TReferences References)
        {
            Data.ResetPositionToLast();
            while (!Data.Bof())
            {
                TBaseParsedToken r = Data.LightPop();
                ptg id             = r.GetBaseId;

                if (id == ptg.Area3d || id == ptg.Ref3d || id == ptg.NameX)
                {
                    if (References != null)
                    {
                        int ExternSheet = r.ExternSheet;
                        if (!References.IsLocalSheet(ExternSheet))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Esempio n. 18
0
        private void SetLastRefOp(ptg aptg, TFmReturnType RefMode)
        {
            byte newptg = (byte)aptg;

            if ((((byte)aptg) & 0x60) != 0)
            {
                switch (RefMode)
                {
                case TFmReturnType.Ref:
                    newptg = (byte)(newptg & 0x9F | 0x20);
                    break;

                case TFmReturnType.Value:
                    newptg = (byte)(newptg & 0x9F | 0x40);
                    break;

                case TFmReturnType.Array:
                    newptg = (byte)(newptg | 0x60);
                    break;
                }
            }

            FParsedDataBuilder[LastRefOp] = FParsedDataBuilder[LastRefOp].SetId((ptg)newptg);
        }
Esempio n. 19
0
        internal void Go(TParsedTokenList Data, bool RefIsInInsertingSheet)
        {
            Data.ResetPositionToStart();
            while (!Data.Eof())
            {
                TBaseParsedToken r = Data.ForwardPop();
                ptg id             = r.GetBaseId;
                switch (id)
                {
                case ptg.Exp:
                    DoArrayFmla((TExp_Token)r);
                    break;

                case ptg.Tbl:
                    TTableToken tbl = r as TTableToken;
                    if (tbl != null)     //might be also TTableObjToken
                    {
                        DoTable(tbl);
                    }
                    break;

                case ptg.Name:
                    DoName((TNameToken)r);
                    break;

                case ptg.RefErr:
                case ptg.Ref:
                case ptg.RefN:
                    DoRef((TRefToken)r, RefIsInInsertingSheet);
                    break;

                case ptg.AreaErr:
                case ptg.Area:
                case ptg.AreaN:
                    DoArea((TAreaToken)r, RefIsInInsertingSheet);
                    break;

                case ptg.MemArea:
                    DoMemArea(Data, (TMemAreaToken)r, RefIsInInsertingSheet);
                    break;

                case ptg.NameX:
                {
                    //We'll do Do3d only for local names.
                    //bool ThisRefIsInInsertingSheet;
                    //Do3D(r, out ThisRefIsInInsertingSheet);
                    DoNameX((TNameXToken)r);
                }
                break;

                case ptg.Ref3d:
                case ptg.Ref3dErr:
                {
                    bool ThisRefIsInInsertingSheet;
                    Do3D(r, out ThisRefIsInInsertingSheet);
                    DoRef((TRef3dToken)r, ThisRefIsInInsertingSheet);
                    break;
                }

                case ptg.Area3dErr:
                case ptg.Area3d:
                {
                    bool ThisRefIsInInsertingSheet;
                    Do3D(r, out ThisRefIsInInsertingSheet);
                    DoArea((TArea3dToken)r, ThisRefIsInInsertingSheet);
                }
                break;
                }
            }
        }
Esempio n. 20
0
 public TFunctionKey(int aIndex, ptg aPtgId, int aArgCount)
 {
     Index    = aIndex;
     PtgId    = aPtgId;
     ArgCount = aArgCount;
 }
Esempio n. 21
0
        private bool Evaluate(TParsedTokenListBuilder TokenBuilder, TTokenOffset TokenOffset, TNameRecordList Names, ptg BaseToken, ptg RealToken,
                              byte[] RPN, ref int tPos, ref int ArrayPos, ref TUnsupportedFormulaErrorType ErrType, ref string ErrName, ref bool HasSubtotal, ref bool HasAggregate)
        {
            switch (BaseToken)
            {
            case ptg.Exp:
                AddParsedExp(TokenBuilder, BitOps.GetWord(RPN, tPos + 1), BitOps.GetWord(RPN, tPos + 3));
                tPos += 4;
                break;

            case ptg.Tbl:
                AddParsedTable(TokenBuilder, BitOps.GetWord(RPN, tPos + 1), BitOps.GetWord(RPN, tPos + 3));
                tPos += 4;
                break;

            case ptg.Add:
            case ptg.Sub:
            case ptg.Mul:
            case ptg.Div:
            case ptg.Power:
            case ptg.Concat:
            case ptg.LT:
            case ptg.LE:
            case ptg.EQ:
            case ptg.GE:
            case ptg.GT:
            case ptg.NE:
            case ptg.Uminus:
            case ptg.Percent:
            case ptg.Uplus:
                AddParsedOp(TokenBuilder, (TOperator)BaseToken); break;

            case ptg.MissArg: AddMissingArg(TokenBuilder); break;


            case ptg.Isect: AddParsedSep(TokenBuilder, BaseToken); break;

            case ptg.Union: AddParsedSep(TokenBuilder, BaseToken); break;

            case ptg.Range: AddParsedSep(TokenBuilder, BaseToken); break;

            case ptg.Paren: Push(TokenBuilder, TParenToken.Instance); break;

            case ptg.Str:
                long   sl     = 0;
                string Result = null;
                StrOps.GetSimpleString(false, RPN, tPos + 1, false, 0, ref Result, ref sl);
                AddParsed(TokenBuilder, Result);
                tPos += (int)sl;
                break;

            case ptg.Attr: int AttrLen = 0; if (!ProcessAttr(TokenBuilder, RPN, tPos + 1, ref AttrLen))
                {
                    return(false);
                }
                tPos += AttrLen; break;

            case ptg.Sheet:  return(false);

            case ptg.EndSheet:  return(false);

            case ptg.Err: AddParsed(TokenBuilder, (TFlxFormulaErrorValue)RPN[tPos + 1]); tPos++; break;

            case ptg.Bool: AddParsed(TokenBuilder, RPN[tPos + 1] == 1); tPos++; break;

            case ptg.Int: AddParsed16(TokenBuilder, BitOps.GetWord(RPN, tPos + 1)); tPos += 2; break;

            case ptg.Num: AddParsed(TokenBuilder, BitConverter.ToDouble(RPN, tPos + 1)); tPos += 8; break;

            case ptg.Array: Push(TokenBuilder, GetArrayDataToken(RealToken, RPN, ref ArrayPos)); tPos += 7; break;

            case ptg.Func:
                bool Result1;
                int  index           = BitOps.GetWord(RPN, tPos + 1);
                TCellFunctionData fd = TXlsFunction.GetData(index, out Result1);
                if (!Result1)
                {
                    return(false);
                }

                Debug.Assert(fd.MinArgCount == fd.MaxArgCount, "On a fixed formula the min count of arguments should be the same as the max");
                AddParsedFormula(TokenBuilder, RealToken, fd, (byte)fd.MinArgCount);
                tPos += 2;
                break;

            case ptg.FuncVar:
                bool Result2;
                int  index2           = BitOps.GetWord(RPN, tPos + 2);
                TCellFunctionData fd2 = TXlsFunction.GetData(index2, out Result2);
                if (!Result2)
                {
                    return(false);
                }

                if (fd2.Index == 344)                       // SubTotal
                {
                    HasSubtotal = true;
                }

                int np = RPN[tPos + 1] & 0x7F;

                if (fd2.Index == 255)
                {
                    CheckFutureFunction(TokenBuilder, ref np, Names, ref fd2, TokenOffset, ref HasAggregate);
                }


                AddParsedFormula(TokenBuilder, RealToken, fd2, (byte)np);

                tPos += 3;
                break;

            case ptg.Name:
                Push(TokenBuilder, new TNameToken(RealToken, BitOps.GetWord(RPN, tPos + 1)));
                tPos += 4;
                break;

            case ptg.NameX:
                Push(TokenBuilder, new TNameXToken(RealToken, BitOps.GetWord(RPN, tPos + 1), BitOps.GetWord(RPN, tPos + 3)));
                tPos += 6;
                break;

            case ptg.RefErr:
            case ptg.Ref:
                AddParsedRef(TokenBuilder, RealToken, BitOps.GetWord(RPN, tPos + 1), BitOps.GetWord(RPN, tPos + 2 + 1)); tPos += 4;
                break;

            case ptg.RefN:
                AddParsedRefN(TokenBuilder, RealToken, BitOps.GetWord(RPN, tPos + 1), BitOps.GetWord(RPN, tPos + 2 + 1)); tPos += 4;
                break;

            case ptg.AreaErr:
            case ptg.Area:
                AddParsedArea(TokenBuilder, RealToken, BitOps.GetWord(RPN, tPos + 1), BitOps.GetWord(RPN, tPos + 2 + 1), BitOps.GetWord(RPN, tPos + 4 + 1), BitOps.GetWord(RPN, tPos + 6 + 1)); tPos += 8;
                break;

            case ptg.AreaN:
                AddParsedAreaN(TokenBuilder, RealToken, BitOps.GetWord(RPN, tPos + 1), BitOps.GetWord(RPN, tPos + 2 + 1), BitOps.GetWord(RPN, tPos + 4 + 1), BitOps.GetWord(RPN, tPos + 6 + 1)); tPos += 8;
                break;

            case ptg.MemArea:
            {
                int ArrayLen;
                Push(TokenBuilder, new TMemAreaToken(RealToken, GetMemControl(RPN, ArrayPos, out ArrayLen), tPos + 1 + 6 + BitOps.GetWord(RPN, tPos + 1 + 4)));
                ArrayPos += ArrayLen; tPos += 6;
                break;                         //this is an optimization, but we don't need it.
            }

            case ptg.MemErr:
            {
                Push(TokenBuilder, new TMemErrToken(RealToken, (TFlxFormulaErrorValue)RPN[tPos + 1], tPos + 1 + 6 + BitOps.GetWord(RPN, tPos + 1 + 4)));
                tPos += 6;
                break;                         //this is an optimization, but we don't need it.
            }

            case ptg.MemNoMem:
            {
                Push(TokenBuilder, new TMemNoMemToken(RealToken, tPos + 1 + 6 + BitOps.GetWord(RPN, tPos + 1 + 4)));
                tPos += 6;
                break;                         //this is an optimization, but we don't need it.
            }

            case ptg.MemFunc:
            {
                Push(TokenBuilder, new TMemFuncToken(RealToken, tPos + 1 + 2 + BitOps.GetWord(RPN, tPos + 1)));
                tPos += 2;
                break;                         //this is an optimization, but we don't need it.
            }

            case ptg.MemAreaN:
            {
                Push(TokenBuilder, new TMemAreaNToken(RealToken, tPos + 1 + 2 + BitOps.GetWord(RPN, tPos + 1)));
                tPos += 2;
                break;                         //this is an optimization, but we don't need it.
            }

            case ptg.MemNoMemN:
            {
                Push(TokenBuilder, new TMemNoMemNToken(RealToken, tPos + 1 + 2 + BitOps.GetWord(RPN, tPos + 1)));
                tPos += 2;
                break;                         //this is an optimization, but we don't need it.
            }


            case ptg.Ref3dErr:
            case ptg.Ref3d:
            {
                int grBit1      = BitOps.GetWord(RPN, tPos + 4 + 1);
                int ExternSheet = BitOps.GetWord(RPN, tPos + 1);
                int Row1        = BitOps.GetWord(RPN, tPos + 2 + 1);
                AddParsed3dRef(TokenBuilder, RealToken, ExternSheet, Row1, grBit1);

                tPos += 6;
                break;
            }

            case ptg.Area3dErr:
            case ptg.Area3d:
            {
                int ExternSheet = BitOps.GetWord(RPN, tPos + 1);
                int Row1        = BitOps.GetWord(RPN, tPos + 2 + 1);
                int Row2        = BitOps.GetWord(RPN, tPos + 4 + 1);
                int grBit1      = BitOps.GetWord(RPN, tPos + 6 + 1);
                int grBit2      = BitOps.GetWord(RPN, tPos + 8 + 1);
                AddParsed3dArea(TokenBuilder, RealToken, ExternSheet, Row1, Row2, grBit1, grBit2);

                tPos += 10;
                break;
            }

            default: return(false);
            }
            return(true);
        }
Esempio n. 22
0
        protected static void AddParsedFormula(TParsedTokenListBuilder TokenBuilder, ptg FmlaPtg, TCellFunctionData Func, byte ArgCount)
        {
            TBaseParsedToken FmlaToken = TParsedTokenListBuilder.GetParsedFormula(FmlaPtg, Func, ArgCount);

            Push(TokenBuilder, FmlaToken);             //Always push unsupported.
        }
Esempio n. 23
0
 protected static void AddParsedArea(TParsedTokenListBuilder TokenBuilder, ptg aId, int Rw1, int Rw2, int grBit1, int grBit2)
 {
     Push(TokenBuilder, new TAreaToken(aId, Biff8Utils.ExpandBiff8Row(Rw1), Biff8Utils.ExpandBiff8Col(grBit1 & ColMask), (grBit1 & 0x8000) == 0, (grBit1 & 0x4000) == 0,
                                       Biff8Utils.ExpandBiff8Row(Rw2), Biff8Utils.ExpandBiff8Col(grBit2 & ColMask), (grBit2 & 0x8000) == 0, (grBit2 & 0x4000) == 0));
 }
Esempio n. 24
0
        private static void Add(Stream Data, Stream ArrayData, TBaseParsedToken Token, ptg BaseToken, TParsedTokenList Tokens, TTokenOffset StreamPos, TFormulaType FmlaType, Int32List FuturePos)
        {
            if (IsError(BaseToken, FmlaType))
            {
                Data.WriteByte(0x1C); //PtgErr
                Data.WriteByte(0x2A);
                return;
            }


            Data.WriteByte((byte)Token.GetId);
            switch (BaseToken)
            {
            case ptg.Exp:
                TExp_Token exp = (TExp_Token)Token;
                Biff8Utils.CheckRow(exp.Row);
                Biff8Utils.CheckCol(exp.Col);
                WriteWord(Data, exp.Row);
                WriteWord(Data, exp.Col);
                break;

            case ptg.Tbl:
                TTableObjToken tblo = Token as TTableObjToken;
                if (tblo != null)
                {
                    //no biff8 checks here. This numbers might be anything.
                    WriteWord(Data, tblo.Row);
                    WriteWord(Data, tblo.Col);
                }
                else
                {
                    TTableToken tbl = (TTableToken)Token;
                    Biff8Utils.CheckRow(tbl.Row);
                    Biff8Utils.CheckCol(tbl.Col);
                    WriteWord(Data, tbl.Row);
                    WriteWord(Data, tbl.Col);
                }
                break;

            case ptg.Add:
            case ptg.Sub:
            case ptg.Mul:
            case ptg.Div:
            case ptg.Power:
            case ptg.Concat:
            case ptg.LT:
            case ptg.LE:
            case ptg.EQ:
            case ptg.GE:
            case ptg.GT:
            case ptg.NE:
            case ptg.Isect:
            case ptg.Union:
            case ptg.Range:
            case ptg.Uplus:
            case ptg.Uminus:
            case ptg.Percent:
            case ptg.Paren:
            case ptg.MissArg:
                break;


            case ptg.Str:
            {
                TStrDataToken tkd = Token as TStrDataToken;
                string        s   = tkd.GetData();
                if (s.Length > FlxConsts.Max_FormulaStringConstant)
                {
                    FlxMessages.ThrowException(FlxErr.ErrStringConstantInFormulaTooLong, s, String.Empty);
                }
                TExcelString Xs = new TExcelString(TStrLenLength.is8bits, s, null, false);
                byte[]       b  = new byte[Xs.TotalSize()];
                Xs.CopyToPtr(b, 0);
                Data.Write(b, 0, b.Length);
                break;
            }

            case ptg.Attr:
                WriteAttr(Data, Token, StreamPos, Tokens.SavePosition());

                break;

            /*
             * case ptg.Sheet: //Can't happen, ConvertBiff8ToInternal skips them.
             * case ptg.EndSheet: //Can't happen, ConvertBiff8ToInternal skips them.
             *  break;*/

            case ptg.Err:
            {
                Data.WriteByte((byte)((TErrDataToken)Token).GetData());
                break;
            }

            case ptg.Bool:
            {
                if (((TBoolDataToken)Token).GetData())
                {
                    Data.WriteByte(1);
                }
                else
                {
                    Data.WriteByte(0);
                }
                break;
            }

            case ptg.Int:
            {
                UInt16 a = (UInt16)((TIntDataToken)Token).GetData();
                WriteWord(Data, a);
                break;
            }

            case ptg.Num:
            {
                double d = ((TNumDataToken)Token).GetData();
                Data.Write(BitConverter.GetBytes(d), 0, 8);
                break;
            }


            case ptg.Array:
            {
                Data.Write(new byte[7], 0, 7);
                TArrayDataToken tk = (TArrayDataToken)Token;
                object[,] Arr = tk.GetData;

                int ColCount = Arr.GetLength(1) - 1;
                if (ColCount < 0 || ColCount > FlxConsts.Max_Columns97_2003)
                {
                    FlxMessages.ThrowException(FlxErr.ErrInvalidCols, ColCount, FlxConsts.Max_Columns97_2003 + 1);
                }
                ArrayData.WriteByte((byte)(ColCount));

                int RowCount = Arr.GetLength(0) - 1;
                if (RowCount < 0 || RowCount > FlxConsts.Max_Rows)
                {
                    FlxMessages.ThrowException(FlxErr.ErrInvalidRows, RowCount, FlxConsts.Max_Rows + 1);
                }
                WriteWord(ArrayData, RowCount);

                for (int r = 0; r <= RowCount; r++)
                {
                    for (int c = 0; c <= ColCount; c++)
                    {
                        WriteArrayObject(ArrayData, Arr[r, c]);
                    }
                }

                break;
            }

            case ptg.Func:
            {
                TBaseFunctionToken ft = (TBaseFunctionToken)Token;
                TCellFunctionData  fd = ft.GetFunctionData();
                WriteWord(Data, fd.Index);
                break;
            }

            case ptg.FuncVar:
            {
                TBaseFunctionToken ft = (TBaseFunctionToken)Token;
                TCellFunctionData  fd = ft.GetFunctionData();
                if (!BackFromFutureToUserDef(Data, Tokens, FuturePos, ft, fd))
                {
                    Data.WriteByte((byte)ft.ArgumentCount);
                    WriteWord(Data, fd.Index);
                }
                break;
            }

            case ptg.Name:
                WriteWord(Data, ((TNameToken)Token).NameIndex);
                WriteWord(Data, 0);
                break;

            case ptg.Ref:
            case ptg.RefN:
            case ptg.RefErr:
            {
                TRefToken reft = (TRefToken)Token;
                WriteRef(Data, reft.CanHaveRelativeOffsets, reft.Row, reft.RowAbs, reft.Col, reft.ColAbs);
                break;
            }

            case ptg.Area:
            case ptg.AreaN:
            case ptg.AreaErr:
            {
                TAreaToken areat = (TAreaToken)Token;
                WriteArea(Data, areat.CanHaveRelativeOffsets, areat.Row1, areat.RowAbs1, areat.Col1, areat.ColAbs1, areat.Row2, areat.RowAbs2, areat.Col2, areat.ColAbs2);
                break;
            }

            case ptg.MemArea:
            {
                WriteWord(Data, 0);
                WriteWord(Data, 0);
                StreamPos.Add((int)Data.Position, Tokens.SavePosition());
                WriteWord(Data, 0);

                TRefRange[] Range = ((TMemAreaToken)Token).Data;
                WriteWord(ArrayData, Range.Length);
                foreach (TRefRange OneRef in Range)
                {
                    int r1 = Biff8Utils.CheckAndContractBiff8Row(OneRef.FirstRow);
                    int r2 = Biff8Utils.CheckAndContractBiff8Row(OneRef.LastRow);
                    int c1 = Biff8Utils.CheckAndContractBiff8Col(OneRef.FirstCol);
                    int c2 = Biff8Utils.CheckAndContractBiff8Col(OneRef.LastCol);

                    WriteWord(ArrayData, r1);
                    WriteWord(ArrayData, r2);
                    WriteWord(ArrayData, c1);
                    WriteWord(ArrayData, c2);
                }

                break;
            }

            case ptg.MemErr:
            case ptg.MemNoMem:
                WriteWord(Data, 0);
                WriteWord(Data, 0);
                StreamPos.Add((int)Data.Position, Tokens.SavePosition());
                WriteWord(Data, 0);
                break;

            case ptg.MemFunc:
            case ptg.MemAreaN:
            case ptg.MemNoMemN:
                StreamPos.Add((int)Data.Position, Tokens.SavePosition());
                WriteWord(Data, 0);
                break;

            case ptg.NameX:
                TNameXToken NameX = (TNameXToken)Token;
                WriteWord(Data, NameX.FExternSheet);
                WriteWord(Data, NameX.NameIndex);
                WriteWord(Data, 0);
                break;

            case ptg.Ref3dErr:
            case ptg.Ref3d:
                TRef3dToken reft3d = (TRef3dToken)Token;
                WriteWord(Data, reft3d.FExternSheet);
                WriteRef(Data, reft3d.CanHaveRelativeOffsets, reft3d.Row, reft3d.RowAbs, reft3d.Col, reft3d.ColAbs);
                break;

            case ptg.Area3d:
            case ptg.Area3dErr:
                TArea3dToken areat3d = (TArea3dToken)Token;
                WriteWord(Data, areat3d.FExternSheet);
                WriteArea(Data, areat3d.CanHaveRelativeOffsets, areat3d.Row1, areat3d.RowAbs1, areat3d.Col1, areat3d.ColAbs1, areat3d.Row2, areat3d.RowAbs2, areat3d.Col2, areat3d.ColAbs2);
                break;

            default:
                XlsMessages.ThrowException(XlsErr.ErrInternal);                         //All tokens here should exist
                break;
            }
        }
Esempio n. 25
0
        private static void Evaluate(TBaseParsedToken Token, bool R1C1, int CellRow, int CellCol, ptg BaseToken, TParsedTokenList RPN, ICellList CellList, TWorkbookGlobals Globals, TFormulaStack ParsedStack, ref string StartFormula, int MaxStringConstantLen, bool WritingXlsx)
        {
            string s1; string s2; string s3;

            switch (BaseToken)
            {
            case ptg.Exp: AddArray(Token, CellRow, CellCol, CellList, Globals, ParsedStack, MaxStringConstantLen, WritingXlsx);
                StartFormula = String.Empty;
                break;

            case ptg.Tbl: AddTable(R1C1, Token, CellList, ParsedStack);
                StartFormula = String.Empty;
                break;

            case ptg.Add: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmPlus) + s2); break;

            case ptg.Sub: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmMinus) + s2); break;

            case ptg.Mul: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmMul) + s2); break;

            case ptg.Div: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmDiv) + s2); break;

            case ptg.Power: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmPower) + s2); break;

            case ptg.Concat: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmAnd) + s2); break;

            case ptg.LT: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmLT) + s2); break;

            case ptg.LE: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmLE) + s2); break;

            case ptg.EQ: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmEQ) + s2); break;

            case ptg.GE: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmGE) + s2); break;

            case ptg.GT: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmGT) + s2); break;

            case ptg.NE: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmNE) + s2); break;

            case ptg.Isect: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmIntersect) + s2); break;

            case ptg.Union: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmUnion) + s2); break;

            case ptg.Range: s2 = ParsedStack.Pop(); s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmRangeSep) + s2); break;

            case ptg.Uplus: s1 = ParsedStack.Pop(); ParsedStack.Push(ParsedStack.FmSpaces + fts(TFormulaToken.fmPlus) + s1); break;

            case ptg.Uminus: s1 = ParsedStack.Pop(); ParsedStack.Push(ParsedStack.FmSpaces + fts(TFormulaToken.fmMinus) + s1); break;

            case ptg.Percent: s1 = ParsedStack.Pop(); ParsedStack.Push(s1 + ParsedStack.FmSpaces + fts(TFormulaToken.fmPercent)); break;

            case ptg.Paren: s1 = ParsedStack.Pop(); ParsedStack.Push(ParsedStack.FmPreSpaces + fts(TFormulaToken.fmOpenParen) + s1 + ParsedStack.FmPostSpaces + fts(TFormulaToken.fmCloseParen)); break;

            case ptg.MissArg: ParsedStack.Push(ParsedStack.FmSpaces); break;

            case ptg.Str:
                ParsedStack.Push(ParsedStack.FmSpaces + fts(TFormulaToken.fmStr)
                                 + GetString(((TStrDataToken)Token).GetData(), MaxStringConstantLen) + fts(TFormulaToken.fmStr));
                break;

            case ptg.Attr: ProcessAttr(Token, ParsedStack); break;

            case ptg.Sheet:  break;

            case ptg.EndSheet:  break;

            case ptg.Err: ParsedStack.Push(ParsedStack.FmSpaces + GetErrorText(((TErrDataToken)Token).GetData())); break;

            case ptg.Bool: ParsedStack.Push(ParsedStack.FmSpaces + GetBoolText(((TBoolDataToken)Token).GetData())); break;

            case ptg.Int: ParsedStack.Push(ParsedStack.FmSpaces + TFormulaMessages.FloatToString(((TIntDataToken)Token).GetData())); break;

            case ptg.Num: ParsedStack.Push(ParsedStack.FmSpaces + TFormulaMessages.FloatToString(((TNumDataToken)Token).GetData())); break;

            case ptg.Array: ParsedStack.Push(ParsedStack.FmSpaces + GetArrayText(((TArrayDataToken)Token).GetData, MaxStringConstantLen)); break;

            case ptg.Func:
            case ptg.FuncVar:
                int                ArgCount;
                bool               IsAddin;
                StringBuilder      sb         = new StringBuilder();
                TBaseFunctionToken FunctionTk = Token as TBaseFunctionToken;

                s3 = ParsedStack.FmSpaces + GetFuncName(FunctionTk, out ArgCount, WritingXlsx, out IsAddin);

                if (ArgCount > 0)
                {
                    sb.Append(ParsedStack.Pop());
                }
                for (int i = 2; i <= ArgCount; i++)
                {
                    s1 = ParsedStack.Pop();
                    sb.Insert(0, s1 + fts(TFormulaToken.fmFunctionSep));
                }

                if (IsAddin)
                {
                    s3 += ConvertInternalFunctionName(Globals, ParsedStack.Pop());
                }
                ParsedStack.Push(s3 + fts(TFormulaToken.fmOpenParen) + ParsedStack.FmPreSpaces + sb.ToString() + ParsedStack.FmPostSpaces + fts(TFormulaToken.fmCloseParen));
                break;

            case ptg.Name: ParsedStack.Push(ParsedStack.FmSpaces + GetName(((TNameToken)Token).NameIndex, -1, Globals, WritingXlsx)); break;

            case ptg.RefN:
            case ptg.Ref: ParsedStack.Push(ParsedStack.FmSpaces + GetRef(R1C1, (TRefToken)Token, CellRow, CellCol)); break;

            case ptg.AreaN:
            case ptg.Area: ParsedStack.Push(ParsedStack.FmSpaces + GetArea(R1C1, (TAreaToken)Token, CellRow, CellCol)); break;

            case ptg.MemArea: break;

            case ptg.MemErr: break;

            case ptg.MemNoMem: break;

            case ptg.MemFunc: break;

            case ptg.RefErr: ParsedStack.Push(ParsedStack.FmSpaces + TFormulaMessages.ErrString(TFlxFormulaErrorValue.ErrRef)); break;

            case ptg.AreaErr: ParsedStack.Push(ParsedStack.FmSpaces + TFormulaMessages.ErrString(TFlxFormulaErrorValue.ErrRef)); break;

            case ptg.MemAreaN: break;

            case ptg.MemNoMemN: break;

            case ptg.NameX: ParsedStack.Push(ParsedStack.FmSpaces + GetNameX((TNameXToken)Token, Globals, WritingXlsx)); break;

            case ptg.Ref3d: ParsedStack.Push(ParsedStack.FmSpaces + GetRef3D(R1C1, (TRef3dToken)Token, CellRow, CellCol, Globals, false, WritingXlsx)); break;

            case ptg.Area3d: ParsedStack.Push(ParsedStack.FmSpaces + GetArea3D(R1C1, (TArea3dToken)Token, CellRow, CellCol, Globals, false, WritingXlsx)); break;

            case ptg.Ref3dErr: ParsedStack.Push(ParsedStack.FmSpaces + GetRef3D(R1C1, (TRef3dToken)Token, -1, -1, Globals, true, WritingXlsx)); break;

            case ptg.Area3dErr: ParsedStack.Push(ParsedStack.FmSpaces + GetArea3D(R1C1, (TArea3dToken)Token, CellRow, CellCol, Globals, true, WritingXlsx)); break;

            default: XlsMessages.ThrowException(XlsErr.ErrBadToken, Token); break;
            }
        }