/// <summary> /// Reads cross reference table(s) and trailer(s). /// </summary> private PdfTrailer ReadXRefTableAndTrailer(PdfCrossReferenceTable xrefTable) { Debug.Assert(xrefTable != null); Symbol symbol = ScanNextToken(); if (symbol == Symbol.XRef) // Is it a cross-reference table? { // Reference: 3.4.3 Cross-Reference Table / Page 93 while (true) { symbol = ScanNextToken(); if (symbol == Symbol.Integer) { int start = _lexer.TokenToInteger; int length = ReadInteger(); for (int id = start; id < start + length; id++) { int position = ReadInteger(); int generation = ReadInteger(); ReadSymbol(Symbol.Keyword); string token = _lexer.Token; // Skip start entry if (id == 0) continue; // Skip unused entries. if (token != "n") continue; // Even it is restricted, an object can exists in more than one subsection. // (PDF Reference Implementation Notes 15). PdfObjectID objectID = new PdfObjectID(id, generation); // Ignore the latter one. if (xrefTable.Contains(objectID)) continue; xrefTable.Add(new PdfReference(objectID, position)); } } else if (symbol == Symbol.Trailer) { ReadSymbol(Symbol.BeginDictionary); PdfTrailer trailer = new PdfTrailer(_document); ReadDictionary(trailer, false); return trailer; } else ParserDiagnostics.HandleUnexpectedToken(_lexer.Token); } } // ReSharper disable once RedundantIfElseBlock because of code readability. else if (symbol == Symbol.Integer) // Is it an cross-reference stream? { // Reference: 3.4.7 Cross-Reference Streams / Page 93 // TODO: Handle PDF files larger than 2 GiB, see implementation note 21 in Appendix H. // The parsed integer is the object id of the cross-refernece stream. return ReadXRefStream(xrefTable); } return null; }
/// <summary> /// /// </summary> PdfTrailer ReadXRefTableAndTrailer(PdfReferenceTable xrefTable) { Debug.Assert(xrefTable != null); Symbol symbol = ScanNextToken(); // Is it an xref stream? if (symbol == Symbol.Integer) throw new PdfReaderException(PSSR.CannotHandleXRefStreams); // TODO: We have all code to handle them -> just do it Debug.Assert(symbol == Symbol.XRef); while (true) { symbol = ScanNextToken(); if (symbol == Symbol.Integer) { int start = this.lexer.TokenToInteger; int length = ReadInteger(); for (int id = start; id < start + length; id++) { int position = ReadInteger(); int generation = ReadInteger(); ReadSymbol(Symbol.Keyword); string token = lexer.Token; // Skip start entry if (id == 0) continue; // Skip unused entries. if (token != "n") continue; // Even it is restricted, an object can exists in more than one subsection. // (PDF Reference Implementation Notes 15). PdfObjectID objectID = new PdfObjectID(id, generation); // Ignore the latter one if (xrefTable.Contains(objectID)) continue; xrefTable.Add(new PdfReference(objectID, position)); } } else if (symbol == Symbol.Trailer) { ReadSymbol(Symbol.BeginDictionary); PdfTrailer trailer = new PdfTrailer(this.document); this.ReadDictionary(trailer, false); return trailer; } else throw new PdfReaderException(PSSR.UnexpectedToken(this.lexer.Token)); } }
void Initialize() { //_info = new PdfInfo(this); _fontTable = new PdfFontTable(this); _imageTable = new PdfImageTable(this); _trailer = new PdfTrailer(this); _irefTable = new PdfCrossReferenceTable(this); _trailer.CreateNewDocumentIDs(); }