Esempio n. 1
0
        /**
         * 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);
                    }
                }
            }
        }
Esempio n. 2
0
        private static int BinarySearch(List <CHPX> chpxs, int startPosition)
        {
            int low  = 0;
            int high = chpxs.Count - 1;

            while (low <= high)
            {
                int  mid      = (low + high) >> 1;
                CHPX midVal   = chpxs[mid];
                int  midValue = midVal.Start;

                if (midValue < startPosition)
                {
                    low = mid + 1;
                }
                else if (midValue > startPosition)
                {
                    high = mid - 1;
                }
                else
                {
                    return(mid); // key found
                }
            }
            return(-(low + 1)); // key not found.
        }
Esempio n. 3
0
        public void AdjustForInsert(int listIndex, int Length)
        {
            int  size = _textRuns.Count;
            CHPX chpx = _textRuns[listIndex];

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

            for (int x = listIndex + 1; x < size; x++)
            {
                chpx       = _textRuns[x];
                chpx.Start = (chpx.Start + Length);
                chpx.End   = (chpx.End + Length);
            }
        }
Esempio n. 4
0
        /**
         * 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);
            }
        }
Esempio n. 5
0
                /**
     * 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);
            }
        }
Esempio n. 6
0
        public void Insert(int listIndex, int cpStart, SprmBuffer buf)
        {
            CHPX insertChpx = new CHPX(0, 0, buf);

            // Ensure character OffSets are really characters
            insertChpx.Start = (cpStart);
            insertChpx.End   = (cpStart);

            if (listIndex == _textRuns.Count)
            {
                _textRuns.Add(insertChpx);
            }
            else
            {
                CHPX chpx = _textRuns[listIndex];
                if (chpx.Start < cpStart)
                {
                    // 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
                    CHPX clone = new CHPX(0, 0, chpx.GetSprmBuf());
                    // Again ensure Contains character based OffSets no matter what
                    clone.Start = (cpStart);
                    clone.End   = (chpx.End);

                    chpx.End = (cpStart);

                    _textRuns.Insert(listIndex + 1, insertChpx);
                    _textRuns.Insert(listIndex + 2, clone);
                }
                else
                {
                    _textRuns.Insert(listIndex, insertChpx);
                }
            }
        }
Esempio n. 7
0
        public void AdjustForDelete(int listIndex, int offset, int Length)
        {
            int size     = _textRuns.Count;
            int endMark  = offset + Length;
            int endIndex = listIndex;

            CHPX chpx = _textRuns[endIndex];

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

            for (int x = endIndex + 1; x < size; x++)
            {
                chpx       = _textRuns[x];
                chpx.Start = (chpx.Start - Length);
                chpx.End   = (chpx.End - Length);
            }
        }
Esempio n. 8
0
        internal byte[] ToArray(int fcMin)
        {
            byte[] buf          = new byte[512];
            int    size         = _chpxList.Count;
            int    grpprlOffset = 511;
            int    offsetOffset = 0;
            int    fcOffset     = 0;

            // total size is currently the size of one FC
            int totalSize = FC_SIZE + 2;

            int index = 0;

            for (; index < size; index++)
            {
                int grpprlLength = (_chpxList[index]).GetGrpprl().Length;

                // check to see if we have enough room for an FC, the grpprl offset,
                // the grpprl size byte and the grpprl.
                totalSize += (FC_SIZE + 2 + grpprlLength);
                // 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 -= (FC_SIZE + 2 + grpprlLength);
                    break;
                }

                // grpprls must fall on word boundaries
                if ((1 + grpprlLength) % 2 > 0)
                {
                    totalSize += 1;
                }
            }

            // see if we couldn't fit some
            if (index != size)
            {
                _overFlow = new List <CHPX>();
                _overFlow.AddRange(_chpxList.GetRange(index, size - index));
            }

            // index should equal number of CHPXs that will be in this fkp now.
            buf[511] = (byte)index;

            offsetOffset = (FC_SIZE * index) + FC_SIZE;
            //grpprlOffset =  offsetOffset + index + (grpprlOffset % 2);

            CHPX chpx = null;

            for (int x = 0; x < index; x++)
            {
                chpx = (CHPX)_chpxList[x];
                byte[] grpprl = chpx.GetGrpprl();

                LittleEndian.PutInt(buf, fcOffset, chpx.StartBytes + fcMin);
                grpprlOffset     -= (1 + grpprl.Length);
                grpprlOffset     -= (grpprlOffset % 2);
                buf[offsetOffset] = (byte)(grpprlOffset / 2);
                buf[grpprlOffset] = (byte)grpprl.Length;
                Array.Copy(grpprl, 0, buf, grpprlOffset + 1, grpprl.Length);

                offsetOffset += 1;
                fcOffset     += FC_SIZE;
            }
            // put the last chpx's end in
            LittleEndian.PutInt(buf, fcOffset, chpx.EndBytes + fcMin);
            return(buf);
        }
Esempio n. 9
0
        public void Rebuild(ComplexFileTable complexFileTable)
        {
            long start = DateTime.Now.Ticks;

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

                // adding CHPX 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       hasChp     = false;
                    SprmBuffer sprmBuffer = sprmBuffers[igrpprl];
                    for (SprmIterator iterator = sprmBuffer.Iterator(); ; iterator
                         .HasNext())
                    {
                        SprmOperation sprmOperation = iterator.Next();
                        if (sprmOperation.Type == SprmOperation.TYPE_CHP)
                        {
                            hasChp = true;
                            break;
                        }
                    }

                    if (hasChp)
                    {
                        SprmBuffer newSprmBuffer;
                        newSprmBuffer = (SprmBuffer)sprmBuffer.Clone();


                        CHPX chpx = new CHPX(textPiece.Start,
                                             textPiece.End, newSprmBuffer);
                        _textRuns.Add(chpx);
                    }
                }
                logger.Log(POILogger.DEBUG,
                           "Merged with CHPX from complex file table in ",
                           DateTime.Now.Ticks - start,
                           " ms (", _textRuns.Count,
                           " elements in total)");
                start = DateTime.Now.Ticks;
            }

            List <CHPX> oldChpxSortedByStartPos = new List <CHPX>(_textRuns);

            oldChpxSortedByStartPos.Sort(
                (IComparer <CHPX>)PropertyNode.CHPXComparator.instance);

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

            Dictionary <CHPX, int> chpxToFileOrder = new Dictionary <CHPX, int>();

            int counter = 0;

            foreach (CHPX chpx in _textRuns)
            {
                chpxToFileOrder.Add(chpx, counter++);
            }


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

            List <int> textRunsBoundariesList;

            List <int> textRunsBoundariesSet = new List <int>();

            foreach (CHPX chpx in _textRuns)
            {
                textRunsBoundariesSet.Add(chpx.Start);
                textRunsBoundariesSet.Add(chpx.End);
            }
            textRunsBoundariesSet.Remove(0);
            textRunsBoundariesList = new List <int>(
                textRunsBoundariesSet);
            textRunsBoundariesList.Sort();


            logger.Log(POILogger.DEBUG, "Texts CHPX boundaries collected in ",
                       DateTime.Now.Ticks - start, " ms");
            start = DateTime.Now.Ticks;

            List <CHPX> newChpxs         = new List <CHPX>();
            int         lastTextRunStart = 0;

            foreach (int objBoundary in textRunsBoundariesList)
            {
                int boundary = objBoundary;

                int startInclusive = lastTextRunStart;
                int endExclusive   = boundary;
                lastTextRunStart = endExclusive;

                int startPosition = BinarySearch(oldChpxSortedByStartPos, boundary);
                startPosition = Math.Abs(startPosition);
                while (startPosition >= oldChpxSortedByStartPos.Count)
                {
                    startPosition--;
                }
                while (startPosition > 0 &&
                       oldChpxSortedByStartPos[startPosition].Start >= boundary)
                {
                    startPosition--;
                }

                List <CHPX> chpxs = new List <CHPX>();
                for (int c = startPosition; c < oldChpxSortedByStartPos.Count; c++)
                {
                    CHPX chpx = oldChpxSortedByStartPos[c];

                    if (boundary < chpx.Start)
                    {
                        break;
                    }

                    int left  = Math.Max(startInclusive, chpx.Start);
                    int right = Math.Min(endExclusive, chpx.End);

                    if (left < right)
                    {
                        chpxs.Add(chpx);
                    }
                }

                if (chpxs.Count == 0)
                {
                    logger.Log(POILogger.WARN, "Text piece [",
                               startInclusive, "; ",
                               endExclusive,
                               ") has no CHPX. Creating new one.");
                    // create it manually
                    CHPX chpx = new CHPX(startInclusive, endExclusive,
                                         new SprmBuffer(0));
                    newChpxs.Add(chpx);
                    continue;
                }

                if (chpxs.Count == 1)
                {
                    // can we reuse existing?
                    CHPX existing = chpxs[0];
                    if (existing.Start == startInclusive &&
                        existing.End == endExclusive)
                    {
                        newChpxs.Add(existing);
                        continue;
                    }
                }
                CHPXToFileComparer chpxFileOrderComparator = new CHPXToFileComparer(chpxToFileOrder);
                chpxs.Sort(chpxFileOrderComparator);

                SprmBuffer sprmBuffer = new SprmBuffer(0);
                foreach (CHPX chpx in chpxs)
                {
                    sprmBuffer.Append(chpx.GetGrpprl(), 0);
                }
                CHPX newChpx = new CHPX(startInclusive, endExclusive, sprmBuffer);
                newChpxs.Add(newChpx);

                continue;
            }
            this._textRuns = new List <CHPX>(newChpxs);

            logger.Log(POILogger.DEBUG, "CHPX rebuilded in ",
                       DateTime.Now.Ticks - start, " ms (",
                       _textRuns.Count, " elements)");
            start = DateTime.Now.Ticks;

            CHPX previous = null;

            for (int iterator = _textRuns.Count; iterator != 0;)
            {
                CHPX current = previous;

                previous = _textRuns[--iterator];
                if (current == null)
                {
                    continue;
                }

                if (previous.End == current.Start &&
                    Arrays
                    .Equals(previous.GetGrpprl(), current.GetGrpprl()))
                {
                    previous.End = current.End;
                    _textRuns.Remove(current);
                    continue;
                }

                previous = current;
            }

            logger.Log(POILogger.DEBUG, "CHPX compacted in ",
                       DateTime.Now.Ticks - start, " ms (",
                       _textRuns.Count, " elements)");
        }
Esempio n. 10
0
        /**
         *
         * @param chpx The chpx this object is based on.
         * @param ss The stylesheet for the document this run belongs to.
         * @param istd The style index if this Run's base style.
         * @param parent The parent range of this character run (usually a paragraph).
         */
        internal CharacterRun(CHPX chpx, StyleSheet ss, short istd, Range parent)
            : base(Math.Max(parent._start, chpx.Start), Math.Min(parent._end, chpx.End), parent)
        {

            _props = chpx.GetCharacterProperties(ss, istd);
            _chpx = chpx.GetSprmBuf();
        }