Ejemplo n.º 1
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);
 }
Ejemplo n.º 2
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
        }
Ejemplo n.º 3
0
        private static void FixFutureFunctions(TNameRecordList Names, Int32List FuturePos, TParsedTokenList Tokens, MemoryStream Data, int[] TokenOffset, ref TTokenOffset StreamPos)
        {
            if (FuturePos.Count == 0)
            {
                return;
            }


            List <byte> NewData = new List <byte>(Data.ToArray()); //we need to insert in any order

            for (int i = 0; i < FuturePos.Count; i++)
            {
                Tokens.MoveTo(FuturePos[i]);
                TBaseFunctionToken FuncToken = (TBaseFunctionToken)Tokens.GetToken(FuturePos[i]);
                for (int k = 0; k < FuncToken.ArgumentCount; k++) //this doesn't include the name.
                {
                    Tokens.Flush();
                }

                int TokPos = Tokens.SavePosition();
                while (TokPos > 0)
                {
                    if (!(Tokens.GetToken(TokPos - 1) is TIgnoreInCalcToken) || Tokens.GetToken(TokPos - 1) is TAttrToken)
                    {
                        break;
                    }
                    TokPos--;
                }

                int ofs = TokenOffset[TokPos];
                WriteFutureName(NewData, ofs, FindName(Names, FuncToken.GetFunctionData().FutureName));

                for (int k = TokPos; k < TokenOffset.Length; k++)
                {
                    TokenOffset[k] += 5;
                }

                TTokenOffset NewStreamPos = new TTokenOffset();
                foreach (int streamofs in StreamPos.Keys)
                {
                    int sofs = streamofs;
                    if (sofs >= ofs)
                    {
                        sofs += 5;
                    }
                    NewStreamPos.Add(sofs, StreamPos[streamofs]);
                }

                StreamPos = NewStreamPos;
            }

            Data.SetLength(0);
            Data.Write(NewData.ToArray(), 0, NewData.Count);
        }
Ejemplo n.º 4
0
        private static string GetFuncName(TBaseFunctionToken Token, out int ArgCount, bool WritingXlsx, out bool IsAddin)
        {
            TCellFunctionData fd = Token.GetFunctionData();

            ArgCount = Token.ArgumentCount;

            IsAddin = Token is TUserDefinedToken;
            if (IsAddin)
            {
                ArgCount--;
                return(String.Empty);
            }

            if (WritingXlsx && fd.FutureInXlsx)
            {
                return(fd.FutureName);
            }
            return(fd.Name);
        }
Ejemplo n.º 5
0
        internal static void UpdateDeletedRanges(TParsedTokenList Data, TDeletedRanges DeletedRanges)
        {
            Data.ResetPositionToLast();
            while (!Data.Bof())
            {
                TBaseParsedToken   tk = Data.LightPop();
                TBaseFunctionToken ft = tk as TBaseFunctionToken;
                if (ft != null)
                {
                    //we need to ensure we don't delete the used _xlfn. ranges. Used def fn don't need to check, because they use the name in the tokenlist.
                    if (ft.GetFunctionData().FutureInXls)
                    {
                        int NameId = DeletedRanges.Names.GetNamePos(-1, ft.GetFunctionData().FutureName);
                        if (NameId >= 0)
                        {
                            DeletedRanges.Reference(NameId);              //No need for recursion here, this name can't use anything else. Also, we don't need to update refs to this range.
                        }
                    }

                    continue;
                }

                TNameToken r = tk as TNameToken; //this includes namex
                if (r == null)
                {
                    continue;
                }
                if (r.GetBaseId == ptg.NameX && !DeletedRanges.References.IsLocalSheet(r.ExternSheet))
                {
                    return;                                                                                     //This name does not point to a name in the NAME table.
                }
                if (DeletedRanges.Update)
                {
                    UpdateRange(r, DeletedRanges);
                }
                else
                {
                    FindReferences(r, DeletedRanges);
                }
            }
        }
Ejemplo n.º 6
0
        private static bool BackFromFutureToUserDef(Stream Data, TParsedTokenList Tokens, Int32List FuturePos, TBaseFunctionToken ft, TCellFunctionData fd)
        {
            string FutureName = fd.FutureName;

            if (FutureName != null)
            {
                Data.WriteByte((byte)(ft.ArgumentCount + 1));
                WriteWord(Data, 0xFF); //User def...
                FuturePos.Add(Tokens.SavePosition());
                return(true);
            }

            return(false);
        }
Ejemplo n.º 7
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;
            }
        }
Ejemplo n.º 8
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;
            }
        }