Pro edycja
Writer — pełna dokumentacja referencyjna
W skrócie
Dział zatytułowany „W skrócie”Moduł Writer zapisuje rewizje aktualizacji przyrostowej PDF i pakuje małe obiekty do Object Stream. Pisarz przyrostowy egzekwuje fail-closed regułę „tylko dopisywanie”: każdy bajt, który bufor zawierał przed rewizją, musi pozostać niezmieniony po niej. Budowniczy Object Stream grupuje kwalifikujące się obiekty w jeden obiekt /Type /ObjStm skompresowany metodą FlateDecode, w granicach ograniczonego rozmiaru.
Dostępność i licencjonowanie
Dział zatytułowany „Dostępność i licencjonowanie”Ta funkcja jest dostarczana w NextPDF Pro (nextpdf/pro) i uaktywnia się wraz z kopertą licencyjną poziomu Pro. Wdrożenie bez tego uprawnienia nie ładuje klas tej funkcji. Porównaj edycje i uzyskaj licencję. Nie ma flagi licencji dla pojedynczej funkcji; kod jest dostarczany z edycją Pro.
Powierzchnia publicznego API
Dział zatytułowany „Powierzchnia publicznego API”Moduł znajduje się w przestrzeni nazw NextPDF\Pro\Writer. Wszystkie symbole publiczne wymieniono poniżej. Obiekty wartości to niezmienne klasy final readonly.
| Symbol | Parametry | Domyślne zachowanie | Zwraca | Zgłasza / kończy się niepowodzeniem | Uwagi |
|---|---|---|---|---|---|
IncrementalUpdateWriter::writeRevision | BinaryBuffer $buffer, ObjectRegistry $registry, int $prevXrefOffset, int $catalogObject, array $catalogEntries, array $catalogUpdates, array $newObjectNumbers, string $fileId | Statyczna. Ponownie zapisuje katalog ze scalonymi wpisami, dopisuje tradycyjną tablicę odsyłaczy (cross-reference) dla nowych i zmodyfikowanych obiektów oraz zapisuje przyczepkę (trailer) z wpisami /Size, /Root, /Prev i /ID. Następnie sprawdza, że prefiks sprzed rewizji jest bajtowo identyczny. | int — przesunięcie bajtowe nowej tablicy odsyłaczy | \NextPDF\Exception\WriterException, gdy kontrola prefiksu „tylko dopisywanie” zawiedzie; getWriterState() zwraca dss-append-only-invariant | Statyczny punkt wejścia. Brak użytecznego wyniku przy naruszeniu. |
ObjectStreamWriter::addObject | int $objectNumber, string $content | Dopisuje jeden obiekt do oczekującego strumienia po kontroli rozmiaru. | void | OverflowException, gdy połączony indeks i treść przekroczyłyby 65 536 bajtów | $content nie zawiera opakowań N 0 obj / endobj. |
ObjectStreamWriter::canAccept | string $content | Szacuje narzut indeksu i porównuje bieżącą sumę z maksimum. | bool | Nie zgłasza wyjątku | Czysty predykat; bez zmiany stanu. |
ObjectStreamWriter::build | brak | Buduje indeks, łączy treści, kompresuje metodą FlateDecode i opakowuje słownik /Type /ObjStm. | string — surowa zawartość Object Stream | ObjectStreamWriteException, gdy nie dodano żadnych obiektów lub przy niepowodzeniu kompresji zlib | Wywołujący przydziela numer obiektu i opakowuje znaczniki. |
ObjectStreamWriter::getEntries | brak | Ponownie oblicza przesunięcia względem treści dla zgromadzonych obiektów. | list<ObjectStreamEntry> | Nie zgłasza wyjątku | Przesunięcia są względne wobec sekcji treści. |
ObjectStreamWriter::count | brak | Podaje liczbę zgromadzonych obiektów. | int | Nie zgłasza wyjątku | — |
ObjStmCompressor::__construct | int $maxStreamSize = 65536, int $maxObjectsPerStream = 200 | Przechowuje limity rozmiaru i liczby obiektów używane przy grupowaniu. | — | Nie zgłasza wyjątku | Wartości domyślne odpowiadają strojeniu Object Stream w module. |
ObjStmCompressor::groupObjects | list<array{number: int, generation?: int, content: string}> $objects | Odfiltrowuje niekwalifikujące się obiekty, a resztę pakuje do pisarzy w granicach limitów rozmiaru i liczby. | list<ObjectStreamWriter> | Nie zgłasza wyjątku; niekwalifikujące się obiekty są pomijane | Obiekty o niezerowym numerze generacji przechodzą do zwykłej serializacji. |
ObjStmCompressor::isEligible | string $content, int $generation = 0 | Odrzuca obiekty strumieniowe, /Encrypt, /XRef, /Catalog oraz dowolną niezerową generację. | bool | Nie zgłasza wyjątku | Dopasowanie /Type toleruje białe znaki i sekwencje ucieczki #xx. |
ObjStmCompressor::writeToBuffer | list<ObjectStreamWriter> $streams, BinaryBuffer $buffer, ObjectRegistry $registry | Przydziela obiekt nośny na każdy strumień, rejestruje skompresowane wpisy typu 2 i zapisuje każdy blok ObjStm. | list<int> — numery obiektów nośnych | Propaguje ObjectStreamWriteException z build() przy rzadkim niepowodzeniu kompresji | Uruchamiaj po zapisaniu niekwalifikujących się obiektów, a przed wyemitowaniem tablicy odsyłaczy. |
ObjStmCompressor::estimateSavings | list<ObjectStreamWriter> $streams, int $originalSize | Buduje każdy strumień, aby zmierzyć rozmiar po kompresji względem oryginału. | ObjStmCompressionResult | Propaguje ObjectStreamWriteException z build() przy rzadkim niepowodzeniu kompresji | Pomocnik pomiarowy tylko do odczytu. |
ObjectStreamEntry::__construct | int $objectNumber, string $content, int $offset | Niezmienny rekord jednego spakowanego obiektu i jego przesunięcia w treści. | — | Nie zgłasza wyjątku | final readonly; właściwości publiczne. |
ObjStmCompressionResult::__construct | int $originalObjectCount, int $streamCount, int $estimatedOriginalSize, int $estimatedCompressedSize | Niezmienny kontener metryk. | — | Nie zgłasza wyjątku | final readonly; właściwości publiczne. |
ObjStmCompressionResult::savedBytes | brak | Zwraca rozmiar oryginału pomniejszony o rozmiar po kompresji. | int | Nie zgłasza wyjątku | Może być ujemny, gdy pakowanie powiększyło dane. |
ObjStmCompressionResult::savedPercent | brak | Zwraca procentową redukcję. | float | Nie zgłasza wyjątku | Zwraca 0.0, gdy rozmiar oryginału wynosi zero. |
ObjStmCompressionResult::compressionRatio | brak | Zwraca rozmiar po kompresji względem oryginału. | float | Nie zgłasza wyjątku | Zwraca 1.0, gdy rozmiar oryginału wynosi zero. |
ObjectStreamWriteException | — | Sygnalizuje niepowodzenie budowy Object Stream. | — | Rozszerza RuntimeException | Zgłaszany przez build(); przechwytywalny przez RuntimeException dla zgodności wstecznej. |
Sygnatury punktów wejścia
Dział zatytułowany „Sygnatury punktów wejścia”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;}Kontrakt zachowania
Dział zatytułowany „Kontrakt zachowania”writeRevision zapisuje jedną rewizję aktualizacji przyrostowej. Przed zapisem wykonuje migawkę istniejącego prefiksu bufora. Ponownie zapisuje katalog ze scalonymi wpisami, rejestruje nowe przesunięcia obiektów, zapisuje tradycyjną tablicę odsyłaczy pogrupowaną w przylegające podsekcje oraz zapisuje przyczepkę (trailer) z wpisami /Size, /Root, /Prev i /ID. Po zapisie ponownie porównuje prefiks. Jeśli jakikolwiek wcześniejszy bajt się zmienił, zgłasza WriterException niosący stan naruszenia reguły „tylko dopisywanie” i nie zwraca użytecznego wyniku. Przy powodzeniu zwraca przesunięcie bajtowe nowej tablicy odsyłaczy, umożliwiające łańcuchowanie kolejnych rewizji. Mieszanie tablic odsyłaczy i strumieni między rewizjami jest dozwolone.
ObjectStreamWriter gromadzi obiekty. addObject zgłasza błąd przepełnienia, gdy połączony indeks i treść przekroczyłyby maksimum 65 536 bajtów bez kompresji. build zgłasza błąd dla pustego strumienia; w przeciwnym razie kompresuje indeks wraz z treścią i zwraca zawartość Object Stream z wpisami /Type /ObjStm, /N, /First, /Length oraz /Filter /FlateDecode. Wywołujący przydziela numer obiektu i opakowuje znaczniki N 0 obj / endobj.
ObjStmCompressor decyduje, które obiekty spakować. Wyklucza obiekty strumieniowe, słowniki szyfrowania, strumienie odsyłaczy, katalog dokumentu oraz dowolny obiekt o niezerowym numerze generacji. writeToBuffer przydziela obiekt nośny na każdy strumień, rejestruje każdy spakowany obiekt jako skompresowany wpis odsyłacza typu 2 i zapisuje blok ObjStm przy bieżącym przesunięciu bufora. estimateSavings buduje każdy strumień, aby obliczyć metryki rozmiaru bez modyfikowania bufora.
Przypadki brzegowe i tryby awarii
Dział zatytułowany „Przypadki brzegowe i tryby awarii”- Kontrola „tylko dopisywanie” kopiuje istniejący prefiks. Jej koszt rośnie wraz z rozmiarem już zapisanego dokumentu. Ten koszt jest zamierzony i chroni podpisane bajty.
- Limit Object Stream dotyczy nieskompresowanego indeksu wraz z treścią. Umieść słownik szyfrowania oraz inne wykluczone typy obiektów jako bezpośrednie obiekty pośrednie.
- Wykluczenie
/Typetoleruje dowolne białe znaki między tokenami i szesnastkowe sekwencje ucieczki#xx. Formy takie jak/Type /Encrypt,/Type\n/Encryptoraz/Type /#45ncryptsą wszystkie odrzucane, nie tylko kanoniczny zapis dosłowny. - Każdy obiekt niosący niezerowy numer generacji jest traktowany jako niekwalifikujący się i przechodzi do zwykłej serializacji
N G obj … endobj, ponieważ generacja obiektu skompresowanego jest niejawnie zerowa. writeToBuffermusi być uruchamiany po zapisaniu wszystkich niekwalifikujących się obiektów, a przed wyemitowaniem tablicy odsyłaczy. Spakowane obiekty nie mogą być dodatkowo serializowane osobno.
Zachowanie w trybie FIPS
Dział zatytułowany „Zachowanie w trybie FIPS”Moduł Writer nie wykonuje żadnych operacji kryptograficznych. Chroni podpisane bajty, odmawiając emisji, gdy wcześniejszy bajt miałby się zmienić, co jest testem równości bajtów, a nie testem kryptograficznym. Wybór algorytmu FIPS do podpisywania i haszowania jest sterowany przez moduł podpisujący, a nie przez ten pisarz. Włączenie lub wyłączenie trybu FIPS nie zmienia zachowania żadnej metody modułu Writer.
Zgodność
Dział zatytułowany „Zgodność”NextPDF implementuje ten moduł zgodnie z ISO 32000-2:2020. Pisarz przyrostowy podąża za gramatyką aktualizacji przyrostowej z §7.5.6: każda rewizja dopisuje sekcję odsyłaczy obejmującą wyłącznie nowe, zmienione lub usunięte obiekty oraz przyczepkę, której wpis /Prev podaje przesunięcie poprzedniej tablicy odsyłaczy. Budowniczy Object Stream podąża za modelem strumienia obiektów z §7.5.7: indeks par numer obiektu–przesunięcie, z przesunięciami mierzonymi od wpisu /First w rosnącej kolejności, poprzedza treści spakowanych obiektów. Oba odniesienia do klauzul zweryfikowano względem korpusu ISO 32000-2:2020. Łańcuchowanie rewizji dla przepływów PAdES B-LT i B-LTA podąża za ETSI EN 319 142-1 §5.4, zgodnie z adnotacjami w źródle. Wsparcie dla klauzuli jest deklaracją możliwości inżynieryjnych, a nie certyfikacją; NextPDF nie posiada formalnej certyfikacji zgodności.
Uwagi dla programistów
Dział zatytułowany „Uwagi dla programistów”- Zainstaluj pakiet poleceniem
composer require nextpdf/pro:^3. Klasy rozwiązują się wNextPDF\Pro\Writer. IncrementalUpdateWriter::writeRevisionto statyczny punkt wejścia; nie przechowuje stanu instancji między rewizjami.ObjectStreamEntry,ObjStmCompressionResult,IncrementalUpdateWriteroraz kompresor razem tworzą publiczną powierzchnię modułu; repozytorium nie dostarcza dla niego uruchamialnego przykładu.WriterExceptionzwriteRevisionoznacza naruszenie reguły „tylko dopisywanie”. Traktuj to jako twardą awarię i odrzuć bufor.- Nośniki Object Stream są obiektami pośrednimi; wywołujący przydziela ich numery obiektów przez rejestr.
Granica publikacji
Dział zatytułowany „Granica publikacji”Ta strona dokumentuje wyłącznie zewnętrznie obserwowalne zachowanie oraz wspieraną powierzchnię publicznego API. Wewnętrzne ścieżki przestrzeni nazw, klasy pomocnicze, tabele mechanizmów, nazwy plików runbooków oraz prefiksy zgłoszeń są poza zakresem.