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,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 | protected: | 423 | protected: |
| 303 | Doc::Linearization& lin; | 424 | Doc::Linearization& lin; |
| 304 | 425 | ||
| @@ -347,7 +468,8 @@ namespace qpdf::impl | @@ -347,7 +468,8 @@ namespace qpdf::impl | ||
| 347 | int events_expected{0}; | 468 | int events_expected{0}; |
| 348 | int events_seen{0}; | 469 | int events_seen{0}; |
| 349 | int next_progress_report{0}; | 470 | int next_progress_report{0}; |
| 350 | - }; | 471 | + }; // class qpdf::impl::Writer |
| 472 | + | ||
| 351 | } // namespace qpdf::impl | 473 | } // namespace qpdf::impl |
| 352 | 474 | ||
| 353 | class QPDFWriter::Members: impl::Writer | 475 | class QPDFWriter::Members: impl::Writer |
| @@ -359,123 +481,6 @@ class QPDFWriter::Members: impl::Writer | @@ -359,123 +481,6 @@ class QPDFWriter::Members: impl::Writer | ||
| 359 | impl::Writer(qpdf, w) | 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 | QPDFWriter::QPDFWriter(QPDF& pdf) : | 486 | QPDFWriter::QPDFWriter(QPDF& pdf) : |
| @@ -632,7 +637,7 @@ QPDFWriter::setMinimumPDFVersion(std::string const& version, int extension_level | @@ -632,7 +637,7 @@ QPDFWriter::setMinimumPDFVersion(std::string const& version, int extension_level | ||
| 632 | } | 637 | } |
| 633 | 638 | ||
| 634 | void | 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 | bool set_version = false; | 642 | bool set_version = false; |
| 638 | bool set_extension_level = false; | 643 | bool set_extension_level = false; |
| @@ -882,7 +887,7 @@ QPDFWriter::setR6EncryptionParameters( | @@ -882,7 +887,7 @@ QPDFWriter::setR6EncryptionParameters( | ||
| 882 | } | 887 | } |
| 883 | 888 | ||
| 884 | void | 889 | void |
| 885 | -QPDFWriter::Members::interpretR3EncryptionParameters( | 890 | +impl::Writer::interpretR3EncryptionParameters( |
| 886 | bool allow_accessibility, | 891 | bool allow_accessibility, |
| 887 | bool allow_extract, | 892 | bool allow_extract, |
| 888 | bool allow_assemble, | 893 | bool allow_assemble, |
| @@ -981,7 +986,7 @@ QPDFWriter::Members::interpretR3EncryptionParameters( | @@ -981,7 +986,7 @@ QPDFWriter::Members::interpretR3EncryptionParameters( | ||
| 981 | } | 986 | } |
| 982 | 987 | ||
| 983 | void | 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 | generateID(true); | 991 | generateID(true); |
| 987 | encryption->setId1(id1); | 992 | encryption->setId1(id1); |
| @@ -996,7 +1001,7 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf) | @@ -996,7 +1001,7 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf) | ||
| 996 | } | 1001 | } |
| 997 | 1002 | ||
| 998 | void | 1003 | void |
| 999 | -QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf) | 1004 | +impl::Writer::copyEncryptionParameters(QPDF& qpdf) |
| 1000 | { | 1005 | { |
| 1001 | cfg.preserve_encryption_ = false; | 1006 | cfg.preserve_encryption_ = false; |
| 1002 | QPDFObjectHandle trailer = qpdf.getTrailer(); | 1007 | QPDFObjectHandle trailer = qpdf.getTrailer(); |
| @@ -1042,7 +1047,7 @@ QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf) | @@ -1042,7 +1047,7 @@ QPDFWriter::Members::copyEncryptionParameters(QPDF& qpdf) | ||
| 1042 | } | 1047 | } |
| 1043 | 1048 | ||
| 1044 | void | 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 | if (!encryption) { | 1052 | if (!encryption) { |
| 1048 | return; | 1053 | return; |
| @@ -1079,7 +1084,7 @@ QPDFWriter::Members::disableIncompatibleEncryption(int major, int minor, int ext | @@ -1079,7 +1084,7 @@ QPDFWriter::Members::disableIncompatibleEncryption(int major, int minor, int ext | ||
| 1079 | } | 1084 | } |
| 1080 | 1085 | ||
| 1081 | void | 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 | major = QUtil::string_to_int(version.c_str()); | 1089 | major = QUtil::string_to_int(version.c_str()); |
| 1085 | minor = 0; | 1090 | minor = 0; |
| @@ -1096,7 +1101,7 @@ QPDFWriter::Members::parseVersion(std::string const& version, int& major, int& m | @@ -1096,7 +1101,7 @@ QPDFWriter::Members::parseVersion(std::string const& version, int& major, int& m | ||
| 1096 | } | 1101 | } |
| 1097 | 1102 | ||
| 1098 | int | 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 | if (major1 < major2) { | 1106 | if (major1 < major2) { |
| 1102 | return -1; | 1107 | return -1; |
| @@ -1111,7 +1116,7 @@ QPDFWriter::Members::compareVersions(int major1, int minor1, int major2, int min | @@ -1111,7 +1116,7 @@ QPDFWriter::Members::compareVersions(int major1, int minor1, int major2, int min | ||
| 1111 | } | 1116 | } |
| 1112 | 1117 | ||
| 1113 | void | 1118 | void |
| 1114 | -QPDFWriter::Members::setEncryptionMinimumVersion() | 1119 | +impl::Writer::setEncryptionMinimumVersion() |
| 1115 | { | 1120 | { |
| 1116 | auto const R = encryption->getR(); | 1121 | auto const R = encryption->getR(); |
| 1117 | if (R >= 6) { | 1122 | if (R >= 6) { |
| @@ -1128,7 +1133,7 @@ QPDFWriter::Members::setEncryptionMinimumVersion() | @@ -1128,7 +1133,7 @@ QPDFWriter::Members::setEncryptionMinimumVersion() | ||
| 1128 | } | 1133 | } |
| 1129 | 1134 | ||
| 1130 | void | 1135 | void |
| 1131 | -QPDFWriter::Members::setDataKey(int objid) | 1136 | +impl::Writer::setDataKey(int objid) |
| 1132 | { | 1137 | { |
| 1133 | if (encryption) { | 1138 | if (encryption) { |
| 1134 | cur_data_key = QPDF::compute_data_key( | 1139 | cur_data_key = QPDF::compute_data_key( |
| @@ -1137,7 +1142,7 @@ QPDFWriter::Members::setDataKey(int objid) | @@ -1137,7 +1142,7 @@ QPDFWriter::Members::setDataKey(int objid) | ||
| 1137 | } | 1142 | } |
| 1138 | 1143 | ||
| 1139 | unsigned int | 1144 | unsigned int |
| 1140 | -QPDFWriter::Members::bytesNeeded(long long n) | 1145 | +impl::Writer::bytesNeeded(long long n) |
| 1141 | { | 1146 | { |
| 1142 | unsigned int bytes = 0; | 1147 | unsigned int bytes = 0; |
| 1143 | while (n) { | 1148 | while (n) { |
| @@ -1148,7 +1153,7 @@ QPDFWriter::Members::bytesNeeded(long long n) | @@ -1148,7 +1153,7 @@ QPDFWriter::Members::bytesNeeded(long long n) | ||
| 1148 | } | 1153 | } |
| 1149 | 1154 | ||
| 1150 | void | 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 | if (bytes > sizeof(unsigned long long)) { | 1158 | if (bytes > sizeof(unsigned long long)) { |
| 1154 | throw std::logic_error("QPDFWriter::writeBinary called with too many bytes"); | 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,44 +1166,44 @@ QPDFWriter::Members::writeBinary(unsigned long long val, unsigned int bytes) | ||
| 1161 | pipeline->write(data, bytes); | 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 | pipeline->write(str); | 1172 | pipeline->write(str); |
| 1168 | return *this; | 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 | pipeline->write(std::to_string(val)); | 1179 | pipeline->write(std::to_string(val)); |
| 1175 | return *this; | 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 | pipeline->write(count, c); | 1186 | pipeline->write(count, c); |
| 1182 | return *this; | 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 | pipeline->write(Name::normalize(str)); | 1193 | pipeline->write(Name::normalize(str)); |
| 1189 | return *this; | 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 | pipeline->write(QPDF_String(str).unparse(force_binary)); | 1200 | pipeline->write(QPDF_String(str).unparse(force_binary)); |
| 1196 | return *this; | 1201 | return *this; |
| 1197 | } | 1202 | } |
| 1198 | 1203 | ||
| 1199 | template <typename... Args> | 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 | if (cfg.qdf_mode_) { | 1208 | if (cfg.qdf_mode_) { |
| 1204 | pipeline->write(std::forward<Args>(args)...); | 1209 | pipeline->write(std::forward<Args>(args)...); |
| @@ -1207,8 +1212,8 @@ QPDFWriter::Members::write_qdf(Args&&... args) | @@ -1207,8 +1212,8 @@ QPDFWriter::Members::write_qdf(Args&&... args) | ||
| 1207 | } | 1212 | } |
| 1208 | 1213 | ||
| 1209 | template <typename... Args> | 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 | if (!cfg.qdf_mode_) { | 1218 | if (!cfg.qdf_mode_) { |
| 1214 | pipeline->write(std::forward<Args>(args)...); | 1219 | pipeline->write(std::forward<Args>(args)...); |
| @@ -1217,7 +1222,7 @@ QPDFWriter::Members::write_no_qdf(Args&&... args) | @@ -1217,7 +1222,7 @@ QPDFWriter::Members::write_no_qdf(Args&&... args) | ||
| 1217 | } | 1222 | } |
| 1218 | 1223 | ||
| 1219 | void | 1224 | void |
| 1220 | -QPDFWriter::Members::adjustAESStreamLength(size_t& length) | 1225 | +impl::Writer::adjustAESStreamLength(size_t& length) |
| 1221 | { | 1226 | { |
| 1222 | if (encryption && !cur_data_key.empty() && cfg.encrypt_use_aes_) { | 1227 | if (encryption && !cur_data_key.empty() && cfg.encrypt_use_aes_) { |
| 1223 | // Stream length will be padded with 1 to 16 bytes to end up as a multiple of 16. It will | 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,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 | if (!(encryption && !cur_data_key.empty())) { | 1237 | if (!(encryption && !cur_data_key.empty())) { |
| 1233 | write(str); | 1238 | write(str); |
| @@ -1241,7 +1246,7 @@ QPDFWriter::Members::write_encrypted(std::string_view str) | @@ -1241,7 +1246,7 @@ QPDFWriter::Members::write_encrypted(std::string_view str) | ||
| 1241 | } | 1246 | } |
| 1242 | 1247 | ||
| 1243 | void | 1248 | void |
| 1244 | -QPDFWriter::Members::computeDeterministicIDData() | 1249 | +impl::Writer::computeDeterministicIDData() |
| 1245 | { | 1250 | { |
| 1246 | if (!id2.empty()) { | 1251 | if (!id2.empty()) { |
| 1247 | // Can't happen in the code | 1252 | // Can't happen in the code |
| @@ -1253,7 +1258,7 @@ QPDFWriter::Members::computeDeterministicIDData() | @@ -1253,7 +1258,7 @@ QPDFWriter::Members::computeDeterministicIDData() | ||
| 1253 | } | 1258 | } |
| 1254 | 1259 | ||
| 1255 | int | 1260 | int |
| 1256 | -QPDFWriter::Members::openObject(int objid) | 1261 | +impl::Writer::openObject(int objid) |
| 1257 | { | 1262 | { |
| 1258 | if (objid == 0) { | 1263 | if (objid == 0) { |
| 1259 | objid = next_objid++; | 1264 | objid = next_objid++; |
| @@ -1264,7 +1269,7 @@ QPDFWriter::Members::openObject(int objid) | @@ -1264,7 +1269,7 @@ QPDFWriter::Members::openObject(int objid) | ||
| 1264 | } | 1269 | } |
| 1265 | 1270 | ||
| 1266 | void | 1271 | void |
| 1267 | -QPDFWriter::Members::closeObject(int objid) | 1272 | +impl::Writer::closeObject(int objid) |
| 1268 | { | 1273 | { |
| 1269 | // Write a newline before endobj as it makes the file easier to repair. | 1274 | // Write a newline before endobj as it makes the file easier to repair. |
| 1270 | write("\nendobj\n").write_qdf("\n"); | 1275 | write("\nendobj\n").write_qdf("\n"); |
| @@ -1273,7 +1278,7 @@ QPDFWriter::Members::closeObject(int objid) | @@ -1273,7 +1278,7 @@ QPDFWriter::Members::closeObject(int objid) | ||
| 1273 | } | 1278 | } |
| 1274 | 1279 | ||
| 1275 | void | 1280 | void |
| 1276 | -QPDFWriter::Members::assignCompressedObjectNumbers(QPDFObjGen og) | 1281 | +impl::Writer::assignCompressedObjectNumbers(QPDFObjGen og) |
| 1277 | { | 1282 | { |
| 1278 | int objid = og.getObj(); | 1283 | int objid = og.getObj(); |
| 1279 | if (og.getGen() != 0 || !object_stream_to_objects.contains(objid)) { | 1284 | if (og.getGen() != 0 || !object_stream_to_objects.contains(objid)) { |
| @@ -1288,7 +1293,7 @@ QPDFWriter::Members::assignCompressedObjectNumbers(QPDFObjGen og) | @@ -1288,7 +1293,7 @@ QPDFWriter::Members::assignCompressedObjectNumbers(QPDFObjGen og) | ||
| 1288 | } | 1293 | } |
| 1289 | 1294 | ||
| 1290 | void | 1295 | void |
| 1291 | -QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) | 1296 | +impl::Writer::enqueue(QPDFObjectHandle const& object) |
| 1292 | { | 1297 | { |
| 1293 | if (object.indirect()) { | 1298 | if (object.indirect()) { |
| 1294 | util::assertion( | 1299 | util::assertion( |
| @@ -1359,7 +1364,7 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) | @@ -1359,7 +1364,7 @@ QPDFWriter::Members::enqueue(QPDFObjectHandle const& object) | ||
| 1359 | } | 1364 | } |
| 1360 | 1365 | ||
| 1361 | void | 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 | if (!cfg.linearized_) { | 1369 | if (!cfg.linearized_) { |
| 1365 | enqueue(child); | 1370 | enqueue(child); |
| @@ -1372,7 +1377,7 @@ QPDFWriter::Members::unparseChild(QPDFObjectHandle const& child, size_t level, i | @@ -1372,7 +1377,7 @@ QPDFWriter::Members::unparseChild(QPDFObjectHandle const& child, size_t level, i | ||
| 1372 | } | 1377 | } |
| 1373 | 1378 | ||
| 1374 | void | 1379 | void |
| 1375 | -QPDFWriter::Members::writeTrailer( | 1380 | +impl::Writer::writeTrailer( |
| 1376 | trailer_e which, int size, bool xref_stream, qpdf_offset_t prev, int linearization_pass) | 1381 | trailer_e which, int size, bool xref_stream, qpdf_offset_t prev, int linearization_pass) |
| 1377 | { | 1382 | { |
| 1378 | auto trailer = trimmed_trailer(); | 1383 | auto trailer = trimmed_trailer(); |
| @@ -1439,7 +1444,7 @@ QPDFWriter::Members::writeTrailer( | @@ -1439,7 +1444,7 @@ QPDFWriter::Members::writeTrailer( | ||
| 1439 | } | 1444 | } |
| 1440 | 1445 | ||
| 1441 | bool | 1446 | bool |
| 1442 | -QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream) | 1447 | +impl::Writer::will_filter_stream(QPDFObjectHandle stream) |
| 1443 | { | 1448 | { |
| 1444 | std::string s; | 1449 | std::string s; |
| 1445 | [[maybe_unused]] auto [filter, ignore1, ignore2] = will_filter_stream(stream, &s); | 1450 | [[maybe_unused]] auto [filter, ignore1, ignore2] = will_filter_stream(stream, &s); |
| @@ -1447,7 +1452,7 @@ QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream) | @@ -1447,7 +1452,7 @@ QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream) | ||
| 1447 | } | 1452 | } |
| 1448 | 1453 | ||
| 1449 | std::tuple<const bool, const bool, const bool> | 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 | const bool is_root_metadata = stream.isRootMetadata(); | 1457 | const bool is_root_metadata = stream.isRootMetadata(); |
| 1453 | bool filter = false; | 1458 | bool filter = false; |
| @@ -1520,7 +1525,7 @@ QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream, std::string* st | @@ -1520,7 +1525,7 @@ QPDFWriter::Members::will_filter_stream(QPDFObjectHandle stream, std::string* st | ||
| 1520 | } | 1525 | } |
| 1521 | 1526 | ||
| 1522 | void | 1527 | void |
| 1523 | -QPDFWriter::Members::unparseObject( | 1528 | +impl::Writer::unparseObject( |
| 1524 | QPDFObjectHandle object, size_t level, int flags, size_t stream_length, bool compress) | 1529 | QPDFObjectHandle object, size_t level, int flags, size_t stream_length, bool compress) |
| 1525 | { | 1530 | { |
| 1526 | QPDFObjGen old_og = object.getObjGen(); | 1531 | QPDFObjGen old_og = object.getObjGen(); |
| @@ -1763,7 +1768,7 @@ QPDFWriter::Members::unparseObject( | @@ -1763,7 +1768,7 @@ QPDFWriter::Members::unparseObject( | ||
| 1763 | } | 1768 | } |
| 1764 | 1769 | ||
| 1765 | void | 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 | qpdf_assert_debug(first_obj > 0); | 1773 | qpdf_assert_debug(first_obj > 0); |
| 1769 | bool is_first = true; | 1774 | bool is_first = true; |
| @@ -1782,7 +1787,7 @@ QPDFWriter::Members::writeObjectStreamOffsets(std::vector<qpdf_offset_t>& offset | @@ -1782,7 +1787,7 @@ QPDFWriter::Members::writeObjectStreamOffsets(std::vector<qpdf_offset_t>& offset | ||
| 1782 | } | 1787 | } |
| 1783 | 1788 | ||
| 1784 | void | 1789 | void |
| 1785 | -QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | 1790 | +impl::Writer::writeObjectStream(QPDFObjectHandle object) |
| 1786 | { | 1791 | { |
| 1787 | // Note: object might be null if this is a place-holder for an object stream that we are | 1792 | // Note: object might be null if this is a place-holder for an object stream that we are |
| 1788 | // generating from scratch. | 1793 | // generating from scratch. |
| @@ -1899,7 +1904,7 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | @@ -1899,7 +1904,7 @@ QPDFWriter::Members::writeObjectStream(QPDFObjectHandle object) | ||
| 1899 | } | 1904 | } |
| 1900 | 1905 | ||
| 1901 | void | 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 | QPDFObjGen old_og = object.getObjGen(); | 1909 | QPDFObjGen old_og = object.getObjGen(); |
| 1905 | 1910 | ||
| @@ -1946,7 +1951,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde | @@ -1946,7 +1951,7 @@ QPDFWriter::Members::writeObject(QPDFObjectHandle object, int object_stream_inde | ||
| 1946 | } | 1951 | } |
| 1947 | 1952 | ||
| 1948 | std::string | 1953 | std::string |
| 1949 | -QPDFWriter::Members::getOriginalID1() | 1954 | +impl::Writer::getOriginalID1() |
| 1950 | { | 1955 | { |
| 1951 | QPDFObjectHandle trailer = qpdf.getTrailer(); | 1956 | QPDFObjectHandle trailer = qpdf.getTrailer(); |
| 1952 | if (trailer.hasKey("/ID")) { | 1957 | if (trailer.hasKey("/ID")) { |
| @@ -1957,7 +1962,7 @@ QPDFWriter::Members::getOriginalID1() | @@ -1957,7 +1962,7 @@ QPDFWriter::Members::getOriginalID1() | ||
| 1957 | } | 1962 | } |
| 1958 | 1963 | ||
| 1959 | void | 1964 | void |
| 1960 | -QPDFWriter::Members::generateID(bool encrypted) | 1965 | +impl::Writer::generateID(bool encrypted) |
| 1961 | { | 1966 | { |
| 1962 | // Generate the ID lazily so that we can handle the user's preference to use static or | 1967 | // Generate the ID lazily so that we can handle the user's preference to use static or |
| 1963 | // deterministic ID generation. | 1968 | // deterministic ID generation. |
| @@ -2047,7 +2052,7 @@ QPDFWriter::Members::generateID(bool encrypted) | @@ -2047,7 +2052,7 @@ QPDFWriter::Members::generateID(bool encrypted) | ||
| 2047 | } | 2052 | } |
| 2048 | 2053 | ||
| 2049 | void | 2054 | void |
| 2050 | -QPDFWriter::Members::initializeSpecialStreams() | 2055 | +impl::Writer::initializeSpecialStreams() |
| 2051 | { | 2056 | { |
| 2052 | // Mark all page content streams in case we are filtering or normalizing. | 2057 | // Mark all page content streams in case we are filtering or normalizing. |
| 2053 | int num = 0; | 2058 | int num = 0; |
| @@ -2072,7 +2077,7 @@ QPDFWriter::Members::initializeSpecialStreams() | @@ -2072,7 +2077,7 @@ QPDFWriter::Members::initializeSpecialStreams() | ||
| 2072 | } | 2077 | } |
| 2073 | 2078 | ||
| 2074 | void | 2079 | void |
| 2075 | -QPDFWriter::Members::preserveObjectStreams() | 2080 | +impl::Writer::preserveObjectStreams() |
| 2076 | { | 2081 | { |
| 2077 | auto const& xref = objects.xref_table(); | 2082 | auto const& xref = objects.xref_table(); |
| 2078 | // Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object | 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,7 +2125,7 @@ QPDFWriter::Members::preserveObjectStreams() | ||
| 2120 | } | 2125 | } |
| 2121 | 2126 | ||
| 2122 | void | 2127 | void |
| 2123 | -QPDFWriter::Members::generateObjectStreams() | 2128 | +impl::Writer::generateObjectStreams() |
| 2124 | { | 2129 | { |
| 2125 | // Basic strategy: make a list of objects that can go into an object stream. Then figure out | 2130 | // Basic strategy: make a list of objects that can go into an object stream. Then figure out |
| 2126 | // how many object streams are needed so that we can distribute objects approximately evenly | 2131 | // how many object streams are needed so that we can distribute objects approximately evenly |
| @@ -2159,7 +2164,7 @@ QPDFWriter::Members::generateObjectStreams() | @@ -2159,7 +2164,7 @@ QPDFWriter::Members::generateObjectStreams() | ||
| 2159 | } | 2164 | } |
| 2160 | 2165 | ||
| 2161 | Dictionary | 2166 | Dictionary |
| 2162 | -QPDFWriter::Members::trimmed_trailer() | 2167 | +impl::Writer::trimmed_trailer() |
| 2163 | { | 2168 | { |
| 2164 | // Remove keys from the trailer that necessarily have to be replaced when writing the file. | 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,7 +2191,7 @@ QPDFWriter::Members::trimmed_trailer() | ||
| 2186 | 2191 | ||
| 2187 | // Make document extension level information direct as required by the spec. | 2192 | // Make document extension level information direct as required by the spec. |
| 2188 | void | 2193 | void |
| 2189 | -QPDFWriter::Members::prepareFileForWrite() | 2194 | +impl::Writer::prepareFileForWrite() |
| 2190 | { | 2195 | { |
| 2191 | qpdf.fixDanglingReferences(); | 2196 | qpdf.fixDanglingReferences(); |
| 2192 | auto root = qpdf.getRoot(); | 2197 | auto root = qpdf.getRoot(); |
| @@ -2209,7 +2214,7 @@ QPDFWriter::Members::prepareFileForWrite() | @@ -2209,7 +2214,7 @@ QPDFWriter::Members::prepareFileForWrite() | ||
| 2209 | } | 2214 | } |
| 2210 | 2215 | ||
| 2211 | void | 2216 | void |
| 2212 | -QPDFWriter::Members::initializeTables(size_t extra) | 2217 | +impl::Writer::initializeTables(size_t extra) |
| 2213 | { | 2218 | { |
| 2214 | auto size = objects.table_size() + 100u + extra; | 2219 | auto size = objects.table_size() + 100u + extra; |
| 2215 | obj.resize(size); | 2220 | obj.resize(size); |
| @@ -2217,7 +2222,7 @@ QPDFWriter::Members::initializeTables(size_t extra) | @@ -2217,7 +2222,7 @@ QPDFWriter::Members::initializeTables(size_t extra) | ||
| 2217 | } | 2222 | } |
| 2218 | 2223 | ||
| 2219 | void | 2224 | void |
| 2220 | -QPDFWriter::Members::doWriteSetup() | 2225 | +impl::Writer::doWriteSetup() |
| 2221 | { | 2226 | { |
| 2222 | if (did_write_setup) { | 2227 | if (did_write_setup) { |
| 2223 | return; | 2228 | return; |
| @@ -2355,7 +2360,7 @@ QPDFWriter::write() | @@ -2355,7 +2360,7 @@ QPDFWriter::write() | ||
| 2355 | } | 2360 | } |
| 2356 | 2361 | ||
| 2357 | void | 2362 | void |
| 2358 | -QPDFWriter::Members::write() | 2363 | +impl::Writer::write() |
| 2359 | { | 2364 | { |
| 2360 | doWriteSetup(); | 2365 | doWriteSetup(); |
| 2361 | 2366 | ||
| @@ -2396,7 +2401,7 @@ QPDFWriter::getWrittenXRefTable() | @@ -2396,7 +2401,7 @@ QPDFWriter::getWrittenXRefTable() | ||
| 2396 | } | 2401 | } |
| 2397 | 2402 | ||
| 2398 | std::map<QPDFObjGen, QPDFXRefEntry> | 2403 | std::map<QPDFObjGen, QPDFXRefEntry> |
| 2399 | -QPDFWriter::Members::getWrittenXRefTable() | 2404 | +impl::Writer::getWrittenXRefTable() |
| 2400 | { | 2405 | { |
| 2401 | std::map<QPDFObjGen, QPDFXRefEntry> result; | 2406 | std::map<QPDFObjGen, QPDFXRefEntry> result; |
| 2402 | 2407 | ||
| @@ -2410,7 +2415,7 @@ QPDFWriter::Members::getWrittenXRefTable() | @@ -2410,7 +2415,7 @@ QPDFWriter::Members::getWrittenXRefTable() | ||
| 2410 | } | 2415 | } |
| 2411 | 2416 | ||
| 2412 | void | 2417 | void |
| 2413 | -QPDFWriter::Members::enqueuePart(std::vector<QPDFObjectHandle>& part) | 2418 | +impl::Writer::enqueuePart(std::vector<QPDFObjectHandle>& part) |
| 2414 | { | 2419 | { |
| 2415 | for (auto const& oh: part) { | 2420 | for (auto const& oh: part) { |
| 2416 | enqueue(oh); | 2421 | enqueue(oh); |
| @@ -2418,7 +2423,7 @@ QPDFWriter::Members::enqueuePart(std::vector<QPDFObjectHandle>& part) | @@ -2418,7 +2423,7 @@ QPDFWriter::Members::enqueuePart(std::vector<QPDFObjectHandle>& part) | ||
| 2418 | } | 2423 | } |
| 2419 | 2424 | ||
| 2420 | void | 2425 | void |
| 2421 | -QPDFWriter::Members::writeEncryptionDictionary() | 2426 | +impl::Writer::writeEncryptionDictionary() |
| 2422 | { | 2427 | { |
| 2423 | encryption_dict_objid = openObject(encryption_dict_objid); | 2428 | encryption_dict_objid = openObject(encryption_dict_objid); |
| 2424 | auto& enc = *encryption; | 2429 | auto& enc = *encryption; |
| @@ -2465,7 +2470,7 @@ QPDFWriter::getFinalVersion() | @@ -2465,7 +2470,7 @@ QPDFWriter::getFinalVersion() | ||
| 2465 | } | 2470 | } |
| 2466 | 2471 | ||
| 2467 | void | 2472 | void |
| 2468 | -QPDFWriter::Members::writeHeader() | 2473 | +impl::Writer::writeHeader() |
| 2469 | { | 2474 | { |
| 2470 | write("%PDF-").write(final_pdf_version); | 2475 | write("%PDF-").write(final_pdf_version); |
| 2471 | if (cfg.pclm_) { | 2476 | if (cfg.pclm_) { |
| @@ -2485,7 +2490,7 @@ QPDFWriter::Members::writeHeader() | @@ -2485,7 +2490,7 @@ QPDFWriter::Members::writeHeader() | ||
| 2485 | } | 2490 | } |
| 2486 | 2491 | ||
| 2487 | void | 2492 | void |
| 2488 | -QPDFWriter::Members::writeHintStream(int hint_id) | 2493 | +impl::Writer::writeHintStream(int hint_id) |
| 2489 | { | 2494 | { |
| 2490 | std::string hint_buffer; | 2495 | std::string hint_buffer; |
| 2491 | int S = 0; | 2496 | int S = 0; |
| @@ -2519,7 +2524,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) | @@ -2519,7 +2524,7 @@ QPDFWriter::Members::writeHintStream(int hint_id) | ||
| 2519 | } | 2524 | } |
| 2520 | 2525 | ||
| 2521 | qpdf_offset_t | 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 | // There are too many extra arguments to replace overloaded function with defaults in the header | 2529 | // There are too many extra arguments to replace overloaded function with defaults in the header |
| 2525 | // file...too much risk of leaving something off. | 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,7 +2532,7 @@ QPDFWriter::Members::writeXRefTable(trailer_e which, int first, int last, int si | ||
| 2527 | } | 2532 | } |
| 2528 | 2533 | ||
| 2529 | qpdf_offset_t | 2534 | qpdf_offset_t |
| 2530 | -QPDFWriter::Members::writeXRefTable( | 2535 | +impl::Writer::writeXRefTable( |
| 2531 | trailer_e which, | 2536 | trailer_e which, |
| 2532 | int first, | 2537 | int first, |
| 2533 | int last, | 2538 | int last, |
| @@ -2562,7 +2567,7 @@ QPDFWriter::Members::writeXRefTable( | @@ -2562,7 +2567,7 @@ QPDFWriter::Members::writeXRefTable( | ||
| 2562 | } | 2567 | } |
| 2563 | 2568 | ||
| 2564 | qpdf_offset_t | 2569 | qpdf_offset_t |
| 2565 | -QPDFWriter::Members::writeXRefStream( | 2570 | +impl::Writer::writeXRefStream( |
| 2566 | int objid, int max_id, qpdf_offset_t max_offset, trailer_e which, int first, int last, int size) | 2571 | int objid, int max_id, qpdf_offset_t max_offset, trailer_e which, int first, int last, int size) |
| 2567 | { | 2572 | { |
| 2568 | // There are too many extra arguments to replace overloaded function with defaults in the header | 2573 | // There are too many extra arguments to replace overloaded function with defaults in the header |
| @@ -2572,7 +2577,7 @@ QPDFWriter::Members::writeXRefStream( | @@ -2572,7 +2577,7 @@ QPDFWriter::Members::writeXRefStream( | ||
| 2572 | } | 2577 | } |
| 2573 | 2578 | ||
| 2574 | qpdf_offset_t | 2579 | qpdf_offset_t |
| 2575 | -QPDFWriter::Members::writeXRefStream( | 2580 | +impl::Writer::writeXRefStream( |
| 2576 | int xref_id, | 2581 | int xref_id, |
| 2577 | int max_id, | 2582 | int max_id, |
| 2578 | qpdf_offset_t max_offset, | 2583 | qpdf_offset_t max_offset, |
| @@ -2668,7 +2673,7 @@ QPDFWriter::Members::writeXRefStream( | @@ -2668,7 +2673,7 @@ QPDFWriter::Members::writeXRefStream( | ||
| 2668 | } | 2673 | } |
| 2669 | 2674 | ||
| 2670 | size_t | 2675 | size_t |
| 2671 | -QPDFWriter::Members::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) | 2676 | +impl::Writer::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) |
| 2672 | { | 2677 | { |
| 2673 | // This routine is called right after a linearization first pass xref stream has been written | 2678 | // This routine is called right after a linearization first pass xref stream has been written |
| 2674 | // without compression. Calculate the amount of padding that would be required in the worst | 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,7 +2685,7 @@ QPDFWriter::Members::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) | ||
| 2680 | } | 2685 | } |
| 2681 | 2686 | ||
| 2682 | void | 2687 | void |
| 2683 | -QPDFWriter::Members::writeLinearized() | 2688 | +impl::Writer::writeLinearized() |
| 2684 | { | 2689 | { |
| 2685 | // Optimize file and enqueue objects in order | 2690 | // Optimize file and enqueue objects in order |
| 2686 | 2691 | ||
| @@ -3027,7 +3032,7 @@ QPDFWriter::Members::writeLinearized() | @@ -3027,7 +3032,7 @@ QPDFWriter::Members::writeLinearized() | ||
| 3027 | } | 3032 | } |
| 3028 | 3033 | ||
| 3029 | void | 3034 | void |
| 3030 | -QPDFWriter::Members::enqueueObjectsStandard() | 3035 | +impl::Writer::enqueueObjectsStandard() |
| 3031 | { | 3036 | { |
| 3032 | if (cfg.preserve_unreferenced_objects_) { | 3037 | if (cfg.preserve_unreferenced_objects_) { |
| 3033 | for (auto const& oh: qpdf.getAllObjects()) { | 3038 | for (auto const& oh: qpdf.getAllObjects()) { |
| @@ -3049,7 +3054,7 @@ QPDFWriter::Members::enqueueObjectsStandard() | @@ -3049,7 +3054,7 @@ QPDFWriter::Members::enqueueObjectsStandard() | ||
| 3049 | } | 3054 | } |
| 3050 | 3055 | ||
| 3051 | void | 3056 | void |
| 3052 | -QPDFWriter::Members::enqueueObjectsPCLm() | 3057 | +impl::Writer::enqueueObjectsPCLm() |
| 3053 | { | 3058 | { |
| 3054 | // Image transform stream content for page strip images. Each of this new stream has to come | 3059 | // Image transform stream content for page strip images. Each of this new stream has to come |
| 3055 | // after every page image strip written in the pclm file. | 3060 | // after every page image strip written in the pclm file. |
| @@ -3073,7 +3078,7 @@ QPDFWriter::Members::enqueueObjectsPCLm() | @@ -3073,7 +3078,7 @@ QPDFWriter::Members::enqueueObjectsPCLm() | ||
| 3073 | } | 3078 | } |
| 3074 | 3079 | ||
| 3075 | void | 3080 | void |
| 3076 | -QPDFWriter::Members::indicateProgress(bool decrement, bool finished) | 3081 | +impl::Writer::indicateProgress(bool decrement, bool finished) |
| 3077 | { | 3082 | { |
| 3078 | if (decrement) { | 3083 | if (decrement) { |
| 3079 | --events_seen; | 3084 | --events_seen; |
| @@ -3107,7 +3112,7 @@ QPDFWriter::registerProgressReporter(std::shared_ptr<ProgressReporter> pr) | @@ -3107,7 +3112,7 @@ QPDFWriter::registerProgressReporter(std::shared_ptr<ProgressReporter> pr) | ||
| 3107 | } | 3112 | } |
| 3108 | 3113 | ||
| 3109 | void | 3114 | void |
| 3110 | -QPDFWriter::Members::writeStandard() | 3115 | +impl::Writer::writeStandard() |
| 3111 | { | 3116 | { |
| 3112 | auto pp_md5 = pipeline_stack.popper(); | 3117 | auto pp_md5 = pipeline_stack.popper(); |
| 3113 | if (cfg.deterministic_id_) { | 3118 | if (cfg.deterministic_id_) { |
libqpdf/qpdf/ObjTable.hh
| @@ -75,7 +75,6 @@ class ObjTable: public std::vector<T> | @@ -75,7 +75,6 @@ class ObjTable: public std::vector<T> | ||
| 75 | return contains(static_cast<size_t>(oh.getObjectID())); | 75 | return contains(static_cast<size_t>(oh.getObjectID())); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | - protected: | ||
| 79 | inline T& | 78 | inline T& |
| 80 | operator[](int id) | 79 | operator[](int id) |
| 81 | { | 80 | { |
libqpdf/qpdf/QPDFObject_private.hh
| @@ -30,6 +30,11 @@ namespace qpdf | @@ -30,6 +30,11 @@ namespace qpdf | ||
| 30 | class Integer; | 30 | class Integer; |
| 31 | class Name; | 31 | class Name; |
| 32 | class Stream; | 32 | class Stream; |
| 33 | + | ||
| 34 | + namespace impl | ||
| 35 | + { | ||
| 36 | + class Writer; | ||
| 37 | + } | ||
| 33 | } // namespace qpdf | 38 | } // namespace qpdf |
| 34 | 39 | ||
| 35 | class QPDF_Array final | 40 | class QPDF_Array final |
| @@ -256,7 +261,7 @@ class QPDF_String final | @@ -256,7 +261,7 @@ class QPDF_String final | ||
| 256 | { | 261 | { |
| 257 | friend class QPDFObject; | 262 | friend class QPDFObject; |
| 258 | friend class qpdf::BaseHandle; | 263 | friend class qpdf::BaseHandle; |
| 259 | - friend class QPDFWriter; | 264 | + friend class qpdf::impl::Writer; |
| 260 | 265 | ||
| 261 | public: | 266 | public: |
| 262 | static std::shared_ptr<QPDFObject> create_utf16(std::string const& utf8_val); | 267 | static std::shared_ptr<QPDFObject> create_utf16(std::string const& utf8_val); |
libqpdf/qpdf/QPDFWriter_private.hh
| @@ -10,40 +10,6 @@ | @@ -10,40 +10,6 @@ | ||
| 10 | // This file is intended for inclusion by QPDFWriter, QPDF, QPDF_optimization and QPDF_linearization | 10 | // This file is intended for inclusion by QPDFWriter, QPDF, QPDF_optimization and QPDF_linearization |
| 11 | // only. | 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 | namespace qpdf | 13 | namespace qpdf |
| 48 | { | 14 | { |
| 49 | namespace impl | 15 | namespace impl |
| @@ -90,4 +56,38 @@ namespace qpdf | @@ -90,4 +56,38 @@ namespace qpdf | ||
| 90 | }; // class Writer | 56 | }; // class Writer |
| 91 | } // namespace qpdf | 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 | #endif // QPDFWRITER_PRIVATE_HH | 93 | #endif // QPDFWRITER_PRIVATE_HH |