public CrossReferencePart ReadPart(PdfStreamReader streamReader, IPdf pdf)
        {
            if (pdf == null)
            {
                throw new ArgumentNullException(nameof(pdf));
            }

            if (pdf.Trailer == null ||
                pdf.Trailer.StartCrossReference == 0)
            {
                return(null);
            }

            var originalPosition = streamReader.Position;

            try
            {
                streamReader.Seek(pdf.Trailer.StartCrossReference, SeekOrigin.Begin);
                var line = streamReader.ReadLine();

                if (line != "xref")
                {
                    throw new ArgumentOutOfRangeException(nameof(streamReader), line, "Invalid Cross Reference Header");
                }

                var subsections = new List <CrossReferencePartSubSection>();
                while (line == "xref")
                {
                    subsections.Add(_subSectionReader.ReadPart(streamReader, pdf));
                    line = streamReader.ReadLine();
                }

                var result = new CrossReferencePart
                {
                    Sections = subsections.ToArray()
                };

                return(result);
            }
            finally
            {
                streamReader.Seek(originalPosition, SeekOrigin.Begin);
            }
        }
예제 #2
0
        public TrailerPart ReadPart(PdfStreamReader streamReader, IPdf pdf)
        {
            var currentPosition = streamReader.Position;

            try
            {
                var trailerBlockSize = 512;
                var block            = new byte[trailerBlockSize];
                int trailerStart;

                //we'll read x number of bytes at a time with a 7 byte overlap to account for the word trailer.
                //length = 1500

                streamReader.Seek(-trailerBlockSize, SeekOrigin.End);
                string content;
                var    foundTrailer = false;
                do
                {
                    var loopPosition = streamReader.Position;

                    streamReader.Read(block, 0, trailerBlockSize);

                    content = Encoding.ASCII.GetString(block);

                    if ((trailerStart = content.IndexOf("trailer")) >= 0)
                    {
                        streamReader.Seek(loopPosition + trailerStart, SeekOrigin.Begin);

                        foundTrailer = true;
                        break;
                    }

                    content = null;

                    if (loopPosition == 0)
                    {
                        //we were at the beginning of the stream meaning we can't go back any more
                        break;
                    }

                    if (streamReader.Position > trailerBlockSize)
                    {
                        streamReader.Seek((trailerBlockSize * -2) + 7, SeekOrigin.Current); //7 byte overlap
                    }
                    else
                    {
                        streamReader.Seek(0, SeekOrigin.Begin);
                    }
                } while (streamReader.Position - trailerBlockSize > 0); //make sure we don't go before the beginning of the stream for files that have no trailer

                if (foundTrailer)
                {
                    var result = ParseTrailer(streamReader, pdf);
                    return(result);
                }

                return(null);
            }
            finally
            {
                // go back to where we were.
                streamReader.Seek(currentPosition, SeekOrigin.Begin);
            }
        }