Zum Inhalt springen
getnextpdf.com

Pro Edition

Writer — Ausführliche Referenz

Das Writer-Modul schreibt PDF-Revisionen als inkrementelle Aktualisierungen und packt kleine Objekte in Object Streams. Der inkrementelle Writer erzwingt eine fail-closed Append-only-Regel: Jedes Byte, das der Puffer vor einer Revision enthielt, muss danach unverändert bleiben. Der Object-Stream-Builder gruppiert geeignete Objekte in ein einzelnes FlateDecode-komprimiertes /Type /ObjStm-Objekt innerhalb einer festgelegten Größe.

Diese Fähigkeit wird mit NextPDF Pro (nextpdf/pro) ausgeliefert und wird mit einem Lizenz-Envelope der Pro-Stufe aktiviert. Eine Bereitstellung ohne diese Berechtigung lädt die Klassen der Fähigkeit nicht. Editionen vergleichen und eine Lizenz erwerben. Es gibt kein Lizenz-Flag pro Feature; der Code wird mit der Pro-Edition ausgeliefert.

Das Modul liegt im Namespace NextPDF\Pro\Writer. Alle öffentlichen Symbole sind unten aufgeführt. Value Objects sind unveränderliche final readonly-Klassen.

SymbolParameterStandardverhaltenRückgabeWirft oder scheitert mitHinweise
IncrementalUpdateWriter::writeRevisionBinaryBuffer $buffer, ObjectRegistry $registry, int $prevXrefOffset, int $catalogObject, array $catalogEntries, array $catalogUpdates, array $newObjectNumbers, string $fileIdStatisch. Schreibt den Katalog mit zusammengeführten Einträgen neu, hängt eine traditionelle Cross-Reference-Tabelle für neue und geänderte Objekte an und schreibt einen Trailer mit /Size, /Root, /Prev und /ID. Prüft danach, ob das Präfix vor der Revision byteweise gleich ist.int — Byte-Offset der neuen Cross-Reference-Tabelle\NextPDF\Exception\WriterException, wenn die Append-only-Präfixprüfung fehlschlägt; getWriterState() gibt dss-append-only-invariant zurückStatischer Einstiegspunkt. Bei einer Verletzung keine verwertbare Ausgabe.
ObjectStreamWriter::addObjectint $objectNumber, string $contentHängt nach einer Größenprüfung ein Objekt an den ausstehenden Stream an.voidOverflowException, wenn der kombinierte Index plus Body 65.536 Bytes überschreiten würde$content schließt die N 0 obj / endobj-Wrapper aus.
ObjectStreamWriter::canAcceptstring $contentSchätzt den Index-Overhead und prüft die laufende Summe gegen das Maximum.boolWirft nichtReines Prädikat; keine Zustandsänderung.
ObjectStreamWriter::buildkeineBaut den Index auf, verkettet die Bodies, komprimiert mit FlateDecode und umschließt das /Type /ObjStm-Dictionary.string — Roher Object-Stream-InhaltObjectStreamWriteException, wenn keine Objekte hinzugefügt wurden, oder bei einem zlib-KomprimierungsfehlerDer Aufrufer weist die Objektnummer zu und umschließt die Marker.
ObjectStreamWriter::getEntrieskeineBerechnet die body-relativen Offsets für die akkumulierten Objekte neu.list<ObjectStreamEntry>Wirft nichtOffsets sind relativ zum Body-Abschnitt.
ObjectStreamWriter::countkeineMeldet die Anzahl der akkumulierten Objekte.intWirft nicht
ObjStmCompressor::__constructint $maxStreamSize = 65536, int $maxObjectsPerStream = 200Speichert die für die Gruppierung verwendeten Größen- und Objektanzahl-Grenzen.Wirft nichtDie Standardwerte entsprechen dem Object-Stream-Tuning des Moduls.
ObjStmCompressor::groupObjectslist<array{number: int, generation?: int, content: string}> $objectsFiltert ungeeignete Objekte heraus und packt dann den Rest innerhalb der Größen- und Anzahlgrenzen in Writer.list<ObjectStreamWriter>Wirft nicht; ungeeignete Objekte werden übersprungenObjekte mit einer Generation ungleich null fallen auf die normale Serialisierung zurück.
ObjStmCompressor::isEligiblestring $content, int $generation = 0Weist Stream-Objekte, /Encrypt, /XRef, /Catalog und jede Generation ungleich null zurück.boolWirft nichtDas /Type-Matching ist tolerant gegenüber Whitespace und #xx-Escapes.
ObjStmCompressor::writeToBufferlist<ObjectStreamWriter> $streams, BinaryBuffer $buffer, ObjectRegistry $registryAllokiert ein Trägerobjekt pro Stream, registriert Typ-2-komprimierte Einträge und schreibt jeden ObjStm-Block.list<int> — Objektnummern der TrägerobjektePropagiert ObjectStreamWriteException aus build() bei einem seltenen KomprimierungsfehlerNach dem Schreiben der nicht geeigneten Objekte und vor der Ausgabe der Cross-Reference auszuführen.
ObjStmCompressor::estimateSavingslist<ObjectStreamWriter> $streams, int $originalSizeBaut jeden Stream auf, um die komprimierte Größe gegen das Original zu messen.ObjStmCompressionResultPropagiert ObjectStreamWriteException aus build() bei einem seltenen KomprimierungsfehlerSchreibgeschützter Mess-Helfer.
ObjectStreamEntry::__constructint $objectNumber, string $content, int $offsetUnveränderlicher Datensatz eines gepackten Objekts und seines Body-Offsets.Wirft nichtfinal readonly; öffentliche Properties.
ObjStmCompressionResult::__constructint $originalObjectCount, int $streamCount, int $estimatedOriginalSize, int $estimatedCompressedSizeUnveränderlicher Metrik-Container.Wirft nichtfinal readonly; öffentliche Properties.
ObjStmCompressionResult::savedByteskeineGibt die Originalgröße minus die komprimierte Größe zurück.intWirft nichtKann negativ sein, wenn das Packen die Daten vergrößert hat.
ObjStmCompressionResult::savedPercentkeineGibt die prozentuale Reduktion zurück.floatWirft nichtGibt 0.0 zurück, wenn die Originalgröße null ist.
ObjStmCompressionResult::compressionRatiokeineGibt die komprimierte Größe geteilt durch das Original zurück.floatWirft nichtGibt 1.0 zurück, wenn die Originalgröße null ist.
ObjectStreamWriteExceptionSignalisiert einen Fehler beim Aufbau eines Object Streams.Erweitert RuntimeExceptionVon build() geworfen; über RuntimeException abfangbar zur Abwärtskompatibilität.
final class IncrementalUpdateWriter
{
public static function writeRevision(
BinaryBuffer $buffer,
ObjectRegistry $registry,
int $prevXrefOffset,
int $catalogObject,
array $catalogEntries,
array $catalogUpdates,
array $newObjectNumbers,
string $fileId,
): int;
}
final class ObjectStreamWriter
{
public function addObject(int $objectNumber, string $content): void;
public function canAccept(string $content): bool;
public function build(): string;
/** @return list<ObjectStreamEntry> */
public function getEntries(): array;
public function count(): int;
}
final class ObjStmCompressor
{
public function __construct(
int $maxStreamSize = 65536,
int $maxObjectsPerStream = 200,
);
/**
* @param list<array{number: int, generation?: int, content: string}> $objects
* @return list<ObjectStreamWriter>
*/
public function groupObjects(array $objects): array;
public function isEligible(string $content, int $generation = 0): bool;
/**
* @param list<ObjectStreamWriter> $streams
* @return list<int>
*/
public function writeToBuffer(array $streams, BinaryBuffer $buffer, ObjectRegistry $registry): array;
/** @param list<ObjectStreamWriter> $streams */
public function estimateSavings(array $streams, int $originalSize): ObjStmCompressionResult;
}

writeRevision schreibt eine Revision als inkrementelle Aktualisierung. Es erstellt vor dem Schreiben einen Snapshot des bestehenden Puffer-Präfixes. Es schreibt den Katalog mit zusammengeführten Einträgen neu, registriert neue Objekt-Offsets, schreibt eine traditionelle Cross-Reference-Tabelle, die in zusammenhängende Untersektionen gruppiert ist, und schreibt einen Trailer mit /Size, /Root, /Prev und /ID. Nach dem Schreiben vergleicht es das Präfix erneut. Wenn sich ein früheres Byte geändert hat, wirft es WriterException mit dem Zustand der Append-only-Verletzung und gibt keine verwertbare Ausgabe zurück. Bei Erfolg gibt es den Byte-Offset der neuen Cross-Reference-Tabelle zur Verkettung weiterer Revisionen zurück. Das Mischen von Cross-Reference-Tabellen und -Streams über Revisionen hinweg ist erlaubt.

ObjectStreamWriter akkumuliert Objekte. addObject wirft einen Overflow-Fehler, wenn der kombinierte Index und Body das Maximum von 65.536 Bytes unkomprimiert überschreiten würden. build wirft einen Fehler bei einem leeren Stream; andernfalls komprimiert es den Index plus Body und gibt den Object-Stream-Inhalt mit den Einträgen /Type /ObjStm, /N, /First, /Length und /Filter /FlateDecode zurück. Der Aufrufer weist die Objektnummer zu und umschließt die N 0 obj / endobj-Marker.

ObjStmCompressor entscheidet, welche Objekte gepackt werden. Es schließt Stream-Objekte, Verschlüsselungs-Dictionaries, Cross-Reference-Streams, den Dokumentkatalog und jedes Objekt mit einer Generationsnummer ungleich null aus. writeToBuffer allokiert ein Trägerobjekt pro Stream, registriert jedes gepackte Objekt als Typ-2-komprimierten Cross-Reference-Eintrag und schreibt den ObjStm-Block am aktuellen Puffer-Offset. estimateSavings baut jeden Stream auf, um Größenmetriken zu berechnen, ohne den Puffer zu verändern.

  • Die Append-only-Prüfung kopiert das bestehende Präfix. Ihre Kosten wachsen mit der Größe des bereits geschriebenen Dokuments. Diese Kosten sind beabsichtigt und schützen signierte Bytes.
  • Die Object-Stream-Grenze gilt für den unkomprimierten Index plus Body. Platzieren Sie das Verschlüsselungs-Dictionary und andere ausgeschlossene Objekttypen als direkte indirekte Objekte.
  • Der /Type-Ausschluss ist tolerant gegenüber beliebigem Whitespace zwischen Tokens und #xx-Hex-Escapes. Formen wie /Type /Encrypt, /Type\n/Encrypt und /Type /#45ncrypt werden allesamt zurückgewiesen, nicht nur die kanonische literale Schreibweise.
  • Jedes Objekt mit einer Generationsnummer ungleich null wird als ungeeignet behandelt und fällt auf die normale N G obj … endobj-Serialisierung zurück, da die Generation eines komprimierten Objekts implizit null ist.
  • writeToBuffer muss ausgeführt werden, nachdem alle nicht geeigneten Objekte geschrieben wurden und bevor die Cross-Reference ausgegeben wird. Gepackte Objekte dürfen nicht zusätzlich separat serialisiert werden.

Das Writer-Modul führt keine kryptografischen Operationen durch. Es schützt signierte Bytes, indem es die Ausgabe verweigert, wenn sich ein früheres Byte ändern würde, was eine Byte-Gleichheitsprüfung und keine kryptografische Prüfung ist. Die FIPS-Algorithmusauswahl für Signierung und Hashing wird vom Signaturmodul gesteuert, nicht von diesem Writer. Das Aktivieren oder Deaktivieren des FIPS-Modus ändert das Verhalten keiner Writer-Methode.

NextPDF implementiert das Modul gegen ISO 32000-2:2020. Der inkrementelle Writer folgt der Grammatik für inkrementelle Aktualisierungen aus §7.5.6: Jede Revision hängt eine Cross-Reference-Sektion an, die nur neue, geänderte oder gelöschte Objekte abdeckt, sowie einen Trailer, dessen /Prev-Eintrag den Offset der vorherigen Cross-Reference angibt. Der Object-Stream-Builder folgt dem Object-Stream-Modell aus §7.5.7: Ein Index aus Paaren von Objektnummer und Offset, mit ab dem /First-Eintrag in aufsteigender Reihenfolge gemessenen Offsets, geht den gepackten Objekt-Bodies voraus. Beide Klauselreferenzen wurden gegen das Korpus von ISO 32000-2:2020 verifiziert. Die Revisionsverkettung für PAdES B-LT- und B-LTA-Workflows folgt ETSI EN 319 142-1 §5.4, wie im Quellcode annotiert. Die Unterstützung einer Klausel ist eine technische Fähigkeitsaussage, keine Zertifizierung; NextPDF besitzt keine formale Konformitätszertifizierung.

  • Installieren Sie das Paket mit composer require nextpdf/pro:^3. Die Klassen werden unter NextPDF\Pro\Writer aufgelöst.
  • IncrementalUpdateWriter::writeRevision ist ein statischer Einstiegspunkt; es hält keinen Instanzzustand zwischen Revisionen.
  • ObjectStreamEntry, ObjStmCompressionResult, IncrementalUpdateWriter und der Compressor bilden zusammen die öffentliche Oberfläche des Moduls; das Repository liefert kein lauffähiges Beispiel dafür aus.
  • Eine WriterException aus writeRevision weist auf eine Append-only-Verletzung hin. Behandeln Sie sie als harten Fehler und verwerfen Sie den Puffer.
  • Object-Stream-Träger sind indirekte Objekte; der Aufrufer weist ihre Objektnummern über die Registry zu.

Diese Seite dokumentiert ausschließlich das extern beobachtbare Verhalten und die unterstützte öffentliche API-Oberfläche. Interne Namespace-Pfade, Hilfsklassen, Mechanismus-Tabellen, Runbook-Dateinamen und Ticket-Präfixe sind nicht im Umfang enthalten.