Xref table expose#1292
Conversation
BobLd
left a comment
There was a problem hiding this comment.
you can also un-comment the asserts in PdfMergerTests
| public IReadOnlyDictionary<IndirectReference, long> ObjectOffsets { get; } | ||
| public IReadOnlyDictionary<IndirectReference, XrefLocation> ObjectOffsets { get; } | ||
|
|
||
| public long Offset { get; private set; } |
There was a problem hiding this comment.
no need for private set;, read only
| public class CrossReferenceTable | ||
| { | ||
| private readonly Dictionary<IndirectReference, long> objectOffsets; | ||
| private readonly List<CrossReferenceTablePart> parts; |
There was a problem hiding this comment.
Change to CrossReferenceTablePart[], no need for a list from what I see
| foreach (var objectOffset in objectOffsets) | ||
| this.objectOffsets = objectOffsets.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); | ||
| var result = new List<CrossReferenceOffset>(); |
There was a problem hiding this comment.
Use a CrossReferenceOffset[] instead
| for (var i = 1; i < parts.Count; i++) | ||
| { | ||
| result[objectOffset.Key] = objectOffset.Value; | ||
| result.Add(new CrossReferenceOffset(parts[i].Offset, parts[i - 1].Previous)); |
There was a problem hiding this comment.
can you double check that it should not be the below instead:
foreach (var part in parts)
{
result.Add(new CrossReferenceOffset(part.Offset, part.Previous));
}|
I have review your PR, let me know if any question, great job! |
|
Also, review |
|
@BobLd Thank you for the review! I’ve applied all the suggested changes:
Could you please take another look when you have time? Thanks again! |
BobLd
left a comment
There was a problem hiding this comment.
Can you also review the AdvanceMerge example? It produces a blank page. Can you also add this example as an integration test, if possible?
| using var output = new FileStream(Path.Combine(filesDirectory, "AdvancedMergeResult.pdf"), FileMode.Create); | ||
| using var input = File.Open(Path.Combine(filesDirectory, "Single Page Simple - from google drive.pdf"), FileMode.Open); | ||
|
|
||
| input2.CopyToAsync(output); |
There was a problem hiding this comment.
input2.CopyToAsync(output); is not awaited, input2.CopyTo(output); should be enough
| /// <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> | ||
| /// /// <param name="prevTableLocation">The offset to the previous xref table if present</param> |
| () => | ||
| { | ||
| using var input2 = File.Open(Path.Combine(filesDirectory, "EmptyPdf.pdf"), FileMode.Open); | ||
| using var output = new FileStream(Path.Combine(filesDirectory, "AdvancedMergeResult.pdf"), FileMode.Create); |
There was a problem hiding this comment.
let's not write the output document to the integration tests folder. new FileStream("AdvancedMergeResult.pdf") should be enough
|
@vafle228 I've added some more comments, let me know if any question. Can you also add an integration test based on |
- Also added nice property for calculating Prev
|
@BobLd Thank you for the new comments! My bad with the |
|
note to self:
|
Description
This PR addresses a long-standing limitation for developers needing to implement incremental PDF updates (e.g., for digital signatures, form filling, or appending objects without full re‑saving). Currently, the
PdfDocument.Structureexposes limited low‑level access, because theCrossReferenceTable(old property) is missing, and the core token writer lacks support for writing a custom xref table with/Prevtrailer.The changes in this PR restore and extend the low-level API to fully support reading and writing both normal xref tables and xref streams, as well as working with trailer dictionaries. This makes it possible to:
CrossReferenceTablePartentries (object number, offset, generation, type)./Prev,/Size,/Root,/Info).Changes Made
CrossReferenceTableis now fully exposed viaPdfDocument.Structure.CrossReferenceTable(previously it was removed). It provides:
ObjectOffsets– mapping fromIndirectReferencetoXrefLocation.Parts- single instance of xref tableTrailerDictionarynow exposes/Prev,/Size,/Root,/Info(and all raw dictionary entries).TokenWriterhas been extended with a new method:AdvancedMerge.csexample of low level tools usage