Pro editie
Writer — Diepe referentie
In één oogopslag
Sectie met titel “In één oogopslag”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.
Beschikbaarheid en licentie
Sectie met titel “Beschikbaarheid en licentie”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.
Publiek API-oppervlak
Sectie met titel “Publiek API-oppervlak”De module leeft onder de namespace NextPDF\Pro\Writer. Alle publieke symbolen staan hieronder. Value objects zijn immutable final readonly-klassen.
| Symbool | Parameters | Standaardgedrag | Retourneert | Werpt of faalt met | Opmerkingen |
|---|---|---|---|---|---|
IncrementalUpdateWriter::writeRevision | BinaryBuffer $buffer, ObjectRegistry $registry, int $prevXrefOffset, int $catalogObject, array $catalogEntries, array $catalogUpdates, array $newObjectNumbers, string $fileId | Statisch. 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-invariant | Statisch entry point. Geen bruikbare uitvoer bij schending. |
ObjectStreamWriter::addObject | int $objectNumber, string $content | Voegt één object toe aan de pending stream na een groottecontrole. | void | OverflowException wanneer de gecombineerde index plus body 65.536 bytes zou overschrijden | $content sluit de N 0 obj / endobj-wrappers uit. |
ObjectStreamWriter::canAccept | string $content | Schat de index-overhead en toetst het lopende totaal aan het maximum. | bool | Werpt niet | Zuivere predicaat; geen statuswijziging. |
ObjectStreamWriter::build | geen | Bouwt de index, concateneert bodies, comprimeert met FlateDecode en wikkelt het /Type /ObjStm-dictionary. | string — ruwe Object Stream-inhoud | ObjectStreamWriteException wanneer geen objecten zijn toegevoegd, of bij een zlib-compressiefout | De caller wijst het objectnummer toe en wikkelt de markers. |
ObjectStreamWriter::getEntries | geen | Herberekent body-relatieve offsets voor de verzamelde objecten. | list<ObjectStreamEntry> | Werpt niet | Offsets zijn relatief aan de body-sectie. |
ObjectStreamWriter::count | geen | Rapporteert het aantal verzamelde objecten. | int | Werpt niet | — |
ObjStmCompressor::__construct | int $maxStreamSize = 65536, int $maxObjectsPerStream = 200 | Bewaart de grootte- en objectaantallimieten die voor het groeperen worden gebruikt. | — | Werpt niet | Standaardwaarden komen overeen met de Object Stream-tuning van de module. |
ObjStmCompressor::groupObjects | list<array{number: int, generation?: int, content: string}> $objects | Filtert ongeschikte objecten en pakt de rest in writers binnen de grootte- en aantallimieten. | list<ObjectStreamWriter> | Werpt niet; ongeschikte objecten worden overgeslagen | Objecten met een generation-nummer ongelijk aan nul vallen terug op normale serialisatie. |
ObjStmCompressor::isEligible | string $content, int $generation = 0 | Weigert stream-objecten, /Encrypt, /XRef, /Catalog en elke generation ongelijk aan nul. | bool | Werpt niet | /Type-matching is tolerant voor whitespace en #xx-escapes. |
ObjStmCompressor::writeToBuffer | list<ObjectStreamWriter> $streams, BinaryBuffer $buffer, ObjectRegistry $registry | Alloceert een carrier-object per stream, registreert type-2 gecomprimeerde entries en schrijft elk ObjStm-blok. | list<int> — carrier-objectnummers | Propageert ObjectStreamWriteException vanuit build() bij een zeldzame compressiefout | Uit te voeren nadat niet-geschikte objecten zijn geschreven en vóór de cross-reference wordt uitgezonden. |
ObjStmCompressor::estimateSavings | list<ObjectStreamWriter> $streams, int $originalSize | Bouwt elke stream om de gecomprimeerde omvang tegen het origineel te meten. | ObjStmCompressionResult | Propageert ObjectStreamWriteException vanuit build() bij een zeldzame compressiefout | Alleen-lezen meethulp. |
ObjectStreamEntry::__construct | int $objectNumber, string $content, int $offset | Immutable record van één ingepakt object en zijn body-offset. | — | Werpt niet | final readonly; publieke properties. |
ObjStmCompressionResult::__construct | int $originalObjectCount, int $streamCount, int $estimatedOriginalSize, int $estimatedCompressedSize | Immutable metrics-container. | — | Werpt niet | final readonly; publieke properties. |
ObjStmCompressionResult::savedBytes | geen | Retourneert originele omvang minus gecomprimeerde omvang. | int | Werpt niet | Kan negatief zijn wanneer het inpakken de data heeft laten groeien. |
ObjStmCompressionResult::savedPercent | geen | Retourneert de procentuele reductie. | float | Werpt niet | Retourneert 0.0 wanneer de originele omvang nul is. |
ObjStmCompressionResult::compressionRatio | geen | Retourneert gecomprimeerde omvang gedeeld door origineel. | float | Werpt niet | Retourneert 1.0 wanneer de originele omvang nul is. |
ObjectStreamWriteException | — | Signaleert een Object Stream-buildfout. | — | Breidt RuntimeException uit | Geworpen door build(); opvangbaar via RuntimeException voor achterwaartse compatibiliteit. |
Signaturen van de entry points
Sectie met titel “Signaturen van de entry points”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;}Gedragscontract
Sectie met titel “Gedragscontract”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.
Randgevallen en faalmodi
Sectie met titel “Randgevallen en faalmodi”- 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/Encrypten/Type /#45ncryptworden 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. writeToBuffermoet 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.
Gedrag in FIPS-modus
Sectie met titel “Gedrag in FIPS-modus”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.
Conformiteit
Sectie met titel “Conformiteit”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.
Ontwikkelnotities
Sectie met titel “Ontwikkelnotities”- Installeer het package met
composer require nextpdf/pro:^3. De klassen resolven onderNextPDF\Pro\Writer. IncrementalUpdateWriter::writeRevisionis een statisch entry point; het houdt geen instance-status vast tussen revisies.ObjectStreamEntry,ObjStmCompressionResult,IncrementalUpdateWriteren de compressor vormen samen het publieke oppervlak van de module; de repository levert er geen uitvoerbaar voorbeeld bij.- Een
WriterExceptionvanuitwriteRevisionduidt 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.
Publicatiegrens
Sectie met titel “Publicatiegrens”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.