Pro edizione
Writer — Riferimento approfondito
In sintesi
Sezione intitolata “In sintesi”Il modulo Writer scrive revisioni PDF di tipo incremental-update e impacchetta gli oggetti di piccole dimensioni negli Object Stream. Il writer incrementale applica una regola append-only fail-closed: ogni byte contenuto nel buffer prima di una revisione deve rimanere invariato dopo di essa. Il costruttore di Object Stream raggruppa gli oggetti idonei in un unico oggetto /Type /ObjStm compresso con FlateDecode entro una dimensione delimitata.
Disponibilità e licenza
Sezione intitolata “Disponibilità e licenza”Questa funzionalità è distribuita in NextPDF Pro (nextpdf/pro) e si attiva con un envelope di licenza di livello Pro. Un deployment privo di tale entitlement non carica le classi della funzionalità. Confronta le edizioni e ottieni una licenza. Non esiste un flag di licenza per singola funzionalità; il codice è distribuito con l’edizione Pro.
Superficie API pubblica
Sezione intitolata “Superficie API pubblica”Il modulo risiede nel namespace NextPDF\Pro\Writer. Di seguito sono elencati tutti i simboli pubblici. I value object sono classi immutabili final readonly.
| Simbolo | Parametri | Comportamento predefinito | Restituisce | Solleva o fallisce con | Note |
|---|---|---|---|---|---|
IncrementalUpdateWriter::writeRevision | BinaryBuffer $buffer, ObjectRegistry $registry, int $prevXrefOffset, int $catalogObject, array $catalogEntries, array $catalogUpdates, array $newObjectNumbers, string $fileId | Statico. Riscrive il catalogo con le voci unite, aggiunge in coda una tabella di cross-reference tradizionale per gli oggetti nuovi e modificati e scrive un trailer con /Size, /Root, /Prev e /ID. Verifica successivamente che il prefisso pre-revisione sia byte-equal. | int — offset di byte della nuova tabella di cross-reference | \NextPDF\Exception\WriterException quando la verifica append-only del prefisso fallisce; getWriterState() restituisce dss-append-only-invariant | Punto di ingresso statico. Nessun output utilizzabile in caso di violazione. |
ObjectStreamWriter::addObject | int $objectNumber, string $content | Aggiunge un oggetto allo stream pendente dopo un controllo di dimensione. | void | OverflowException quando l’indice più il corpo combinati supererebbero 65.536 byte | $content esclude i wrapper N 0 obj / endobj. |
ObjectStreamWriter::canAccept | string $content | Stima l’overhead dell’indice e verifica il totale corrente rispetto al massimo. | bool | Non solleva eccezioni | Predicato puro; nessuna modifica di stato. |
ObjectStreamWriter::build | nessuno | Costruisce l’indice, concatena i corpi, comprime con FlateDecode e racchiude il dizionario /Type /ObjStm. | string — contenuto grezzo dell’Object Stream | ObjectStreamWriteException quando non è stato aggiunto alcun oggetto, o su un errore di compressione zlib | Il chiamante assegna il numero dell’oggetto e racchiude i marker. |
ObjectStreamWriter::getEntries | nessuno | Ricalcola gli offset relativi al corpo per gli oggetti accumulati. | list<ObjectStreamEntry> | Non solleva eccezioni | Gli offset sono relativi alla sezione del corpo. |
ObjectStreamWriter::count | nessuno | Riporta il numero di oggetti accumulati. | int | Non solleva eccezioni | — |
ObjStmCompressor::__construct | int $maxStreamSize = 65536, int $maxObjectsPerStream = 200 | Memorizza i limiti di dimensione e di conteggio degli oggetti usati per il raggruppamento. | — | Non solleva eccezioni | I valori predefiniti corrispondono alla taratura degli Object Stream del modulo. |
ObjStmCompressor::groupObjects | list<array{number: int, generation?: int, content: string}> $objects | Filtra gli oggetti non idonei, quindi impacchetta i restanti in writer entro i limiti di dimensione e conteggio. | list<ObjectStreamWriter> | Non solleva eccezioni; gli oggetti non idonei vengono ignorati | Gli oggetti con generation diversa da zero ricadono nella serializzazione normale. |
ObjStmCompressor::isEligible | string $content, int $generation = 0 | Rifiuta gli oggetti stream, /Encrypt, /XRef, /Catalog e qualsiasi generation diversa da zero. | bool | Non solleva eccezioni | Il confronto di /Type tollera gli spazi e gli escape #xx. |
ObjStmCompressor::writeToBuffer | list<ObjectStreamWriter> $streams, BinaryBuffer $buffer, ObjectRegistry $registry | Alloca un oggetto contenitore per stream, registra le voci compresse di tipo 2 e scrive ciascun blocco ObjStm. | list<int> — numeri degli oggetti contenitore | Propaga ObjectStreamWriteException da build() su un raro errore di compressione | Da eseguire dopo la scrittura degli oggetti non idonei e prima dell’emissione della cross-reference. |
ObjStmCompressor::estimateSavings | list<ObjectStreamWriter> $streams, int $originalSize | Costruisce ciascuno stream per misurare la dimensione compressa rispetto all’originale. | ObjStmCompressionResult | Propaga ObjectStreamWriteException da build() su un raro errore di compressione | Helper di misurazione in sola lettura. |
ObjectStreamEntry::__construct | int $objectNumber, string $content, int $offset | Record immutabile di un oggetto impacchettato e del suo offset nel corpo. | — | Non solleva eccezioni | final readonly; proprietà pubbliche. |
ObjStmCompressionResult::__construct | int $originalObjectCount, int $streamCount, int $estimatedOriginalSize, int $estimatedCompressedSize | Contenitore immutabile di metriche. | — | Non solleva eccezioni | final readonly; proprietà pubbliche. |
ObjStmCompressionResult::savedBytes | nessuno | Restituisce la dimensione originale meno quella compressa. | int | Non solleva eccezioni | Può essere negativo quando l’impacchettamento ha espanso i dati. |
ObjStmCompressionResult::savedPercent | nessuno | Restituisce la percentuale di riduzione. | float | Non solleva eccezioni | Restituisce 0.0 quando la dimensione originale è zero. |
ObjStmCompressionResult::compressionRatio | nessuno | Restituisce la dimensione compressa sull’originale. | float | Non solleva eccezioni | Restituisce 1.0 quando la dimensione originale è zero. |
ObjectStreamWriteException | — | Segnala un errore di costruzione di un Object Stream. | — | Estende RuntimeException | Sollevata da build(); intercettabile tramite RuntimeException per retrocompatibilità. |
Firme dei punti di ingresso
Sezione intitolata “Firme dei punti di ingresso”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;}Contratto di comportamento
Sezione intitolata “Contratto di comportamento”writeRevision scrive una revisione di tipo incremental-update. Effettua uno snapshot del prefisso del buffer esistente prima di scrivere. Riscrive il catalogo con le voci unite, registra i nuovi offset degli oggetti, scrive una tabella di cross-reference tradizionale raggruppata in sottosezioni contigue e scrive un trailer con /Size, /Root, /Prev e /ID. Dopo la scrittura, confronta nuovamente il prefisso. Se un qualsiasi byte precedente è cambiato, solleva WriterException che trasporta lo stato di violazione append-only e non restituisce alcun output utilizzabile. In caso di successo restituisce l’offset di byte della nuova tabella di cross-reference per il concatenamento di ulteriori revisioni. È consentito mescolare tabelle e stream di cross-reference tra le revisioni.
ObjectStreamWriter accumula oggetti. addObject solleva un errore di overflow quando l’indice e il corpo combinati supererebbero il massimo di 65.536 byte non compressi. build solleva un errore su uno stream vuoto; in caso contrario comprime l’indice più il corpo e restituisce il contenuto dell’Object Stream con le voci /Type /ObjStm, /N, /First, /Length e /Filter /FlateDecode. Il chiamante assegna il numero dell’oggetto e racchiude i marker N 0 obj / endobj.
ObjStmCompressor decide quali oggetti impacchettare. Esclude gli oggetti stream, i dizionari di cifratura, gli stream di cross-reference, il catalogo del documento e qualsiasi oggetto con un numero di generation diverso da zero. writeToBuffer alloca un oggetto contenitore per stream, registra ciascun oggetto impacchettato come voce di cross-reference compressa di tipo 2 e scrive il blocco ObjStm all’offset corrente del buffer. estimateSavings costruisce ciascuno stream per calcolare le metriche di dimensione senza mutare il buffer.
Casi limite e modalità di fallimento
Sezione intitolata “Casi limite e modalità di fallimento”- La verifica append-only copia il prefisso esistente. Il suo costo cresce con la dimensione del documento già scritto. Questo costo è intenzionale e protegge i byte firmati.
- Il limite degli Object Stream si applica all’indice più il corpo non compressi. Collocare il dizionario di cifratura e gli altri tipi di oggetto esclusi come oggetti indiretti diretti.
- L’esclusione di
/Typetollera spazi arbitrari tra i token e l’escape esadecimale#xx. Forme come/Type /Encrypt,/Type\n/Encrypte/Type /#45ncryptvengono tutte rifiutate, non soltanto la grafia letterale canonica. - Qualsiasi oggetto che rechi un numero di generation diverso da zero è trattato come non idoneo e ricade nella serializzazione normale
N G obj … endobj, perché la generation di un oggetto compresso è implicitamente zero. writeToBufferdeve essere eseguito dopo la scrittura di tutti gli oggetti non idonei e prima dell’emissione della cross-reference. Gli oggetti impacchettati non devono essere serializzati anche separatamente.
Comportamento in modalità FIPS
Sezione intitolata “Comportamento in modalità FIPS”Il modulo Writer non esegue alcuna operazione crittografica. Protegge i byte firmati rifiutando di emettere quando un byte precedente cambierebbe, il che è un test di uguaglianza byte-a-byte e non un test crittografico. La selezione dell’algoritmo FIPS per la firma e l’hashing è governata dal modulo di firma, non da questo writer. L’abilitazione o la disabilitazione della modalità FIPS non modifica il comportamento di alcun metodo del Writer.
Conformità
Sezione intitolata “Conformità”NextPDF implementa il modulo rispetto a ISO 32000-2:2020. Il writer incrementale segue la grammatica dell’incremental-update del §7.5.6: ogni revisione aggiunge una sezione di cross-reference che copre solo gli oggetti nuovi, modificati o cancellati, e un trailer la cui voce /Prev fornisce l’offset della cross-reference precedente. Il costruttore di Object Stream segue il modello degli object-stream del §7.5.7: un indice di coppie numero-oggetto e offset, con gli offset misurati dalla voce /First in ordine crescente, precede i corpi degli oggetti impacchettati. Entrambi i riferimenti di clausola sono stati verificati rispetto al corpus ISO 32000-2:2020. Il concatenamento delle revisioni per i workflow PAdES B-LT e B-LTA segue ETSI EN 319 142-1 §5.4, come annotato nel sorgente. Il supporto di una clausola è una dichiarazione di capacità ingegneristica, non una certificazione; NextPDF non detiene alcuna certificazione formale di conformità.
Note di sviluppo
Sezione intitolata “Note di sviluppo”- Installare il pacchetto con
composer require nextpdf/pro:^3. Le classi si risolvono inNextPDF\Pro\Writer. IncrementalUpdateWriter::writeRevisionè un punto di ingresso statico; non mantiene alcuno stato di istanza tra le revisioni.ObjectStreamEntry,ObjStmCompressionResult,IncrementalUpdateWritere il compressor formano insieme la superficie pubblica del modulo; il repository non fornisce alcun esempio eseguibile per esso.- Una
WriterExceptiondawriteRevisionindica una violazione append-only. Trattarla come un fallimento irreversibile e scartare il buffer. - I contenitori degli Object Stream sono oggetti indiretti; il chiamante assegna i loro numeri di oggetto tramite il registry.
Ambito di pubblicazione
Sezione intitolata “Ambito di pubblicazione”Questa pagina documenta esclusivamente il comportamento osservabile dall’esterno e la superficie API pubblica supportata. I percorsi di namespace interni, le classi helper, le tabelle dei meccanismi, i nomi dei file di runbook e i prefissi dei ticket sono fuori ambito.