Beispiel #1
0
        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();
        }
Beispiel #2
0
        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();
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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());
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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;
            }
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }