/// <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> /// 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); }