/// <summary> /// Load a single object from the PDF data stream, starting at a paritcular offset /// </summary> /// <param name="Offset">Offset into data stream of object to read</param> /// <returns>Object as read out of data stream, or null if no object could be parsed</returns> private IPDFObject LoadObjectAtOffset(int Offset) { IPDFObject objectDefinition = PDFObjectParser.Parse(RawData, out _, Offset); if (objectDefinition.Type == PDFObjectType.ObjectDefinition) { return(((PDFObjectDefinition)objectDefinition).Object); } return(objectDefinition); }
public List <IPDFObject> GetObjects(int MaxObjects) { byte[] AllData = File.ReadAllBytes(Filepath); int EndingIndex = 0; List <IPDFObject> objects = new List <IPDFObject>(); IPDFObject nextObject; while ((objects.Count < MaxObjects) && ((nextObject = PDFObjectParser.Parse(AllData, out EndingIndex, EndingIndex)) != null)) { objects.Add(nextObject); } return(objects); }
/// <summary> /// Attempt to parse the given data stream, returning an indicator of parse progress /// </summary> /// <param name="StartingToken">The token immediately preceeding the starting index in Data stream</param> /// <param name="Data">Raw byte stream to parse</param> /// <param name="StartingIndex">0-based starting index into Data where StartingToken appears</param> /// <param name="EndingIndex">Index into data stream where parsing ended (either successfully or unsuccessfully)</param> /// <returns>Object parsed from data stream, or NULL if unable to parse. If NULL and EndingIndex is equal to Data.Length, parsing may be successful with more data</returns> public static IPDFObject TryParse(string StartingToken, byte[] Data, int StartingIndex, out int EndingIndex) { Dictionary <string, IPDFObject> KeyValuePairs = new Dictionary <string, IPDFObject>(); EndingIndex = StartingIndex; if (StartingToken.Equals("<<")) { EndingIndex += StartingToken.Length; while (EndingIndex < Data.Length) { int TokEnd; if (">>".Equals(PDFObjectParser.GetTokenString(Data, EndingIndex, out _, out TokEnd))) { EndingIndex = TokEnd; if ("stream".Equals(PDFObjectParser.GetTokenString(Data, EndingIndex, out _, out TokEnd))) { return(PDFStream.MakeStream(new PDFDictionary(KeyValuePairs), Data, EndingIndex, out EndingIndex)); } else { return(new PDFDictionary(KeyValuePairs)); } } IPDFObject Key = PDFObjectParser.Parse(Data, out EndingIndex, EndingIndex); if (Key == null) { return(null); // No key found } if (Key.Type != PDFObjectType.Name) { return(null); // Invalid key type found } IPDFObject Value = PDFObjectParser.Parse(Data, out EndingIndex, EndingIndex); if (Value == null) { return(null); // No value found } KeyValuePairs.Add(Key.Description, Value); } } // Didn't find a dictionary delimiter return(null); }
/// <summary> /// Attempt to parse the given data stream, returning an indicator of parse progress /// </summary> /// <param name="StartingToken">The token immediately preceeding the starting index in Data stream</param> /// <param name="Data">Raw byte stream to parse</param> /// <param name="StartingIndex">0-based starting index into Data where StartingToken appears</param> /// <param name="EndingIndex">Index into data stream where parsing ended (either successfully or unsuccessfully)</param> /// <returns>Object parsed from data stream, or NULL if unable to parse. If NULL and EndingIndex is equal to Data.Length, parsing may be successful with more data</returns> public static IPDFObject TryParse(string StartingToken, byte[] Data, int StartingIndex, out int EndingIndex) { int Number; EndingIndex = StartingIndex; if (int.TryParse(StartingToken, out Number)) { string Declaration = PDFObjectParser.GetTokenString(Data, StartingIndex + StartingToken.Length, out _, out EndingIndex, 2); if (!String.IsNullOrEmpty(Declaration)) { Match objMatch = Regex.Match(Declaration, @"([+-]?\d+) obj"); if (objMatch.Success) { if (Declaration.Length != objMatch.Length) { EndingIndex = EndingIndex - (Declaration.Length - objMatch.Length) - 1; } int Generation = int.Parse(objMatch.Groups[1].Value); // Parse the indirect object content (should be a single object) IPDFObject PDFObject = PDFObjectParser.Parse(Data, out EndingIndex, EndingIndex); if (PDFObject != null) { int ObjectEndIndex = PDF.FirstOccurance(Data, Encoding.UTF8.GetBytes("endobj"), EndingIndex); if (ObjectEndIndex > 0) { // Format error - tokens after object definition but before "endobj" } EndingIndex = ObjectEndIndex + "endobj".Length; return(new PDFObjectDefinition(Number, Generation, PDFObject)); } } } } return(null); }
/// <summary> /// Attempt to parse the given data stream, returning an indicator of parse progress /// </summary> /// <param name="StartingToken">The token immediately preceeding the starting index in Data stream</param> /// <param name="Data">Raw byte stream to parse</param> /// <param name="StartingIndex">0-based starting index into Data where StartingToken appears</param> /// <param name="EndingIndex">Index into data stream where parsing ended (either successfully or unsuccessfully)</param> /// <returns>Object parsed from data stream, or NULL if unable to parse. If NULL and EndingIndex is equal to Data.Length, parsing may be successful with more data</returns> public static IPDFObject TryParse(string StartingToken, byte[] Data, int StartingIndex, out int EndingIndex) { EndingIndex = StartingIndex; if (!String.IsNullOrEmpty(StartingToken) && (StartingToken[0] == '[')) { PDFArray ObjectArray = new PDFArray(); EndingIndex = StartingIndex + 1; while (EndingIndex < Data.Length) { IPDFObject nextObject = PDFObjectParser.Parse(Data, out EndingIndex, EndingIndex); if (nextObject != null) { ObjectArray.Add(nextObject); } byte nextChar = PDF.Whitespace[0]; while (PDF.IsWhitespace(nextChar)) { nextChar = Data[EndingIndex++]; } if (nextChar == ']') { return(ObjectArray); } else { EndingIndex--; } } } return(null); }