Пример #1
0
        public static PDFStream MakeStream(PDFDictionary StreamDictionary, byte[] Data, int StartingIndex, out int EndingIndex)
        {
            int TokEnd;

            int StreamLength = 0;

            if (StreamDictionary.ContainsKey("Length"))
            {
                StreamLength = (int)(Decimal.Parse(StreamDictionary["Length"].Description));
            }
            else
            {
                StreamLength = PDF.FirstOccurance(Data, Encoding.UTF8.GetBytes("endstream"), StartingIndex);
            }

            EndingIndex = StartingIndex;
            if ("stream".Equals(PDFObjectParser.GetTokenString(Data, EndingIndex, out _, out TokEnd)))
            {
                if ((StreamLength > 0) && (Data.Length >= TokEnd + 1 + StreamLength))
                {
                    byte[] StreamBytes = new byte[StreamLength];
                    Array.Copy(Data, TokEnd + 1, StreamBytes, 0, StreamLength);
                    EndingIndex = TokEnd + 1 + StreamLength;
                    if (!"endstream".Equals(PDFObjectParser.GetTokenString(Data, EndingIndex, out _, out EndingIndex)))
                    {
                    }   // Error - missing "endstream"
                    return(new PDFStream(StreamDictionary, StreamBytes));
                }
            }

            // Unable to make a stream from this data
            return(null);
        }
Пример #2
0
        /// <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 StartIndex;
            int Number;

            EndingIndex = StartingIndex;
            if (int.TryParse(StartingToken, out Number))
            {
                string Declaration = PDFObjectParser.GetTokenString(Data, StartingIndex + StartingToken.Length, out StartIndex, out EndingIndex, 2);
                if (!String.IsNullOrEmpty(Declaration))
                {
                    Match objMatch = Regex.Match(Declaration, @"([+-]?\d+) R");
                    if (objMatch.Success)
                    {
                        int Generation = int.Parse(objMatch.Groups[1].Value);
                        if (Declaration.Length != objMatch.Length)
                        {
                            EndingIndex = EndingIndex - (Declaration.Length - objMatch.Length) - 1;
                        }
                        return(new PDFIndirectObject(Number, Generation));
                    }
                }
            }

            return(null);
        }
Пример #3
0
Файл: PDF.cs Проект: jrhay/PKPDF
        /// <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);
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
Файл: PDF.cs Проект: jrhay/PKPDF
        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);
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <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);
        }