private static void ProcessAttr(TBaseParsedToken Token, TFormulaStack ParsedStack) { TAttrSpaceToken SpaceToken = Token as TAttrSpaceToken; if (SpaceToken != null) { switch (SpaceToken.SpaceType) { case FormulaAttr.bitFSpace: ParsedStack.FmSpaces += new String(' ', SpaceToken.SpaceCount); break; case FormulaAttr.bitFEnter: ParsedStack.FmSpaces += new String('\u000D', SpaceToken.SpaceCount); break; case FormulaAttr.bitFPreSpace: ParsedStack.FmPreSpaces += new String(' ', SpaceToken.SpaceCount); break; case FormulaAttr.bitFPreEnter: ParsedStack.FmPreSpaces += new String('\u000D', SpaceToken.SpaceCount); break; case FormulaAttr.bitFPostSpace: ParsedStack.FmPostSpaces += new String(' ', SpaceToken.SpaceCount); break; case FormulaAttr.bitFPostEnter: ParsedStack.FmPostSpaces += new String('\u000D', SpaceToken.SpaceCount); break; case FormulaAttr.bitFPreFmlaSpace: break; //not handled; } //case } if (Token is TAttrSumToken) { string s = ParsedStack.Pop(); ParsedStack.Push(ParsedStack.FmSpaces + TXlsFunction.GetData(4).Name + fts(TFormulaToken.fmOpenParen) + ParsedStack.FmPreSpaces + s + ParsedStack.FmPostSpaces + fts(TFormulaToken.fmCloseParen)); } }
/// <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()); } } }
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()); }
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); }
private void AddParsedNoPop(TBaseParsedToken obj) { if (obj.GetId != ptg.Paren && obj.GetId != ptg.Attr) //Those are "transparent" for reference ops. { LastRefOp = FParsedDataBuilder.Count; } FParsedDataBuilder.Add(obj); }
private static byte[] ConvertToBiff8(TExternSheetList ExternSheetList, byte Token, byte[] Data, ref int tPos) { byte[] Result; int rPos = 0; switch (TBaseParsedToken.CalcBaseToken((ptg)Token)) { case ptg.Name: Result = new byte[4]; //Wrong on Excel docs! BitOps.SetWord(Result, 0, BitOps.GetWord(Data, tPos)); tPos += 14; return(Result); case ptg.NameX: Result = new byte[6]; //This is actually 6 BitOps.SetWord(Result, 2, BitOps.GetWord(Data, tPos + 10)); tPos += 24; return(Result); case ptg.Ref: case ptg.RefN: Result = new byte[4]; ConvertRowsAndColumns7To8(Data, Result, ref tPos, ref rPos, false); return(Result); case ptg.Area: case ptg.AreaN: Result = new byte[8]; ConvertRowsAndColumns7To8(Data, Result, ref tPos, ref rPos, true); return(Result); case ptg.RefErr: tPos += 3; return(new byte[4]); case ptg.AreaErr: tPos += 6; return(new byte[8]); case ptg.Ref3d: case ptg.Ref3dErr: Result = new byte[6]; Convert3D7To8(ExternSheetList, Token, Data, Result, ref tPos, ref rPos); ConvertRowsAndColumns7To8(Data, Result, ref tPos, ref rPos, false); return(Result); case ptg.Area3d: case ptg.Area3dErr: Result = new byte[10]; Convert3D7To8(ExternSheetList, Token, Data, Result, ref tPos, ref rPos); ConvertRowsAndColumns7To8(Data, Result, ref tPos, ref rPos, true); return(Result); } XlsMessages.ThrowException(XlsErr.ErrBadToken, Token); return(null); //just to compile. }
protected override void AddParsedOp(TOperator op) { TBaseParsedToken OpToken = TParsedTokenListBuilder.GetParsedOp(op); if (OpToken is TUnsupportedToken) { DoError(FlxErr.ErrFormulaInvalid, 2); } else { Push(OpToken); } }
private static void AddTable(bool R1C1, TBaseParsedToken Token, ICellList CellList, TFormulaStack ParsedStack) { if (CellList == null || Token is TTableObjToken) { ParsedStack.Push(" <Table> "); return; } ParsedStack.Push(fts(TFormulaToken.fmOpenArray) + fts(TFormulaToken.fmStartFormula) + fts(TFormulaToken.fmTableText) + fts(TFormulaToken.fmOpenParen) + GetTableText(R1C1, CellList.TableFormula(((TTableToken)Token).Row, ((TTableToken)Token).Col)) + fts(TFormulaToken.fmCloseParen) + fts(TFormulaToken.fmCloseArray)); }
static TToken[] Convert(TParsedTokenList Tokens) { TToken[] Result = new TToken[Tokens.Count]; Tokens.ResetPositionToStart(); int i = 0; while (!Tokens.Eof()) { TBaseParsedToken tk = Tokens.ForwardPop(); Result[i] = GetPublicToken(tk); i++; } return(Result); }
internal static void ArrangeSharedFormulas(TParsedTokenList Data, int Row, int Col, bool FromBiff8) { Data.ResetPositionToLast(); while (!Data.Bof()) { TBaseParsedToken r = Data.LightPop(); switch (r.GetBaseId) { case ptg.RefN: case ptg.AreaN: Data.UnShare(Row, Col, FromBiff8); break; } } }
protected override void Do3D(TBaseParsedToken tk, out bool RefIsInInsertingSheet) { RefIsInInsertingSheet = false; if (SheetInfo.SourceReferences != null) { RefIsInInsertingSheet = SheetInfo.SourceReferences.GetJustOneSheet(tk.ExternSheet) == SheetInfo.InsSheet; if (Bounds != null) { Bounds.AddSheets(SheetInfo.SourceReferences.GetAllSheets(tk.ExternSheet)); } } else { Debug.Assert(Bounds == null); //we would have problems if references is null and we try to use Bounds. } }
protected override void AddParsedFunction(TCellFunctionData Func, byte ArgCount) { ptg FmlaPtg; if (Func.MinArgCount != Func.MaxArgCount || Func.FutureInXls) { FmlaPtg = GetRealPtg(ptg.FuncVar, Func.ReturnType); } else { FmlaPtg = GetRealPtg(ptg.Func, Func.ReturnType); } TBaseParsedToken FmlaToken = TParsedTokenListBuilder.GetParsedFormula(FmlaPtg, Func, ArgCount); Push(FmlaToken); }
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); }
protected override void Do3D(TBaseParsedToken tk, out bool RefIsInInsertingSheet) { RefIsInInsertingSheet = false; if (SheetInfo.SourceReferences != null) { if (SheetInfo.DestReferences != SheetInfo.SourceReferences) //Copy the external refs to the new file. { int refpos = SheetInfo.DestReferences.CopySheet(tk.ExternSheet, SheetInfo); if (refpos < 0) { //CreateInvalidRef(ref Data[tkPos]); //SetWord(Data, tPos, SheetInfo.DestReferences.SetSheet(SheetInfo.DestFormulaSheet)); //Ensure we have a valid externsheet. A reference to a non existing externsheet will raise an error in Excel, even if the reference is not valid. tk.ExternSheet = SheetInfo.DestReferences.AddSheet(SheetInfo.DestGlobals.SheetCount, 0xFFFF); //A reference to a deleted sheet. } else { tk.ExternSheet = refpos; //this copies external refs to the old sheet to the new sheet if (Bounds != null) { Bounds.AddSheets(SheetInfo.DestReferences.GetAllSheets(refpos)); } } } else { int SingleLocalSheet = SheetInfo.SourceReferences.GetJustOneSheet(tk.ExternSheet); RefIsInInsertingSheet = SingleLocalSheet == SheetInfo.InsSheet; if (InsertingSheet && (SingleLocalSheet == SheetInfo.SourceFormulaSheet)) //We will only convert those names that reference a single sheet. { tk.ExternSheet = SheetInfo.SourceReferences.AddSheet(SheetInfo.SourceGlobals.SheetCount, SheetInfo.InsSheet); //this copies external refs to the old sheet to the new sheet } if (Bounds != null) { Bounds.AddSheets(SheetInfo.DestReferences.GetAllSheets(tk.ExternSheet)); } } } else { Debug.Assert(Bounds == null); //we would have problems if references is null and we try to use Bounds. } }
private static void AddArray(TBaseParsedToken Token, int CellRow, int CellCol, ICellList CellList, TWorkbookGlobals Globals, TFormulaStack ParsedStack, int MaxStringConstantLen, bool WritingXlsx) { if (CellList == null) { ParsedStack.Push(" <Ref> "); return; } string Start = ""; string Stop = ""; if (!WritingXlsx) { Start = fts(TFormulaToken.fmOpenArray); Stop = fts(TFormulaToken.fmCloseArray); } ParsedStack.Push(Start + TFormulaConvertInternalToText.AsString(CellList.ArrayFormula(((TExp_Token)Token).Row, ((TExp_Token)Token).Col), CellRow, CellCol, CellList, Globals, MaxStringConstantLen, WritingXlsx) + Stop); }
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); } } }
private static void FixGotoAndMemTokens(TParsedTokenList Tokens, MemoryStream Data, int[] TokenOffset, TTokenOffset StreamPos) { foreach (int streamofs in StreamPos.Keys) { TBaseParsedToken Token = Tokens.GetToken(StreamPos[streamofs]); Data.Position = streamofs; TAttrOptIfToken oiftk = Token as TAttrOptIfToken; if (oiftk != null) { WriteWord(Data, TokenOffset[oiftk.PositionOfNextPtg] - (streamofs + 2)); continue; } TAttrOptChooseToken ctk = Token as TAttrOptChooseToken; if (ctk != null) { for (int i = 0; i < ctk.PositionOfNextPtg.Length; i++) { WriteWord(Data, TokenOffset[ctk.PositionOfNextPtg[i]] - streamofs); } continue; } TAttrGotoToken gtk = Token as TAttrGotoToken; if (gtk != null) { WriteWord(Data, TokenOffset[gtk.PositionOfNextPtg] - (streamofs + 2) - 1); continue; } TSimpleMemToken memtk = Token as TSimpleMemToken; if (memtk != null) { WriteWord(Data, TokenOffset[memtk.PositionOfNextPtg] - (streamofs + 2)); continue; } } }
internal static readonly TCellComparer Instance = new TCellComparer(); //STATIC* #region IComparer Members public int Compare(object x, object y) { x = TExcelTypes.ConvertToAllowedObject(x, TBaseParsedToken.Dates1904); y = TExcelTypes.ConvertToAllowedObject(y, TBaseParsedToken.Dates1904); //null values go always at the bottom. (in ascending or descending order) if (x == null) { if (y == null) { return(0); } return(1); } if (y == null) { return(-1); } if (x is TFlxFormulaErrorValue) { if (y is TFlxFormulaErrorValue) { return(((int)x).CompareTo((int)y)); } return(1); } if (y is TFlxFormulaErrorValue) { return(-1); } object Result = TBaseParsedToken.CompareValues(x, y); if (Result is int) { return((int)Result); } return(0); }
private void CheckRadioButtons(ExcelFile Workbook, int ActiveSheet, int i, TCellAddress LinkedCell) { int Sheet = ActiveSheet + 1; if (!string.IsNullOrEmpty(LinkedCell.Sheet)) { Sheet = Workbook.GetSheetIndex(LinkedCell.Sheet, false); } if (Sheet > 0) { int XF = 1; object r = Workbook.GetCellValue(Sheet, LinkedCell.Row, LinkedCell.Col, ref XF); if (r == null) { CheckGroup(i, 0); return; } if (r is TFlxFormulaErrorValue) { if ((TFlxFormulaErrorValue)r == TFlxFormulaErrorValue.ErrNA) { CheckGroup(i, 0); return; } //if it isn't n/a, its value doesn't matter. rb stays as is. } else { double pd; if (TBaseParsedToken.ExtToDouble(r, out pd)) //something like a string doesn't matter { if (pd <= 0 || pd >= int.MaxValue) { CheckGroup(i, 0); return; } // in this case it does matter, all cbs are unselected. int p = (int)pd; CheckGroup(i, p); } } } }
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); }
private static TToken GetPublicToken(TBaseParsedToken tk) { /* ptg BaseToken = tk.GetBaseId; * * * switch (BaseToken) * { * case ptg.Exp: //must be array, can't be shared formula * return; * case ptg.Tbl: AddTable(R1C1, Token, CellList, ParsedStack); * StartFormula = String.Empty; * break; * case ptg.Add: return new TTokenOperator(TOperator.Add); * case ptg.Sub: return new TTokenOperator(TOperator.Sub); * case ptg.Mul: return new TTokenOperator(TOperator.Mul); * case ptg.Div: return new TTokenOperator(TOperator.Div); * case ptg.Power: return new TTokenOperator(TOperator.Power); * case ptg.Concat: return new TTokenOperator(TOperator.Concat); * case ptg.LT: return new TTokenOperator(TOperator.LT); * case ptg.LE: return new TTokenOperator(TOperator.LE); * case ptg.EQ: return new TTokenOperator(TOperator.EQ); * case ptg.GE: return new TTokenOperator(TOperator.GE); * case ptg.GT: return new TTokenOperator(TOperator.GT); * case ptg.NE: return new TTokenOperator(TOperator.NE); * * case ptg.Isect: return new TTokenRangeOp(TRangeOp.Intersection); * case ptg.Union: return new TTokenRangeOp(TRangeOp.Union); * case ptg.Range: return new TTokenRangeOp(TRangeOp.Range); * * case ptg.Uplus: return new TTokenOperator(TOperator.UPlus); * case ptg.Uminus: return new TTokenOperator(TOperator.Neg); * case ptg.Percent: return new TTokenOperator(TOperator.Percent); * * case ptg.Paren: return new TTokenParethesis(); * case ptg.MissArg: return new TTokenMissingArgument(); * case ptg.Str: return new TTokenData(((TStrDataToken)tk).GetData()); * * case ptg.Attr: ProcessAttr(Token, ParsedStack); break; * case ptg.Sheet: return new TTokenUnsupported(); * case ptg.EndSheet: new TTokenUnsupported(); * case ptg.Err: return new TTokenData(((TErrDataToken)tk).GetData()); * case ptg.Bool: return new TTokenData(((TBoolDataToken)tk).GetData()); * case ptg.Int: return new TTokenData(((TIntDataToken)tk).GetData()); * case ptg.Num: return new TTokenData(((TNumDataToken)tk).GetData()); * case ptg.Array: ParsedStack.Push(ParsedStack.FmSpaces + GetArrayText(((TArrayDataToken)Token).GetData, MaxStringConstantLen)); break; * * case ptg.Func: * case ptg.FuncVar: * int ArgCount; * bool IsAddin; * TBaseFunctionToken Function = tk as TBaseFunctionToken; * * string FuncName = GetFuncName(Function, out ArgCount, false, out IsAddin); * if (IsAddin) FuncName = ConvertInternalFunctionName(Globals, ParsedStack.Pop()); * return new TTokenFunction(FuncName, ArgCount); * * 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; * }*/ return(null); }
protected abstract void Do3D(TBaseParsedToken tk, out bool RefIsInInsertingSheet);
internal override bool Same(TBaseParsedToken aBaseParsedToken) { return(false); //we don't care about this in tags. }
protected static void Push(TParsedTokenListBuilder TokenBuilder, TBaseParsedToken obj) { TokenBuilder.Add(obj); }
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. }
private static void WriteAttr(Stream Data, TBaseParsedToken Token, TTokenOffset StreamPos, int TokenPos) { if (Token is TAttrVolatileToken) { Data.WriteByte(0x01); WriteWord(Data, 0); return; } if (Token is TAttrSumToken) { Data.WriteByte(0x10); WriteWord(Data, 0); return; } if (Token is TAttrSpaceToken) { int Id = 0x40; TAttrSpaceToken sp = (TAttrSpaceToken)Token; if (sp.Volatile) { Id |= 0x01; } Data.WriteByte((byte)Id); Data.WriteByte((byte)sp.SpaceType); Data.WriteByte((byte)sp.SpaceCount); return; } TAttrOptIfToken oiftk = Token as TAttrOptIfToken; if (oiftk != null) { Data.WriteByte(0x02); StreamPos.Add((int)Data.Position, TokenPos); WriteWord(Data, 0); return; } TAttrOptChooseToken ctk = Token as TAttrOptChooseToken; if (ctk != null) { Data.WriteByte(0x04); WriteWord(Data, ctk.PositionOfNextPtg.Length - 1); StreamPos.Add((int)Data.Position, TokenPos); for (int i = 0; i < ctk.PositionOfNextPtg.Length; i++) { WriteWord(Data, 0); } return; } TAttrGotoToken gtk = Token as TAttrGotoToken; if (gtk != null) { Data.WriteByte(0x08); StreamPos.Add((int)Data.Position, TokenPos); WriteWord(Data, 0); return; } XlsMessages.ThrowException(XlsErr.ErrInternal); //All tokens here should exist }
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; } } }
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; } }
protected void Push(TBaseParsedToken obj) { PopWhiteSpace(); AddParsedNoPop(obj); }
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; } }