public string Build() { PdfMetadata = ValueOrDefault(PdfMetadata, PdfMetadataDefaultValue); AddMetadata(PdfMetadata); StringBuilder sb = new StringBuilder(); sb.Append($"%PDF-{Version}\n"); sb.Append(BinaryComment()); foreach (PdfObject pdfObject in PdfObjects) { sb.Append(pdfObject.Build()); } var pdfFileUpUntilXref = sb.ToString(); // Temp pdf so that we can calculate position to Reference table var xref = new PdfReferenceTable(pdfFileUpUntilXref, PdfObjects); var xrefPosition = PdfHelpers.Encoding.GetByteCount(pdfFileUpUntilXref); sb.Append($"{xref.ToString()}"); var trailer = new PdfTrailer(this.Catalog, PdfObjects.Count + 1, PdfMetadata); sb.Append(trailer.Build()); // Tells pdf where to find xref table sb.Append("startxref\n"); sb.Append($"{xrefPosition}\n"); sb.Append("%%EOF"); return(sb.ToString()); }
/// <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: It is very high on the todo list, but still undone 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)); } } }