예제 #1
0
        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.
            }
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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);
        }
예제 #4
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);
        }