internal static int GetLength(pxl Record, TPxlVersion PxlVersion) { switch (Record) { case pxl.BLANK: return(5); case pxl.BOF: return(4); case pxl.BOOLERR: return(7); case pxl.BOUNDSHEET: return(2); // Variable case pxl.COLINFO: if (PxlVersion == TPxlVersion.v20) { return(9); } else { return(6); } case pxl.DEFAULTROWHEIGHT: return(4); case pxl.DEFCOLWIDTH: return(6); case pxl.EOF: return(0); case pxl.FILEPASS: return(14); case pxl.FONT: return(15); // Variable; case pxl.xFORMAT: return(1); // Variable; case pxl.FORMULA: return(16); // Variable; case pxl.LABEL: return(7); // Variable; case pxl.NAME: if (PxlVersion == TPxlVersion.v20) { return(7); } else { return(5); // Variable } case pxl.NUMBER: return(13); case pxl.PANE: return(9); case pxl.ROW: return(8); case pxl.SELECTION: return(9); case pxl.STRING: if (PxlVersion == TPxlVersion.v20) { return(2); } else { return(2); // Variable } case pxl.WINDOW1: return(4); case pxl.WINDOW2: if (PxlVersion == TPxlVersion.v20) { return(5); } else { return(3); } case pxl.XF: return(22); case pxl.CODEPAGE: return(2); case pxl.COUNTRY: return(4); default: XlsMessages.ThrowException(XlsErr.ErrPxlIsInvalidToken, (int)Record); return(-1); //just to keep compiler happy. } }
internal void LoadBiff7(byte[] Data, int Pos, TExternSheetList ExternSheetList, TPxlVersion PxlVersion) { TFormulaErrorValue Err = Load(Data, Pos, TFmlaConvert.Biff7To8, PxlVersion, ExternSheetList, null); //No references to load Biff7 if (Err != null) { XlsMessages.ThrowException(XlsErr.ErrBadToken, Err.Token); } }
internal override TBaseRecord LoadRecord(out int rRow, bool InGlobalSection) { int Id = RecordHeader.Id; byte[] Data = new byte[RecordHeader.Size]; if (BofData != null) { Array.Copy(BofData, 1, Data, 0, Data.Length); BofData = null; } else { ShRead(DataStream, Data, 0, Data.Length); } TBaseRecord R = null; if (Encryption.Engine != null && Id != (int)pxl.BOF) { Data = Encryption.Engine.Decode(Data, DataStream.Position - Data.Length, 0, Data.Length, Data.Length); //Note that we do not care about BoundSheet, as it's data won't be used. } if (Data.Length > 2) { rRow = BitConverter.ToUInt16(Data, 0); } else { rRow = 0; } switch (Id) { case (int)xlr.BOF: R = new TBOFRecord((int)xlr.BOF, GetBofData(Data)); if (PxlVersion == TPxlVersion.Undefined) { switch (BitOps.GetWord(Data, 0)) { case 0x0009: PxlVersion = TPxlVersion.v10; break; case 0x010F: PxlVersion = TPxlVersion.v20; break; case 0x010E: PxlVersion = TPxlVersion.v20; break; default: XlsMessages.ThrowException(XlsErr.ErrPxlIsInvalid); break; } } break; case (int)xlr.EOF: R = new TEOFRecord((int)xlr.EOF, GetEofData(Data)); break; case (int)xlr.FORMULA: R = TFormulaRecord.CreateFromBiff8(Names, (int)xlr.FORMULA, GetFormulaData(Data), null); break; case (int)xlr.BOUNDSHEET: R = new TBoundSheetRecord(0, GetBoundSheetName(Data)); break; case (int)xlr.BLANK: R = new TBlankRecord(Data[2], GetXFAt3(Data)); break; case (int)xlr.BOOLERR: R = new TBoolErrRecord(Data[2], GetXFAt3(Data), Data[5], Data[6]); break; case (int)xlr.NUMBER: R = new TNumberRecord(Data[2], GetXFAt3(Data), BitConverter.ToDouble(Data, 5)); break; case (int)xlr.STRING: if (PxlVersion == TPxlVersion.v10) { R = new TStringRecord(ReadString(Data[0])); } else { R = new TStringRecord(ReadString(BitOps.GetWord(Data, 0))); //Wrong Docs! } break; //String record saves the result of a formula case (int)xlr.XF: R = new TXFRecord((int)xlr.XF, GetXFData(Data), BorderList, PatternList, null); XFCount++; break; case (int)xlr.FONT: R = new TFontRecord((int)xlr.FONT, GetFontData(Data)); break; case (int)xlr.xFORMAT: R = new TFormatRecord(ReadString(Data[0]), FormatId); FormatId++; break; case (int)xlr.LABEL: TLabelSSTRecord SSR = new TLabelSSTRecord(Data[2], GetXFAt3(Data), SST, FontList, ReadString(BitOps.GetWord(Data, 5))); R = SSR; break; case (int)xlr.ROW: R = new TRowRecord((int)xlr.ROW, GetRowData(Data), null); break; case (int)xlr.NAME: R = TNameRecord.CreateFromBiff8(Names, (int)xlr.NAME, GetNameData(Data)); break; case (int)xlr.WINDOW1: R = new TWindow1Record((int)xlr.WINDOW1, GetWindow1Data(Data)); break; case (int)xlr.WINDOW2: R = new TWindow2Record((int)xlr.WINDOW2, GetWindow2Data(Data)); break; case (int)xlr.PANE: R = new TPaneRecord((int)xlr.PANE, GetPaneData(Data)); break; case (int)xlr.SELECTION: R = new TBiff8SelectionRecord((int)xlr.SELECTION, GetSelectionData(Data)); break; case (int)xlr.COLINFO: R = new TColInfoRecord((int)xlr.COLINFO, GetColInfoData(Data), null); break; case (int)xlr.DEFAULTROWHEIGHT: R = new TDefaultRowHeightRecord((int)xlr.DEFAULTROWHEIGHT, GetDefRowHeightData(Data)); break; case (int)xlr.DEFCOLWIDTH: R = new TDefColWidthRecord((int)xlr.DEFCOLWIDTH, GetDefColWidthData(Data)); break; case (int)xlr.FILEPASS: XlsMessages.ThrowException(XlsErr.ErrFileIsPasswordProtected); break; /* * TFilePassRecord Fr = new TFilePassRecord(Id, Data, true); * if (Encryption.OnPassword!=null) * { * OnPasswordEventArgs ea= new OnPasswordEventArgs(Encryption.Xls); * Encryption.OnPassword(ea); * Encryption.ReadPassword=ea.Password; * } * Encryption.Engine=Fr.CreateEncryptionEngine(Encryption.ReadPassword); R=null;break; */ case (int)xlr.CODEPAGE: R = new TCodePageRecord(Id, Data); break; case (int)xlr.COUNTRY: R = new TCountryRecord(Id, Data); break; default: XlsMessages.ThrowException(XlsErr.ErrPxlIsInvalid); break; } //case //Peek at the next record... if (!Eof) { ReadHeader(); int Id2 = RecordHeader.Id; switch (Id2) { case (int)xlr.STRING: if (!(R is TFormulaRecord) & !(R is TBiff8ShrFmlaRecord) & !(R is TArrayRecord) & !(R is TTableRecord)) { XlsMessages.ThrowException(XlsErr.ErrExcelInvalid); } break; } } else { //Array.Clear(RecordHeader.Data,0,RecordHeader.Length); RecordHeader.Id = (int)xlr.EOF; //Return EOFs, so in case of bad formed files we don't get on an infinite loop. RecordHeader.Size = 0; } return(R); }
private TFormulaErrorValue Load(byte[] Data, int Pos, TFmlaConvert ConvertType, TPxlVersion PxlVersion, TExternSheetList ExternSheetList, TReferences References) { int tPos = Pos; int bPos = Pos; int fPos = Data.Length; while (tPos < fPos) { byte Token = Data[tPos]; if (Token >= 0x3 && Token <= 0x16) { tPos++; //XlsTokens.IsUnaryOp(Token)||XlsTokens.IsBinaryOp(Token) || Token==XlsTokens.tk_MissArg ; } else if (XlsTokens.Is_tk_Operand(Token)) { tPos++; Flush(Data, ref bPos, tPos); if (ConvertType == TFmlaConvert.Biff7To8) { ParsedTokens.Add(ConvertToBiff8(ExternSheetList, Token, Data, ref tPos)); } else { byte[] ConvertedData = ConvertToBiff7(References, Token, Data, ref tPos); if (ConvertedData == null) { return(new TFormulaErrorValue(Token)); } ParsedTokens.Add(ConvertedData); } bPos = tPos; } else { switch (Token) { case XlsTokens.tk_Str: if (PxlVersion == TPxlVersion.v10) { tPos++; Flush(Data, ref bPos, tPos); byte[] StrValue = new byte[Data[tPos] + 2]; StrValue[0] = Data[tPos]; //String len. StrValue[1] = 0; //Not wide string. Array.Copy(Data, tPos + 1, StrValue, 2, StrValue.Length - 2); ParsedTokens.Add(StrValue); tPos += Data[tPos] + 1; bPos = tPos; } else { tPos += 1 + (int)StrOps.GetStrLen(false, Data, tPos + 1, false, 0); } break; case XlsTokens.tk_Err: case XlsTokens.tk_Bool: tPos += 1 + 1; break; case XlsTokens.tk_Int: case 0x21: //XlsTokens.Is_tk_Func(Token): case 0x41: case 0x61: tPos += 1 + 2; break; case 0x22: //XlsTokens.Is_tk_FuncVar(Token): case 0x42: case 0x62: tPos += 1 + 3; break; case XlsTokens.tk_Num: tPos += 1 + 8; break; case XlsTokens.tk_Attr: bool IgnoreAttr = false; if ((Data[tPos + 1] & (0x2 | 0x4 | 0x8)) != 0) //optimized if, goto, optimized chose. { Flush(Data, ref bPos, tPos); IgnoreAttr = true; } if ((Data[tPos + 1] & 0x04) == 0x04) { tPos += (BitOps.GetWord(Data, tPos + 2) + 1) * 2; } tPos += 1 + 3; if (IgnoreAttr) { bPos = tPos; //ignore the attribute, as it contains offsets to the formula that will change. } break; case XlsTokens.tk_Table: return(new TFormulaErrorValue(Token)); case XlsTokens.tk_MemFunc: case XlsTokens.tk_MemFunc + 0x20: case XlsTokens.tk_MemFunc + 0x40: tPos += 1 + 2; //+ GetWord(Data, tPos+1); break; case XlsTokens.tk_MemArea: case XlsTokens.tk_MemArea + 0x20: case XlsTokens.tk_MemArea + 0x40: case XlsTokens.tk_MemErr: case XlsTokens.tk_MemErr + 0x20: case XlsTokens.tk_MemErr + 0x40: case XlsTokens.tk_MemNoMem: case XlsTokens.tk_MemNoMem + 0x20: case XlsTokens.tk_MemNoMem + 0x40: tPos += 1 + 6; //+ GetWord(Data, tPos+1); break; default: return(new TFormulaErrorValue(Token)); } } }//while Flush(Data, ref bPos, tPos); return(null); }