/// <summary> /// Matches and parses the trailer dictionary that must be present in a PDF document file that is between the trailer marker and the startxref marker /// </summary> /// <param name="trailerPos"></param> /// <param name="startxrefPos"></param> /// <returns></returns> protected PDFDictionary GetTrailerDictionary(PDFFileRange trailerPos, PDFFileRange startxrefPos) { string fulltrailer = Searcher.GetInnerText(trailerPos, startxrefPos); fulltrailer = fulltrailer.Trim(); PDFDictionary trailer = PDFDictionary.Parse(fulltrailer); return(trailer); }
public virtual PDFDictionary Clone() { PDFDictionary theClone = (PDFDictionary)this.MemberwiseClone(); theClone.Clear(); foreach (KeyValuePair <PDFName, IFileObject> item in this) { theClone.Add(item.Key, item.Value); } return(theClone); }
/// <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); }
public static PDFDictionary ParseDictionary(string value, int offset, out int end) { AssertValidValue(value, offset + 1); if (value[offset] != DictionaryStartChar) { throw new PDFNativeParserException(CommonErrors.DictionaryDoesNotStartWithRequiredChar); } if (value[offset + 1] != DictionaryStartChar) { throw new PDFNativeParserException(CommonErrors.DictionaryDoesNotStartWithRequiredChar); } PDFDictionary dict = new PDFDictionary(); offset += 2; while (offset < value.Length) { char c = value[offset]; if (char.IsWhiteSpace(c)) { offset++; } else if (c == NameStartCharacter) { PDFName name = ParseName(value, offset, out end); offset = end; IFileObject obj = InferAndParseNextObject(value, offset, out end); dict[name] = obj; offset = end; } else if (c == DictionaryEndChar) { if (value.Length > offset + 1 && value[offset + 1] == DictionaryEndChar) { offset += 2; break; } else { throw new PDFNativeParserException(CommonErrors.DictionaryDoesNotEndWithRequiredChar); } } else { throw new PDFNativeParserException(CommonErrors.AllDictionaryKeysMustBePDFNames); } } end = offset; return(dict); }
protected static PDFObjectRef AssertGetObjectRef(PDFDictionary dict, PDFName entry, string errorMessage) { IFileObject found; if (!dict.TryGetValue(entry, out found)) { throw new PDFNativeParserException(errorMessage); } if (found.Type != PDFObjectTypes.ObjectRef) { throw new PDFNativeParserException(errorMessage); } return((PDFObjectRef)found); }
/// <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); } }