Beispiel #1
0
        /**
         * <summary>Retrieves the file information.</summary>
         */
        public FileInfo ReadInfo(
            )
        {
            //TODO:hybrid xref table/stream
            Version       version = Version.Get(parser.RetrieveVersion());
            PdfDictionary trailer = null;
            SortedDictionary <int, XRefEntry> xrefEntries = new SortedDictionary <int, XRefEntry>();

            {
                long sectionOffset = parser.RetrieveXRefOffset();
                while (sectionOffset > -1)
                {
                    // Move to the start of the xref section!
                    parser.Seek(sectionOffset);

                    PdfDictionary sectionTrailer;
                    if (parser.GetToken(1).Equals(Keyword.XRef)) // XRef-table section.
                    {
                        // Looping sequentially across the subsections inside the current xref-table section...
                        while (true)
                        {
                            /*
                             * NOTE: Each iteration of this block represents the scanning of one subsection.
                             * We get its bounds (first and last object numbers within its range) and then collect
                             * its entries.
                             */
                            // 1. First object number.
                            parser.MoveNext();
                            if ((parser.TokenType == PostScriptParser.TokenTypeEnum.Keyword) &&
                                parser.Token.Equals(Keyword.Trailer)) // XRef-table section ended.
                            {
                                break;
                            }
                            else if (parser.TokenType != PostScriptParser.TokenTypeEnum.Integer)
                            {
                                throw new ParseException("Neither object number of the first object in this xref subsection nor end of xref section found.", parser.Position);
                            }

                            // Get the object number of the first object in this xref-table subsection!
                            int startObjectNumber = (int)parser.Token;

                            // 2. Last object number.
                            parser.MoveNext();
                            if (parser.TokenType != PostScriptParser.TokenTypeEnum.Integer)
                            {
                                throw new ParseException("Number of entries in this xref subsection not found.", parser.Position);
                            }

                            // Get the object number of the last object in this xref-table subsection!
                            int endObjectNumber = (int)parser.Token + startObjectNumber;

                            // 3. XRef-table subsection entries.
                            for (
                                int index = startObjectNumber;
                                index < endObjectNumber;
                                index++
                                )
                            {
                                if (xrefEntries.ContainsKey(index)) // Already-defined entry.
                                {
                                    // Skip to the next entry!
                                    parser.MoveNext(3);
                                    continue;
                                }

                                // Get the indirect object offset!
                                int offset = (int)parser.GetToken(1);
                                // Get the object generation number!
                                int generation = (int)parser.GetToken(1);
                                // Get the usage tag!
                                XRefEntry.UsageEnum usage;
                                {
                                    string usageToken = (string)parser.GetToken(1);
                                    if (usageToken.Equals(Keyword.InUseXrefEntry))
                                    {
                                        usage = XRefEntry.UsageEnum.InUse;
                                    }
                                    else if (usageToken.Equals(Keyword.FreeXrefEntry))
                                    {
                                        usage = XRefEntry.UsageEnum.Free;
                                    }
                                    else
                                    {
                                        throw new ParseException("Invalid xref entry.", parser.Position);
                                    }
                                }

                                // Define entry!
                                xrefEntries[index] = new XRefEntry(
                                    index,
                                    generation,
                                    offset,
                                    usage
                                    );
                            }
                        }

                        // Get the previous trailer!
                        sectionTrailer = (PdfDictionary)parser.ParsePdfObject(1);
                    }
                    else // XRef-stream section.
                    {
                        XRefStream stream = (XRefStream)parser.ParsePdfObject(3); // Gets the xref stream skipping the indirect-object header.
                        // XRef-stream subsection entries.
                        foreach (XRefEntry xrefEntry in stream.Values)
                        {
                            if (xrefEntries.ContainsKey(xrefEntry.Number)) // Already-defined entry.
                            {
                                continue;
                            }

                            // Define entry!
                            xrefEntries[xrefEntry.Number] = xrefEntry;
                        }

                        // Get the previous trailer!
                        sectionTrailer = stream.Header;
                    }

                    if (trailer == null)
                    {
                        trailer = sectionTrailer;
                    }

                    // Get the previous xref-table section's offset!
                    PdfInteger prevXRefOffset = (PdfInteger)sectionTrailer[PdfName.Prev];
                    sectionOffset = (prevXRefOffset != null ? prevXRefOffset.IntValue : -1);
                }
            }
            return(new FileInfo(version, trailer, xrefEntries));
        }