Ir al contenido
getnextpdf.com

Pro edición

Writer — Referencia detallada

El módulo Writer escribe revisiones PDF de actualización incremental y empaqueta objetos pequeños en Object Streams. El escritor incremental impone una regla de solo anexado (append-only) con cierre a prueba de fallos: cada byte que el búfer contenía antes de una revisión debe permanecer inalterado después de ella. El constructor de Object Streams agrupa los objetos elegibles en un único objeto /Type /ObjStm comprimido con FlateDecode y de tamaño acotado.

Esta capacidad se distribuye en NextPDF Pro (nextpdf/pro) y se activa con un sobre de licencia de nivel Pro. Una implementación sin ese derecho no carga las clases de la capacidad. Comparar ediciones y obtener una licencia. No existe un indicador de licencia por función; el código se distribuye con la edición Pro.

El módulo reside bajo el espacio de nombres NextPDF\Pro\Writer. A continuación se enumeran todos los símbolos públicos. Los objetos de valor son clases inmutables final readonly.

SímboloParámetrosComportamiento por defectoDevuelveLanza o falla conNotas
IncrementalUpdateWriter::writeRevisionBinaryBuffer $buffer, ObjectRegistry $registry, int $prevXrefOffset, int $catalogObject, array $catalogEntries, array $catalogUpdates, array $newObjectNumbers, string $fileIdEstático. Reescribe el catálogo con las entradas combinadas, anexa una tabla de referencias cruzadas tradicional para los objetos nuevos y modificados, y escribe un tráiler con /Size, /Root, /Prev e /ID. Verifica después que el prefijo previo a la revisión sea byte a byte idéntico.int — desplazamiento en bytes de la nueva tabla de referencias cruzadas\NextPDF\Exception\WriterException cuando falla la comprobación de solo anexado; getWriterState() devuelve dss-append-only-invariantPunto de entrada estático. Sin salida utilizable en caso de infracción.
ObjectStreamWriter::addObjectint $objectNumber, string $contentAnexa un objeto al flujo pendiente tras una comprobación de tamaño.voidOverflowException cuando el índice combinado más el cuerpo superarían los 65 536 bytes$content excluye los envoltorios N 0 obj / endobj.
ObjectStreamWriter::canAcceptstring $contentEstima la sobrecarga del índice y compara el total acumulado con el máximo.boolNo lanzaPredicado puro; no cambia el estado.
ObjectStreamWriter::buildningunoConstruye el índice, concatena los cuerpos, comprime con FlateDecode y envuelve el diccionario /Type /ObjStm.string — contenido bruto del Object StreamObjectStreamWriteException cuando no se ha añadido ningún objeto, o ante un fallo de compresión de zlibQuien lo invoca asigna el número de objeto y envuelve los marcadores.
ObjectStreamWriter::getEntriesningunoRecalcula los desplazamientos relativos al cuerpo para los objetos acumulados.list<ObjectStreamEntry>No lanzaLos desplazamientos son relativos a la sección del cuerpo.
ObjectStreamWriter::countningunoInforma del número de objetos acumulados.intNo lanza
ObjStmCompressor::__constructint $maxStreamSize = 65536, int $maxObjectsPerStream = 200Almacena los límites de tamaño y de número de objetos utilizados para la agrupación.No lanzaLos valores por defecto coinciden con el ajuste de Object Stream del módulo.
ObjStmCompressor::groupObjectslist<array{number: int, generation?: int, content: string}> $objectsFiltra los objetos no elegibles y luego empaqueta el resto en escritores dentro de los límites de tamaño y de número.list<ObjectStreamWriter>No lanza; los objetos no elegibles se omitenLos objetos con número de generación distinto de cero pasan a la serialización normal.
ObjStmCompressor::isEligiblestring $content, int $generation = 0Rechaza los objetos de flujo, /Encrypt, /XRef, /Catalog y cualquier generación distinta de cero.boolNo lanzaLa comparación de /Type es tolerante a espacios en blanco y a escapes #xx.
ObjStmCompressor::writeToBufferlist<ObjectStreamWriter> $streams, BinaryBuffer $buffer, ObjectRegistry $registryAsigna un objeto portador por flujo, registra entradas comprimidas de tipo 2 y escribe cada bloque ObjStm.list<int> — números de los objetos portadoresPropaga ObjectStreamWriteException de build() ante un raro fallo de compresiónEjecutar después de escribir los objetos no elegibles y antes de emitir las referencias cruzadas.
ObjStmCompressor::estimateSavingslist<ObjectStreamWriter> $streams, int $originalSizeConstruye cada flujo para medir el tamaño comprimido frente al original.ObjStmCompressionResultPropaga ObjectStreamWriteException de build() ante un raro fallo de compresiónAyudante de medición de solo lectura.
ObjectStreamEntry::__constructint $objectNumber, string $content, int $offsetRegistro inmutable de un objeto empaquetado y su desplazamiento en el cuerpo.No lanzafinal readonly; propiedades públicas.
ObjStmCompressionResult::__constructint $originalObjectCount, int $streamCount, int $estimatedOriginalSize, int $estimatedCompressedSizeContenedor inmutable de métricas.No lanzafinal readonly; propiedades públicas.
ObjStmCompressionResult::savedBytesningunoDevuelve el tamaño original menos el comprimido.intNo lanzaPuede ser negativo cuando el empaquetado ha expandido los datos.
ObjStmCompressionResult::savedPercentningunoDevuelve el porcentaje de reducción.floatNo lanzaDevuelve 0.0 cuando el tamaño original es cero.
ObjStmCompressionResult::compressionRationingunoDevuelve el tamaño comprimido dividido entre el original.floatNo lanzaDevuelve 1.0 cuando el tamaño original es cero.
ObjectStreamWriteExceptionSeñala un fallo en la construcción de un Object Stream.Extiende RuntimeExceptionLanzada por build(); capturable mediante RuntimeException por retrocompatibilidad.
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 escribe una revisión de actualización incremental. Toma una instantánea del prefijo del búfer existente antes de escribir. Reescribe el catálogo con las entradas combinadas, registra los desplazamientos de los objetos nuevos, escribe una tabla de referencias cruzadas tradicional agrupada en subsecciones contiguas y escribe un tráiler con /Size, /Root, /Prev e /ID. Tras escribir, compara de nuevo el prefijo. Si algún byte anterior ha cambiado, lanza WriterException con el estado de infracción de solo anexado y no devuelve ninguna salida utilizable. En caso de éxito, devuelve el desplazamiento en bytes de la nueva tabla de referencias cruzadas para encadenar más revisiones. Está permitido mezclar tablas y flujos de referencias cruzadas entre revisiones.

ObjectStreamWriter acumula objetos. addObject lanza un error de desbordamiento cuando el índice y el cuerpo combinados superarían el máximo de 65 536 bytes sin comprimir. build lanza un error ante un flujo vacío; de lo contrario, comprime el índice más el cuerpo y devuelve el contenido del Object Stream con las entradas /Type /ObjStm, /N, /First, /Length y /Filter /FlateDecode. Quien lo invoca asigna el número de objeto y envuelve los marcadores N 0 obj / endobj.

ObjStmCompressor decide qué objetos empaquetar. Excluye los objetos de flujo, los diccionarios de cifrado, los flujos de referencias cruzadas, el catálogo del documento y cualquier objeto con un número de generación distinto de cero. writeToBuffer asigna un objeto portador por flujo, registra cada objeto empaquetado como una entrada de referencia cruzada comprimida de tipo 2 y escribe el bloque ObjStm en el desplazamiento actual del búfer. estimateSavings construye cada flujo para calcular las métricas de tamaño sin modificar el búfer.

  • La comprobación de solo anexado copia el prefijo existente. Su coste crece con el tamaño del documento ya escrito. Ese coste es intencionado y protege los bytes firmados.
  • El límite del Object Stream se aplica al índice más el cuerpo sin comprimir. Coloque el diccionario de cifrado y otros tipos de objeto excluidos como objetos indirectos directos.
  • La exclusión de /Type es tolerante a espacios en blanco arbitrarios entre tokens y a los escapes hexadecimales #xx. Formas como /Type /Encrypt, /Type\n/Encrypt y /Type /#45ncrypt se rechazan todas, no solo la escritura literal canónica.
  • Cualquier objeto que lleve un número de generación distinto de cero se considera no elegible y pasa a la serialización normal N G obj … endobj, porque la generación de un objeto comprimido es implícitamente cero.
  • writeToBuffer debe ejecutarse después de que se hayan escrito todos los objetos no elegibles y antes de que se emitan las referencias cruzadas. Los objetos empaquetados no deben serializarse también por separado.

El módulo Writer no realiza operaciones criptográficas. Protege los bytes firmados negándose a emitir cuando un byte anterior fuera a cambiar, lo cual es una prueba de igualdad de bytes y no criptográfica. La selección de algoritmos FIPS para la firma y el hash la rige el módulo de firma, no este escritor. Habilitar o deshabilitar el modo FIPS no cambia el comportamiento de ningún método de Writer.

NextPDF implementa el módulo conforme a ISO 32000-2:2020. El escritor incremental sigue la gramática de actualización incremental de §7.5.6: cada revisión anexa una sección de referencias cruzadas que abarca solo los objetos nuevos, modificados o eliminados, y un tráiler cuya entrada /Prev da el desplazamiento de las referencias cruzadas anteriores. El constructor de Object Streams sigue el modelo de flujo de objetos de §7.5.7: un índice de pares número-de-objeto y desplazamiento, con los desplazamientos medidos desde la entrada /First en orden creciente, precede a los cuerpos de los objetos empaquetados. Ambas referencias a cláusulas se verificaron frente al corpus de ISO 32000-2:2020. El encadenamiento de revisiones para los flujos de trabajo PAdES B-LT y B-LTA sigue ETSI EN 319 142-1 §5.4, según lo anotado en el código fuente. La compatibilidad con una cláusula es una declaración de capacidad de ingeniería, no una certificación; NextPDF no posee ninguna certificación formal de conformidad.

  • Instale el paquete con composer require nextpdf/pro:^3. Las clases se resuelven bajo NextPDF\Pro\Writer.
  • IncrementalUpdateWriter::writeRevision es un punto de entrada estático; no conserva estado de instancia entre revisiones.
  • ObjectStreamEntry, ObjStmCompressionResult, IncrementalUpdateWriter y el compresor forman en conjunto la superficie pública del módulo; el repositorio no incluye ningún ejemplo ejecutable para él.
  • Una WriterException de writeRevision indica una infracción de solo anexado. Trátela como un fallo grave y descarte el búfer.
  • Los portadores de Object Stream son objetos indirectos; quien invoca les asigna los números de objeto a través del registro.

Esta página documenta únicamente el comportamiento observable externamente y la superficie de la API pública admitida. Las rutas de espacios de nombres internos, las clases auxiliares, las tablas de mecanismos, los nombres de archivo de los runbooks y los prefijos de tickets quedan fuera de su alcance.