Pro edisi
Writer — Referensi Mendalam
Sekilas pandang
Bagian berjudul “Sekilas pandang”Modul Writer menulis revisi incremental-update PDF dan mengemas objek-objek kecil ke dalam Object Stream. Incremental writer menegakkan aturan append-only yang fail-closed: setiap byte yang dimiliki buffer sebelum sebuah revisi harus tetap tidak berubah setelahnya. Pembangun Object Stream mengelompokkan objek-objek yang memenuhi syarat ke dalam satu objek /Type /ObjStm terkompresi FlateDecode di bawah batas ukuran tertentu.
Ketersediaan & lisensi
Bagian berjudul “Ketersediaan & lisensi”Kapabilitas ini hadir dalam NextPDF Pro (nextpdf/pro) dan aktif dengan envelope lisensi tingkat Pro. Deployment tanpa entitlement tersebut tidak memuat kelas-kelas kapabilitas ini. Bandingkan edisi dan dapatkan lisensi. Tidak ada flag lisensi per-fitur; kodenya hadir bersama edisi Pro.
Permukaan API publik
Bagian berjudul “Permukaan API publik”Modul ini berada di bawah namespace NextPDF\Pro\Writer. Semua simbol publik tercantum di bawah ini. Value object adalah kelas final readonly yang immutable.
| Simbol | Parameter | Perilaku default | Mengembalikan | Melempar atau gagal dengan | Catatan |
|---|---|---|---|---|---|
IncrementalUpdateWriter::writeRevision | BinaryBuffer $buffer, ObjectRegistry $registry, int $prevXrefOffset, int $catalogObject, array $catalogEntries, array $catalogUpdates, array $newObjectNumbers, string $fileId | Statis. Menulis ulang katalog dengan entri yang digabung, menambahkan tabel referensi-silang tradisional untuk objek baru dan yang dimodifikasi, dan menulis trailer dengan /Size, /Root, /Prev, dan /ID. Memverifikasi bahwa prefiks pra-revisi byte-equal setelahnya. | int — offset byte tabel referensi-silang baru | \NextPDF\Exception\WriterException ketika pemeriksaan prefiks append-only gagal; getWriterState() mengembalikan dss-append-only-invariant | Titik masuk statis. Tidak ada keluaran yang dapat digunakan pada pelanggaran. |
ObjectStreamWriter::addObject | int $objectNumber, string $content | Menambahkan satu objek ke stream tertunda setelah pemeriksaan ukuran. | void | OverflowException ketika gabungan indeks ditambah body akan melampaui 65.536 byte | $content tidak menyertakan pembungkus N 0 obj / endobj. |
ObjectStreamWriter::canAccept | string $content | Mengestimasi overhead indeks dan menguji total berjalan terhadap maksimum. | bool | Tidak melempar | Predikat murni; tanpa perubahan state. |
ObjectStreamWriter::build | tidak ada | Membangun indeks, menggabungkan body, mengompresi dengan FlateDecode, dan membungkus dictionary /Type /ObjStm. | string — konten Object Stream mentah | ObjectStreamWriteException ketika tidak ada objek yang ditambahkan, atau pada kegagalan kompresi zlib | Pemanggil menetapkan nomor objek dan membungkus markernya. |
ObjectStreamWriter::getEntries | tidak ada | Menghitung ulang offset relatif-body untuk objek yang terakumulasi. | list<ObjectStreamEntry> | Tidak melempar | Offset bersifat relatif terhadap seksi body. |
ObjectStreamWriter::count | tidak ada | Melaporkan jumlah objek yang terakumulasi. | int | Tidak melempar | — |
ObjStmCompressor::__construct | int $maxStreamSize = 65536, int $maxObjectsPerStream = 200 | Menyimpan batas ukuran dan jumlah-objek yang digunakan untuk pengelompokan. | — | Tidak melempar | Nilai default sesuai dengan penyetelan Object Stream modul. |
ObjStmCompressor::groupObjects | list<array{number: int, generation?: int, content: string}> $objects | Memfilter objek yang tidak memenuhi syarat, lalu mengemas sisanya ke dalam writer dalam batas ukuran dan jumlah. | list<ObjectStreamWriter> | Tidak melempar; objek yang tidak memenuhi syarat dilewati | Objek dengan generation bukan-nol jatuh ke serialisasi normal. |
ObjStmCompressor::isEligible | string $content, int $generation = 0 | Menolak objek stream, /Encrypt, /XRef, /Catalog, dan setiap generation bukan-nol. | bool | Tidak melempar | Pencocokan /Type toleran terhadap whitespace dan escape #xx. |
ObjStmCompressor::writeToBuffer | list<ObjectStreamWriter> $streams, BinaryBuffer $buffer, ObjectRegistry $registry | Mengalokasikan satu objek carrier per stream, mendaftarkan entri terkompresi type-2, dan menulis setiap blok ObjStm. | list<int> — nomor objek carrier | Meneruskan ObjectStreamWriteException dari build() pada kegagalan kompresi yang jarang | Jalankan setelah objek non-eligible ditulis dan sebelum referensi-silang dipancarkan. |
ObjStmCompressor::estimateSavings | list<ObjectStreamWriter> $streams, int $originalSize | Membangun setiap stream untuk mengukur ukuran terkompresi terhadap aslinya. | ObjStmCompressionResult | Meneruskan ObjectStreamWriteException dari build() pada kegagalan kompresi yang jarang | Helper pengukuran read-only. |
ObjectStreamEntry::__construct | int $objectNumber, string $content, int $offset | Rekaman immutable dari satu objek yang dikemas dan offset body-nya. | — | Tidak melempar | final readonly; properti publik. |
ObjStmCompressionResult::__construct | int $originalObjectCount, int $streamCount, int $estimatedOriginalSize, int $estimatedCompressedSize | Kontainer metrik immutable. | — | Tidak melempar | final readonly; properti publik. |
ObjStmCompressionResult::savedBytes | tidak ada | Mengembalikan ukuran asli dikurangi ukuran terkompresi. | int | Tidak melempar | Dapat bernilai negatif ketika pengemasan memperbesar data. |
ObjStmCompressionResult::savedPercent | tidak ada | Mengembalikan persentase pengurangan. | float | Tidak melempar | Mengembalikan 0.0 ketika ukuran asli adalah nol. |
ObjStmCompressionResult::compressionRatio | tidak ada | Mengembalikan ukuran terkompresi dibagi aslinya. | float | Tidak melempar | Mengembalikan 1.0 ketika ukuran asli adalah nol. |
ObjectStreamWriteException | — | Menandakan kegagalan build Object Stream. | — | Memperluas RuntimeException | Dilempar oleh build(); dapat ditangkap via RuntimeException untuk kompatibilitas mundur. |
Tanda tangan titik-masuk
Bagian berjudul “Tanda tangan titik-masuk”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;}Kontrak perilaku
Bagian berjudul “Kontrak perilaku”writeRevision menulis satu revisi incremental-update. Ia mengambil snapshot prefiks buffer yang ada sebelum menulis. Ia menulis ulang katalog dengan entri yang digabung, mendaftarkan offset objek baru, menulis tabel referensi-silang tradisional yang dikelompokkan menjadi subseksi kontigu, dan menulis trailer dengan /Size, /Root, /Prev, dan /ID. Setelah menulis, ia membandingkan prefiks kembali. Jika ada byte sebelumnya yang berubah, ia memunculkan WriterException yang membawa state pelanggaran-append-only dan tidak mengembalikan keluaran yang dapat digunakan. Pada keberhasilan, ia mengembalikan offset byte tabel referensi-silang baru untuk merangkai revisi selanjutnya. Mencampur tabel referensi-silang dan stream lintas revisi diperbolehkan.
ObjectStreamWriter mengakumulasi objek. addObject memunculkan galat overflow ketika gabungan indeks dan body akan melampaui maksimum 65.536 byte tak-terkompresi. build memunculkan galat pada stream kosong; jika tidak, ia mengompresi indeks ditambah body dan mengembalikan konten Object Stream dengan entri /Type /ObjStm, /N, /First, /Length, dan /Filter /FlateDecode. Pemanggil menetapkan nomor objek dan membungkus marker N 0 obj / endobj.
ObjStmCompressor memutuskan objek mana yang dikemas. Ia mengecualikan objek stream, dictionary enkripsi, stream referensi-silang, katalog dokumen, dan setiap objek dengan nomor generation bukan-nol. writeToBuffer mengalokasikan satu objek carrier per stream, mendaftarkan setiap objek yang dikemas sebagai entri referensi-silang terkompresi type-2, dan menulis blok ObjStm pada offset buffer saat ini. estimateSavings membangun setiap stream untuk menghitung metrik ukuran tanpa memutasi buffer.
Kasus tepi & mode kegagalan
Bagian berjudul “Kasus tepi & mode kegagalan”- Pemeriksaan append-only menyalin prefiks yang ada. Biayanya bertambah seiring ukuran dokumen yang sudah ditulis. Biaya ini disengaja dan melindungi byte yang ditandatangani.
- Batas Object Stream berlaku pada indeks tak-terkompresi ditambah body. Tempatkan dictionary enkripsi dan tipe objek yang dikecualikan lainnya sebagai objek tak-langsung yang langsung.
- Pengecualian
/Typetoleran terhadap whitespace antar-token yang sembarang dan escape heksa#xx. Bentuk seperti/Type /Encrypt,/Type\n/Encrypt, dan/Type /#45ncryptsemuanya ditolak, bukan hanya ejaan literal kanonik. - Setiap objek yang membawa nomor generation bukan-nol diperlakukan sebagai tidak memenuhi syarat dan jatuh ke serialisasi
N G obj … endobjnormal, karena generation objek terkompresi secara implisit adalah nol. writeToBufferharus berjalan setelah semua objek non-eligible ditulis dan sebelum referensi-silang dipancarkan. Objek yang dikemas tidak boleh juga diserialisasi secara terpisah.
Perilaku mode FIPS
Bagian berjudul “Perilaku mode FIPS”Modul Writer tidak melakukan operasi kriptografis. Ia melindungi byte yang ditandatangani dengan menolak memancarkan ketika sebuah byte sebelumnya akan berubah, yang merupakan uji byte-equality alih-alih uji kriptografis. Pemilihan algoritma FIPS untuk penandatanganan dan hashing diatur oleh modul penandatanganan, bukan oleh writer ini. Mengaktifkan atau menonaktifkan mode FIPS tidak mengubah perilaku metode Writer mana pun.
Kesesuaian
Bagian berjudul “Kesesuaian”NextPDF mengimplementasikan modul ini terhadap ISO 32000-2:2020. Incremental writer mengikuti tata bahasa incremental-update §7.5.6: setiap revisi menambahkan seksi referensi-silang yang mencakup hanya objek baru, yang diubah, atau yang dihapus, dan sebuah trailer yang entri /Prev-nya memberikan offset referensi-silang sebelumnya. Pembangun Object Stream mengikuti model object-stream §7.5.7: sebuah indeks berisi pasangan nomor-objek dan offset, dengan offset diukur dari entri /First dalam urutan menaik, mendahului body objek yang dikemas. Kedua rujukan klausa diverifikasi terhadap korpus ISO 32000-2:2020. Perangkaian revisi untuk alur kerja PAdES B-LT dan B-LTA mengikuti ETSI EN 319 142-1 §5.4, sebagaimana dianotasi dalam sumbernya. Dukungan atas suatu klausa adalah pernyataan kapabilitas rekayasa, bukan sertifikasi; NextPDF tidak memegang sertifikasi kesesuaian formal.
Catatan pengembangan
Bagian berjudul “Catatan pengembangan”- Pasang paket dengan
composer require nextpdf/pro:^3. Kelas-kelasnya teresolusi di bawahNextPDF\Pro\Writer. IncrementalUpdateWriter::writeRevisionadalah titik masuk statis; ia tidak menyimpan state instance antar revisi.ObjectStreamEntry,ObjStmCompressionResult,IncrementalUpdateWriter, dan compressor bersama-sama membentuk permukaan publik modul; repositori tidak menyertakan contoh yang dapat dijalankan untuknya.- Sebuah
WriterExceptiondariwriteRevisionmenandakan pelanggaran append-only. Perlakukan sebagai kegagalan keras dan buang buffer. - Carrier Object Stream adalah objek tak-langsung; pemanggil menetapkan nomor objeknya melalui registry.
Batas publikasi
Bagian berjudul “Batas publikasi”Halaman ini hanya mendokumentasikan perilaku yang dapat diamati secara eksternal dan permukaan API publik yang didukung. Path namespace internal, kelas helper, tabel mekanisme, nama file runbook, dan prefiks tiket berada di luar cakupan.