/// <summary> /// Attempt to parse a sequence of bytes as a PDF object /// </summary> /// <param name="Data">Bytes to parse</param> /// <param name="EndingIndex">0-based index into data indicating the byte after the last parsed byte</param> /// <param name="StartingIndex">0-based index into data at which to start parsing (default: 0)</param> /// <returns>PDF object successfully parsed from the data, or NULL if no complete object was parsable</returns> public static IPDFObject Parse(byte[] Data, out int EndingIndex, int StartingIndex = 0) { int StartTokenIndex; int EndTokenIndex; IPDFObject ParsedObject = null; string Token = GetTokenString(Data, StartingIndex, out StartTokenIndex, out EndTokenIndex); if (!string.IsNullOrEmpty(Token)) { if ((ParsedObject = PDFDictionary.TryParse(Token, Data, StartTokenIndex, out EndingIndex)) != null) { return(ParsedObject); } if ((ParsedObject = PDFArray.TryParse(Token, Data, StartTokenIndex, out EndingIndex)) != null) { return(ParsedObject); } if ((ParsedObject = PDFString.TryParse(Token, Data, StartTokenIndex, out EndingIndex)) != null) { return(ParsedObject); } if ((ParsedObject = PDFHexString.TryParse(Token, Data, StartTokenIndex, out EndingIndex)) != null) { return(ParsedObject); } if ((ParsedObject = PDFObjectDefinition.TryParse(Token, Data, StartTokenIndex, out EndingIndex)) != null) { return(ParsedObject); } if ((ParsedObject = PDFIndirectObject.TryParse(Token, Data, StartTokenIndex, out EndingIndex)) != null) { return(ParsedObject); } if ((ParsedObject = PDFNumber.TryParse(Token, Data, StartTokenIndex, out EndingIndex)) != null) { return(ParsedObject); } if ((ParsedObject = PDFName.TryParse(Token, Data, StartTokenIndex, out EndingIndex)) != null) { return(ParsedObject); } if ((ParsedObject = PDFComment.TryParse(Token, Data, StartTokenIndex, out EndingIndex)) != null) { return(ParsedObject); } } // Could not parse next object EndingIndex = StartingIndex; return(null); }
/// <summary> /// Read the trailer from a PDF data file /// </summary> /// <param name="Data">Data to read</param> /// <param name="StartIndex">Starting index of where to look for trailer, or -1 to look from end of file (default: -1)</param> /// <returns>TRUE if a trailer was successfully read, FALSE otherwise</returns> public static PDFTrailer ReadTrailer(byte[] Data, int StartIndex = -1) { int EndIndex = StartIndex; if (EndIndex < 0) { EndIndex = PDF.FindEOF(Data, Data.Length - 1); } if (EndIndex < 0) { return(null); } int EndOfLineIndex; byte[] LineData = PDF.ExtractPreviousPDFLine(Data, EndIndex, out EndIndex, out EndOfLineIndex); while (LineData != null) { if ("trailer".Equals(Encoding.UTF8.GetString(LineData).Trim())) { int TokenStartIndex = 0; string Token = PDFObjectParser.GetTokenString(Data, EndOfLineIndex, out TokenStartIndex, out EndIndex); PDFDictionary TrailerDictionary = (PDFDictionary)PDFDictionary.TryParse(Token, Data, TokenStartIndex, out EndIndex); if (TrailerDictionary != null) { LineData = PDF.ExtractPDFLine(Data, EndIndex, out EndIndex); if ("startxref".Equals(Encoding.UTF8.GetString(LineData).Trim())) { Token = PDFObjectParser.GetTokenString(Data, EndIndex, out TokenStartIndex, out _); PDFNumber Offset = (PDFNumber)PDFNumber.TryParse(Token, Data, TokenStartIndex, out EndIndex); PDFCrossReference CrossRef = PDFCrossReference.ReadCrossReference(Data, Offset, out _); return(new PDFTrailer(TrailerDictionary, CrossRef)); } else { return(null); } } else { return(null); } } else { LineData = PDF.ExtractPreviousPDFLine(Data, EndIndex, out EndIndex, out EndOfLineIndex); } } return(null); }