/** * Constructor used to read a binTable in from a Word document. */ public CHPBinTable(byte[] documentStream, byte[] tableStream, int offset, int size, CharIndexTranslator translator) { PlexOfCps binTable = new PlexOfCps(tableStream, offset, size, 4); int length = binTable.Length; for (int x = 0; x < length; x++) { GenericPropertyNode node = binTable.GetProperty(x); int pageNum = LittleEndian.GetInt(node.Bytes); int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE * pageNum; CHPFormattedDiskPage cfkp = new CHPFormattedDiskPage(documentStream, pageOffset, translator); int fkpSize = cfkp.Size(); for (int y = 0; y < fkpSize; y++) { CHPX chpx = cfkp.GetCHPX(y); if (chpx != null) { _textRuns.Add(chpx); } } } }
public PAPBinTable(byte[] documentStream, byte[] tableStream, byte[] dataStream, int offset, int size, CharIndexTranslator charIndexTranslator) { PlexOfCps binTable = new PlexOfCps(tableStream, offset, size, 4); int length = binTable.Length; for (int x = 0; x < length; x++) { GenericPropertyNode node = binTable.GetProperty(x); int pageNum = LittleEndian.GetInt(node.Bytes); int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE * pageNum; PAPFormattedDiskPage pfkp = new PAPFormattedDiskPage(documentStream, dataStream, pageOffset, charIndexTranslator); int fkpSize = pfkp.Size(); for (int y = 0; y < fkpSize; y++) { PAPX papx = pfkp.GetPAPX(y); _paragraphs.Add(papx); } } _dataStream = dataStream; }
public void WriteTo(HWPFFileSystem sys, CharIndexTranslator translator) { HWPFStream wordDocumentStream = sys.GetStream("WordDocument"); HWPFStream tableStream = sys.GetStream("1Table"); WriteTo(wordDocumentStream, tableStream, translator); }
public PAPX(int fcStart, int fcEnd, CharIndexTranslator translator, byte[] papx, ParagraphHeight phe, byte[] dataStream) : base(fcStart, fcEnd, translator, new SprmBuffer(papx,2)) { _phe = phe; SprmBuffer buf = FindHuge(new SprmBuffer(papx,2), dataStream); if (buf != null) _buf = buf; }
public PAPX(int fcStart, int fcEnd, CharIndexTranslator translator, SprmBuffer buf, byte[] dataStream) : base(fcStart, fcEnd, translator, buf) { _phe = new ParagraphHeight(); buf = FindHuge(buf, dataStream); if (buf != null) _buf = buf; }
public PAPX(int fcStart, int fcEnd, CharIndexTranslator translator, SprmBuffer buf, byte[] dataStream) : base(fcStart, fcEnd, translator, buf) { _phe = new ParagraphHeight(); buf = FindHuge(buf, dataStream); if (buf != null) { _buf = buf; } }
public PAPX(int fcStart, int fcEnd, CharIndexTranslator translator, byte[] papx, ParagraphHeight phe, byte[] dataStream) : base(fcStart, fcEnd, translator, new SprmBuffer(papx, 2)) { _phe = phe; SprmBuffer buf = FindHuge(new SprmBuffer(papx, 2), dataStream); if (buf != null) { _buf = buf; } }
/** * @param fcStart The start of the text for this property, in _bytes_ * @param fcEnd The end of the text for this property, in _bytes_ */ public BytePropertyNode(int fcStart, int fcEnd, CharIndexTranslator translator, object buf) : base( translator.GetCharIndex(fcStart), translator.GetCharIndex(fcEnd, translator.GetCharIndex(fcStart)), buf) { if (fcStart > fcEnd) throw new ArgumentException("fcStart (" + fcStart + ") > fcEnd (" + fcEnd + ")"); this.startBytes = fcStart; this.endBytes = fcEnd; }
public void WriteTo(HWPFStream docStream, HWPFStream tableStream, CharIndexTranslator translator) { PlexOfCps binTable = new PlexOfCps(4); // each FKP must start on a 512 byte page. int docOffset = docStream.Offset; int mod = docOffset % POIFSConstants.SMALLER_BIG_BLOCK_SIZE; if (mod != 0) { byte[] pAdding = new byte[POIFSConstants.SMALLER_BIG_BLOCK_SIZE - mod]; docStream.Write(pAdding); } // get the page number for the first fkp docOffset = docStream.Offset; int pageNum = docOffset / POIFSConstants.SMALLER_BIG_BLOCK_SIZE; // get the ending fc int endingFc = ((PropertyNode)_paragraphs[_paragraphs.Count - 1]).End; List <PAPX> overflow = _paragraphs; do { PropertyNode startingProp = (PropertyNode)overflow[0]; int start = translator.GetByteIndex(startingProp.Start); PAPFormattedDiskPage pfkp = new PAPFormattedDiskPage(_dataStream); pfkp.Fill(overflow); byte[] bufFkp = pfkp.ToByteArray(tableStream, translator); docStream.Write(bufFkp); overflow = pfkp.GetOverflow(); int end = endingFc; if (overflow != null) { end = translator.GetByteIndex(overflow[0].Start); } byte[] intHolder = new byte[4]; LittleEndian.PutInt(intHolder, pageNum++); binTable.AddProperty(new GenericPropertyNode(start, end, intHolder)); }while (overflow != null); byte[] bytes = binTable.ToByteArray(); tableStream.Write(bytes, 0, bytes.Length); }
/** * @param fcStart The start of the text for this property, in _bytes_ * @param fcEnd The end of the text for this property, in _bytes_ */ public BytePropertyNode(int fcStart, int fcEnd, CharIndexTranslator translator, object buf) : base( translator.GetCharIndex(fcStart), translator.GetCharIndex(fcEnd, translator.GetCharIndex(fcStart)), buf) { if (fcStart > fcEnd) { throw new ArgumentException("fcStart (" + fcStart + ") > fcEnd (" + fcEnd + ")"); } this.startBytes = fcStart; this.endBytes = fcEnd; }
/** * This constructs a CHPFormattedDiskPage from a raw fkp (512 byte array * read from a Word file). */ public CHPFormattedDiskPage(byte[] documentStream, int offset, CharIndexTranslator translator) : base(documentStream, offset) { for (int x = 0; x < _crun; x++) { int bytesStartAt = GetStart(x); int bytesEndAt = GetEnd(x); int charStartAt = translator.GetCharIndex(bytesStartAt); int charEndAt = translator.GetCharIndex(bytesEndAt, charStartAt); CHPX chpx = new CHPX(charStartAt, charEndAt, new SprmBuffer( GetGrpprl(x), 0)); _chpxList.Add(chpx); } }
/** * Creates a PAPFormattedDiskPage from a 512 byte array */ public PAPFormattedDiskPage(byte[] documentStream, byte[] dataStream, int offset, CharIndexTranslator translator) : base(documentStream, offset) { for (int x = 0; x < _crun; x++) { int bytesStartAt = GetStart(x); int bytesEndAt = GetEnd(x); int charStartAt = translator.GetCharIndex(bytesStartAt); int charEndAt = translator.GetCharIndex(bytesEndAt, charStartAt); PAPX papx = new PAPX(charStartAt, charEndAt, GetGrpprl(x), GetParagraphHeight(x), dataStream); _papxList.Add(papx); } _fkp = null; }
/** * Creates a PAPFormattedDiskPage from a 512 byte array */ public PAPFormattedDiskPage(byte[] documentStream, byte[] dataStream, int offset, CharIndexTranslator translator) :base(documentStream, offset) { for (int x = 0; x < _crun; x++) { int bytesStartAt = GetStart(x); int bytesEndAt = GetEnd(x); int charStartAt = translator.GetCharIndex(bytesStartAt); int charEndAt = translator.GetCharIndex(bytesEndAt, charStartAt); PAPX papx = new PAPX(charStartAt, charEndAt, GetGrpprl(x), GetParagraphHeight(x), dataStream); _papxList.Add(papx); } _fkp = null; }
/** * 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; }
/** * 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); }
public CHPX(int fcStart, int fcEnd, CharIndexTranslator translator, SprmBuffer buf) : base(fcStart, translator.LookIndexBackward(fcEnd), translator, buf) { }
public CHPX(int fcStart, int fcEnd, CharIndexTranslator translator, byte[] grpprl) : base(fcStart, translator.LookIndexBackward(fcEnd), translator, new SprmBuffer(grpprl)) { }