Beispiel #1
0
 /**
  * Reset all data so that it can be used to rebuild the trailer.
  *
  */
 public void reset()
 {
     foreach (XrefTrailerObj trailerObj in bytePosToXrefMap.Values)
     {
         trailerObj.reset();
     }
     curXrefTrailerObj   = null;
     resolvedXrefTrailer = null;
 }
Beispiel #2
0
        /**
         * Sets the byte position of the first XRef
         * (has to be called after very last startxref was read).
         * This is used to resolve chain of active XRef/trailer.
         *
         * In case startxref position is not found we output a
         * warning and use all XRef/trailer objects combined
         * in byte position order.
         * Thus for incomplete PDF documents with missing
         * startxref one could call this method with parameter value -1.
         *
         * @param startxrefBytePosValue starting position of the first XRef
         *
         */
        public void setStartxref(long startxrefBytePosValue)
        {
            if (resolvedXrefTrailer != null)
            {
                //LOG.warn("Method must be called only ones with last startxref value.");
                return;
            }

            resolvedXrefTrailer = new XrefTrailerObj {
                trailer = new CosDictionary()
            };

            bytePosToXrefMap.TryGetValue(startxrefBytePosValue, out XrefTrailerObj curObj);

            List <long> xrefSeqBytePos = new List <long>();

            if (curObj == null)
            {
                // no XRef at given position
                //LOG.warn("Did not found XRef object at specified startxref position " + startxrefBytePosValue);

                // use all objects in byte position order (last entries overwrite previous ones)
                xrefSeqBytePos.AddRange(bytePosToXrefMap.Keys);
                xrefSeqBytePos.Sort();
            }
            else
            {
                // copy xref type
                resolvedXrefTrailer.xrefType = curObj.xrefType;
                // found starting Xref object
                // add this and follow chain defined by 'Prev' keys
                xrefSeqBytePos.Add(startxrefBytePosValue);
                while (curObj.trailer != null)
                {
                    long prevBytePos = curObj.trailer.getLong(CosName.PREV, -1L);
                    if (prevBytePos == -1)
                    {
                        break;
                    }

                    bytePosToXrefMap.TryGetValue(prevBytePos, out curObj);
                    if (curObj == null)
                    {
                        //LOG.warn("Did not found XRef object pointed to by 'Prev' key at position " + prevBytePos);
                        break;
                    }
                    xrefSeqBytePos.Add(prevBytePos);

                    // sanity check to prevent infinite loops
                    if (xrefSeqBytePos.Count >= bytePosToXrefMap.Count)
                    {
                        break;
                    }
                }
                // have to reverse order so that later XRefs will overwrite previous ones
                xrefSeqBytePos.Reverse();
            }

            // merge used and sorted XRef/trailer
            foreach (long bPos in xrefSeqBytePos)
            {
                bytePosToXrefMap.TryGetValue(bPos, out curObj);
                if (curObj.trailer != null)
                {
                    resolvedXrefTrailer.trailer.addAll(curObj.trailer);
                }

                foreach (var item in curObj.xrefTable)
                {
                    resolvedXrefTrailer.xrefTable[item.Key] = item.Value;
                }
            }
        }
Beispiel #3
0
 /**
  * Signals that a new XRef object (table or stream) starts.
  * @param startBytePos the offset to start at
  * @param type the type of the Xref object
  */
 public void nextXrefObj(long startBytePos, XRefType type)
 {
     bytePosToXrefMap[startBytePos] = curXrefTrailerObj = new XrefTrailerObj();
     curXrefTrailerObj.xrefType     = type;
 }