public void TestReadWrite() { FileInformationBlock fib = _hWPFDocFixture._fib; byte[] tableStream = _hWPFDocFixture._tableStream; int listOffset = fib.GetFcPlcfLst(); int lfoOffset = fib.GetFcPlfLfo(); if (listOffset != 0 && fib.GetLcbPlcfLst() != 0) { ListTables listTables = new ListTables(tableStream, fib.GetFcPlcfLst(), fib.GetFcPlfLfo()); HWPFFileSystem fileSys = new HWPFFileSystem(); HWPFStream tableOut = fileSys.GetStream("1Table"); listTables.WriteListDataTo(tableOut); int offset = tableOut.Offset; listTables.WriteListOverridesTo(tableOut); ListTables newTables = new ListTables(tableOut.ToArray(), 0, offset); Assert.AreEqual(listTables, newTables); } }
public static int Write(HWPFStream tableStream, String[] entries) { byte[] header = new byte[6]; LittleEndian.PutShort(header, 0, unchecked((short)0xffff)); if (entries == null || entries.Length == 0) { LittleEndian.PutInt(header, 2, 0); tableStream.Write(header); return 6; } LittleEndian.PutInt(header, 2, entries.Length); tableStream.Write(header); int size = 6; foreach (String entry in entries) { byte[] buf = new byte[entry.Length * 2 + 2]; LittleEndian.PutShort(buf, 0, (short)entry.Length); StringUtil.PutUnicodeLE(entry, buf, 2); tableStream.Write(buf); size += buf.Length; } return size; }
public void WriteRef(FileInformationBlock fib, HWPFStream tableStream) { if (descriptors == null || descriptors.Length == 0) { fib.SetNotesDescriptorsOffset(noteType, tableStream.Offset); fib.SetNotesDescriptorsSize(noteType, 0); return; } int start = tableStream.Offset; byte[] data = descriptors.ToByteArray(); tableStream.Write(data); int end =tableStream.Offset; fib.SetNotesDescriptorsOffset(noteType, start); fib.SetNotesDescriptorsSize(noteType, end - start); }
public void TestReadWrite() { FileInformationBlock fib = _hWPFDocFixture._fib; byte[] tableStream = _hWPFDocFixture._tableStream; int fcSttbfffn = fib.GetFcSttbfffn(); int lcbSttbfffn = fib.GetLcbSttbfffn(); _fontTable = new FontTable(tableStream, fcSttbfffn, lcbSttbfffn); HWPFFileSystem fileSys = new HWPFFileSystem(); _fontTable.WriteTo(fileSys); HWPFStream tableOut = fileSys.GetStream("1Table"); byte[] newTableStream = tableOut.ToArray(); FontTable newFontTable = new FontTable(newTableStream, 0, newTableStream.Length); Assert.IsTrue(_fontTable.Equals(newFontTable)); }
public void WriteTo(byte[] mainStream, HWPFStream tableStream) { //HWPFOutputStream mainDocument = sys.GetStream("WordDocument"); //HWPFOutputStream tableStream = sys.GetStream("1Table"); base.Serialize(mainStream, 0); int size = base.GetSize(); _shortHandler.Serialize(mainStream); _longHandler.Serialize(mainStream, size + _shortHandler.SizeInBytes()); _fieldHandler.WriteTo(mainStream, base.GetSize() + _shortHandler.SizeInBytes() + _longHandler.SizeInBytes(), tableStream); }
public void WriteTxt(FileInformationBlock fib, HWPFStream tableStream) { if (textPositions == null || textPositions.Length == 0) { fib.SetNotesTextPositionsOffset(noteType, tableStream.Offset); fib.SetNotesTextPositionsSize(noteType, 0); return; } int start = tableStream.Offset; byte[] data = textPositions.ToByteArray(); tableStream.Write(data); int end = tableStream.Offset; fib.SetNotesTextPositionsOffset(noteType, start); fib.SetNotesTextPositionsSize(noteType, end - start); }
private int SavePlex(FileInformationBlock fib, FieldsDocumentPart part, PlexOfCps plexOfCps, HWPFStream outputStream) { if (plexOfCps == null || plexOfCps.Length == 0) { fib.SetFieldsPlcfOffset(part, outputStream.Offset); fib.SetFieldsPlcfLength(part, 0); return 0; } byte[] data = plexOfCps.ToByteArray(); int start = outputStream.Offset; int length = data.Length; outputStream.Write(data); fib.SetFieldsPlcfOffset(part, start); fib.SetFieldsPlcfLength(part, length); return length; }
public void WriteListDataTo(HWPFStream tableStream) { int listSize = _listMap.Count; // use this stream as a buffer for the levels since their size varies. MemoryStream levelBuf = new MemoryStream(); byte[] shortHolder = new byte[2]; LittleEndian.PutShort(shortHolder, (short)listSize); tableStream.Write(shortHolder); //TODO:: sort the keys foreach (int x in _listMap.Keys) { ListData lst = _listMap[x]; tableStream.Write(lst.ToArray()); ListLevel[] lvls = lst.GetLevels(); for (int y = 0; y < lvls.Length; y++) { byte[] bytes = lvls[y].ToArray(); levelBuf.Write(bytes, 0, bytes.Length); } } tableStream.Write(levelBuf.ToArray()); }
internal void WriteTo(byte[] mainStream, int offset, HWPFStream tableStream) { int length = _fields.Length / 2; LittleEndian.PutShort(mainStream, offset, (short)length); offset += LittleEndianConsts.SHORT_SIZE; for (int x = 0; x < length; x++) { UnhandledDataStructure ds = (UnhandledDataStructure)_unknownMap[x]; if (ds != null) { LittleEndian.PutInt(mainStream, offset, tableStream.Offset); offset += LittleEndianConsts.INT_SIZE; byte[] buf = ds.GetBuf(); tableStream.Write(buf); LittleEndian.PutInt(mainStream, offset, buf.Length); offset += LittleEndianConsts.INT_SIZE; } else { LittleEndian.PutInt(mainStream, offset, _fields[x * 2]); offset += LittleEndianConsts.INT_SIZE; LittleEndian.PutInt(mainStream, offset, _fields[(x * 2) + 1]); offset += LittleEndianConsts.INT_SIZE; } } }
/** * Writes this table to the table stream. * * @param tableStream the table stream to write to. * @throws IOException if an error occurs while writing. */ public void WriteTo(HWPFStream tableStream) { byte[] header = new byte[6]; LittleEndian.PutShort(header, 0, unknownValue); LittleEndian.PutInt(header, 2, entries.Length * 2); tableStream.Write(header); for (int i = 0; i < entries.Length; i++) { WriteStringValue(tableStream, entries[i].GetUserName()); WriteStringValue(tableStream, entries[i].GetSaveLocation()); } }
private void WriteStringValue(HWPFStream tableStream, String value) { byte[] buf = new byte[value.Length * 2 + 2]; LittleEndian.PutShort(buf, 0, (short)value.Length); StringUtil.PutUnicodeLE(value, buf, 2); tableStream.Write(buf); }
/** * Writes this table to the table stream. * * @param tableStream the table stream to write to. * @throws IOException if an error occurs while writing. */ public void WriteTo(HWPFStream tableStream) { byte[] header = new byte[6]; LittleEndian.PutShort(header, 0, fExtend); LittleEndian.PutShort(header, 2, cData); LittleEndian.PutShort(header, 4, cbExtra); tableStream.Write(header); foreach (String name in entries) { byte[] buf = new byte[name.Length * 2 + 2]; LittleEndian.PutShort(buf, 0, (short)name.Length); StringUtil.PutUnicodeLE(name, buf, 2); tableStream.Write(buf); } }
public void WriteSttbfBkmk(FileInformationBlock fib, HWPFStream tableStream) { if (names == null || names.Length == 0) { fib.SetFcSttbfbkmk(0); fib.SetLcbSttbfbkmk(0); return; } int start = tableStream.Offset; SttbfUtils.Write(tableStream, names); int end = tableStream.Offset; fib.SetFcSttbfbkmk(start); fib.SetLcbSttbfbkmk(end - start); }
public void WritePlcfBkmkl(FileInformationBlock fib, HWPFStream tableStream) { if (descriptorsLim == null || descriptorsLim.Length == 0) { fib.SetFcPlcfbkl(0); fib.SetLcbPlcfbkl(0); return; } int start = tableStream.Offset; tableStream.Write(descriptorsLim.ToByteArray()); int end = tableStream.Offset; fib.SetFcPlcfbkl(start); fib.SetLcbPlcfbkl(end - start); }
public void WriteListOverridesTo(HWPFStream tableStream) { // use this stream as a buffer for the levels since their size varies. MemoryStream levelBuf = new MemoryStream(); int size = _overrideList.Count; byte[] intHolder = new byte[4]; LittleEndian.PutInt(intHolder, size); tableStream.Write(intHolder); for (int x = 0; x < size; x++) { ListFormatOverride lfo = _overrideList[x]; tableStream.Write(lfo.ToArray()); ListFormatOverrideLevel[] lfolvls = lfo.GetLevelOverrides(); for (int y = 0; y < lfolvls.Length; y++) { byte[] bytes = lfolvls[y].ToArray(); levelBuf.Write(bytes, 0, bytes.Length); } } tableStream.Write(levelBuf.ToArray()); }
/** * Writes out the word file that is represented by an instance of this class. * * @param out The OutputStream to write to. * @throws IOException If there is an unexpected IOException from the passed * in OutputStream. */ public override void Write(Stream out1) { // Initialize our streams for writing. HWPFFileSystem docSys = new HWPFFileSystem(); HWPFStream mainStream = docSys.GetStream("WordDocument"); HWPFStream tableStream = docSys.GetStream("1Table"); //HWPFOutputStream dataStream = docSys.GetStream("Data"); int tableOffset = 0; // FileInformationBlock fib = (FileInformationBlock)_fib.Clone(); // clear the offSets and sizes in our FileInformationBlock. _fib.ClearOffsetsSizes(); // determine the FileInformationBLock size int fibSize = _fib.GetSize(); fibSize += POIFSConstants.SMALLER_BIG_BLOCK_SIZE - (fibSize % POIFSConstants.SMALLER_BIG_BLOCK_SIZE); // preserve space for the FileInformationBlock because we will be writing // it after we write everything else. byte[] placeHolder = new byte[fibSize]; mainStream.Write(placeHolder); int mainOffset = mainStream.Offset; // write out the StyleSheet. _fib.SetFcStshf(tableOffset); _ss.WriteTo(tableStream); _fib.SetLcbStshf(tableStream.Offset - tableOffset); tableOffset = tableStream.Offset; // get fcMin and fcMac because we will be writing the actual text with the // complex table. int fcMin = mainOffset; // write out the Complex table, includes text. _fib.SetFcClx(tableOffset); _cft.WriteTo(mainStream, tableStream); _fib.SetLcbClx(tableStream.Offset - tableOffset); tableOffset = tableStream.Offset; int fcMac = mainStream.Offset; // write out the CHPBinTable. _fib.SetFcPlcfbteChpx(tableOffset); _cbt.WriteTo(docSys, fcMin); _fib.SetLcbPlcfbteChpx(tableStream.Offset - tableOffset); tableOffset = tableStream.Offset; // write out the PAPBinTable. _fib.SetFcPlcfbtePapx(tableOffset); _pbt.WriteTo(mainStream, tableStream, _cft.GetTextPieceTable()); _fib.SetLcbPlcfbtePapx(tableStream.Offset - tableOffset); tableOffset = tableStream.Offset; /* * plcfendRef (endnote reference position table) Written immediately * after the previously recorded table if the document contains endnotes * * plcfendTxt (endnote text position table) Written immediately after * the plcfendRef if the document contains endnotes * * Microsoft Office Word 97-2007 Binary File Format (.doc) * Specification; Page 24 of 210 */ _endnotesTables.WriteRef(_fib, tableStream); _endnotesTables.WriteTxt(_fib, tableStream); tableOffset = tableStream.Offset; /* * plcffndRef (footnote reference position table) Written immediately * after the stsh if the document contains footnotes * * plcffndTxt (footnote text position table) Written immediately after * the plcffndRef if the document contains footnotes * * Microsoft Office Word 97-2007 Binary File Format (.doc) * Specification; Page 24 of 210 */ _footnotesTables.WriteRef(_fib, tableStream); _footnotesTables.WriteTxt(_fib, tableStream); tableOffset = tableStream.Offset; // write out the SectionTable. _fib.SetFcPlcfsed(tableOffset); _st.WriteTo(docSys, fcMin); _fib.SetLcbPlcfsed(tableStream.Offset - tableOffset); tableOffset = tableStream.Offset; // write out the list tables if (_lt != null) { _fib.SetFcPlcfLst(tableOffset); _lt.WriteListDataTo(tableStream); _fib.SetLcbPlcfLst(tableStream.Offset - tableOffset); } /* * plflfo (more list formats) Written immediately after the end of the * plcflst and its accompanying data, if there are any lists defined in * the document. This consists first of a PL of LFO records, followed by * the allocated data (if any) hanging off the LFOs. The allocated data * consists of the array of LFOLVLFs for each LFO (and each LFOLVLF is * immediately followed by some LVLs). * * Microsoft Office Word 97-2007 Binary File Format (.doc) * Specification; Page 26 of 210 */ if (_lt != null) { _fib.SetFcPlfLfo(tableStream.Offset); _lt.WriteListOverridesTo(tableStream); _fib.SetLcbPlfLfo(tableStream.Offset - tableOffset); tableOffset = tableStream.Offset; } /* * sttbfBkmk (table of bookmark name strings) Written immediately after * the previously recorded table, if the document contains bookmarks. * * Microsoft Office Word 97-2007 Binary File Format (.doc) * Specification; Page 27 of 210 */ if (_bookmarksTables != null) { _bookmarksTables.WriteSttbfBkmk(_fib, tableStream); tableOffset = tableStream.Offset; } // write out the saved-by table. if (_sbt != null) { _fib.SetFcSttbSavedBy(tableOffset); _sbt.WriteTo(tableStream); _fib.SetLcbSttbSavedBy(tableStream.Offset - tableOffset); tableOffset = tableStream.Offset; } // write out the revision mark authors table. if (_rmat != null) { _fib.SetFcSttbfRMark(tableOffset); _rmat.WriteTo(tableStream); _fib.SetLcbSttbfRMark(tableStream.Offset - tableOffset); tableOffset = tableStream.Offset; } // write out the FontTable. _fib.SetFcSttbfffn(tableOffset); _ft.WriteTo(docSys); _fib.SetLcbSttbfffn(tableStream.Offset - tableOffset); tableOffset = tableStream.Offset; // write out the DocumentProperties. _fib.SetFcDop(tableOffset); byte[] buf = new byte[_dop.GetSize()]; _fib.SetLcbDop(_dop.GetSize()); _dop.Serialize(buf, 0); tableStream.Write(buf); // set some variables in the FileInformationBlock. _fib.SetFcMin(fcMin); _fib.SetFcMac(fcMac); _fib.SetCbMac(mainStream.Offset); // make sure that the table, doc and data streams use big blocks. byte[] mainBuf = mainStream.ToArray(); if (mainBuf.Length < 4096) { byte[] tempBuf = new byte[4096]; Array.Copy(mainBuf, 0, tempBuf, 0, mainBuf.Length); mainBuf = tempBuf; } // write out the FileInformationBlock. //_fib.Serialize(mainBuf, 0); _fib.WriteTo(mainBuf, tableStream); byte[] tableBuf = tableStream.ToArray(); if (tableBuf.Length < 4096) { byte[] tempBuf = new byte[4096]; Array.Copy(tableBuf, 0, tempBuf, 0, tableBuf.Length); tableBuf = tempBuf; } byte[] dataBuf = _dataStream; if (dataBuf == null) { dataBuf = new byte[4096]; } if (dataBuf.Length < 4096) { byte[] tempBuf = new byte[4096]; Array.Copy(dataBuf, 0, tempBuf, 0, dataBuf.Length); dataBuf = tempBuf; } // spit out the Word document. POIFSFileSystem pfs = new POIFSFileSystem(); pfs.CreateDocument(new MemoryStream(mainBuf), "WordDocument"); pfs.CreateDocument(new MemoryStream(tableBuf), "1Table"); pfs.CreateDocument(new MemoryStream(dataBuf), "Data"); WriteProperties(pfs); pfs.WriteFileSystem(out1); }
public void WriteTo(HWPFStream wordDocumentStream,HWPFStream tableStream) { tableStream.Write(TEXT_PIECE_TABLE_TYPE); byte[] table = _tpt.WriteTo(wordDocumentStream); byte[] numHolder = new byte[LittleEndianConsts.INT_SIZE]; LittleEndian.PutInt(numHolder, table.Length); tableStream.Write(numHolder); tableStream.Write(table); }
public void WriteTo(HWPFStream out1) { int offset = 0; // add two bytes so we can prepend the stylesheet w/ its size byte[] buf = new byte[_stshiLength + 2]; LittleEndian.PutShort(buf, offset, (short)_stshiLength); offset += LittleEndianConsts.SHORT_SIZE; LittleEndian.PutShort(buf, offset, (short)_styleDescriptions.Length); offset += LittleEndianConsts.SHORT_SIZE; LittleEndian.PutShort(buf, offset, (short)_baseLength); offset += LittleEndianConsts.SHORT_SIZE; LittleEndian.PutShort(buf, offset, (short)_flags); offset += LittleEndianConsts.SHORT_SIZE; LittleEndian.PutShort(buf, offset, (short)_maxIndex); offset += LittleEndianConsts.SHORT_SIZE; LittleEndian.PutShort(buf, offset, (short)_maxFixedIndex); offset += LittleEndianConsts.SHORT_SIZE; LittleEndian.PutShort(buf, offset, (short)_stylenameVersion); offset += LittleEndianConsts.SHORT_SIZE; LittleEndian.PutShort(buf, offset, (short)_rgftc[0]); offset += LittleEndianConsts.SHORT_SIZE; LittleEndian.PutShort(buf, offset, (short)_rgftc[1]); offset += LittleEndianConsts.SHORT_SIZE; LittleEndian.PutShort(buf, offset, (short)_rgftc[2]); out1.Write(buf); byte[] sizeHolder = new byte[2]; for (int x = 0; x < _styleDescriptions.Length; x++) { if (_styleDescriptions[x] != null) { byte[] std = _styleDescriptions[x].ToArray(); // adjust the size so it is always on a word boundary LittleEndian.PutShort(sizeHolder, (short)((std.Length) + (std.Length % 2))); out1.Write(sizeHolder); out1.Write(std); // Must always start on a word boundary. if (std.Length % 2 == 1) { out1.Write('\0'); } } else { sizeHolder[0] = 0; sizeHolder[1] = 0; out1.Write(sizeHolder); } } }
public void Write(FileInformationBlock fib, HWPFStream tableStream) { Array values = Enum.GetValues(typeof(FieldsDocumentPart)); foreach (FieldsDocumentPart part in values) { PlexOfCps plexOfCps = _tables[part]; SavePlex(fib, part, plexOfCps, tableStream); } }
/** * Creates a byte array representation of this data structure. Suitable for * writing to a Word document. * * @param fcMin The file offset in the main stream where text begins. * @return A byte array representing this data structure. */ internal byte[] ToByteArray(HWPFStream dataStream, CharIndexTranslator translator) { byte[] buf = new byte[512]; int size = _papxList.Count; int grpprlOffset = 0; int bxOffset = 0; int fcOffset = 0; byte[] lastGrpprl = new byte[0]; // total size is currently the size of one FC int totalSize = FC_SIZE; int index = 0; for (; index < size; index++) { byte[] grpprl = ((PAPX)_papxList[index]).GetGrpprl(); int grpprlLength = grpprl.Length; // is grpprl huge? if (grpprlLength > 488) { grpprlLength = 8; // set equal to size of sprmPHugePapx grpprl } // check to see if we have enough room for an FC, a BX, and the grpprl // and the 1 byte size of the grpprl. int addition = 0; if (!Arrays.Equals(grpprl, lastGrpprl)) { addition = (FC_SIZE + BX_SIZE + grpprlLength + 1); } else { addition = (FC_SIZE + BX_SIZE); } totalSize += addition; // if size is uneven we will have to add one so the first grpprl falls // on a word boundary if (totalSize > 511 + (index % 2)) { totalSize -= addition; break; } // grpprls must fall on word boundaries if (grpprlLength % 2 > 0) { totalSize += 1; } else { totalSize += 2; } lastGrpprl = grpprl; } // see if we couldn't fit some if (index != size) { _overFlow = new List<PAPX>(); _overFlow.AddRange(_papxList.GetRange(index, size-index)); } // index should equal number of papxs that will be in this fkp now. buf[511] = (byte)index; bxOffset = (FC_SIZE * index) + FC_SIZE; grpprlOffset = 511; PAPX papx = null; lastGrpprl = new byte[0]; for (int x = 0; x < index; x++) { papx = _papxList[x]; byte[] phe = papx.GetParagraphHeight().ToArray(); byte[] grpprl = papx.GetGrpprl(); // is grpprl huge? if (grpprl.Length > 488) { /* // if so do we have storage at GetHugeGrpprloffset() int hugeGrpprlOffset = papx.GetHugeGrpprlOffset(); if (hugeGrpprlOffset == -1) // then we have no storage... { throw new InvalidOperationException( "This Paragraph has no dataStream storage."); } // we have some storage... // get the size of the existing storage int maxHugeGrpprlSize = LittleEndian.GetUShort(_dataStream, hugeGrpprlOffset); if (maxHugeGrpprlSize < grpprl.Length - 2) { // grpprl.Length-2 because we don't store the istd throw new InvalidOperationException( "This Paragraph's dataStream storage is too small."); } // store grpprl at hugeGrpprlOffset Array.Copy(grpprl, 2, _dataStream, hugeGrpprlOffset + 2, grpprl.Length - 2); // grpprl.Length-2 because we don't store the istd LittleEndian.PutUShort(_dataStream, hugeGrpprlOffset, grpprl.Length - 2); */ byte[] hugePapx = new byte[grpprl.Length - 2]; System.Array.Copy(grpprl, 2, hugePapx, 0, grpprl.Length - 2); int dataStreamOffset = dataStream.Offset; dataStream.Write(hugePapx); // grpprl = grpprl Containing only a sprmPHugePapx2 int istd = LittleEndian.GetUShort(grpprl, 0); grpprl = new byte[8]; LittleEndian.PutUShort(grpprl, 0, istd); LittleEndian.PutUShort(grpprl, 2, 0x6646); // sprmPHugePapx2 LittleEndian.PutInt(grpprl, 4, dataStreamOffset); } bool same = Arrays.Equals(lastGrpprl, grpprl); if (!same) { grpprlOffset -= (grpprl.Length + (2 - grpprl.Length % 2)); grpprlOffset -= (grpprlOffset % 2); } LittleEndian.PutInt(buf, fcOffset, translator.GetByteIndex(papx.Start)); buf[bxOffset] = (byte)(grpprlOffset / 2); Array.Copy(phe, 0, buf, bxOffset + 1, phe.Length); // refer to the section on PAPX in the spec. Places a size on the front // of the PAPX. Has to do with how the grpprl stays on word // boundaries. if (!same) { int copyOffset = grpprlOffset; if ((grpprl.Length % 2) > 0) { buf[copyOffset++] = (byte)((grpprl.Length + 1) / 2); } else { buf[++copyOffset] = (byte)((grpprl.Length) / 2); copyOffset++; } Array.Copy(grpprl, 0, buf, copyOffset, grpprl.Length); lastGrpprl = grpprl; } bxOffset += BX_SIZE; fcOffset += FC_SIZE; } LittleEndian.PutInt(buf, fcOffset, translator.GetByteIndex(papx.End)); return buf; }