Commit 242ddf15949dc1b59cf3bba8d8edd50941894cc1

Authored by m-holger
1 parent decd3650

Refactor `reserveObjects`: move logic to `ObjCopier::reserve_objects`, simplify …

…object reservation, and streamline method usage.
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;