Commit ce21a65188c99f1b305a773223267cdfaf97b782
1 parent
db2a22ea
Refactor `QPDFWriter`: move `Members` functionality into `impl::Writer`, consoli…
…date logic, and improve encapsulation.
Showing
4 changed files
with
229 additions
and
220 deletions
libqpdf/QPDFWriter.cc
| ... | ... | @@ -299,6 +299,127 @@ namespace qpdf::impl |
| 299 | 299 | { |
| 300 | 300 | } |
| 301 | 301 | |
| 302 | + void write(); | |
| 303 | + std::map<QPDFObjGen, QPDFXRefEntry> getWrittenXRefTable(); | |
| 304 | + void setMinimumPDFVersion(std::string const& version, int extension_level); | |
| 305 | + void copyEncryptionParameters(QPDF&); | |
| 306 | + void doWriteSetup(); | |
| 307 | + void prepareFileForWrite(); | |
| 308 | + | |
| 309 | + void disableIncompatibleEncryption(int major, int minor, int extension_level); | |
| 310 | + void interpretR3EncryptionParameters( | |
| 311 | + bool allow_accessibility, | |
| 312 | + bool allow_extract, | |
| 313 | + bool allow_assemble, | |
| 314 | + bool allow_annotate_and_form, | |
| 315 | + bool allow_form_filling, | |
| 316 | + bool allow_modify_other, | |
| 317 | + qpdf_r3_print_e print, | |
| 318 | + qpdf_r3_modify_e modify); | |
| 319 | + void setEncryptionParameters(char const* user_password, char const* owner_password); | |
| 320 | + void setEncryptionMinimumVersion(); | |
| 321 | + void parseVersion(std::string const& version, int& major, int& minor) const; | |
| 322 | + int compareVersions(int major1, int minor1, int major2, int minor2) const; | |
| 323 | + void generateID(bool encrypted); | |
| 324 | + std::string getOriginalID1(); | |
| 325 | + void initializeTables(size_t extra = 0); | |
| 326 | + void preserveObjectStreams(); | |
| 327 | + void generateObjectStreams(); | |
| 328 | + void initializeSpecialStreams(); | |
| 329 | + void enqueue(QPDFObjectHandle const& object); | |
| 330 | + void enqueueObjectsStandard(); | |
| 331 | + void enqueueObjectsPCLm(); | |
| 332 | + void enqueuePart(std::vector<QPDFObjectHandle>& part); | |
| 333 | + void assignCompressedObjectNumbers(QPDFObjGen og); | |
| 334 | + Dictionary trimmed_trailer(); | |
| 335 | + | |
| 336 | + // Returns tuple<filter, compress_stream, is_root_metadata> | |
| 337 | + std::tuple<const bool, const bool, const bool> | |
| 338 | + will_filter_stream(QPDFObjectHandle stream, std::string* stream_data); | |
| 339 | + | |
| 340 | + // Test whether stream would be filtered if it were written. | |
| 341 | + bool will_filter_stream(QPDFObjectHandle stream); | |
| 342 | + unsigned int bytesNeeded(long long n); | |
| 343 | + void writeBinary(unsigned long long val, unsigned int bytes); | |
| 344 | + Writer& write(std::string_view str); | |
| 345 | + Writer& write(size_t count, char c); | |
| 346 | + Writer& write(std::integral auto val); | |
| 347 | + Writer& write_name(std::string const& str); | |
| 348 | + Writer& write_string(std::string const& str, bool force_binary = false); | |
| 349 | + Writer& write_encrypted(std::string_view str); | |
| 350 | + | |
| 351 | + template <typename... Args> | |
| 352 | + Writer& write_qdf(Args&&... args); | |
| 353 | + template <typename... Args> | |
| 354 | + Writer& write_no_qdf(Args&&... args); | |
| 355 | + void writeObjectStreamOffsets(std::vector<qpdf_offset_t>& offsets, int first_obj); | |
| 356 | + void writeObjectStream(QPDFObjectHandle object); | |
| 357 | + void writeObject(QPDFObjectHandle object, int object_stream_index = -1); | |
| 358 | + void writeTrailer( | |
| 359 | + trailer_e which, | |
| 360 | + int size, | |
| 361 | + bool xref_stream, | |
| 362 | + qpdf_offset_t prev, | |
| 363 | + int linearization_pass); | |
| 364 | + void unparseObject( | |
| 365 | + QPDFObjectHandle object, | |
| 366 | + size_t level, | |
| 367 | + int flags, | |
| 368 | + // for stream dictionaries | |
| 369 | + size_t stream_length = 0, | |
| 370 | + bool compress = false); | |
| 371 | + void unparseChild(QPDFObjectHandle const& child, size_t level, int flags); | |
| 372 | + int openObject(int objid = 0); | |
| 373 | + void closeObject(int objid); | |
| 374 | + void writeStandard(); | |
| 375 | + void writeLinearized(); | |
| 376 | + void writeEncryptionDictionary(); | |
| 377 | + void writeHeader(); | |
| 378 | + void writeHintStream(int hint_id); | |
| 379 | + qpdf_offset_t writeXRefTable(trailer_e which, int first, int last, int size); | |
| 380 | + qpdf_offset_t writeXRefTable( | |
| 381 | + trailer_e which, | |
| 382 | + int first, | |
| 383 | + int last, | |
| 384 | + int size, | |
| 385 | + // for linearization | |
| 386 | + qpdf_offset_t prev, | |
| 387 | + bool suppress_offsets, | |
| 388 | + int hint_id, | |
| 389 | + qpdf_offset_t hint_offset, | |
| 390 | + qpdf_offset_t hint_length, | |
| 391 | + int linearization_pass); | |
| 392 | + qpdf_offset_t writeXRefStream( | |
| 393 | + int objid, | |
| 394 | + int max_id, | |
| 395 | + qpdf_offset_t max_offset, | |
| 396 | + trailer_e which, | |
| 397 | + int first, | |
| 398 | + int last, | |
| 399 | + int size); | |
| 400 | + qpdf_offset_t writeXRefStream( | |
| 401 | + int objid, | |
| 402 | + int max_id, | |
| 403 | + qpdf_offset_t max_offset, | |
| 404 | + trailer_e which, | |
| 405 | + int first, | |
| 406 | + int last, | |
| 407 | + int size, | |
| 408 | + // for linearization | |
| 409 | + qpdf_offset_t prev, | |
| 410 | + int hint_id, | |
| 411 | + qpdf_offset_t hint_offset, | |
| 412 | + qpdf_offset_t hint_length, | |
| 413 | + bool skip_compression, | |
| 414 | + int linearization_pass); | |
| 415 | + | |
| 416 | + void setDataKey(int objid); | |
| 417 | + void indicateProgress(bool decrement, bool finished); | |
| 418 | + size_t calculateXrefStreamPadding(qpdf_offset_t xref_bytes); | |
| 419 | + | |
| 420 | + void adjustAESStreamLength(size_t& length); | |
| 421 | + void computeDeterministicIDData(); | |
| 422 | + | |
| 302 | 423 | protected: |
| 303 | 424 | Doc::Linearization& lin; |
| 304 | 425 | |
| ... | ... | @@ -347,7 +468,8 @@ namespace qpdf::impl |
| 347 | 468 | int events_expected{0}; |
| 348 | 469 | int events_seen{0}; |
| 349 | 470 | int next_progress_report{0}; |
| 350 | - }; | |
| 471 | + }; // class qpdf::impl::Writer | |
| 472 | + | |
| 351 | 473 | } // namespace qpdf::impl |
| 352 | 474 | |
| 353 | 475 | class QPDFWriter::Members: impl::Writer |
| ... | ... | @@ -359,123 +481,6 @@ class QPDFWriter::Members: impl::Writer |
| 359 | 481 | impl::Writer(qpdf, w) |
| 360 | 482 | { |
| 361 | 483 | } |
| 362 | - | |
| 363 | - void write(); | |
| 364 | - std::map<QPDFObjGen, QPDFXRefEntry> getWrittenXRefTable(); | |
| 365 | - void setMinimumPDFVersion(std::string const& version, int extension_level); | |
| 366 | - void copyEncryptionParameters(QPDF&); | |
| 367 | - void doWriteSetup(); | |
| 368 | - void prepareFileForWrite(); | |
| 369 | - | |
| 370 | - void disableIncompatibleEncryption(int major, int minor, int extension_level); | |
| 371 | - void interpretR3EncryptionParameters( | |
| 372 | - bool allow_accessibility, | |
| 373 | - bool allow_extract, | |
| 374 | - bool allow_assemble, | |
| 375 | - bool allow_annotate_and_form, | |
| 376 | - bool allow_form_filling, | |
| 377 | - bool allow_modify_other, | |
| 378 | - qpdf_r3_print_e print, | |
| 379 | - qpdf_r3_modify_e modify); | |
| 380 | - void setEncryptionParameters(char const* user_password, char const* owner_password); | |
| 381 | - void setEncryptionMinimumVersion(); | |
| 382 | - void parseVersion(std::string const& version, int& major, int& minor) const; | |
| 383 | - int compareVersions(int major1, int minor1, int major2, int minor2) const; | |
| 384 | - void generateID(bool encrypted); | |
| 385 | - std::string getOriginalID1(); | |
| 386 | - void initializeTables(size_t extra = 0); | |
| 387 | - void preserveObjectStreams(); | |
| 388 | - void generateObjectStreams(); | |
| 389 | - void initializeSpecialStreams(); | |
| 390 | - void enqueue(QPDFObjectHandle const& object); | |
| 391 | - void enqueueObjectsStandard(); | |
| 392 | - void enqueueObjectsPCLm(); | |
| 393 | - void enqueuePart(std::vector<QPDFObjectHandle>& part); | |
| 394 | - void assignCompressedObjectNumbers(QPDFObjGen og); | |
| 395 | - Dictionary trimmed_trailer(); | |
| 396 | - | |
| 397 | - // Returns tuple<filter, compress_stream, is_root_metadata> | |
| 398 | - std::tuple<const bool, const bool, const bool> | |
| 399 | - will_filter_stream(QPDFObjectHandle stream, std::string* stream_data); | |
| 400 | - | |
| 401 | - // Test whether stream would be filtered if it were written. | |
| 402 | - bool will_filter_stream(QPDFObjectHandle stream); | |
| 403 | - unsigned int bytesNeeded(long long n); | |
| 404 | - void writeBinary(unsigned long long val, unsigned int bytes); | |
| 405 | - Members& write(std::string_view str); | |
| 406 | - Members& write(size_t count, char c); | |
| 407 | - Members& write(std::integral auto val); | |
| 408 | - Members& write_name(std::string const& str); | |
| 409 | - Members& write_string(std::string const& str, bool force_binary = false); | |
| 410 | - Members& write_encrypted(std::string_view str); | |
| 411 | - | |
| 412 | - template <typename... Args> | |
| 413 | - Members& write_qdf(Args&&... args); | |
| 414 | - template <typename... Args> | |
| 415 | - Members& write_no_qdf(Args&&... args); | |
| 416 | - void writeObjectStreamOffsets(std::vector<qpdf_offset_t>& offsets, int first_obj); | |
| 417 | - void writeObjectStream(QPDFObjectHandle object); | |
| 418 | - void writeObject(QPDFObjectHandle object, int object_stream_index = -1); | |
| 419 | - void writeTrailer( | |
| 420 | - trailer_e which, int size, bool xref_stream, qpdf_offset_t prev, int linearization_pass); | |
| 421 | - void unparseObject( | |
| 422 | - QPDFObjectHandle object, | |
| 423 | - size_t level, | |
| 424 | - int flags, | |
| 425 | - // for stream dictionaries | |
| 426 | - size_t stream_length = 0, | |
| 427 | - bool compress = false); | |
| 428 | - void unparseChild(QPDFObjectHandle const& child, size_t level, int flags); | |
| 429 | - int openObject(int objid = 0); | |
| 430 | - void closeObject(int objid); | |
| 431 | - void writeStandard(); | |
| 432 | - void writeLinearized(); | |
| 433 | - void writeEncryptionDictionary(); | |
| 434 | - void writeHeader(); | |
| 435 | - void writeHintStream(int hint_id); | |
| 436 | - qpdf_offset_t writeXRefTable(trailer_e which, int first, int last, int size); | |
| 437 | - qpdf_offset_t writeXRefTable( | |
| 438 | - trailer_e which, | |
| 439 | - int first, | |
| 440 | - int last, | |
| 441 | - int size, | |
| 442 | - // for linearization | |
| 443 | - qpdf_offset_t prev, | |
| 444 | - bool suppress_offsets, | |
| 445 | - int hint_id, | |
| 446 | - qpdf_offset_t hint_offset, | |
| 447 | - qpdf_offset_t hint_length, | |
| 448 | - int linearization_pass); | |
| 449 | - qpdf_offset_t writeXRefStream( | |
| 450 | - int objid, | |
| 451 | - int max_id, | |
| 452 | - qpdf_offset_t max_offset, | |
| 453 | - trailer_e which, | |
| 454 | - int first, | |
| 455 | - int last, | |
| 456 | - int size); | |
| 457 | - qpdf_offset_t writeXRefStream( | |
| 458 | - int objid, | |
| 459 | - int max_id, | |
| 460 | - qpdf_offset_t max_offset, | |
| 461 | - trailer_e which, | |
| 462 | - int first, | |
| 463 | - int last, | |
| 464 | - int size, | |
| 465 | - // for linearization | |
| 466 | - qpdf_offset_t prev, | |
| 467 | - int hint_id, | |
| 468 | - qpdf_offset_t hint_offset, | |
| 469 | - qpdf_offset_t hint_length, | |
| 470 | - bool skip_compression, | |
| 471 | - int linearization_pass); | |
| 472 | - | |
| 473 | - void setDataKey(int objid); | |
| 474 | - void indicateProgress(bool decrement, bool finished); | |
| 475 | - size_t calculateXrefStreamPadding(qpdf_offset_t xref_bytes); | |
| 476 | - | |
| 477 | - void adjustAESStreamLength(size_t& length); | |
| 478 | - void computeDeterministicIDData(); | |
| 479 | 484 | }; |
| 480 | 485 | |
| 481 | 486 | QPDFWriter::QPDFWriter(QPDF& pdf) : |
| ... | ... | @@ -632,7 +637,7 @@ QPDFWriter::setMinimumPDFVersion(std::string const& version, int extension_level |
| 632 | 637 | } |
| 633 | 638 | |
| 634 | 639 | void |
| 635 | -QPDFWriter::Members::setMinimumPDFVersion(std::string const& version, int extension_level) | |
| 640 | +impl::Writer::setMinimumPDFVersion(std::string const& version, int extension_level) | |
| 636 | 641 | { |
| 637 | 642 | bool set_version = false; |
| 638 | 643 | bool set_extension_level = false; |
| ... | ... | @@ -882,7 +887,7 @@ QPDFWriter::setR6EncryptionParameters( |
| 882 | 887 | } |
| 883 | 888 | |
| 884 | 889 | void |
| 885 | -QPDFWriter::Members::interpretR3EncryptionParameters( | |
| 890 | +impl::Writer::interpretR3EncryptionParameters( | |
| 886 | 891 | bool allow_accessibility, |
| 887 | 892 | bool allow_extract, |
| 888 | 893 | bool allow_assemble, |
| ... | ... | @@ -981,7 +986,7 @@ QPDFWriter::Members::interpretR3EncryptionParameters( |
| 981 | 986 | } |
| 982 | 987 | |
| 983 | 988 | void |
| 984 | -QPDFWriter::Members::setEncryptionParameters(char const* user_password, char const* owner_password) | |
| 989 | +impl::Writer::setEncryptionParameters(char const* user_password, char const* owner_password) | |
| 985 | 990 | { |
| 986 | 991 | generateID(true); |
| 987 | 992 | encryption->setId1(id1); |
| ... | ... | @@ -996,7 +1001,7 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf) |
| 996 | 1001 | } |
| 997 | 1002 | |
| 998 | 1003 | void |
| 999 | -QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf) | |
| 1004 | +impl::Writer::copyEncryptionParameters(QPDF& qpdf) | |
| 1000 | 1005 | { |
| 1001 | 1006 | cfg.preserve_encryption_ = false; |
| 1002 | 1007 | QPDFObjectHandle trailer = qpdf.getTrailer(); |
| ... | ... | @@ -1042,7 +1047,7 @@ QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf) |
| 1042 | 1047 | } |
| 1043 | 1048 | |
| 1044 | 1049 | void |
| 1045 | -QPDFWriter::Members::disableIncompatibleEncryption(int major, int minor, int extension_level) | |
| 1050 | +impl::Writer::disableIncompatibleEncryption(int major, int minor, int extension_level) | |
| 1046 | 1051 | { |
| 1047 | 1052 | if (!encryption) { |
| 1048 | 1053 | return; |
| ... | ... | @@ -1079,7 +1084,7 @@ QPDFWriter::Members::disableIncompatibleEncryption(int major, int minor, int ext |
| 1079 | 1084 | } |
| 1080 | 1085 | |
| 1081 | 1086 | void |
| 1082 | -QPDFWriter::Members::parseVersion(std::string const& version, int& major, int& minor) const | |
| 1087 | +impl::Writer::parseVersion(std::string const& version, int& major, int& minor) const | |
| 1083 | 1088 | { |
| 1084 | 1089 | major = QUtil::string_to_int(version.c_str()); |
| 1085 | 1090 | minor = 0; |
| ... | ... | @@ -1096,7 +1101,7 @@ QPDFWriter::Members::parseVersion(std::string const& version, int& major, int& m |
| 1096 | 1101 | } |
| 1097 | 1102 | |
| 1098 | 1103 | int |
| 1099 | -QPDFWriter::Members::compareVersions(int major1, int minor1, int major2, int minor2) const | |
| 1104 | +impl::Writer::compareVersions(int major1, int minor1, int major2, int minor2) const | |
| 1100 | 1105 | { |
| 1101 | 1106 | if (major1 < major2) { |
| 1102 | 1107 | return -1; |
| ... | ... | @@ -1111,7 +1116,7 @@ QPDFWriter::Members::compareVersions(int major1, int minor1, int major2, int min |
| 1111 | 1116 | } |
| 1112 | 1117 | |
| 1113 | 1118 | void |
| 1114 | -QPDFWriter::Members::setEncryptionMinimumVersion() | |
| 1119 | +impl::Writer::setEncryptionMinimumVersion() | |
| 1115 | 1120 | { |
| 1116 | 1121 | auto const R = encryption->getR(); |
| 1117 | 1122 | if (R >= 6) { |
| ... | ... | @@ -1128,7 +1133,7 @@ QPDFWriter::Members::setEncryptionMinimumVersion() |
| 1128 | 1133 | } |
| 1129 | 1134 | |
| 1130 | 1135 | void |
| 1131 | -QPDFWriter::Members::setDataKey(int objid) | |
| 1136 | +impl::Writer::setDataKey(int objid) | |
| 1132 | 1137 | { |
| 1133 | 1138 | if (encryption) { |
| 1134 | 1139 | cur_data_key = QPDF::compute_data_key( |
| ... | ... | @@ -1137,7 +1142,7 @@ QPDFWriter::Members::setDataKey(int objid) |
| 1137 | 1142 | } |
| 1138 | 1143 | |
| 1139 | 1144 | unsigned int |
| 1140 | -QPDFWriter::Members::bytesNeeded(long long n) | |
| 1145 | +impl::Writer::bytesNeeded(long long n) | |
| 1141 | 1146 | { |
| 1142 | 1147 | unsigned int bytes = 0; |
| 1143 | 1148 | while (n) { |
| ... | ... | @@ -1148,7 +1153,7 @@ QPDFWriter::Members::bytesNeeded(long long n) |
| 1148 | 1153 | } |
| 1149 | 1154 | |
| 1150 | 1155 | void |
| 1151 | -QPDFWriter::Members::writeBinary(unsigned long long val, unsigned int bytes) | |
| 1156 | +impl::Writer::writeBinary(unsigned long long val, unsigned int bytes) | |
| 1152 | 1157 | { |
| 1153 | 1158 | if (bytes > sizeof(unsigned long long)) { |
| 1154 | 1159 | throw std::logic_error("QPDFWriter::writeBinary called with too many bytes"); |
| ... | ... | @@ -1161,44 +1166,44 @@ QPDFWriter::Members::writeBinary(unsigned long long val, unsigned int bytes) |
| 1161 | 1166 | pipeline->write(data, bytes); |
| 1162 | 1167 | } |
| 1163 | 1168 | |
| 1164 | -QPDFWriter::Members& | |
| 1165 | -QPDFWriter::Members::write(std::string_view str) | |
| 1169 | +impl::Writer& | |
| 1170 | +impl::Writer::write(std::string_view str) | |
| 1166 | 1171 | { |
| 1167 | 1172 | pipeline->write(str); |
| 1168 | 1173 | return *this; |
| 1169 | 1174 | } |
| 1170 | 1175 | |
| 1171 | -QPDFWriter::Members& | |
| 1172 | -QPDFWriter::Members::write(std::integral auto val) | |
| 1176 | +impl::Writer& | |
| 1177 | +impl::Writer::write(std::integral auto val) | |
| 1173 | 1178 | { |
| 1174 | 1179 | pipeline->write(std::to_string(val)); |
| 1175 | 1180 | return *this; |
| 1176 | 1181 | } |
| 1177 | 1182 | |
| 1178 | -QPDFWriter::Members& | |
| 1179 | -QPDFWriter::Members::write(size_t count, char c) | |
| 1183 | +impl::Writer& | |
| 1184 | +impl::Writer::write(size_t count, char c) | |
| 1180 | 1185 | { |
| 1181 | 1186 | pipeline->write(count, c); |
| 1182 | 1187 | return *this; |
| 1183 | 1188 | } |
| 1184 | 1189 | |
| 1185 | -QPDFWriter::Members& | |
| 1186 | -QPDFWriter::Members::write_name(std::string const& str) | |
| 1190 | +impl::Writer& | |
| 1191 | +impl::Writer::write_name(std::string const& str) | |
| 1187 | 1192 | { |
| 1188 | 1193 | pipeline->write(Name::normalize(str)); |
| 1189 | 1194 | return *this; |
| 1190 | 1195 | } |
| 1191 | 1196 | |
| 1192 | -QPDFWriter::Members& | |
| 1193 | -QPDFWriter::Members::write_string(std::string const& str, bool force_binary) | |
| 1197 | +impl::Writer& | |
| 1198 | +impl::Writer::write_string(std::string const& str, bool force_binary) | |
| 1194 | 1199 | { |
| 1195 | 1200 | pipeline->write(QPDF_String(str).unparse(force_binary)); |
| 1196 | 1201 | return *this; |
| 1197 | 1202 | } |
| 1198 | 1203 | |
| 1199 | 1204 | template <typename... Args> |
| 1200 | -QPDFWriter::Members& | |
| 1201 | -QPDFWriter::Members::write_qdf(Args&&... args) | |
| 1205 | +impl::Writer& | |
| 1206 | +impl::Writer::write_qdf(Args&&... args) | |
| 1202 | 1207 | { |
| 1203 | 1208 | if (cfg.qdf_mode_) { |
| 1204 | 1209 | pipeline->write(std::forward<Args>(args)...); |
| ... | ... | @@ -1207,8 +1212,8 @@ QPDFWriter::Members::write_qdf(Args&&... args) |
| 1207 | 1212 | } |
| 1208 | 1213 | |
| 1209 | 1214 | template <typename... Args> |
| 1210 | -QPDFWriter::Members& | |
| 1211 | -QPDFWriter::Members::write_no_qdf(Args&&... args) | |
| 1215 | +impl::Writer& | |
| 1216 | +impl::Writer::write_no_qdf(Args&&... args) | |
| 1212 | 1217 | { |
| 1213 | 1218 | if (!cfg.qdf_mode_) { |
| 1214 | 1219 | pipeline->write(std::forward<Args>(args)...); |
| ... | ... | @@ -1217,7 +1222,7 @@ QPDFWriter::Members::write_no_qdf(Args&&... args) |
| 1217 | 1222 | } |
| 1218 | 1223 | |
| 1219 | 1224 | void |
| 1220 | -QPDFWriter::Members::adjustAESStreamLength(size_t& length) | |
| 1225 | +impl::Writer::adjustAESStreamLength(size_t& length) | |
| 1221 | 1226 | { |
| 1222 | 1227 | if (encryption && !cur_data_key.empty() && cfg.encrypt_use_aes_) { |
| 1223 | 1228 | // Stream length will be padded with 1 to 16 bytes to end up as a multiple of 16. It will |
| ... | ... | @@ -1226,8 +1231,8 @@ QPDFWriter::Members::adjustAESStreamLength(size_t& length) |
| 1226 | 1231 | } |
| 1227 | 1232 | } |
| 1228 | 1233 | |
| 1229 | -QPDFWriter::Members& | |
| 1230 | -QPDFWriter::Members::write_encrypted(std::string_view str) | |
| 1234 | +impl::Writer& | |
| 1235 | +impl::Writer::write_encrypted(std::string_view str) | |
| 1231 | 1236 | { |
| 1232 | 1237 | if (!(encryption && !cur_data_key.empty())) { |
| 1233 | 1238 | write(str); |
| ... | ... | @@ -1241,7 +1246,7 @@ QPDFWriter::Members::write_encrypted(std::string_view str) |
| 1241 | 1246 | } |
| 1242 | 1247 | |
| 1243 | 1248 | void |
| 1244 | -QPDFWriter::Members::computeDeterministicIDData() | |
| 1249 | +impl::Writer::computeDeterministicIDData() | |
| 1245 | 1250 | { |
| 1246 | 1251 | if (!id2.empty()) { |
| 1247 | 1252 | // Can't happen in the code |
| ... | ... | @@ -1253,7 +1258,7 @@ QPDFWriter::Members::computeDeterministicIDData() |
| 1253 | 1258 | } |
| 1254 | 1259 | |
| 1255 | 1260 | int |
| 1256 | -QPDFWriter::Members::openObject(int objid) | |
| 1261 | +impl::Writer::openObject(int objid) | |
| 1257 | 1262 | { |
| 1258 | 1263 | if (objid == 0) { |
| 1259 | 1264 | objid = next_objid++; |
| ... | ... | @@ -1264,7 +1269,7 @@ QPDFWriter::Members::openObject(int objid) |
| 1264 | 1269 | } |
| 1265 | 1270 | |
| 1266 | 1271 | void |
| 1267 | -QPDFWriter::Members::closeObject(int objid) | |
| 1272 | +impl::Writer::closeObject(int objid) | |
| 1268 | 1273 | { |
| 1269 | 1274 | // Write a newline before endobj as it makes the file easier to repair. |
| 1270 | 1275 | write("\nendobj\n").write_qdf("\n"); |
| ... | ... | @@ -1273,7 +1278,7 @@ QPDFWriter::Members::closeObject(int objid) |
| 1273 | 1278 | } |
| 1274 | 1279 | |
| 1275 | 1280 | void |
| 1276 | -QPDFWriter::Members::assignCompressedObjectNumbers(QPDFObjGen og) | |
| 1281 | +impl::Writer::assignCompressedObjectNumbers(QPDFObjGen og) | |
| 1277 | 1282 | { |
| 1278 | 1283 | int objid = og.getObj(); |
| 1279 | 1284 | if (og.getGen() != 0 || !object_stream_to_objects.contains(objid)) { |
| ... | ... | @@ -1288,7 +1293,7 @@ QPDFWriter::Members::assignCompressedObjectNumbers(QPDFObjGen og) |
| 1288 | 1293 | } |
| 1289 | 1294 | |
| 1290 | 1295 | void |
| 1291 | -QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) | |
| 1296 | +impl::Writer::enqueue(QPDFObjectHandle const& object) | |
| 1292 | 1297 | { |
| 1293 | 1298 | if (object.indirect()) { |
| 1294 | 1299 | util::assertion( |
| ... | ... | @@ -1359,7 +1364,7 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) |
| 1359 | 1364 | } |
| 1360 | 1365 | |
| 1361 | 1366 | void |
| 1362 | -QPDFWriter::Members::unparseChild(QPDFObjectHandle const& child, size_t level, int flags) | |
| 1367 | +impl::Writer::unparseChild(QPDFObjectHandle const& child, size_t level, int flags) | |
| 1363 | 1368 | { |
| 1364 | 1369 | if (!cfg.linearized_) { |
| 1365 | 1370 | enqueue(child); |
| ... | ... | @@ -1372,7 +1377,7 @@ QPDFWriter::Members::unparseChild(QPDFObjectHandle const& child, size_t level, i |
| 1372 | 1377 | } |
| 1373 | 1378 | |
| 1374 | 1379 | void |
| 1375 | -QPDFWriter::Members::writeTrailer( | |
| 1380 | +impl::Writer::writeTrailer( | |
| 1376 | 1381 | trailer_e which, int size, bool xref_stream, qpdf_offset_t prev, int linearization_pass) |
| 1377 | 1382 | { |
| 1378 | 1383 | auto trailer = trimmed_trailer(); |
| ... | ... | @@ -1439,7 +1444,7 @@ QPDFWriter::Members::writeTrailer( |
| 1439 | 1444 | } |
| 1440 | 1445 | |
| 1441 | 1446 | bool |
| 1442 | -QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream) | |
| 1447 | +impl::Writer::will_filter_stream(QPDFObjectHandle stream) | |
| 1443 | 1448 | { |
| 1444 | 1449 | std::string s; |
| 1445 | 1450 | [[maybe_unused]] auto [filter, ignore1, ignore2] = will_filter_stream(stream, &s); |
| ... | ... | @@ -1447,7 +1452,7 @@ QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream) |
| 1447 | 1452 | } |
| 1448 | 1453 | |
| 1449 | 1454 | std::tuple<const bool, const bool, const bool> |
| 1450 | -QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream, std::string* stream_data) | |
| 1455 | +impl::Writer::will_filter_stream(QPDFObjectHandle stream, std::string* stream_data) | |
| 1451 | 1456 | { |
| 1452 | 1457 | const bool is_root_metadata = stream.isRootMetadata(); |
| 1453 | 1458 | bool filter = false; |
| ... | ... | @@ -1520,7 +1525,7 @@ QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream, std::string* st |
| 1520 | 1525 | } |
| 1521 | 1526 | |
| 1522 | 1527 | void |
| 1523 | -QPDFWriter::Members::unparseObject( | |
| 1528 | +impl::Writer::unparseObject( | |
| 1524 | 1529 | QPDFObjectHandle object, size_t level, int flags, size_t stream_length, bool compress) |
| 1525 | 1530 | { |
| 1526 | 1531 | QPDFObjGen old_og = object.getObjGen(); |
| ... | ... | @@ -1763,7 +1768,7 @@ QPDFWriter::Members::unparseObject( |
| 1763 | 1768 | } |
| 1764 | 1769 | |
| 1765 | 1770 | void |
| 1766 | -QPDFWriter::Members::writeObjectStreamOffsets(std::vector<qpdf_offset_t>& offsets, int first_obj) | |
| 1771 | +impl::Writer::writeObjectStreamOffsets(std::vector<qpdf_offset_t>& offsets, int first_obj) | |
| 1767 | 1772 | { |
| 1768 | 1773 | qpdf_assert_debug(first_obj > 0); |
| 1769 | 1774 | bool is_first = true; |
| ... | ... | @@ -1782,7 +1787,7 @@ QPDFWriter::Members::writeObjectStreamOffsets(std::vector<qpdf_offset_t>& offset |
| 1782 | 1787 | } |
| 1783 | 1788 | |
| 1784 | 1789 | void |
| 1785 | -QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | |
| 1790 | +impl::Writer::writeObjectStream(QPDFObjectHandle object) | |
| 1786 | 1791 | { |
| 1787 | 1792 | // Note: object might be null if this is a place-holder for an object stream that we are |
| 1788 | 1793 | // generating from scratch. |
| ... | ... | @@ -1899,7 +1904,7 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) |
| 1899 | 1904 | } |
| 1900 | 1905 | |
| 1901 | 1906 | void |
| 1902 | -QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_index) | |
| 1907 | +impl::Writer::writeObject(QPDFObjectHandle object, int object_stream_index) | |
| 1903 | 1908 | { |
| 1904 | 1909 | QPDFObjGen old_og = object.getObjGen(); |
| 1905 | 1910 | |
| ... | ... | @@ -1946,7 +1951,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde |
| 1946 | 1951 | } |
| 1947 | 1952 | |
| 1948 | 1953 | std::string |
| 1949 | -QPDFWriter::Members::getOriginalID1() | |
| 1954 | +impl::Writer::getOriginalID1() | |
| 1950 | 1955 | { |
| 1951 | 1956 | QPDFObjectHandle trailer = qpdf.getTrailer(); |
| 1952 | 1957 | if (trailer.hasKey("/ID")) { |
| ... | ... | @@ -1957,7 +1962,7 @@ QPDFWriter::Members::getOriginalID1() |
| 1957 | 1962 | } |
| 1958 | 1963 | |
| 1959 | 1964 | void |
| 1960 | -QPDFWriter::Members::generateID(bool encrypted) | |
| 1965 | +impl::Writer::generateID(bool encrypted) | |
| 1961 | 1966 | { |
| 1962 | 1967 | // Generate the ID lazily so that we can handle the user's preference to use static or |
| 1963 | 1968 | // deterministic ID generation. |
| ... | ... | @@ -2047,7 +2052,7 @@ QPDFWriter::Members::generateID(bool encrypted) |
| 2047 | 2052 | } |
| 2048 | 2053 | |
| 2049 | 2054 | void |
| 2050 | -QPDFWriter::Members::initializeSpecialStreams() | |
| 2055 | +impl::Writer::initializeSpecialStreams() | |
| 2051 | 2056 | { |
| 2052 | 2057 | // Mark all page content streams in case we are filtering or normalizing. |
| 2053 | 2058 | int num = 0; |
| ... | ... | @@ -2072,7 +2077,7 @@ QPDFWriter::Members::initializeSpecialStreams() |
| 2072 | 2077 | } |
| 2073 | 2078 | |
| 2074 | 2079 | void |
| 2075 | -QPDFWriter::Members::preserveObjectStreams() | |
| 2080 | +impl::Writer::preserveObjectStreams() | |
| 2076 | 2081 | { |
| 2077 | 2082 | auto const& xref = objects.xref_table(); |
| 2078 | 2083 | // Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object |
| ... | ... | @@ -2120,7 +2125,7 @@ QPDFWriter::Members::preserveObjectStreams() |
| 2120 | 2125 | } |
| 2121 | 2126 | |
| 2122 | 2127 | void |
| 2123 | -QPDFWriter::Members::generateObjectStreams() | |
| 2128 | +impl::Writer::generateObjectStreams() | |
| 2124 | 2129 | { |
| 2125 | 2130 | // Basic strategy: make a list of objects that can go into an object stream. Then figure out |
| 2126 | 2131 | // how many object streams are needed so that we can distribute objects approximately evenly |
| ... | ... | @@ -2159,7 +2164,7 @@ QPDFWriter::Members::generateObjectStreams() |
| 2159 | 2164 | } |
| 2160 | 2165 | |
| 2161 | 2166 | Dictionary |
| 2162 | -QPDFWriter::Members::trimmed_trailer() | |
| 2167 | +impl::Writer::trimmed_trailer() | |
| 2163 | 2168 | { |
| 2164 | 2169 | // Remove keys from the trailer that necessarily have to be replaced when writing the file. |
| 2165 | 2170 | |
| ... | ... | @@ -2186,7 +2191,7 @@ QPDFWriter::Members::trimmed_trailer() |
| 2186 | 2191 | |
| 2187 | 2192 | // Make document extension level information direct as required by the spec. |
| 2188 | 2193 | void |
| 2189 | -QPDFWriter::Members::prepareFileForWrite() | |
| 2194 | +impl::Writer::prepareFileForWrite() | |
| 2190 | 2195 | { |
| 2191 | 2196 | qpdf.fixDanglingReferences(); |
| 2192 | 2197 | auto root = qpdf.getRoot(); |
| ... | ... | @@ -2209,7 +2214,7 @@ QPDFWriter::Members::prepareFileForWrite() |
| 2209 | 2214 | } |
| 2210 | 2215 | |
| 2211 | 2216 | void |
| 2212 | -QPDFWriter::Members::initializeTables(size_t extra) | |
| 2217 | +impl::Writer::initializeTables(size_t extra) | |
| 2213 | 2218 | { |
| 2214 | 2219 | auto size = objects.table_size() + 100u + extra; |
| 2215 | 2220 | obj.resize(size); |
| ... | ... | @@ -2217,7 +2222,7 @@ QPDFWriter::Members::initializeTables(size_t extra) |
| 2217 | 2222 | } |
| 2218 | 2223 | |
| 2219 | 2224 | void |
| 2220 | -QPDFWriter::Members::doWriteSetup() | |
| 2225 | +impl::Writer::doWriteSetup() | |
| 2221 | 2226 | { |
| 2222 | 2227 | if (did_write_setup) { |
| 2223 | 2228 | return; |
| ... | ... | @@ -2355,7 +2360,7 @@ QPDFWriter::write() |
| 2355 | 2360 | } |
| 2356 | 2361 | |
| 2357 | 2362 | void |
| 2358 | -QPDFWriter::Members::write() | |
| 2363 | +impl::Writer::write() | |
| 2359 | 2364 | { |
| 2360 | 2365 | doWriteSetup(); |
| 2361 | 2366 | |
| ... | ... | @@ -2396,7 +2401,7 @@ QPDFWriter::getWrittenXRefTable() |
| 2396 | 2401 | } |
| 2397 | 2402 | |
| 2398 | 2403 | std::map<QPDFObjGen, QPDFXRefEntry> |
| 2399 | -QPDFWriter::Members::getWrittenXRefTable() | |
| 2404 | +impl::Writer::getWrittenXRefTable() | |
| 2400 | 2405 | { |
| 2401 | 2406 | std::map<QPDFObjGen, QPDFXRefEntry> result; |
| 2402 | 2407 | |
| ... | ... | @@ -2410,7 +2415,7 @@ QPDFWriter::Members::getWrittenXRefTable() |
| 2410 | 2415 | } |
| 2411 | 2416 | |
| 2412 | 2417 | void |
| 2413 | -QPDFWriter::Members::enqueuePart(std::vector<QPDFObjectHandle>& part) | |
| 2418 | +impl::Writer::enqueuePart(std::vector<QPDFObjectHandle>& part) | |
| 2414 | 2419 | { |
| 2415 | 2420 | for (auto const& oh: part) { |
| 2416 | 2421 | enqueue(oh); |
| ... | ... | @@ -2418,7 +2423,7 @@ QPDFWriter::Members::enqueuePart(std::vector<QPDFObjectHandle>& part) |
| 2418 | 2423 | } |
| 2419 | 2424 | |
| 2420 | 2425 | void |
| 2421 | -QPDFWriter::Members::writeEncryptionDictionary() | |
| 2426 | +impl::Writer::writeEncryptionDictionary() | |
| 2422 | 2427 | { |
| 2423 | 2428 | encryption_dict_objid = openObject(encryption_dict_objid); |
| 2424 | 2429 | auto& enc = *encryption; |
| ... | ... | @@ -2465,7 +2470,7 @@ QPDFWriter::getFinalVersion() |
| 2465 | 2470 | } |
| 2466 | 2471 | |
| 2467 | 2472 | void |
| 2468 | -QPDFWriter::Members::writeHeader() | |
| 2473 | +impl::Writer::writeHeader() | |
| 2469 | 2474 | { |
| 2470 | 2475 | write("%PDF-").write(final_pdf_version); |
| 2471 | 2476 | if (cfg.pclm_) { |
| ... | ... | @@ -2485,7 +2490,7 @@ QPDFWriter::Members::writeHeader() |
| 2485 | 2490 | } |
| 2486 | 2491 | |
| 2487 | 2492 | void |
| 2488 | -QPDFWriter::Members::writeHintStream(int hint_id) | |
| 2493 | +impl::Writer::writeHintStream(int hint_id) | |
| 2489 | 2494 | { |
| 2490 | 2495 | std::string hint_buffer; |
| 2491 | 2496 | int S = 0; |
| ... | ... | @@ -2519,7 +2524,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) |
| 2519 | 2524 | } |
| 2520 | 2525 | |
| 2521 | 2526 | qpdf_offset_t |
| 2522 | -QPDFWriter::Members::writeXRefTable(trailer_e which, int first, int last, int size) | |
| 2527 | +impl::Writer::writeXRefTable(trailer_e which, int first, int last, int size) | |
| 2523 | 2528 | { |
| 2524 | 2529 | // There are too many extra arguments to replace overloaded function with defaults in the header |
| 2525 | 2530 | // file...too much risk of leaving something off. |
| ... | ... | @@ -2527,7 +2532,7 @@ QPDFWriter::Members::writeXRefTable(trailer_e which, int first, int last, int si |
| 2527 | 2532 | } |
| 2528 | 2533 | |
| 2529 | 2534 | qpdf_offset_t |
| 2530 | -QPDFWriter::Members::writeXRefTable( | |
| 2535 | +impl::Writer::writeXRefTable( | |
| 2531 | 2536 | trailer_e which, |
| 2532 | 2537 | int first, |
| 2533 | 2538 | int last, |
| ... | ... | @@ -2562,7 +2567,7 @@ QPDFWriter::Members::writeXRefTable( |
| 2562 | 2567 | } |
| 2563 | 2568 | |
| 2564 | 2569 | qpdf_offset_t |
| 2565 | -QPDFWriter::Members::writeXRefStream( | |
| 2570 | +impl::Writer::writeXRefStream( | |
| 2566 | 2571 | int objid, int max_id, qpdf_offset_t max_offset, trailer_e which, int first, int last, int size) |
| 2567 | 2572 | { |
| 2568 | 2573 | // There are too many extra arguments to replace overloaded function with defaults in the header |
| ... | ... | @@ -2572,7 +2577,7 @@ QPDFWriter::Members::writeXRefStream( |
| 2572 | 2577 | } |
| 2573 | 2578 | |
| 2574 | 2579 | qpdf_offset_t |
| 2575 | -QPDFWriter::Members::writeXRefStream( | |
| 2580 | +impl::Writer::writeXRefStream( | |
| 2576 | 2581 | int xref_id, |
| 2577 | 2582 | int max_id, |
| 2578 | 2583 | qpdf_offset_t max_offset, |
| ... | ... | @@ -2668,7 +2673,7 @@ QPDFWriter::Members::writeXRefStream( |
| 2668 | 2673 | } |
| 2669 | 2674 | |
| 2670 | 2675 | size_t |
| 2671 | -QPDFWriter::Members::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) | |
| 2676 | +impl::Writer::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) | |
| 2672 | 2677 | { |
| 2673 | 2678 | // This routine is called right after a linearization first pass xref stream has been written |
| 2674 | 2679 | // without compression. Calculate the amount of padding that would be required in the worst |
| ... | ... | @@ -2680,7 +2685,7 @@ QPDFWriter::Members::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) |
| 2680 | 2685 | } |
| 2681 | 2686 | |
| 2682 | 2687 | void |
| 2683 | -QPDFWriter::Members::writeLinearized() | |
| 2688 | +impl::Writer::writeLinearized() | |
| 2684 | 2689 | { |
| 2685 | 2690 | // Optimize file and enqueue objects in order |
| 2686 | 2691 | |
| ... | ... | @@ -3027,7 +3032,7 @@ QPDFWriter::Members::writeLinearized() |
| 3027 | 3032 | } |
| 3028 | 3033 | |
| 3029 | 3034 | void |
| 3030 | -QPDFWriter::Members::enqueueObjectsStandard() | |
| 3035 | +impl::Writer::enqueueObjectsStandard() | |
| 3031 | 3036 | { |
| 3032 | 3037 | if (cfg.preserve_unreferenced_objects_) { |
| 3033 | 3038 | for (auto const& oh: qpdf.getAllObjects()) { |
| ... | ... | @@ -3049,7 +3054,7 @@ QPDFWriter::Members::enqueueObjectsStandard() |
| 3049 | 3054 | } |
| 3050 | 3055 | |
| 3051 | 3056 | void |
| 3052 | -QPDFWriter::Members::enqueueObjectsPCLm() | |
| 3057 | +impl::Writer::enqueueObjectsPCLm() | |
| 3053 | 3058 | { |
| 3054 | 3059 | // Image transform stream content for page strip images. Each of this new stream has to come |
| 3055 | 3060 | // after every page image strip written in the pclm file. |
| ... | ... | @@ -3073,7 +3078,7 @@ QPDFWriter::Members::enqueueObjectsPCLm() |
| 3073 | 3078 | } |
| 3074 | 3079 | |
| 3075 | 3080 | void |
| 3076 | -QPDFWriter::Members::indicateProgress(bool decrement, bool finished) | |
| 3081 | +impl::Writer::indicateProgress(bool decrement, bool finished) | |
| 3077 | 3082 | { |
| 3078 | 3083 | if (decrement) { |
| 3079 | 3084 | --events_seen; |
| ... | ... | @@ -3107,7 +3112,7 @@ QPDFWriter::registerProgressReporter(std::shared_ptr<ProgressReporter> pr) |
| 3107 | 3112 | } |
| 3108 | 3113 | |
| 3109 | 3114 | void |
| 3110 | -QPDFWriter::Members::writeStandard() | |
| 3115 | +impl::Writer::writeStandard() | |
| 3111 | 3116 | { |
| 3112 | 3117 | auto pp_md5 = pipeline_stack.popper(); |
| 3113 | 3118 | if (cfg.deterministic_id_) { | ... | ... |
libqpdf/qpdf/ObjTable.hh
libqpdf/qpdf/QPDFObject_private.hh
| ... | ... | @@ -30,6 +30,11 @@ namespace qpdf |
| 30 | 30 | class Integer; |
| 31 | 31 | class Name; |
| 32 | 32 | class Stream; |
| 33 | + | |
| 34 | + namespace impl | |
| 35 | + { | |
| 36 | + class Writer; | |
| 37 | + } | |
| 33 | 38 | } // namespace qpdf |
| 34 | 39 | |
| 35 | 40 | class QPDF_Array final |
| ... | ... | @@ -256,7 +261,7 @@ class QPDF_String final |
| 256 | 261 | { |
| 257 | 262 | friend class QPDFObject; |
| 258 | 263 | friend class qpdf::BaseHandle; |
| 259 | - friend class QPDFWriter; | |
| 264 | + friend class qpdf::impl::Writer; | |
| 260 | 265 | |
| 261 | 266 | public: |
| 262 | 267 | static std::shared_ptr<QPDFObject> create_utf16(std::string const& utf8_val); | ... | ... |
libqpdf/qpdf/QPDFWriter_private.hh
| ... | ... | @@ -10,40 +10,6 @@ |
| 10 | 10 | // This file is intended for inclusion by QPDFWriter, QPDF, QPDF_optimization and QPDF_linearization |
| 11 | 11 | // only. |
| 12 | 12 | |
| 13 | -struct QPDFWriter::Object | |
| 14 | -{ | |
| 15 | - int renumber{0}; | |
| 16 | - int gen{0}; | |
| 17 | - int object_stream{0}; | |
| 18 | -}; | |
| 19 | - | |
| 20 | -struct QPDFWriter::NewObject | |
| 21 | -{ | |
| 22 | - QPDFXRefEntry xref; | |
| 23 | - qpdf_offset_t length{0}; | |
| 24 | -}; | |
| 25 | - | |
| 26 | -class QPDFWriter::ObjTable: public ::ObjTable<QPDFWriter::Object> | |
| 27 | -{ | |
| 28 | - friend class QPDFWriter; | |
| 29 | - | |
| 30 | - public: | |
| 31 | - bool | |
| 32 | - getStreamsEmpty() const noexcept | |
| 33 | - { | |
| 34 | - return streams_empty; | |
| 35 | - } | |
| 36 | - | |
| 37 | - private: | |
| 38 | - // For performance, set by QPDFWriter rather than tracked by ObjTable. | |
| 39 | - bool streams_empty{false}; | |
| 40 | -}; | |
| 41 | - | |
| 42 | -class QPDFWriter::NewObjTable: public ::ObjTable<QPDFWriter::NewObject> | |
| 43 | -{ | |
| 44 | - friend class QPDFWriter; | |
| 45 | -}; | |
| 46 | - | |
| 47 | 13 | namespace qpdf |
| 48 | 14 | { |
| 49 | 15 | namespace impl |
| ... | ... | @@ -90,4 +56,38 @@ namespace qpdf |
| 90 | 56 | }; // class Writer |
| 91 | 57 | } // namespace qpdf |
| 92 | 58 | |
| 59 | +struct QPDFWriter::Object | |
| 60 | +{ | |
| 61 | + int renumber{0}; | |
| 62 | + int gen{0}; | |
| 63 | + int object_stream{0}; | |
| 64 | +}; | |
| 65 | + | |
| 66 | +struct QPDFWriter::NewObject | |
| 67 | +{ | |
| 68 | + QPDFXRefEntry xref; | |
| 69 | + qpdf_offset_t length{0}; | |
| 70 | +}; | |
| 71 | + | |
| 72 | +class QPDFWriter::ObjTable: public ::ObjTable<QPDFWriter::Object> | |
| 73 | +{ | |
| 74 | + friend class qpdf::impl::Writer; | |
| 75 | + | |
| 76 | + public: | |
| 77 | + bool | |
| 78 | + getStreamsEmpty() const noexcept | |
| 79 | + { | |
| 80 | + return streams_empty; | |
| 81 | + } | |
| 82 | + | |
| 83 | + private: | |
| 84 | + // For performance, set by QPDFWriter rather than tracked by ObjTable. | |
| 85 | + bool streams_empty{false}; | |
| 86 | +}; | |
| 87 | + | |
| 88 | +class QPDFWriter::NewObjTable: public ::ObjTable<QPDFWriter::NewObject> | |
| 89 | +{ | |
| 90 | + friend class QPDFWriter; | |
| 91 | +}; | |
| 92 | + | |
| 93 | 93 | #endif // QPDFWRITER_PRIVATE_HH | ... | ... |