コンテンツにスキップ
getnextpdf.com

Pro エディション

Writer

Writer モジュールは、差分更新リビジョンを PDF に追記し、小さなオブジェクトを Object Stream にパックします。差分ライターは追記専用ルールを強制します。リビジョンより前に存在していたバイトは変更されてはなりません。

この機能は NextPDF Pronextpdf/pro)に同梱され、Pro ティアのライセンスエンベロープで有効化されます。そのエンタイトルメントを持たないデプロイでは、当該機能のクラスはロードされません。エディションを比較してライセンスを取得。機能ごとの個別のライセンスフラグはありません。コードは Pro エディションに同梱されます。

Terminal window
composer require nextpdf/pro:^3

コードは NextPDF\Pro\Writer 名前空間の下にあります。

2 つのケーパビリティが提供されます。

  • IncrementalUpdateWriter は新しいリビジョンを書き込みます。マージされたエントリでカタログを書き直し、新しいオブジェクトと変更されたオブジェクトのための従来型の相互参照テーブルを追記し、前のリビジョンへリンクするトレーラーを書き込みます。フェイルクローズの追記専用ルールを強制します。
  • ObjectStreamWriter は、小さなオブジェクトを単一の圧縮された Object Stream にグループ化します。これにより相互参照テーブルのサイズが減少し、圧縮が改善されます。最大ストリームサイズを超えるオブジェクトを拒否し、空のストリームを拒否します。

追記専用ルールは既存の署名を保護します。リビジョンより前にバッファが保持していたすべてのバイトは、リビジョン後も同じ位置に変更されずに現れなければなりません。それ以前のいずれかのバイトが変更された場合、ライターはエラーを発生させ、出力を生成しません。

要となる選択は、追記専用ゲートがどこに存在するかです。ゲートは上位のオーケストレーターだけではなく、ライタースコープに位置します。そのため、現在および将来のすべての呼び出し元がフェイルクローズのカバレッジを継承します。このチェックは純粋なプレフィックス等価性テストです。ライターは追記の前にバッファのプレフィックスをスナップショットし、その後で以前のすべてのバイトが変更されていないことを確認します。これにより、/ByteRange がプレフィックスをカバーしていたあらゆる署名が保護されます。1 バイトでも改変されれば、その署名は密かに無効化されるからです。差分更新は書き換えではなく追記でなければならないため、従来型の相互参照テーブルと /Prev ポインターが新しいリビジョンを担います。検証コストは既存プレフィックスに対して線形であり、そのコストは意図的に受け入れられています。署名されたバイトの整合性は、2 つ目のコピーよりも優先されます。

設計の背景: Incremental updates and why they matter

  • IncrementalUpdateWriter::writeRevision(...) は、新しい相互参照テーブルのバイトオフセットを返すため、さらにリビジョンをチェーンできます。
  • ライターは、書き込みの前後で元のプレフィックスがバイト単位で等しいことを検証します。相違は、追記専用違反の状態を保持するライターexceptionを発生させます。
  • 新しいリビジョンは、従来型の相互参照テーブルと /Prev ポインターを持つトレーラーを使用します。リビジョン間でテーブルとストリームを混在させることは許可されています。
  • ObjectStreamWriter::addObject() は、オブジェクトの追加が最大ストリームサイズ(インデックスとボディで非圧縮 65,536 バイト)を超える場合にオーバーフローエラーを発生させます。
  • ObjectStreamWriter::build() は、オブジェクトが追加されていない場合にエラーを発生させます。そうでない場合は、圧縮された Object Stream コンテンツを返します。

以下は、文書化されたパブリック API を反映しています。リポジトリには、このモジュールの実行可能なサンプルは同梱されていません。

use NextPDF\Pro\Writer\ObjectStreamWriter;
$writer = new ObjectStreamWriter();
$writer->addObject(10, $serializedObjectBody);
$objStm = $writer->build();
use NextPDF\Pro\Writer\IncrementalUpdateWriter;
$newXrefOffset = IncrementalUpdateWriter::writeRevision(
$buffer,
$registry,
$prevXrefOffset,
$catalogObject,
$catalogEntries,
$catalogUpdates,
$newObjectNumbers,
$fileId,
);
// A WriterException here means the append-only rule was violated.
// Treat it as a hard failure; do not emit the output.
  • 追記専用チェックは既存のプレフィックスをコピーします。そのコストは、すでに書き込まれたドキュメントのサイズとともに増大します。このコストは意図的なものであり、署名されたバイトを保護します。
  • Object Stream のサイズ制限は、圧縮前の結合されたインデックスとボディに対するものです。それに応じてオブジェクトをグループ化してください。
  • Object Stream には特定のオブジェクトタイプ(たとえば暗号化ディクショナリ)を含めてはなりません。それらは直接的な間接オブジェクトとして配置してください。

追記専用検証は、既存のドキュメントプレフィックスのサイズに対して線形です。Object Stream のパッキングは、追加の圧縮パス 1 回のコストと引き換えに、相互参照のサイズを減少させ、圧縮を改善します。公表されたスループットの数値はありません。代表的なドキュメントで測定してください。

差分ライターはフェイルクローズです。あるコードパスが、それ以前の署名がカバーしていたバイトを変更しようとした場合、ライターはドキュメントを生成する代わりにエラーを発生させます。これは、リビジョンチェーンされたワークフローにおける署名の整合性を保護します。ドキュメントコンテンツはログに記録されません。

ソースは、ISO 32000-2 の差分更新文法と Object Stream モデル、そして ETSI EN 319 142-1 PAdES プロファイルのリビジョンチェーン要件を注釈しています。執筆時点で RAG コーパスが利用できなかったため、このページはソース自体が宣言する節参照のみを繰り返し、追加の外部の節識別子を一切主張しません。

Enterprise は、差分更新の上に挙動レベルで構築される、より上位の署名ライフサイクル機能(長期検証と更新)を追加します。Writer モジュールはリビジョンプリミティブのみを提供します。それらの上位機能は別途文書化されており、リビジョンを書き込むために必須ではありません。

Pro なしの場合は、NextPDF Core の基本ライターを使用してください。追記専用ゲートを備えた差分更新リビジョンと Object Stream のパッキングは Pro の追加機能です。/modules/writer/ を参照してください。

このページは、外部から観測可能な挙動と、サポートされるパブリック API サーフェスのみを記述します。内部の名前空間パス、ヘルパークラス、機構テーブル、ランブックのファイル名、チケットプレフィックスは対象外です。