Ga naar inhoud
getnextpdf.com

Pro editie

Writer — Diepe referentie

De Writer-module schrijft PDF incremental-update-revisies en pakt kleine objecten in Object Streams. De incremental writer dwingt een fail-closed append-only-regel af: elke byte die de buffer vóór een revisie bevatte, moet erna ongewijzigd blijven. De Object Stream-builder groepeert geschikte objecten in één met FlateDecode gecomprimeerd /Type /ObjStm-object binnen een begrensde omvang.

Deze mogelijkheid wordt geleverd in NextPDF Pro (nextpdf/pro) en wordt geactiveerd met een licentie-envelope van het Pro-niveau. Een deployment zonder die entitlement laadt de klassen van de mogelijkheid niet. Vergelijk edities en vraag een licentie aan. Er is geen licentievlag per feature; de code wordt geleverd met de Pro-editie.

De module leeft onder de namespace NextPDF\Pro\Writer. Alle publieke symbolen staan hieronder. Value objects zijn immutable final readonly-klassen.

SymboolParametersStandaardgedragRetourneertWerpt of faalt metOpmerkingen
IncrementalUpdateWriter::writeRevisionBinaryBuffer $buffer, ObjectRegistry $registry, int $prevXrefOffset, int $catalogObject, array $catalogEntries, array $catalogUpdates, array $newObjectNumbers, string $fileIdStatisch. Herschrijft de catalogus met samengevoegde entries, voegt een traditionele cross-reference table toe voor nieuwe en gewijzigde objecten, en schrijft een trailer met /Size, /Root, /Prev en /ID. Verifieert daarna dat de prefix van vóór de revisie byte-gelijk is.int — byte-offset van de nieuwe cross-reference table\NextPDF\Exception\WriterException wanneer de append-only-prefixcontrole faalt; getWriterState() retourneert dss-append-only-invariantStatisch entry point. Geen bruikbare uitvoer bij schending.
ObjectStreamWriter::addObjectint $objectNumber, string $contentVoegt één object toe aan de pending stream na een groottecontrole.voidOverflowException wanneer de gecombineerde index plus body 65.536 bytes zou overschrijden$content sluit de N 0 obj / endobj-wrappers uit.
ObjectStreamWriter::canAcceptstring $contentSchat de index-overhead en toetst het lopende totaal aan het maximum.boolWerpt nietZuivere predicaat; geen statuswijziging.
ObjectStreamWriter::buildgeenBouwt de index, concateneert bodies, comprimeert met FlateDecode en wikkelt het /Type /ObjStm-dictionary.string — ruwe Object Stream-inhoudObjectStreamWriteException wanneer geen objecten zijn toegevoegd, of bij een zlib-compressiefoutDe caller wijst het objectnummer toe en wikkelt de markers.
ObjectStreamWriter::getEntriesgeenHerberekent body-relatieve offsets voor de verzamelde objecten.list<ObjectStreamEntry>Werpt nietOffsets zijn relatief aan de body-sectie.
ObjectStreamWriter::countgeenRapporteert het aantal verzamelde objecten.intWerpt niet
ObjStmCompressor::__constructint $maxStreamSize = 65536, int $maxObjectsPerStream = 200Bewaart de grootte- en objectaantallimieten die voor het groeperen worden gebruikt.Werpt nietStandaardwaarden komen overeen met de Object Stream-tuning van de module.
ObjStmCompressor::groupObjectslist<array{number: int, generation?: int, content: string}> $objectsFiltert ongeschikte objecten en pakt de rest in writers binnen de grootte- en aantallimieten.list<ObjectStreamWriter>Werpt niet; ongeschikte objecten worden overgeslagenObjecten met een generation-nummer ongelijk aan nul vallen terug op normale serialisatie.
ObjStmCompressor::isEligiblestring $content, int $generation = 0Weigert stream-objecten, /Encrypt, /XRef, /Catalog en elke generation ongelijk aan nul.boolWerpt niet/Type-matching is tolerant voor whitespace en #xx-escapes.
ObjStmCompressor::writeToBufferlist<ObjectStreamWriter> $streams, BinaryBuffer $buffer, ObjectRegistry $registryAlloceert een carrier-object per stream, registreert type-2 gecomprimeerde entries en schrijft elk ObjStm-blok.list<int> — carrier-objectnummersPropageert ObjectStreamWriteException vanuit build() bij een zeldzame compressiefoutUit te voeren nadat niet-geschikte objecten zijn geschreven en vóór de cross-reference wordt uitgezonden.
ObjStmCompressor::estimateSavingslist<ObjectStreamWriter> $streams, int $originalSizeBouwt elke stream om de gecomprimeerde omvang tegen het origineel te meten.ObjStmCompressionResultPropageert ObjectStreamWriteException vanuit build() bij een zeldzame compressiefoutAlleen-lezen meethulp.
ObjectStreamEntry::__constructint $objectNumber, string $content, int $offsetImmutable record van één ingepakt object en zijn body-offset.Werpt nietfinal readonly; publieke properties.
ObjStmCompressionResult::__constructint $originalObjectCount, int $streamCount, int $estimatedOriginalSize, int $estimatedCompressedSizeImmutable metrics-container.Werpt nietfinal readonly; publieke properties.
ObjStmCompressionResult::savedBytesgeenRetourneert originele omvang minus gecomprimeerde omvang.intWerpt nietKan negatief zijn wanneer het inpakken de data heeft laten groeien.
ObjStmCompressionResult::savedPercentgeenRetourneert de procentuele reductie.floatWerpt nietRetourneert 0.0 wanneer de originele omvang nul is.
ObjStmCompressionResult::compressionRatiogeenRetourneert gecomprimeerde omvang gedeeld door origineel.floatWerpt nietRetourneert 1.0 wanneer de originele omvang nul is.
ObjectStreamWriteExceptionSignaleert een Object Stream-buildfout.Breidt RuntimeException uitGeworpen door build(); opvangbaar via RuntimeException voor achterwaartse compatibiliteit.
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 schrijft één incremental-update-revisie. Het maakt een snapshot van de bestaande bufferprefix voordat het schrijft. Het herschrijft de catalogus met samengevoegde entries, registreert nieuwe object-offsets, schrijft een traditionele cross-reference table gegroepeerd in aaneengesloten subsecties, en schrijft een trailer met /Size, /Root, /Prev en /ID. Na het schrijven vergelijkt het de prefix opnieuw. Als een eerdere byte is gewijzigd, werpt het WriterException die de append-only-violation-status draagt en retourneert het geen bruikbare uitvoer. Bij succes retourneert het de byte-offset van de nieuwe cross-reference table om verdere revisies aaneen te ketenen. Het mengen van cross-reference tables en streams over revisies heen is toegestaan.

ObjectStreamWriter verzamelt objecten. addObject werpt een overflow-fout wanneer de gecombineerde index en body het maximum van 65.536 bytes ongecomprimeerd zouden overschrijden. build werpt een fout bij een lege stream; anders comprimeert het de index plus body en retourneert het de Object Stream-inhoud met de entries /Type /ObjStm, /N, /First, /Length en /Filter /FlateDecode. De caller wijst het objectnummer toe en wikkelt de N 0 obj / endobj-markers.

ObjStmCompressor beslist welke objecten worden ingepakt. Het sluit stream-objecten, encryption dictionaries, cross-reference streams, de document-catalogus en elk object met een generation-nummer ongelijk aan nul uit. writeToBuffer alloceert een carrier-object per stream, registreert elk ingepakt object als een type-2 gecomprimeerde cross-reference entry, en schrijft het ObjStm-blok op de huidige buffer-offset. estimateSavings bouwt elke stream om de groottemetrieken te berekenen zonder de buffer te muteren.

  • De append-only-controle kopieert de bestaande prefix. De kosten ervan groeien mee met de grootte van het al geschreven document. Deze kosten zijn opzettelijk en beschermen ondertekende bytes.
  • De Object Stream-limiet geldt voor de ongecomprimeerde index plus body. Plaats het encryption dictionary en andere uitgesloten objecttypen als directe indirecte objecten.
  • De /Type-uitsluiting is tolerant voor willekeurige inter-token-whitespace en #xx-hex-escaping. Vormen zoals /Type /Encrypt, /Type\n/Encrypt en /Type /#45ncrypt worden allemaal geweigerd, niet alleen de canonieke letterlijke schrijfwijze.
  • Elk object met een generation-nummer ongelijk aan nul wordt als ongeschikt behandeld en valt terug op normale N G obj … endobj-serialisatie, omdat de generation van een gecomprimeerd object impliciet nul is.
  • writeToBuffer moet worden uitgevoerd nadat alle niet-geschikte objecten zijn geschreven en vóór de cross-reference wordt uitgezonden. Ingepakte objecten mogen niet ook afzonderlijk worden geserialiseerd.

De Writer-module voert geen cryptografische bewerkingen uit. Het beschermt ondertekende bytes door te weigeren uit te zenden wanneer een eerdere byte zou veranderen, wat een byte-gelijkheidstest is en geen cryptografische test. De FIPS-algoritmeselectie voor ondertekenen en hashen wordt beheerd door de ondertekeningsmodule, niet door deze writer. Het in- of uitschakelen van de FIPS-modus verandert het gedrag van geen enkele Writer-methode.

NextPDF implementeert de module tegen ISO 32000-2:2020. De incremental writer volgt de incremental-update-grammatica uit §7.5.6: elke revisie voegt een cross-reference-sectie toe die alleen nieuwe, gewijzigde of verwijderde objecten dekt, en een trailer waarvan de /Prev-entry de offset van de vorige cross-reference aangeeft. De Object Stream-builder volgt het object-stream-model uit §7.5.7: een index van paren object-nummer en offset, met offsets gemeten vanaf de /First-entry in oplopende volgorde, gaat vooraf aan de ingepakte object-bodies. Beide clausulereferenties zijn geverifieerd tegen het ISO 32000-2:2020-corpus. Het aaneenketenen van revisies voor PAdES B-LT- en B-LTA-workflows volgt ETSI EN 319 142-1 §5.4, zoals geannoteerd in de bron. Ondersteuning voor een clausule is een engineering-capaciteitsverklaring, geen certificering; NextPDF beschikt over geen formele conformiteitscertificering.

  • Installeer het package met composer require nextpdf/pro:^3. De klassen resolven onder NextPDF\Pro\Writer.
  • IncrementalUpdateWriter::writeRevision is een statisch entry point; het houdt geen instance-status vast tussen revisies.
  • ObjectStreamEntry, ObjStmCompressionResult, IncrementalUpdateWriter en de compressor vormen samen het publieke oppervlak van de module; de repository levert er geen uitvoerbaar voorbeeld bij.
  • Een WriterException vanuit writeRevision duidt op een append-only-schending. Behandel het als een harde fout en gooi de buffer weg.
  • Object Stream-carriers zijn indirecte objecten; de caller wijst hun objectnummers toe via de registry.

Deze pagina documenteert uitsluitend extern waarneembaar gedrag en het ondersteunde publieke API-oppervlak. Interne namespace-paden, helper-klassen, mechanisme-tabellen, runbook-bestandsnamen en ticket-prefixes vallen buiten de scope.