public WorkbookStream InitializeGlobalStreamLabels() { List <BoundSheet8> sheets = WbStream.GetAllRecordsByType <BoundSheet8>(); BiffRecord lastCountryRecord = WbStream.GetAllRecordsByType <Country>().Last(); SupBook supBookRecord = new SupBook(sheets.Count, 0x401); int macroOffset = sheets.TakeWhile(s => s.dt != BoundSheet8.SheetType.Macrosheet).Count(); ExternSheet externSheetRecord = new ExternSheet(1, new List <XTI>() { new XTI(0, macroOffset, macroOffset) }); if (WbStream.GetAllRecordsByType <SupBook>().Count > 0) { WbStream = WbStream.ReplaceRecord(WbStream.GetAllRecordsByType <SupBook>().First(), supBookRecord); } else { WbStream = WbStream.InsertRecord(supBookRecord, lastCountryRecord); } if (WbStream.GetAllRecordsByType <ExternSheet>().Count > 0) { WbStream = WbStream.InsertRecord(externSheetRecord, WbStream.GetAllRecordsByType <ExternSheet>().Last()); } else { WbStream = WbStream.InsertRecord(externSheetRecord, supBookRecord); } return(WbStream); }
/// <summary> /// Ctor /// </summary> /// <param name="supbook">SUPBOOK BIFF Record </param> public SupBookData(SupBook supbook) { this.rgst = supbook.rgst; this.virtPath = supbook.virtpathstring; this.selfref = supbook.isselfreferencing; this.xctDataList = new LinkedList <XCTData>(); this.externNames = new LinkedList <string>(); }
public WorkbookStream AddLabel(string label, Stack <AbstractPtg> rgce, bool isMacroStack = false) { /* * Labels require a reference to an XTI index which is used to say which * BoundSheet8 record maps to the appropriate tab. In order to make this * record we need a SupBook record, and ExternSheet record to specify * which BoundSheet8 record to use. * * Currently this assumes there are no SupBook or ExternSheet records in * use, handling of these cases for complex decoy docs is coming * in the future. * * TODO handle existing SupBook/ExternSheet records when adding Lbl entries */ List <BoundSheet8> sheets = WbStream.GetAllRecordsByType <BoundSheet8>(); List <SupBook> supBooksExisting = WbStream.GetAllRecordsByType <SupBook>(); List <ExternSheet> externSheetsExisting = WbStream.GetAllRecordsByType <ExternSheet>(); ExternSheet lastExternSheet; if (supBooksExisting.Count > 0 || externSheetsExisting.Count > 0) { lastExternSheet = externSheetsExisting.Last(); } else { BiffRecord lastCountryRecord = WbStream.GetAllRecordsByType <Country>().Last(); SupBook supBookRecord = new SupBook(sheets.Count, 0x401); int macroOffset = sheets.TakeWhile(s => s.dt != BoundSheet8.SheetType.Macrosheet).Count(); ExternSheet externSheetRecord = new ExternSheet(1, new List <XTI>() { new XTI(0, macroOffset, macroOffset) }); WbStream = WbStream.InsertRecord(supBookRecord, lastCountryRecord); WbStream = WbStream.InsertRecord(externSheetRecord, supBookRecord); lastExternSheet = externSheetRecord; } Lbl newLbl = new Lbl(label, 0); if (isMacroStack) { newLbl.fProc = true; newLbl.fFunc = true; } newLbl.SetRgce(rgce); WbStream = WbStream.InsertRecord(newLbl, lastExternSheet); WbStream = WbStream.FixBoundSheetOffsets(); return(WbStream); }
/// <summary> /// Add a SUPBOOK BIFF Record to the list /// </summary> /// <param name="sup"></param> public void addSupBookData(SupBook sup) { var supbook = new SupBookData(sup); if (!supbook.SelfRef) { this.refWorkBookNumber++; supbook.Number = this.refWorkBookNumber; } this.supBookDataList.AddLast(supbook); }
public WorkbookStream AddLabel(string label, int rw, int col) { /* * Labels require a reference to an XTI index which is used to say which * BoundSheet8 record maps to the appropriate tab. In order to make this * record we need a SupBook record, and ExternSheet record to specify * which BoundSheet8 record to use. * * Currently this assumes there are no SupBook or ExternSheet records in * use, handling of these cases for complex decoy docs is coming * in the future. * * TODO handle existing SupBook/ExternSheet records when adding Lbl entries */ List <BoundSheet8> sheets = WbStream.GetAllRecordsByType <BoundSheet8>(); List <SupBook> supBooksExisting = WbStream.GetAllRecordsByType <SupBook>(); List <ExternSheet> externSheetsExisting = WbStream.GetAllRecordsByType <ExternSheet>(); if (supBooksExisting.Count > 0 || externSheetsExisting.Count > 0) { throw new NotImplementedException("Use a Decoy Document with no Labels"); } BiffRecord lastCountryRecord = WbStream.GetAllRecordsByType <Country>().Last(); SupBook supBookRecord = new SupBook(sheets.Count, 0x401); int macroOffset = sheets.TakeWhile(s => s.dt != BoundSheet8.SheetType.Macrosheet).Count(); ExternSheet externSheetRecord = new ExternSheet(1, new List <XTI>() { new XTI(0, macroOffset, macroOffset) }); Stack <AbstractPtg> ptgStack = new Stack <AbstractPtg>(); ptgStack.Push(new PtgRef3d(rw, col, 0)); Lbl newLbl = new Lbl(label, 0); newLbl.SetRgce(ptgStack); WbStream = WbStream.InsertRecord(supBookRecord, lastCountryRecord); WbStream = WbStream.InsertRecord(externSheetRecord, supBookRecord); WbStream = WbStream.InsertRecord(newLbl, externSheetRecord); WbStream = WbStream.FixBoundSheetOffsets(); return(WbStream); }
/// <summary> /// Extracts the data from the stream /// </summary> public override void extractData() { BiffHeader bh; //try //{ while (this.StreamReader.BaseStream.Position < this.StreamReader.BaseStream.Length) { bh.id = (RecordType)this.StreamReader.ReadUInt16(); bh.length = this.StreamReader.ReadUInt16(); // Debugging output TraceLogger.DebugInternal("BIFF {0}\t{1}\t", bh.id, bh.length); switch (bh.id) { case RecordType.BoundSheet8: { // Extracts the Boundsheet data BoundSheet8 bs = new BoundSheet8(this.StreamReader, bh.id, bh.length); TraceLogger.DebugInternal(bs.ToString()); SheetData sheetData = null; switch (bs.dt) { case BoundSheet8.SheetType.Worksheet: sheetData = new WorkSheetData(); this.oldOffset = this.StreamReader.BaseStream.Position; this.StreamReader.BaseStream.Seek(bs.lbPlyPos, SeekOrigin.Begin); WorksheetExtractor se = new WorksheetExtractor(this.StreamReader, sheetData as WorkSheetData); this.StreamReader.BaseStream.Seek(oldOffset, SeekOrigin.Begin); break; case BoundSheet8.SheetType.Chartsheet: ChartSheetData chartSheetData = new ChartSheetData(); this.oldOffset = this.StreamReader.BaseStream.Position; this.StreamReader.BaseStream.Seek(bs.lbPlyPos, SeekOrigin.Begin); chartSheetData.ChartSheetSequence = new ChartSheetSequence(this.StreamReader); this.StreamReader.BaseStream.Seek(oldOffset, SeekOrigin.Begin); sheetData = chartSheetData; break; default: TraceLogger.Info("Unsupported sheet type: {0}", bs.dt); break; } if (sheetData != null) { // add general sheet info sheetData.boundsheetRecord = bs; this.workBookData.addBoundSheetData(sheetData); } } break; case RecordType.Template: { this.workBookData.Template = true; } break; case RecordType.SST: { /* reads the shared string table biff record and following continue records * creates an array of bytes and then puts that into a memory stream * this all is used to create a longer biffrecord then 8224 bytes. If theres a string * beginning in the SST that is then longer then the 8224 bytes, it continues in the * CONTINUE BiffRecord, so the parser has to read over the SST border. * The problem here is, that the parser has to overread the continue biff record header */ //SST sst; //UInt16 length = bh.length; //// save the old offset from this record begin //this.oldOffset = this.StreamReader.BaseStream.Position; //// create a list of bytearrays to store the following continue records //// List<byte[]> byteArrayList = new List<byte[]>(); //byte[] buffer = new byte[length]; //LinkedList<VirtualStreamReader> vsrList = new LinkedList<VirtualStreamReader>(); //buffer = this.StreamReader.ReadBytes((int)length); //// byteArrayList.Add(buffer); //// create a new memory stream and a new virtualstreamreader //MemoryStream bufferstream = new MemoryStream(buffer); //VirtualStreamReader binreader = new VirtualStreamReader(bufferstream); //BiffHeader bh2; //bh2.id = (RecordType)this.StreamReader.ReadUInt16(); //while (bh2.id == RecordType.Continue) //{ // bh2.length = (UInt16)(this.StreamReader.ReadUInt16()); // buffer = new byte[bh2.length]; // // create a buffer with the bytes from the records and put that array into the // // list // buffer = this.StreamReader.ReadBytes((int)bh2.length); // // byteArrayList.Add(buffer); // // create for each continue record a new streamreader !! // MemoryStream contbufferstream = new MemoryStream(buffer); // VirtualStreamReader contreader = new VirtualStreamReader(contbufferstream); // vsrList.AddLast(contreader); // // take next Biffrecord ID // bh2.id = (RecordType)this.StreamReader.ReadUInt16(); //} //// set the old position of the stream //this.StreamReader.BaseStream.Position = this.oldOffset; SST sst = new SST(this.StreamReader, bh.id, bh.length); //this.StreamReader.BaseStream.Position = this.oldOffset + bh.length; this.workBookData.SstData = sst; } break; case RecordType.EOF: { // Reads the end of the internal file !!! this.StreamReader.BaseStream.Seek(0, SeekOrigin.End); } break; case RecordType.ExternSheet: { ExternSheet extsheet = new ExternSheet(this.StreamReader, bh.id, bh.length); this.externSheets.Add(extsheet); this.workBookData.addExternSheetData(extsheet); } break; case RecordType.SupBook: { SupBook supbook = new SupBook(this.StreamReader, bh.id, bh.length); this.supBooks.Add(supbook); this.workBookData.addSupBookData(supbook); } break; case RecordType.XCT: { XCT xct = new XCT(this.StreamReader, bh.id, bh.length); this.XCTList.Add(xct); this.workBookData.addXCT(xct); } break; case RecordType.CRN: { CRN crn = new CRN(this.StreamReader, bh.id, bh.length); this.CRNList.Add(crn); this.workBookData.addCRN(crn); } break; case RecordType.ExternName: { ExternName externname = new ExternName(this.StreamReader, bh.id, bh.length); this.workBookData.addEXTERNNAME(externname); } break; case RecordType.Format: { Format format = new Format(this.StreamReader, bh.id, bh.length); this.workBookData.styleData.addFormatValue(format); } break; case RecordType.XF: { XF xf = new XF(this.StreamReader, bh.id, bh.length); this.workBookData.styleData.addXFDataValue(xf); } break; case RecordType.Style: { Style style = new Style(this.StreamReader, bh.id, bh.length); this.workBookData.styleData.addStyleValue(style); } break; case RecordType.Font: { Font font = new Font(this.StreamReader, bh.id, bh.length); this.workBookData.styleData.addFontData(font); } break; case RecordType.NAME: case RecordType.Lbl: { Lbl name = new Lbl(this.StreamReader, bh.id, bh.length); this.workBookData.addDefinedName(name); } break; case RecordType.BOF: { this.workBookData.BOF = new BOF(this.StreamReader, bh.id, bh.length); } break; case RecordType.CodeName: { this.workBookData.CodeName = new CodeName(this.StreamReader, bh.id, bh.length); } break; case RecordType.FilePass: { throw new ExtractorException(ExtractorException.FILEENCRYPTED); } break; case RecordType.Palette: { Palette palette = new Palette(this.StreamReader, bh.id, bh.length); workBookData.styleData.setColorList(palette.rgbColorList); } break; default: { // this else statement is used to read BiffRecords which aren't implemented byte[] buffer = new byte[bh.length]; buffer = this.StreamReader.ReadBytes(bh.length); TraceLogger.Debug("Unknown record found. ID {0}", bh.id); } break; } } //} //catch (Exception ex) //{ // TraceLogger.Error(ex.Message); // TraceLogger.Debug(ex.ToString()); //} }