예제 #1
0
 public PDFXRefTable(int generation, int startindex, PDFXRefTable previous)
 {
     this._gen      = generation;
     this._prev     = previous;
     this._sections = new List <PDFXRefTableSection>();
     this._sections.Add(new PDFXRefTableSection(startindex, generation));
     if (startindex == 0)
     {
         this._sections[0].Add(new EmptyRef(0, 65535, 0));
     }
 }
예제 #2
0
        /// <summary>
        /// Matches and parses the XRefTable in the this instances PDF data stream that is
        /// specified pased on the position value between the startXRefPos and the end of file marker
        /// </summary>
        /// <param name="startxrefPos"></param>
        /// <param name="eofPos"></param>
        /// <param name="trailerPrevOffset">The offset marked in the trailer dictionary of any previous XRefTable this file contains.</param>
        /// <returns></returns>
        protected PDFXRefTable GetXRefTable(PDFFileRange startxrefPos, PDFFileRange eofPos, long trailerPrevOffset)
        {
            long xrefPos = long.Parse(this.Searcher.GetInnerText(startxrefPos, eofPos).Trim());

            this.Searcher.Position = xrefPos;
            string       fullXRef = this.Searcher.GetInnerText((int)(eofPos.StartOffset - xrefPos));
            int          end;
            PDFXRefTable table = PDFXRefTable.Parse(fullXRef, 0, out end);

            table.Offset = xrefPos;

            if (trailerPrevOffset > 0) // we have a previous entry
            {
                this.Searcher.Position = trailerPrevOffset;

                if (startxrefPos.Found)
                {
                    eofPos       = this.Searcher.MatchForwardString(EndOfFileMarker);
                    startxrefPos = AssertFoundRange(this.Searcher.MatchBackwardString(XRefMarker), XRefMarker);
                    PDFFileRange trailerPos = AssertFoundRange(this.Searcher.MatchBackwardString(TrailerMarker), TrailerMarker);

                    PDFDictionary trailer = GetTrailerDictionary(trailerPos, startxrefPos);
                    IFileObject   prevEntry;

                    if (trailer.TryGetValue(PrevXRefName, out prevEntry))
                    {
                        if (prevEntry is PDFNumber)
                        {
                            trailerPrevOffset = ((PDFNumber)prevEntry).Value;
                        }
                        else if (prevEntry is PDFReal)
                        {
                            trailerPrevOffset = (long)((PDFReal)prevEntry).Value;
                        }
                        else
                        {
                            trailerPrevOffset = -1;
                        }
                    }
                    else
                    {
                        trailerPrevOffset = -1;
                    }

                    PDFXRefTable prevTable = GetXRefTable(startxrefPos, eofPos, trailerPrevOffset);
                    table.Previous = prevTable;
                }
            }

            return(table);
        }
예제 #3
0
        public static PDFXRefTable Parse(string value, int offset, out int end)
        {
            if (value.Substring(offset, 4) != "xref")
            {
                throw new PDFNativeParserException(CommonErrors.XRefTableDoesNotStartWithXRef);
            }
            offset += 4;

            PDFXRefTable table = new PDFXRefTable(0);

            while (char.IsWhiteSpace(value, offset))
            {
                offset++;
            }

            //Force at least one subsection with at least one entry.
            if (char.IsDigit(value, offset) == false)
            {
                throw new PDFNativeParserException(CommonErrors.XRefTableSectionMustBe2Integers);
            }

            PDFXRefTableSection section = PDFXRefTableSection.Parse(value, offset, out end);

            if (section.Count == 0)
            {
                throw new PDFNativeParserException(CommonErrors.XRefTableSectionMustBe2Integers);
            }

            offset = end;

            table._sections.Clear();
            table._sections.Add(section);

            while (offset < value.Length)
            {
                if (char.IsDigit(value, offset))
                {
                    section = PDFXRefTableSection.Parse(value, offset, out end);
                    table._sections.Add(section);
                    offset = end;
                }
                else
                {
                    break;
                }
            }
            return(table);
        }
예제 #4
0
        /// <summary>
        /// Initializes the known PDF file data such as trailers, xref tables and catalogs
        /// </summary>
        protected override void InitData(PDFTraceLog log)
        {
            try
            {
                if (log.ShouldLog(TraceLevel.Debug))
                {
                    log.Add(TraceLevel.Debug, "PDFReader", "Finding end of file, startxref and trailer positions");
                }

                this.Searcher.Position = this.Searcher.Length;
                PDFFileRange eofPos       = AssertFoundRange(Searcher.MatchBackwardString(EndOfFileMarker), EndOfFileMarker);
                PDFFileRange startxrefPos = AssertFoundRange(Searcher.MatchBackwardString(StartXRefMarker), StartXRefMarker);

                PDFFileRange trailerPos = AssertFoundRange(Searcher.MatchBackwardString(TrailerMarker), TrailerMarker);

                if (log.ShouldLog(TraceLevel.Debug))
                {
                    log.Add(TraceLevel.Debug, "PDFReader", "Markers found, loading the trailer dictionary");
                }

                PDFDictionary trailer = GetTrailerDictionary(trailerPos, startxrefPos);
                this._trailer = trailer;

                if (log.ShouldLog(TraceLevel.Debug))
                {
                    log.Add(TraceLevel.Debug, "PDFReader", "Markers found, loading the XRef table");
                }

                PDFObjectRef catalogRef = AssertGetObjectRef(trailer, CatalogObjName, "The '" + CatalogObjName + "' entry couldnot be found in the documents trailer dictionary");
                PDFObjectRef infoRef    = AssertGetObjectRef(trailer, InfoObjName, "The '" + InfoObjName + "' entry couldnot be found in the documents trailer dictionary");
                IFileObject  prevXRefObj;
                trailer.TryGetValue(PrevXRefName, out prevXRefObj);
                long prevOffset = -1;
                if (prevXRefObj is PDFNumber)
                {
                    prevOffset = ((PDFNumber)prevXRefObj).Value;
                }
                else if (prevXRefObj is PDFReal)
                {
                    prevOffset = (long)((PDFNumber)prevXRefObj).Value;
                }

                PDFXRefTable xref = GetXRefTable(startxrefPos, eofPos, prevOffset);


                if (log.ShouldLog(TraceLevel.Debug))
                {
                    log.Add(TraceLevel.Debug, "PDFReader", "References for the catalog and document info found");
                }

                this._xreftable = xref;
                this._info      = (PDFFileIndirectObject)this.GetObject(infoRef);

                if (log.ShouldLog(TraceLevel.Debug))
                {
                    log.Add(TraceLevel.Debug, "PDFReader", "Loaded the document Info indirect object");
                }

                this._catalog = (PDFFileIndirectObject)this.GetObject(catalogRef);

                if (log.ShouldLog(TraceLevel.Debug))
                {
                    log.Add(TraceLevel.Debug, "PDFReader", "Loaded the document Catalog indirect object");
                }

                //TODO: Look for more updates and read those in too
            }
            catch (Exception ex)
            {
                throw new PDFNativeParserException(CommonErrors.CouldNotInitializeThePDFReader, ex);
            }
        }