internal TExcelString(TStrLenLength aStrLenLength, ref TxBaseRecord aRecord, ref int Ofs) { StrLenLength = aStrLenLength; byte[] tmpLen = new byte[(byte)StrLenLength]; int StrLen = 0; BitOps.ReadMem(ref aRecord, ref Ofs, tmpLen); if (StrLenLength == TStrLenLength.is8bits) { StrLen = tmpLen[0]; } else { StrLen = BitConverter.ToUInt16(tmpLen, 0); } byte[] of1 = new byte[1]; BitOps.ReadMem(ref aRecord, ref Ofs, of1); OptionFlags = of1[0]; if (HasRichText) { byte [] NumberRichTextFormatsArray = new byte[2]; BitOps.ReadMem(ref aRecord, ref Ofs, NumberRichTextFormatsArray); RichTextFormats = new byte[4 * BitConverter.ToUInt16(NumberRichTextFormatsArray, 0)]; } else { RichTextFormats = null; } if (HasFarInfo) { byte [] FarEastDataSizeArray = new byte[4]; BitOps.ReadMem(ref aRecord, ref Ofs, FarEastDataSizeArray); FarEastData = new byte[BitConverter.ToUInt32(FarEastDataSizeArray, 0)]; } else { FarEastData = null; } StringBuilder s = new StringBuilder(StrLen); StrOps.ReadStr(ref aRecord, ref Ofs, s, OptionFlags, ref OptionFlags, StrLen); Data = s.ToString(); if (RichTextFormats != null) { BitOps.ReadMem(ref aRecord, ref Ofs, RichTextFormats); } if (FarEastData != null) { BitOps.ReadMem(ref aRecord, ref Ofs, FarEastData); } //We have to include all data on the hash. Hash = GetHashString().GetHashCode(); }
internal TExcelString(TStrLenLength aStrLenLength, string s, TRTFRun[] RTFRuns, bool ForceWide) { StrLenLength = aStrLenLength; if (StrLenLength == TStrLenLength.is8bits) { if (s.Length > 0xFF) { XlsMessages.ThrowException(XlsErr.ErrInvalidStringRecord); } } OptionFlags = 0; if (ForceWide || StrOps.IsWide(s)) { OptionFlags = 1; } if ((RTFRuns != null) && (RTFRuns.Length > 0)) { OptionFlags = (byte)(OptionFlags | 8); RichTextFormats = TRTFRun.ToByteArray(RTFRuns); } else { RichTextFormats = null; } FarEastData = null; Data = s; //We have to include all data on the hash. Hash = GetHashString().GetHashCode(); }
internal TNoteRecord(int aId, byte[] aData) : base(aId, BitOps.GetWord(aData, 2)) { OptionFlags = BitConverter.ToUInt16(aData, 4); ObjId = BitConverter.ToUInt16(aData, 6); long aSize = 0; StrOps.GetSimpleString(true, aData, 8, false, 0, ref Author, ref aSize); }
private void WriteLocalFile(IDataStream DataStream, string value, ref int NewPos) { int i = 0; while (i + 3 <= value.Length && value.Substring(i, 3) == ".." + Path.DirectorySeparatorChar) { i += 3; } value = value.Substring(i); bool IsCompressed = !StrOps.IsWide(value); int WideDataLen = 0; byte[] ByteStr = null; if (!IsCompressed) { ByteStr = Encoding.Unicode.GetBytes(value); WideDataLen = 4 + 2 + ByteStr.Length; } NewPos += 2 + 4 + value.Length + 1 + 24 + 4 + WideDataLen; if (DataStream == null) { return; } DataStream.Write16((UInt16)(i / 3)); DataStream.Write32((UInt32)(value.Length + 1)); byte[] NewData = new byte[value.Length + 1]; StrOps.CompressBestUnicode(value, NewData, 0); DataStream.Write(NewData, NewData.Length); DataStream.Write32(0xDEADFFFF); NewData = new byte[20]; DataStream.Write(NewData, NewData.Length); if (IsCompressed) { DataStream.Write32(0); return; } else { DataStream.Write32((UInt32)(4 + 2 + ByteStr.Length)); } DataStream.Write32((UInt32)ByteStr.Length); DataStream.Write16(0x0003); DataStream.Write(ByteStr, ByteStr.Length); }
private string ReadLocalFile(byte[] Data, ref int Pos) { StringBuilder Result = new StringBuilder(); int DirUp = BitOps.GetWord(Data, Pos); for (int i = 0; i < DirUp; i++) { Result.Append(".." + Path.DirectorySeparatorChar); } Pos += 2; int StrLen = (int)BitOps.GetCardinal(Data, Pos); if (StrLen > 1) { StrLen--; } string s8 = StrOps.UnCompressUnicode(Data, Pos + 4, StrLen); Pos += 4 + StrLen + 1 + 24; int RLen = (int)BitOps.GetCardinal(Data, Pos); Pos += 4; if (RLen == 0) { Result.Append(s8); return(Result.ToString()); } int XLen = (int)BitOps.GetCardinal(Data, Pos); Pos += 4 + 2; Result.Append(Encoding.Unicode.GetString(Data, Pos, XLen)); Pos += XLen; return(Result.ToString()); }
private static object GetArrayObject(byte[] RPN, ref int ArrayPos) { byte ValueType = RPN[ArrayPos]; ArrayPos++; switch (ValueType) { case 0x00: ArrayPos += 8; return(null); case 0x01: ArrayPos += 8; return(BitConverter.ToDouble(RPN, ArrayPos - 8)); case 0x02: long sl = 0; string s = null; StrOps.GetSimpleString(true, RPN, ArrayPos, false, 0, ref s, ref sl); ArrayPos += (int)sl; return(s); case 0x04: ArrayPos += 8; return(GetBool(RPN[ArrayPos - 8])); case 0x10: ArrayPos += 8; return(GetError(RPN[ArrayPos - 8])); default: XlsMessages.ThrowException(XlsErr.ErrBadToken, ValueType); break; } //case return(String.Empty); }
internal void CopyToPtr(byte [] pData, int ofs, bool IncludeLen) { if (IncludeLen) { switch (StrLenLength) { case TStrLenLength.is8bits: pData[ofs] = (byte)Data.Length; ofs++; break; case TStrLenLength.is16bits: BitConverter.GetBytes((UInt16)Data.Length).CopyTo(pData, ofs); ofs += 2; break; } } pData[ofs] = OptionFlags; ofs++; if (HasRichText) { BitConverter.GetBytes((UInt16)(RichTextFormats.Length / 4)).CopyTo(pData, ofs); ofs += 2; } if (HasFarInfo) { BitConverter.GetBytes((UInt32)FarEastData.Length).CopyTo(pData, ofs); ofs += 4; } if (Data.Length > 0) { if (CharSize == 1) { if (!StrOps.CompressUnicode(Data, pData, ofs)) { XlsMessages.ThrowException(XlsErr.ErrInvalidStringRecord); } ofs += Data.Length; } else { Encoding.Unicode.GetBytes(Data, 0, Data.Length, pData, ofs); ofs += Data.Length * CharSize; } } if (HasRichText) { RichTextFormats.CopyTo(pData, ofs); ofs += RichTextFormats.Length; } if (HasFarInfo) { FarEastData.CopyTo(pData, ofs); ofs += FarEastData.Length; } }
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); }
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); }