Commit 242ddf15949dc1b59cf3bba8d8edd50941894cc1
1 parent
decd3650
Refactor `reserveObjects`: move logic to `ObjCopier::reserve_objects`, simplify …
…object reservation, and streamline method usage.
Showing
3 changed files
with
22 additions
and
21 deletions
include/qpdf/QPDF.hh
| @@ -806,7 +806,6 @@ class QPDF | @@ -806,7 +806,6 @@ class QPDF | ||
| 806 | std::unique_ptr<Pipeline>& heap); | 806 | std::unique_ptr<Pipeline>& heap); |
| 807 | 807 | ||
| 808 | // Methods to support object copying | 808 | // Methods to support object copying |
| 809 | - void reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top); | ||
| 810 | void copyStreamData(QPDFObjectHandle dest_stream, QPDFObjectHandle src_stream); | 809 | void copyStreamData(QPDFObjectHandle dest_stream, QPDFObjectHandle src_stream); |
| 811 | 810 | ||
| 812 | struct HPageOffsetEntry; | 811 | struct HPageOffsetEntry; |
libqpdf/QPDF.cc
| @@ -527,7 +527,7 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign) | @@ -527,7 +527,7 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign) | ||
| 527 | // obj_copier.object_map maps foreign QPDFObjGen to local objects. For everything new that we | 527 | // obj_copier.object_map maps foreign QPDFObjGen to local objects. For everything new that we |
| 528 | // have to copy, the local object will be a reservation, unless it is a stream, in which case | 528 | // have to copy, the local object will be a reservation, unless it is a stream, in which case |
| 529 | // the local object will already be a stream. | 529 | // the local object will already be a stream. |
| 530 | - reserveObjects(foreign, obj_copier, true); | 530 | + obj_copier.reserve_objects(*this, foreign); |
| 531 | 531 | ||
| 532 | if (!obj_copier.visiting.empty()) { | 532 | if (!obj_copier.visiting.empty()) { |
| 533 | throw std::logic_error("obj_copier.visiting is not empty after reserving objects"); | 533 | throw std::logic_error("obj_copier.visiting is not empty after reserving objects"); |
| @@ -556,53 +556,52 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign) | @@ -556,53 +556,52 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign) | ||
| 556 | } | 556 | } |
| 557 | 557 | ||
| 558 | void | 558 | void |
| 559 | -QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) | 559 | +QPDF::ObjCopier::reserve_objects(QPDF& target, QPDFObjectHandle const& foreign, bool top) |
| 560 | { | 560 | { |
| 561 | - auto foreign_tc = foreign.getTypeCode(); | ||
| 562 | - if (foreign_tc == ::ot_reserved) { | ||
| 563 | - throw std::logic_error("QPDF: attempting to copy a foreign reserved object"); | ||
| 564 | - } | 561 | + auto foreign_tc = foreign.type_code(); |
| 562 | + util::assertion( | ||
| 563 | + foreign_tc != ::ot_reserved, "QPDF: attempting to copy a foreign reserved object"); | ||
| 565 | 564 | ||
| 566 | if (foreign.isPagesObject()) { | 565 | if (foreign.isPagesObject()) { |
| 567 | return; | 566 | return; |
| 568 | } | 567 | } |
| 569 | 568 | ||
| 570 | - if (foreign.isIndirect()) { | 569 | + if (foreign.indirect()) { |
| 571 | QPDFObjGen foreign_og(foreign.getObjGen()); | 570 | QPDFObjGen foreign_og(foreign.getObjGen()); |
| 572 | - if (!obj_copier.visiting.add(foreign_og)) { | 571 | + if (!visiting.add(foreign_og)) { |
| 573 | return; | 572 | return; |
| 574 | } | 573 | } |
| 575 | - if (obj_copier.object_map.contains(foreign_og)) { | ||
| 576 | - if (!(top && foreign.isPageObject() && obj_copier.object_map[foreign_og].null())) { | ||
| 577 | - obj_copier.visiting.erase(foreign); | 574 | + if (object_map.contains(foreign_og)) { |
| 575 | + if (!(top && foreign.isPageObject() && object_map[foreign_og].null())) { | ||
| 576 | + visiting.erase(foreign); | ||
| 578 | return; | 577 | return; |
| 579 | } | 578 | } |
| 580 | } else { | 579 | } else { |
| 581 | - obj_copier.object_map[foreign_og] = | ||
| 582 | - foreign.isStream() ? newStream() : newIndirectNull(); | 580 | + object_map[foreign_og] = |
| 581 | + foreign.isStream() ? target.newStream() : target.newIndirectNull(); | ||
| 583 | if (!top && foreign.isPageObject()) { | 582 | if (!top && foreign.isPageObject()) { |
| 584 | - obj_copier.visiting.erase(foreign_og); | 583 | + visiting.erase(foreign_og); |
| 585 | return; | 584 | return; |
| 586 | } | 585 | } |
| 587 | } | 586 | } |
| 588 | - obj_copier.to_copy.emplace_back(foreign); | 587 | + to_copy.emplace_back(foreign); |
| 589 | } | 588 | } |
| 590 | 589 | ||
| 591 | if (foreign_tc == ::ot_array) { | 590 | if (foreign_tc == ::ot_array) { |
| 592 | for (auto const& item: foreign.as_array()) { | 591 | for (auto const& item: foreign.as_array()) { |
| 593 | - reserveObjects(item, obj_copier, false); | 592 | + reserve_objects(target, item, false); |
| 594 | } | 593 | } |
| 595 | } else if (foreign_tc == ::ot_dictionary) { | 594 | } else if (foreign_tc == ::ot_dictionary) { |
| 596 | - for (auto const& item: foreign.as_dictionary()) { | 595 | + for (auto const& item: Dictionary(foreign)) { |
| 597 | if (!item.second.null()) { | 596 | if (!item.second.null()) { |
| 598 | - reserveObjects(item.second, obj_copier, false); | 597 | + reserve_objects(target, item.second, false); |
| 599 | } | 598 | } |
| 600 | } | 599 | } |
| 601 | } else if (foreign_tc == ::ot_stream) { | 600 | } else if (foreign_tc == ::ot_stream) { |
| 602 | - reserveObjects(foreign.getDict(), obj_copier, false); | 601 | + reserve_objects(target, foreign.getDict(), false); |
| 603 | } | 602 | } |
| 604 | 603 | ||
| 605 | - obj_copier.visiting.erase(foreign); | 604 | + visiting.erase(foreign); |
| 606 | } | 605 | } |
| 607 | 606 | ||
| 608 | QPDFObjectHandle | 607 | QPDFObjectHandle |
libqpdf/qpdf/QPDF_private.hh
| @@ -49,6 +49,9 @@ class QPDF::ObjCopier | @@ -49,6 +49,9 @@ class QPDF::ObjCopier | ||
| 49 | public: | 49 | public: |
| 50 | QPDFObjectHandle | 50 | QPDFObjectHandle |
| 51 | replace_indirect_object(QPDF& target, QPDFObjectHandle const& oh, bool top = true); | 51 | replace_indirect_object(QPDF& target, QPDFObjectHandle const& oh, bool top = true); |
| 52 | + | ||
| 53 | + void reserve_objects(QPDF& target, QPDFObjectHandle const& oh, bool top = true); | ||
| 54 | + | ||
| 52 | std::map<QPDFObjGen, QPDFObjectHandle> object_map; | 55 | std::map<QPDFObjGen, QPDFObjectHandle> object_map; |
| 53 | std::vector<QPDFObjectHandle> to_copy; | 56 | std::vector<QPDFObjectHandle> to_copy; |
| 54 | QPDFObjGen::set visiting; | 57 | QPDFObjGen::set visiting; |