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> /// Add the ExternSheetData extracted from an EXTERNSHEET BIFF Record /// </summary> /// <param name="ext">BIFF Record</param> public void addExternSheetData(ExternSheet ext) { for (int i = 0; i < ext.cXTI; i++) { var extdata = new ExternSheetData(ext.iSUPBOOK[i], ext.itabFirst[i], ext.itabLast[i]); this.externSheetDataList.Add(extdata); } }
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); }
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); }
public WorkbookStream AddExistingLabel(Lbl existingLbl, ushort iTab = 0) { List <Lbl> existingLbls = WbStream.GetAllRecordsByType <Lbl>(); ExternSheet lastExternSheet = WbStream.GetAllRecordsByType <ExternSheet>().LastOrDefault(); existingLbl.itab = iTab; if (existingLbls.Count > 0) { WbStream = WbStream.InsertRecord(existingLbl, existingLbls.Last()); } else { if (lastExternSheet == null) { throw new NotImplementedException("AddExistingLabel assumes an ExternSheet exists"); } WbStream = WbStream.InsertRecord(existingLbl, lastExternSheet); } 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()); //} }
private static Stack <AbstractPtg> UpdateSheetReferences(Stack <AbstractPtg> ptgStack, List <BoundSheet8> sheetRecords, ExternSheet externSheetRecord) { List <AbstractPtg> modifiedStack = new List <AbstractPtg>(); foreach (var ptg in ptgStack) { if (ptg is PtgRef3d) { PtgRef3d ref3d = (ptg as PtgRef3d); int index = ref3d.ixti; XTI relevantXti = externSheetRecord.rgXTI[index]; //Make sure this isn't a sheet or workbook level reference if (relevantXti.itabFirst >= 0) { BoundSheet8 relevantSheet = sheetRecords[relevantXti.itabFirst]; string sheetName = relevantSheet.stName.Value; modifiedStack.Add(new PtgRef3d(ref3d.rw, ref3d.col, ref3d.ixti, ref3d.rwRelative, ref3d.colRelative, sheetName)); } else { modifiedStack.Add(ptg); } } else { modifiedStack.Add(ptg); } } modifiedStack.Reverse(); return(new Stack <AbstractPtg>(modifiedStack)); }