예제 #1
0
파일: PAPBinTable.cs 프로젝트: zzy092/npoi
        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;
        }
예제 #2
0
        public OldPAPBinTable(byte[] documentStream, int OffSet,
                              int size, int fcMin, TextPieceTable tpt)
        {
            PlexOfCps binTable = new PlexOfCps(documentStream, OffSet, size, 2);

            int length = binTable.Length;

            for (int x = 0; x < length; x++)
            {
                GenericPropertyNode node = binTable.GetProperty(x);

                int pageNum    = LittleEndian.GetShort(node.Bytes);
                int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE * pageNum;

                PAPFormattedDiskPage pfkp = new PAPFormattedDiskPage(documentStream,
                                                                     documentStream, pageOffset, tpt);

                int fkpSize = pfkp.Size();

                for (int y = 0; y < fkpSize; y++)
                {
                    PAPX papx = pfkp.GetPAPX(y);
                    _paragraphs.Add(papx);
                }
            }
            _paragraphs.Sort((IComparer <PAPX>)PropertyNode.PAPXComparator.instance);
        }
예제 #3
0
파일: PAPBinTable.cs 프로젝트: zzy092/npoi
        public void AdjustForInsert(int listIndex, int Length)
        {
            int  size = _paragraphs.Count;
            PAPX papx = (PAPX)_paragraphs[listIndex];

            papx.End = (papx.End + Length);

            for (int x = listIndex + 1; x < size; x++)
            {
                papx       = (PAPX)_paragraphs[x];
                papx.Start = (papx.Start + Length);
                papx.End   = (papx.End + Length);
            }
        }
예제 #4
0
파일: ListEntry.cs 프로젝트: ctddjyds/npoi
        internal ListEntry(PAPX papx, Range parent, ListTables tables)
            : base(papx, parent)
        {

            if (tables != null)
            {
                ListFormatOverride override1 = tables.GetOverride(_props.GetIlfo());
                _overrideLevel = override1.GetOverrideLevel(_props.GetIlvl());
                _level = tables.GetLevel(override1.GetLsid(), _props.GetIlvl());
            }
            else
            {
                //log.log(POILogger.WARN, "No ListTables found for ListEntry - document probably partly corrupt, and you may experience problems");
            }
        }
예제 #5
0
        /**
         * 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;
        }
예제 #6
0
        /**
 * 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;
        }
예제 #7
0
파일: PAPBinTable.cs 프로젝트: zzy092/npoi
        public void Insert(int listIndex, int cpStart, SprmBuffer buf)
        {
            PAPX forInsert = new PAPX(0, 0, buf);

            // Ensure character OffSets are really characters
            forInsert.Start = cpStart;
            forInsert.End   = cpStart;

            if (listIndex == _paragraphs.Count)
            {
                _paragraphs.Add(forInsert);
            }
            else
            {
                PAPX currentPap = _paragraphs[listIndex];
                if (currentPap != null && currentPap.Start < cpStart)
                {
                    SprmBuffer ClonedBuf = null;
                    ClonedBuf = (SprmBuffer)currentPap.GetSprmBuf().Clone();


                    // Copy the properties of the one before to afterwards
                    // Will go:
                    //  Original, until insert at point
                    //  New one
                    //  Clone of original, on to the old end
                    PAPX clone = new PAPX(0, 0, ClonedBuf);
                    // Again ensure Contains character based OffSets no matter what
                    clone.Start = (cpStart);
                    clone.End   = (currentPap.End);

                    currentPap.End = cpStart;

                    _paragraphs.Insert(listIndex + 1, forInsert);
                    _paragraphs.Insert(listIndex + 2, clone);
                }
                else
                {
                    _paragraphs.Insert(listIndex, forInsert);
                }
            }
        }
예제 #8
0
파일: PAPBinTable.cs 프로젝트: zzy092/npoi
        public void AdjustForDelete(int listIndex, int offset, int Length)
        {
            int size     = _paragraphs.Count;
            int endMark  = offset + Length;
            int endIndex = listIndex;

            PAPX papx = _paragraphs[endIndex];

            while (papx.End < endMark)
            {
                papx = _paragraphs[++endIndex];
            }
            if (listIndex == endIndex)
            {
                papx     = _paragraphs[endIndex];
                papx.End = ((papx.End - endMark) + offset);
            }
            else
            {
                papx     = _paragraphs[listIndex];
                papx.End = (offset);
                for (int x = listIndex + 1; x < endIndex; x++)
                {
                    papx       = _paragraphs[x];
                    papx.Start = (offset);
                    papx.End   = (offset);
                }
                papx     = _paragraphs[endIndex];
                papx.End = ((papx.End - endMark) + offset);
            }

            for (int x = endIndex + 1; x < size; x++)
            {
                papx       = _paragraphs[x];
                papx.Start = (papx.Start - Length);
                papx.End   = (papx.End - Length);
            }
        }
예제 #9
0
 public PAPXTreeNode(PAPX papx)
 {
     this.Record = papx;
 }
예제 #10
0
        /**
         * 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);
        }
예제 #11
0
파일: Paragraph.cs 프로젝트: 89sos98/npoi
        internal Paragraph(PAPX papx, Range parent)
            : base(Math.Max(parent._start, papx.Start), Math.Min(parent._end, papx.End), parent)
        {

            _props = papx.GetParagraphProperties(_doc.GetStyleSheet());
            _papx = papx.GetSprmBuf();
            _istd = papx.GetIstd();
        }
예제 #12
0
파일: PAPBinTable.cs 프로젝트: zzy092/npoi
        public void Rebuild(StringBuilder docText,
                            ComplexFileTable complexFileTable)
        {
            long start = DateTime.Now.Ticks;

            if (complexFileTable != null)
            {
                SprmBuffer[] sprmBuffers = complexFileTable.GetGrpprls();

                // adding PAPX from fast-saved SPRMs
                foreach (TextPiece textPiece in complexFileTable.GetTextPieceTable()
                         .TextPieces)
                {
                    PropertyModifier prm = textPiece.PieceDescriptor.Prm;
                    if (!prm.IsComplex())
                    {
                        continue;
                    }
                    int igrpprl = prm.GetIgrpprl();

                    if (igrpprl < 0 || igrpprl >= sprmBuffers.Length)
                    {
                        logger.Log(POILogger.WARN, textPiece
                                   + "'s PRM references to unknown grpprl");
                        continue;
                    }

                    bool       hasPap     = false;
                    SprmBuffer sprmBuffer = sprmBuffers[igrpprl];
                    for (SprmIterator iterator = sprmBuffer.Iterator(); iterator
                         .HasNext();)
                    {
                        SprmOperation sprmOperation = iterator.Next();
                        if (sprmOperation.Type == SprmOperation.TYPE_PAP)
                        {
                            hasPap = true;
                            break;
                        }
                    }

                    if (hasPap)
                    {
                        SprmBuffer newSprmBuffer = new SprmBuffer(2);
                        newSprmBuffer.Append(sprmBuffer.ToByteArray());

                        PAPX papx = new PAPX(textPiece.Start,
                                             textPiece.End, newSprmBuffer);
                        _paragraphs.Add(papx);
                    }
                }

                logger.Log(POILogger.DEBUG,
                           "Merged (?) with PAPX from complex file table in ",
                           DateTime.Now.Ticks - start,
                           " ms (", _paragraphs.Count,
                           " elements in total)");
                start = DateTime.Now.Ticks;
            }

            List <PAPX> oldPapxSortedByEndPos = new List <PAPX>(_paragraphs);

            oldPapxSortedByEndPos.Sort(
                (IComparer <PAPX>)PropertyNode.PAPXComparator.instance);

            logger.Log(POILogger.DEBUG, "PAPX sorted by end position in ",
                       DateTime.Now.Ticks - start, " ms");
            start = DateTime.Now.Ticks;

            Dictionary <PAPX, int> papxToFileOrder = new Dictionary <PAPX, int>();
            int counter = 0;

            foreach (PAPX papx in _paragraphs)
            {
                papxToFileOrder[papx] = counter++;
            }

            logger.Log(POILogger.DEBUG, "PAPX's order map created in ",
                       DateTime.Now.Ticks - start, " ms");
            start = DateTime.Now.Ticks;

            List <PAPX> newPapxs      = new List <PAPX>();
            int         lastParStart  = 0;
            int         lastPapxIndex = 0;

            for (int charIndex = 0; charIndex < docText.Length; charIndex++)
            {
                char c = docText[charIndex];
                if (c != 13 && c != 7 && c != 12)
                {
                    continue;
                }

                int startInclusive = lastParStart;
                int endExclusive   = charIndex + 1;

                bool        broken = false;
                List <PAPX> papxs  = new List <PAPX>();
                for (int papxIndex = lastPapxIndex; papxIndex < oldPapxSortedByEndPos
                     .Count; papxIndex++)
                {
                    broken = false;
                    PAPX papx = oldPapxSortedByEndPos[papxIndex];


                    if (papx.End - 1 > charIndex)
                    {
                        lastPapxIndex = papxIndex;
                        broken        = true;
                        break;
                    }

                    papxs.Add(papx);
                }
                if (!broken)
                {
                    lastPapxIndex = oldPapxSortedByEndPos.Count - 1;
                }

                if (papxs.Count == 0)
                {
                    logger.Log(POILogger.WARN, "Paragraph [",
                               startInclusive, "; ",
                               endExclusive,
                               ") has no PAPX. Creating new one.");
                    // create it manually
                    PAPX papx = new PAPX(startInclusive, endExclusive,
                                         new SprmBuffer(2));
                    newPapxs.Add(papx);

                    lastParStart = endExclusive;
                    continue;
                }

                if (papxs.Count == 1)
                {
                    // can we reuse existing?
                    PAPX existing = papxs[0];
                    if (existing.Start == startInclusive &&
                        existing.End == endExclusive)
                    {
                        newPapxs.Add(existing);
                        lastParStart = endExclusive;
                        continue;
                    }
                }
                PAPXToFileComparer papxFileOrderComparator = new PAPXToFileComparer(papxToFileOrder);
                // restore file order of PAPX
                papxs.Sort(papxFileOrderComparator);

                SprmBuffer sprmBuffer = null;
                foreach (PAPX papx in papxs)
                {
                    if (sprmBuffer == null)
                    {
                        sprmBuffer = (SprmBuffer)papx.GetSprmBuf().Clone();
                    }

                    else
                    {
                        sprmBuffer.Append(papx.GetGrpprl(), 2);
                    }
                }
                PAPX newPapx = new PAPX(startInclusive, endExclusive, sprmBuffer);
                newPapxs.Add(newPapx);

                lastParStart = endExclusive;
                continue;
            }
            this._paragraphs = new List <PAPX>(newPapxs);

            logger.Log(POILogger.DEBUG, "PAPX rebuilded from document text in ",
                       DateTime.Now.Ticks - start, " ms (",
                       _paragraphs.Count, " elements)");
            start = DateTime.Now.Ticks;
        }