internal TSharedFormula(TNameRecordList Names, UInt64 aKey, byte[] aData, int start, int len) { Key = aKey; TFormulaConvertBiff8ToInternal p = new TFormulaConvertBiff8ToInternal(); Data = p.ParseRPN(Names, -1, -1, aData, start, len, true); //no real need for relative since shared formulas can't be 3d, and we only need relative for the non-existing tokens ptgarea3dn and ptgref3dn. }
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); }
internal static TParsedTokenList CreateObjFmlaFromBiff8(TNameRecordList Names, int aRow, int aCol, byte[] aData, int aStart, int aLen, bool aRelative3dRanges) { TFormulaConvertBiff8ToInternal rpn = new TFormulaConvertBiff8ToInternal(); bool HasSubtotal; bool HasAggregate; return(rpn.ParseRPN(Names, aRow, aCol, aData, aStart, aLen, aRelative3dRanges, out HasSubtotal, out HasAggregate, true)); }
/// <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 bool Update; //We will contemplate 2 ways of working for this. When Update is true, ranges will be modified, else we will just build the list. internal TDeletedRanges(int NameCount, TReferences aReferences, TNameRecordList aNames) { Refs = new bool[NameCount]; Offs = new int[NameCount]; Length = NameCount; References = aReferences; Names = aNames; Update = false; }
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); }
internal TCopiedGen DrawingGen; //used when copying to make sure we don't repeat. #endregion #region Constructor internal TWorkbookGlobals(ExcelFile aWorkbook) { FWorkbook = aWorkbook; FFileEncryption = new TFileEncryption(); FLel = new TMiscRecordList(); FBoundSheets = new TBoundSheetList(); FFnGroups = new TMiscRecordList(); FWorkbookProtection = new TWorkbookProtection(); FFonts = new TFontRecordList(); FFormats = TFormatRecordList.Create(); FStyleXF = new TXFRecordList(); FCellXF = new TXFRecordList(); FDXF = new TDXFRecordList(); FStyles = new TStyleRecordList(); FTableStyles = new TTableStyleRecordList(); FPivotCache = new TMiscRecordList(); #if (FRAMEWORK30 && !COMPACTFRAMEWORK) FXlsxPivotCache = new TXlsxPivotCacheList(); FXlsxConnections = null; #endif FDocRoute = new TMiscRecordList(); FUserBView = new TMiscRecordList(); FMetaData = new TMiscRecordList(); FNames = new TNameRecordList(); FRealTimeData = new TMiscRecordList(); FReferences = new TReferences(); FHeaderImages = new TDrawingGroup(xlr.HEADERIMG, 14); FDrawingGroup = new TDrawingGroup(xlr.MSODRAWINGGROUP, 0); FSST = new TSST(); FWebPub = new TMiscRecordList(); FFeatHdr = new TMiscRecordList(); FDConn = new TMiscRecordList(); FBorders = new TBorderList(); FPatterns = new TPatternList(); FFutureRecords = new TMiscRecordList(); StylesFutureStorage = null; CalcOptions = new TCalcOptions(); ThemeRecord = new TThemeRecord(); #if (FRAMEWORK30 && !COMPACTFRAMEWORK) CustomXMLData = new TCustomXMLDataStorageList(); #endif }
protected TBaseRecordLoader(TSST aSST, IFlexCelFontList aFontList, TEncryptionData aEncryption, TXlsBiffVersion aXlsBiffVersion, TBiff8XFMap aXFMap, TNameRecordList aNames, TVirtualReader aVirtualReader) { RecordHeader = new TRecordHeader(); SST = aSST; FontList = aFontList; Encryption = aEncryption; XlsBiffVersion = aXlsBiffVersion; XFMap = aXFMap; Names = aNames; VirtualReader = aVirtualReader; }
public TParsedTokenList ParseRPN(TNameRecordList Names, int aRow, int aCol, byte[] Data, int atPos, int fmlaLen, bool aRelative3dRanges, out bool HasSubtotal, out bool HasAggregate, bool aIsFmlaObject) { HasSubtotal = false; HasAggregate = false; Relative3dRanges = aRelative3dRanges; IsFmlaObject = aIsFmlaObject; TParsedTokenListBuilder TokenBuilder = new TParsedTokenListBuilder(); if (!DoRPN(TokenBuilder, Names, Data, atPos, atPos + fmlaLen, ref HasSubtotal, ref HasAggregate)) { XlsMessages.ThrowException(XlsErr.ErrBadFormula, aRow + 1, aCol + 1, 0); } return(TokenBuilder.ToParsedTokenList()); }
internal static void SaveToStream(TNameRecordList Names, IDataStream Workbook, TFormulaType FmlaType, TParsedTokenList Data, bool WriteLen) { if (Data.TextLenght > FlxConsts.Max_FormulaLen97_2003) { FlxMessages.ThrowException(FlxErr.ErrFormulaTooLong, TFormulaConvertInternalToText.AsString(Data, 0, 0, null)); } int FmlaNoArrayLen; byte[] bData = TFormulaConvertInternalToBiff8.GetTokenData(Names, Data, FmlaType, out FmlaNoArrayLen); if (WriteLen) { Workbook.Write16((UInt16)FmlaNoArrayLen); } Workbook.Write(bData, bData.Length); }
private static int FindName(TNameRecordList Names, string Name) { if (Names == null) { return(0); //Calculating length. } for (int i = 0; i < Names.Count; i++) { if (String.Equals(Name, Names[i].Name, StringComparison.CurrentCultureIgnoreCase) && (Names[i].IsAddin)) { return(i + 1); } } FlxMessages.ThrowException(FlxErr.ErrCantFindNamedRange, Name); return(-1); }
internal void MergeFromPxlGlobals(TWorkbookGlobals SourceGlobals) { sBOF = SourceGlobals.sBOF; FSST = SourceGlobals.FSST; FReferences = SourceGlobals.FReferences; FBoundSheets = SourceGlobals.FBoundSheets; //Pxl doesn't have styles. CellXF.MergeFromPxlXF(SourceGlobals.CellXF, Fonts.Count - 1, this, SourceGlobals); //-1 because fonts[0] will be merged FFonts.MergeFromPxlFont(SourceGlobals.Fonts); //Formats are added in FXF.Merge FNames = SourceGlobals.FNames; Window1 = SourceGlobals.Window1; CodePage = SourceGlobals.CodePage; Country = SourceGlobals.Country; }
internal TXlsRecordLoader(TOle2File aDataStream, TBiff8XFMap aXFMap, TSST aSST, IFlexCelFontList aFontList, TBorderList aBorderList, TPatternList aPatternList, TEncryptionData aEncryption, TXlsBiffVersion aXlsBiffVersion, TNameRecordList aNames, TVirtualReader VirtualReader) : base(aSST, aFontList, aEncryption, aXlsBiffVersion, aXFMap, aNames, VirtualReader) { DataStream = aDataStream; BorderList = aBorderList; PatternList = aPatternList; }
internal TParsedTokenList ParseRPN(TNameRecordList Names, int aCol, int aRow, byte[] Data, int p, int FLen, bool aRelative3dRanges) { bool HasSubtotal; bool HasAggregate; return(ParseRPN(Names, aCol, aRow, Data, p, FLen, aRelative3dRanges, out HasSubtotal, out HasAggregate, false)); }
private void CheckFutureFunction(TParsedTokenListBuilder TokenBuilder, ref int np, TNameRecordList Names, ref TCellFunctionData fd2, TTokenOffset TokenOffset, ref bool HasAggregate) { //We need to recursively read parameters in back order to find out the name, which is stored as far as possible from the function :( TParsedTokenList ParsedList = TokenBuilder.ToParsedTokenList(); ParsedList.ResetPositionToLast(); for (int i = 0; i < np; i++) //np is +1. But we will move below the name, then inc 1, so we know there isn't a "neutral" token like parent or memarea, intead of the real thing. { ParsedList.Flush(); } ParsedList.MoveBack(); TNameToken bp = ParsedList.ForwardPop() as TNameToken; if (bp is TNameXToken) { return; //This name isn't an internal 2007 name. } if (bp == null) { return; } if (bp.NameIndex <= 0 || bp.NameIndex > Names.Count) { return; } string FunctionName = Names[bp.NameIndex - 1].Name; if (FunctionName.StartsWith("_xlfn.", StringComparison.InvariantCultureIgnoreCase)) { TCellFunctionData fn = TXlsFunction.GetData(FunctionName.Substring("_xlfn.".Length)); if (fn != null) { if (fn.Index == (int)TFutureFunctions.Aggregate) { HasAggregate = true; } fd2 = fn; int tPos = ParsedList.SavePosition(); TokenBuilder.RemoveAt(tPos); TokenOffset.RemoveToken(tPos); np--; } } }
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); }
protected TBinRecordLoader(TSST aSST, IFlexCelFontList aFontList, TEncryptionData aEncryption, TXlsBiffVersion aXlsBiffVersion, TBiff8XFMap aXFMap, TNameRecordList aNames, TVirtualReader aVirtualReader) : base(aSST, aFontList, aEncryption, aXlsBiffVersion, aXFMap, aNames, aVirtualReader) { }
internal TPxlRecordLoader(Stream aDataStream, TExternSheetList aExternSheetList, TEncryptionData aEncryption, TSST aSST, IFlexCelFontList aFontList, TBorderList aBorderList, TPatternList aPatternList, ExcelFile aWorkbook, TBiff8XFMap aXFMap, int aMainBookXFCount, TNameRecordList aNames, TVirtualReader VirtualReader) : base(aSST, aFontList, aEncryption, aWorkbook.XlsBiffVersion, aXFMap, aNames, VirtualReader) { DataStream = aDataStream; FExternSheetList = aExternSheetList; FormatId = 233; FWorkbook = aWorkbook; BorderList = aBorderList; PatternList = aPatternList; DataStreamLength = DataStream.Length; DataStreamPosition = DataStream.Position; //cached for performance. MainBookXFCount = aMainBookXFCount; }