Package com.pd4ml.pdf.cos.writer
Class IncrementalUpdateWriter
- java.lang.Object
-
- com.pd4ml.pdf.cos.writer.IncrementalUpdateWriter
-
public final class IncrementalUpdateWriter extends java.lang.ObjectAppends a PDF incremental update (ISO 32000-1 §7.5.6) over an existing file's bytes: new and/or rewritten indirect objects, a classic cross-reference table covering just those objects, and a trailer whose/Prevchains back to the base file's own cross-reference section.This is the generic mechanics every incremental-update writer needs (allocate object numbers, track byte offsets, emit a correct xref + trailer) with no knowledge of what's actually being added -- filling a form field, adding an annotation, appending a digital signature (see
com.pd4ml.pdf.sign.pdf.IncrementalPdfSigner, which builds on this), or anything else. The original bytes are never modified; nothing is re-parsed or re-validated beyond whatCOSParseralready did to produce theCOSDocumentpassed in.Typical use:
IncrementalUpdateWriter update = new IncrementalUpdateWriter(originalBytes, document); COSDictionary newThing = new COSDictionary(); update.assignNewKey(newThing); someExistingDict.setItem("Foo", newThing); // wire it in update.writeObject(someExistingDict); // it changed -> must be rewritten update.writeObject(newThing); // brand new -> also written byte[] result = update.finish();
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interfaceIncrementalUpdateWriter.CustomBodyWriterCallback forwriteObjectCustom(com.pd4ml.pdf.cos.COSObjectKey, com.pd4ml.pdf.cos.writer.IncrementalUpdateWriter.CustomBodyWriter): writes exactly one object's body (no header/endobj -- those are handled for you).
-
Constructor Summary
Constructors Constructor Description IncrementalUpdateWriter(byte[] originalBytes, COSDocument document)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description COSObjectKeyallocateKey()Allocates the next free object number (generation 0) for a new indirect object.voidassignNewKey(COSBase obj)Allocates a key and assigns it toobjin one step --objis now a new indirect object.byte[]finish()Finishes the update: writes the cross-reference table for every object written so far, then a trailer (/Size,/Rootfrom the parsed document's catalog,/Infoif the original had one, a fresh/ID, and/Prevchained back to the base file's ownstartxref), and returns the complete file (original bytes + this update).longnextObjectNumber()Highest object number this writer has handed out so far (i.e.intposition()Current length of the buffer being built, i.e.voidwriteObject(COSBase obj)Writesobjas a complete indirect object using its own (already-assigned, viaassignNewKey(com.pd4ml.pdf.cos.COSBase)or from the original parse) key, recording its offset for the xref table.voidwriteObjectCustom(COSObjectKey key, IncrementalUpdateWriter.CustomBodyWriter bodyWriter)LikewriteObject(com.pd4ml.pdf.cos.COSBase), but the object's body is written bybodyWriterinstead of the genericCOSWritervisitor -- for the rare case where a caller needs to track exact byte offsets inside the body itself (a PDF signature's/Contentsand/ByteRangebeing the motivating example).COSWriterwriter()The sharedCOSWriter, for callers that need to hand-write part of an object's body (seewriteObjectCustom(com.pd4ml.pdf.cos.COSObjectKey, com.pd4ml.pdf.cos.writer.IncrementalUpdateWriter.CustomBodyWriter)).
-
-
-
Constructor Detail
-
IncrementalUpdateWriter
public IncrementalUpdateWriter(byte[] originalBytes, COSDocument document)
-
-
Method Detail
-
allocateKey
public COSObjectKey allocateKey()
Allocates the next free object number (generation 0) for a new indirect object.
-
assignNewKey
public void assignNewKey(COSBase obj)
Allocates a key and assigns it toobjin one step --objis now a new indirect object.
-
writer
public COSWriter writer()
The sharedCOSWriter, for callers that need to hand-write part of an object's body (seewriteObjectCustom(com.pd4ml.pdf.cos.COSObjectKey, com.pd4ml.pdf.cos.writer.IncrementalUpdateWriter.CustomBodyWriter)).
-
position
public int position()
Current length of the buffer being built, i.e. the absolute file offset the next byte written will land at.
-
writeObject
public void writeObject(COSBase obj) throws COSException
Writesobjas a complete indirect object using its own (already-assigned, viaassignNewKey(com.pd4ml.pdf.cos.COSBase)or from the original parse) key, recording its offset for the xref table. Use this both for brand-new objects and for existing objects you've mutated in place and need rewritten under the same identity.- Throws:
COSException
-
writeObjectCustom
public void writeObjectCustom(COSObjectKey key, IncrementalUpdateWriter.CustomBodyWriter bodyWriter) throws COSException
LikewriteObject(com.pd4ml.pdf.cos.COSBase), but the object's body is written bybodyWriterinstead of the genericCOSWritervisitor -- for the rare case where a caller needs to track exact byte offsets inside the body itself (a PDF signature's/Contentsand/ByteRangebeing the motivating example).- Throws:
COSException
-
finish
public byte[] finish() throws COSExceptionFinishes the update: writes the cross-reference table for every object written so far, then a trailer (/Size,/Rootfrom the parsed document's catalog,/Infoif the original had one, a fresh/ID, and/Prevchained back to the base file's ownstartxref), and returns the complete file (original bytes + this update). Call at most once.- Throws:
COSException
-
nextObjectNumber
public long nextObjectNumber()
Highest object number this writer has handed out so far (i.e. what/Sizewill become).
-
-