Pular para o conteúdo
getnextpdf.com

Pro edição

Writer — Referência Profunda

O módulo Writer grava revisões de atualização incremental de PDF e empacota objetos pequenos em Object Streams. O writer incremental impõe uma regra somente-acréscimo (append-only) com falha fechada: cada byte que o buffer continha antes de uma revisão deve permanecer inalterado depois dela. O construtor de Object Stream agrupa objetos elegíveis em um único objeto /Type /ObjStm compactado com FlateDecode, dentro de um tamanho delimitado.

Este recurso é distribuído no NextPDF Pro (nextpdf/pro) e é ativado com um envelope de licença de nível Pro. Uma implantação sem esse direito não carrega as classes do recurso. Compare edições e obtenha uma licença. Não há sinalizador de licença por recurso; o código é distribuído com a edição Pro.

O módulo reside no namespace NextPDF\Pro\Writer. Todos os símbolos públicos estão listados abaixo. Os value objects são classes imutáveis final readonly.

SímboloParâmetrosComportamento padrãoRetornaLança ou falha comNotas
IncrementalUpdateWriter::writeRevisionBinaryBuffer $buffer, ObjectRegistry $registry, int $prevXrefOffset, int $catalogObject, array $catalogEntries, array $catalogUpdates, array $newObjectNumbers, string $fileIdEstático. Reescreve o catálogo com entradas mescladas, anexa uma tabela de referência cruzada tradicional para objetos novos e modificados, e grava um trailer com /Size, /Root, /Prev e /ID. Verifica depois que o prefixo anterior à revisão é byte a byte igual.int — offset em bytes da nova tabela de referência cruzada\NextPDF\Exception\WriterException quando a verificação de prefixo somente-acréscimo falha; getWriterState() retorna dss-append-only-invariantPonto de entrada estático. Nenhuma saída utilizável em caso de violação.
ObjectStreamWriter::addObjectint $objectNumber, string $contentAnexa um objeto ao stream pendente após uma verificação de tamanho.voidOverflowException quando o índice combinado mais o corpo excederiam 65.536 bytes$content exclui os invólucros N 0 obj / endobj.
ObjectStreamWriter::canAcceptstring $contentEstima a sobrecarga do índice e testa o total corrente contra o máximo.boolNão lançaPredicado puro; sem alteração de estado.
ObjectStreamWriter::buildnenhumConstrói o índice, concatena os corpos, compacta com FlateDecode e encapsula o dicionário /Type /ObjStm.string — conteúdo bruto do Object StreamObjectStreamWriteException quando nenhum objeto foi adicionado, ou em uma falha de compactação zlibO chamador atribui o número do objeto e encapsula os marcadores.
ObjectStreamWriter::getEntriesnenhumRecalcula os offsets relativos ao corpo para os objetos acumulados.list<ObjectStreamEntry>Não lançaOs offsets são relativos à seção de corpo.
ObjectStreamWriter::countnenhumInforma o número de objetos acumulados.intNão lança
ObjStmCompressor::__constructint $maxStreamSize = 65536, int $maxObjectsPerStream = 200Armazena os limites de tamanho e de contagem de objetos usados no agrupamento.Não lançaOs padrões correspondem ao ajuste de Object Stream do módulo.
ObjStmCompressor::groupObjectslist<array{number: int, generation?: int, content: string}> $objectsFiltra objetos inelegíveis e depois empacota o restante em writers dentro dos limites de tamanho e contagem.list<ObjectStreamWriter>Não lança; objetos inelegíveis são ignoradosObjetos com generation diferente de zero passam à serialização normal.
ObjStmCompressor::isEligiblestring $content, int $generation = 0Rejeita objetos de stream, /Encrypt, /XRef, /Catalog e qualquer generation diferente de zero.boolNão lançaA correspondência de /Type é tolerante a espaços em branco e a escapes #xx.
ObjStmCompressor::writeToBufferlist<ObjectStreamWriter> $streams, BinaryBuffer $buffer, ObjectRegistry $registryAloca um objeto portador por stream, registra entradas compactadas de tipo 2 e grava cada bloco ObjStm.list<int> — números dos objetos portadoresPropaga ObjectStreamWriteException de build() em uma rara falha de compactaçãoExecute após os objetos não elegíveis serem gravados e antes de a referência cruzada ser emitida.
ObjStmCompressor::estimateSavingslist<ObjectStreamWriter> $streams, int $originalSizeConstrói cada stream para medir o tamanho compactado em relação ao original.ObjStmCompressionResultPropaga ObjectStreamWriteException de build() em uma rara falha de compactaçãoAuxiliar de medição somente leitura.
ObjectStreamEntry::__constructint $objectNumber, string $content, int $offsetRegistro imutável de um objeto empacotado e seu offset no corpo.Não lançafinal readonly; propriedades públicas.
ObjStmCompressionResult::__constructint $originalObjectCount, int $streamCount, int $estimatedOriginalSize, int $estimatedCompressedSizeContêiner imutável de métricas.Não lançafinal readonly; propriedades públicas.
ObjStmCompressionResult::savedBytesnenhumRetorna o tamanho original menos o compactado.intNão lançaPode ser negativo quando o empacotamento expandiu os dados.
ObjStmCompressionResult::savedPercentnenhumRetorna a redução percentual.floatNão lançaRetorna 0.0 quando o tamanho original é zero.
ObjStmCompressionResult::compressionRationenhumRetorna o tamanho compactado sobre o original.floatNão lançaRetorna 1.0 quando o tamanho original é zero.
ObjectStreamWriteExceptionSinaliza uma falha na construção do Object Stream.Estende RuntimeExceptionLançada por build(); capturável via RuntimeException para compatibilidade retroativa.
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 grava uma revisão de atualização incremental. Ele captura um snapshot do prefixo do buffer existente antes de gravar. Ele reescreve o catálogo com entradas mescladas, registra os offsets dos novos objetos, grava uma tabela de referência cruzada tradicional agrupada em subseções contíguas e grava um trailer com /Size, /Root, /Prev e /ID. Após gravar, ele compara o prefixo novamente. Se qualquer byte anterior mudou, ele gera WriterException carregando o estado de violação de somente-acréscimo e não retorna saída utilizável. Em caso de sucesso, ele retorna o offset em bytes da nova tabela de referência cruzada para encadear revisões adicionais. É permitido misturar tabelas e streams de referência cruzada entre revisões.

ObjectStreamWriter acumula objetos. addObject gera um erro de estouro quando o índice combinado e o corpo excederiam o máximo de 65.536 bytes descompactados. build gera um erro em um stream vazio; caso contrário, ele compacta o índice mais o corpo e retorna o conteúdo do Object Stream com as entradas /Type /ObjStm, /N, /First, /Length e /Filter /FlateDecode. O chamador atribui o número do objeto e encapsula os marcadores N 0 obj / endobj.

ObjStmCompressor decide quais objetos empacotar. Ele exclui objetos de stream, dicionários de criptografia, streams de referência cruzada, o catálogo do documento e qualquer objeto com número de generation diferente de zero. writeToBuffer aloca um objeto portador por stream, registra cada objeto empacotado como uma entrada de referência cruzada compactada de tipo 2 e grava o bloco ObjStm no offset atual do buffer. estimateSavings constrói cada stream para calcular as métricas de tamanho sem alterar o buffer.

  • A verificação de somente-acréscimo copia o prefixo existente. Seu custo cresce com o tamanho do documento já gravado. Esse custo é intencional e protege os bytes assinados.
  • O limite do Object Stream aplica-se ao índice descompactado mais o corpo. Coloque o dicionário de criptografia e outros tipos de objeto excluídos como objetos indiretos diretos.
  • A exclusão de /Type é tolerante a espaços em branco arbitrários entre tokens e a escapes hexadecimais #xx. Formas como /Type /Encrypt, /Type\n/Encrypt e /Type /#45ncrypt são todas rejeitadas, não apenas a grafia literal canônica.
  • Qualquer objeto que carregue um número de generation diferente de zero é tratado como inelegível e passa à serialização normal N G obj … endobj, porque a generation de um objeto compactado é implicitamente zero.
  • writeToBuffer deve ser executado após todos os objetos não elegíveis terem sido gravados e antes de a referência cruzada ser emitida. Objetos empacotados não devem também ser serializados separadamente.

O módulo Writer não realiza operações criptográficas. Ele protege os bytes assinados recusando-se a emitir quando um byte anterior mudaria, o que é um teste de igualdade de bytes, e não um teste criptográfico. A seleção de algoritmos FIPS para assinatura e hashing é regida pelo módulo de assinatura, não por este writer. Ativar ou desativar o modo FIPS não altera o comportamento de nenhum método do Writer.

O NextPDF implementa o módulo em conformidade com a ISO 32000-2:2020. O writer incremental segue a gramática de atualização incremental da §7.5.6: cada revisão anexa uma seção de referência cruzada cobrindo apenas objetos novos, alterados ou excluídos, e um trailer cuja entrada /Prev fornece o offset da referência cruzada anterior. O construtor de Object Stream segue o modelo de object-stream da §7.5.7: um índice de pares de número de objeto e offset, com offsets medidos a partir da entrada /First em ordem crescente, precede os corpos dos objetos empacotados. Ambas as referências de cláusula foram verificadas contra o corpus da ISO 32000-2:2020. O encadeamento de revisões para os fluxos de trabalho PAdES B-LT e B-LTA segue a ETSI EN 319 142-1 §5.4, conforme anotado no código-fonte. O suporte a uma cláusula é uma declaração de capacidade de engenharia, não uma certificação; o NextPDF não possui nenhuma certificação formal de conformidade.

  • Instale o pacote com composer require nextpdf/pro:^3. As classes resolvem sob NextPDF\Pro\Writer.
  • IncrementalUpdateWriter::writeRevision é um ponto de entrada estático; ele não mantém estado de instância entre revisões.
  • ObjectStreamEntry, ObjStmCompressionResult, IncrementalUpdateWriter e o compressor juntos formam a superfície pública do módulo; o repositório não distribui nenhum exemplo executável para ele.
  • Uma WriterException de writeRevision indica uma violação de somente-acréscimo. Trate-a como uma falha grave e descarte o buffer.
  • Os portadores de Object Stream são objetos indiretos; o chamador atribui seus números de objeto por meio do registry.

Esta página documenta apenas o comportamento observável externamente e a superfície de API pública suportada. Caminhos de namespace internos, classes auxiliares, tabelas de mecanismos, nomes de arquivos de runbook e prefixos de ticket estão fora do escopo.