Make it possible to inject a custom ITokenWriter in PdfDocumentBuilder.

This commit is contained in:
mvantzet
2022-12-20 10:50:41 +01:00
parent 3594231c67
commit 6125c00089
5 changed files with 34 additions and 26 deletions

View File

@@ -1,5 +1,7 @@
namespace UglyToad.PdfPig.Writer;
using Core;
using System.Collections.Generic;
using System.IO;
using Tokens;
@@ -14,4 +16,22 @@ public interface ITokenWriter
/// <param name="token">The token to write to the stream.</param>
/// <param name="outputStream">The stream to write the token to.</param>
void WriteToken(IToken token, Stream outputStream);
/// <summary>
/// Writes pre-serialized token as an object token to the output stream.
/// </summary>
/// <param name="objectNumber">Object number of the indirect object.</param>
/// <param name="generation">Generation of the indirect object.</param>
/// <param name="data">Pre-serialized object contents.</param>
/// <param name="outputStream">The stream to write the token to.</param>
void WriteObject(long objectNumber, int generation, byte[] data, Stream outputStream);
/// <summary>
/// Writes a valid single section cross-reference (xref) table plus trailer dictionary to the output for the set of object offsets.
/// </summary>
/// <param name="objectOffsets">The byte offset from the start of the document for each object in the document.</param>
/// <param name="catalogToken">The object representing the catalog dictionary which is referenced from the trailer dictionary.</param>
/// <param name="outputStream">The output stream to write to.</param>
/// <param name="documentInformationReference">The object reference for the document information dictionary if present.</param>
void WriteCrossReferenceTable(IReadOnlyDictionary<IndirectReference, long> objectOffsets, IndirectReference catalogToken, Stream outputStream, IndirectReference? documentInformationReference);
}

View File

@@ -8,7 +8,7 @@
{
private readonly Dictionary<byte[], IndirectReferenceToken> hashes = new Dictionary<byte[], IndirectReferenceToken>(new FNVByteComparison());
public PdfDedupStreamWriter(Stream stream, bool dispose) : base(stream, dispose)
public PdfDedupStreamWriter(Stream stream, bool dispose, ITokenWriter tokenWriter = null) : base(stream, dispose, tokenWriter)
{
}

View File

@@ -3,7 +3,6 @@ namespace UglyToad.PdfPig.Writer
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Content;
@@ -27,7 +26,7 @@ namespace UglyToad.PdfPig.Writer
private readonly Dictionary<int, PdfPageBuilder> pages = new Dictionary<int, PdfPageBuilder>();
private readonly Dictionary<Guid, FontStored> fonts = new Dictionary<Guid, FontStored>();
private bool completed = false;
internal int fontId = 0;
private int fontId = 0;
private readonly static ArrayToken DefaultProcSet = new ArrayToken(new List<NameToken>
{
@@ -90,20 +89,21 @@ namespace UglyToad.PdfPig.Writer
/// <param name="disposeStream">If stream should be disposed when builder is.</param>
/// <param name="type">Type of pdf stream writer to use</param>
/// <param name="version">Pdf version to use in header.</param>
public PdfDocumentBuilder(Stream stream, bool disposeStream = false, PdfWriterType type = PdfWriterType.Default, decimal version = 1.7m)
/// <param name="tokenWriter">Token writer to use</param>
public PdfDocumentBuilder(Stream stream, bool disposeStream = false, PdfWriterType type = PdfWriterType.Default, decimal version = 1.7m, ITokenWriter tokenWriter = null)
{
switch (type)
{
case PdfWriterType.ObjectInMemoryDedup:
context = new PdfDedupStreamWriter(stream, disposeStream);
context = new PdfDedupStreamWriter(stream, disposeStream, tokenWriter);
break;
default:
context = new PdfStreamWriter(stream, disposeStream);
context = new PdfStreamWriter(stream, disposeStream, tokenWriter);
break;
}
context.InitializePdf(version);
}
/// <summary>
/// Determines whether the bytes of the TrueType font file provided can be used in a PDF document.
/// </summary>

View File

@@ -18,17 +18,17 @@
protected bool DisposeStream { get; set; }
protected bool Initialized { get; set; }
protected int CurrentNumber { get; set; } = 1;
protected readonly static TokenWriter TokenWriter = new TokenWriter();
protected readonly ITokenWriter TokenWriter;
internal PdfStreamWriter(Stream baseStream, bool disposeStream = true)
internal PdfStreamWriter(Stream baseStream, bool disposeStream = true, ITokenWriter tokenWriter = null)
{
Stream = baseStream ?? throw new ArgumentNullException(nameof(baseStream));
if (!baseStream.CanWrite)
{
throw new ArgumentException("Output stream must be writable");
}
DisposeStream = disposeStream;
TokenWriter = tokenWriter ?? new TokenWriter();
}
public Stream Stream { get; protected set; }

View File

@@ -135,14 +135,8 @@
}
}
/// <summary>
/// Writes a valid single section cross-reference (xref) table plus trailer dictionary to the output for the set of object offsets.
/// </summary>
/// <param name="objectOffsets">The byte offset from the start of the document for each object in the document.</param>
/// <param name="catalogToken">The object representing the catalog dictionary which is referenced from the trailer dictionary.</param>
/// <param name="outputStream">The output stream to write to.</param>
/// <param name="documentInformationReference">The object reference for the document information dictionary if present.</param>
internal void WriteCrossReferenceTable(IReadOnlyDictionary<IndirectReference, long> objectOffsets,
/// <inheritdoc cref="ITokenWriter.WriteCrossReferenceTable" />
public void WriteCrossReferenceTable(IReadOnlyDictionary<IndirectReference, long> objectOffsets,
IndirectReference catalogToken,
Stream outputStream,
IndirectReference? documentInformationReference)
@@ -277,14 +271,8 @@
outputStream.Write(Eof, 0, Eof.Length);
}
/// <summary>
/// Writes pre-serialized token as an object token to the output stream.
/// </summary>
/// <param name="objectNumber">Object number of the indirect object.</param>
/// <param name="generation">Generation of the indirect object.</param>
/// <param name="data">Pre-serialized object contents.</param>
/// <param name="outputStream">The stream to write the token to.</param>
internal void WriteObject(long objectNumber, int generation, byte[] data, Stream outputStream)
/// <inheritdoc cref="ITokenWriter.WriteObject" />
public void WriteObject(long objectNumber, int generation, byte[] data, Stream outputStream)
{
WriteLong(objectNumber, outputStream);
WriteWhitespace(outputStream);