Commit c5bf0fdf2be1d2d02a8a1b8b1825e6c753478500

Authored by m-holger
1 parent b20ff968

Refactor `ObjCopier` into `Objects::Foreign::Copier`: improve encapsulation, str…

…eamline foreign object handling, and simplify method structure.
include/qpdf/QPDF.hh
@@ -742,7 +742,6 @@ class QPDF @@ -742,7 +742,6 @@ class QPDF
742 static std::string const qpdf_version; 742 static std::string const qpdf_version;
743 743
744 class ObjCache; 744 class ObjCache;
745 - class ObjCopier;  
746 class EncryptionParameters; 745 class EncryptionParameters;
747 class ForeignStreamData; 746 class ForeignStreamData;
748 class CopiedStreamDataProvider; 747 class CopiedStreamDataProvider;
libqpdf/QPDF.cc
@@ -167,8 +167,7 @@ QPDF::Members::Members(QPDF& qpdf) : @@ -167,8 +167,7 @@ QPDF::Members::Members(QPDF& qpdf) :
167 pages(doc.pages()), 167 pages(doc.pages()),
168 log(QPDFLogger::defaultLogger()), 168 log(QPDFLogger::defaultLogger()),
169 file(std::make_shared<InvalidInputSource>()), 169 file(std::make_shared<InvalidInputSource>()),
170 - encp(std::make_shared<EncryptionParameters>()),  
171 - obj_copier(qpdf) 170 + encp(std::make_shared<EncryptionParameters>())
172 { 171 {
173 } 172 }
174 173
@@ -474,11 +473,11 @@ QPDF::getObjectByID(int objid, int generation) @@ -474,11 +473,11 @@ QPDF::getObjectByID(int objid, int generation)
474 QPDFObjectHandle 473 QPDFObjectHandle
475 QPDF::copyForeignObject(QPDFObjectHandle foreign) 474 QPDF::copyForeignObject(QPDFObjectHandle foreign)
476 { 475 {
477 - return m->obj_copier.copied(foreign); 476 + return m->objects.foreign().copied(foreign);
478 } 477 }
479 478
480 -QPDF::ObjCopier::Copier&  
481 -QPDF::ObjCopier::copier(QPDFObjectHandle const& foreign) 479 +Objects ::Foreign::Copier&
  480 +Objects::Foreign::copier(QPDFObjectHandle const& foreign)
482 { 481 {
483 if (!foreign.isIndirect()) { 482 if (!foreign.isIndirect()) {
484 throw std::logic_error("QPDF::copyForeign called with direct object handle"); 483 throw std::logic_error("QPDF::copyForeign called with direct object handle");
@@ -491,7 +490,7 @@ QPDF::ObjCopier::copier(QPDFObjectHandle const&amp; foreign) @@ -491,7 +490,7 @@ QPDF::ObjCopier::copier(QPDFObjectHandle const&amp; foreign)
491 } 490 }
492 491
493 QPDFObjectHandle 492 QPDFObjectHandle
494 -QPDF::ObjCopier::Copier::copied(QPDFObjectHandle const& foreign) 493 +Objects::Foreign::Copier::copied(QPDFObjectHandle const& foreign)
495 { 494 {
496 // Here's an explanation of what's going on here. 495 // Here's an explanation of what's going on here.
497 // 496 //
@@ -501,7 +500,7 @@ QPDF::ObjCopier::Copier::copied(QPDFObjectHandle const&amp; foreign) @@ -501,7 +500,7 @@ QPDF::ObjCopier::Copier::copied(QPDFObjectHandle const&amp; foreign)
501 // references to the corresponding object in the local file. 500 // references to the corresponding object in the local file.
502 // 501 //
503 // To do this, we maintain mappings from foreign object IDs to local object IDs for each foreign 502 // To do this, we maintain mappings from foreign object IDs to local object IDs for each foreign
504 - // QPDF that we are copying from. The mapping is stored in an ObjCopier, which contains a 503 + // QPDF that we are copying from. The mapping is stored in an Foreign::Copier, which contains a
505 // mapping from the foreign ObjGen to the local QPDFObjectHandle. 504 // mapping from the foreign ObjGen to the local QPDFObjectHandle.
506 // 505 //
507 // To copy, we do a deep traversal of the foreign object with loop detection to discover all 506 // To copy, we do a deep traversal of the foreign object with loop detection to discover all
@@ -561,7 +560,7 @@ QPDF::ObjCopier::Copier::copied(QPDFObjectHandle const&amp; foreign) @@ -561,7 +560,7 @@ QPDF::ObjCopier::Copier::copied(QPDFObjectHandle const&amp; foreign)
561 } 560 }
562 561
563 void 562 void
564 -QPDF::ObjCopier::Copier::reserve_objects(QPDFObjectHandle const& foreign, bool top) 563 +Objects::Foreign::Copier::reserve_objects(QPDFObjectHandle const& foreign, bool top)
565 { 564 {
566 auto foreign_tc = foreign.type_code(); 565 auto foreign_tc = foreign.type_code();
567 util::assertion( 566 util::assertion(
@@ -609,7 +608,7 @@ QPDF::ObjCopier::Copier::reserve_objects(QPDFObjectHandle const&amp; foreign, bool t @@ -609,7 +608,7 @@ QPDF::ObjCopier::Copier::reserve_objects(QPDFObjectHandle const&amp; foreign, bool t
609 } 608 }
610 609
611 QPDFObjectHandle 610 QPDFObjectHandle
612 -QPDF::ObjCopier::Copier::replace_indirect_object(QPDFObjectHandle const& foreign, bool top) 611 +Objects::Foreign::Copier::replace_indirect_object(QPDFObjectHandle const& foreign, bool top)
613 { 612 {
614 auto foreign_tc = foreign.type_code(); 613 auto foreign_tc = foreign.type_code();
615 614
libqpdf/qpdf/QPDF_private.hh
@@ -44,55 +44,6 @@ class QPDF::ObjCache @@ -44,55 +44,6 @@ class QPDF::ObjCache
44 qpdf_offset_t end_after_space{0}; 44 qpdf_offset_t end_after_space{0};
45 }; 45 };
46 46
47 -class QPDF::ObjCopier  
48 -{  
49 - class Copier  
50 - {  
51 - public:  
52 - Copier(QPDF& qpdf) :  
53 - qpdf(qpdf)  
54 - {  
55 - }  
56 -  
57 - QPDFObjectHandle copied(QPDFObjectHandle const& foreign);  
58 -  
59 - private:  
60 - QPDFObjectHandle replace_indirect_object(QPDFObjectHandle const& foreign, bool top = false);  
61 - void reserve_objects(QPDFObjectHandle const& foreign, bool top = false);  
62 -  
63 - QPDF& qpdf;  
64 - std::map<QPDFObjGen, QPDFObjectHandle> object_map;  
65 - std::vector<QPDFObjectHandle> to_copy;  
66 - QPDFObjGen::set visiting;  
67 - };  
68 -  
69 - public:  
70 - ObjCopier(QPDF& qpdf) :  
71 - qpdf(qpdf)  
72 - {  
73 - }  
74 -  
75 - ObjCopier() = delete;  
76 - ObjCopier(ObjCopier const&) = delete;  
77 - ObjCopier(ObjCopier&&) = delete;  
78 - ObjCopier& operator=(ObjCopier const&) = delete;  
79 - ObjCopier& operator=(ObjCopier&&) = delete;  
80 - ~ObjCopier() = default;  
81 -  
82 - // Return a local handle to the foreign object. Copy the foreign object if necessary.  
83 - QPDFObjectHandle  
84 - copied(QPDFObjectHandle const& foreign)  
85 - {  
86 - return copier(foreign).copied(foreign);  
87 - }  
88 -  
89 - private:  
90 - Copier& copier(QPDFObjectHandle const& foreign);  
91 -  
92 - QPDF& qpdf;  
93 - std::map<unsigned long long, Copier> copiers;  
94 -};  
95 -  
96 class QPDF::EncryptionParameters 47 class QPDF::EncryptionParameters
97 { 48 {
98 friend class QPDF; 49 friend class QPDF;
@@ -619,6 +570,57 @@ class QPDF::Doc @@ -619,6 +570,57 @@ class QPDF::Doc
619 class Objects 570 class Objects
620 { 571 {
621 public: 572 public:
  573 + class Foreign
  574 + {
  575 + class Copier
  576 + {
  577 + public:
  578 + Copier(QPDF& qpdf) :
  579 + qpdf(qpdf)
  580 + {
  581 + }
  582 +
  583 + QPDFObjectHandle copied(QPDFObjectHandle const& foreign);
  584 +
  585 + private:
  586 + QPDFObjectHandle
  587 + replace_indirect_object(QPDFObjectHandle const& foreign, bool top = false);
  588 + void reserve_objects(QPDFObjectHandle const& foreign, bool top = false);
  589 +
  590 + QPDF& qpdf;
  591 + std::map<QPDFObjGen, QPDFObjectHandle> object_map;
  592 + std::vector<QPDFObjectHandle> to_copy;
  593 + QPDFObjGen::set visiting;
  594 + };
  595 +
  596 + public:
  597 + Foreign(QPDF& qpdf) :
  598 + qpdf(qpdf)
  599 + {
  600 + }
  601 +
  602 + Foreign() = delete;
  603 + Foreign(Foreign const&) = delete;
  604 + Foreign(Foreign&&) = delete;
  605 + Foreign& operator=(Foreign const&) = delete;
  606 + Foreign& operator=(Foreign&&) = delete;
  607 + ~Foreign() = default;
  608 +
  609 + // Return a local handle to the foreign object. Copy the foreign object if necessary.
  610 + QPDFObjectHandle
  611 + copied(QPDFObjectHandle const& foreign)
  612 + {
  613 + return copier(foreign).copied(foreign);
  614 + }
  615 +
  616 + private:
  617 + Copier& copier(QPDFObjectHandle const& foreign);
  618 +
  619 + QPDF& qpdf;
  620 + std::map<unsigned long long, Copier> copiers;
  621 + }; // class QPDF::Doc::Objects::Foreign
  622 +
  623 + public:
622 Objects() = delete; 624 Objects() = delete;
623 Objects(Objects const&) = delete; 625 Objects(Objects const&) = delete;
624 Objects(Objects&&) = delete; 626 Objects(Objects&&) = delete;
@@ -628,8 +630,15 @@ class QPDF::Doc @@ -628,8 +630,15 @@ class QPDF::Doc
628 630
629 Objects(QPDF& qpdf, QPDF::Members* m) : 631 Objects(QPDF& qpdf, QPDF::Members* m) :
630 qpdf(qpdf), 632 qpdf(qpdf),
631 - m(m) 633 + m(m),
  634 + foreign_(qpdf)
  635 + {
  636 + }
  637 +
  638 + Foreign&
  639 + foreign()
632 { 640 {
  641 + return foreign_;
633 } 642 }
634 643
635 void parse(char const* password); 644 void parse(char const* password);
@@ -704,9 +713,10 @@ class QPDF::Doc @@ -704,9 +713,10 @@ class QPDF::Doc
704 bool isUnresolved(QPDFObjGen og); 713 bool isUnresolved(QPDFObjGen og);
705 void setLastObjectDescription(std::string const& description, QPDFObjGen og); 714 void setLastObjectDescription(std::string const& description, QPDFObjGen og);
706 715
707 - private:  
708 QPDF& qpdf; 716 QPDF& qpdf;
709 QPDF::Members* m; 717 QPDF::Members* m;
  718 +
  719 + Foreign foreign_;
710 }; // class QPDF::Doc::Objects 720 }; // class QPDF::Doc::Objects
711 721
712 // This class is used to represent a PDF Pages tree. 722 // This class is used to represent a PDF Pages tree.
@@ -888,7 +898,6 @@ class QPDF::Members @@ -888,7 +898,6 @@ class QPDF::Members
888 bool ever_pushed_inherited_attributes_to_pages{false}; 898 bool ever_pushed_inherited_attributes_to_pages{false};
889 bool ever_called_get_all_pages{false}; 899 bool ever_called_get_all_pages{false};
890 std::vector<QPDFExc> warnings; 900 std::vector<QPDFExc> warnings;
891 - QPDF::ObjCopier obj_copier;  
892 std::shared_ptr<CopiedStreamDataProvider> copied_stream_data_provider; 901 std::shared_ptr<CopiedStreamDataProvider> copied_stream_data_provider;
893 bool reconstructed_xref{false}; 902 bool reconstructed_xref{false};
894 bool in_read_xref_stream{false}; 903 bool in_read_xref_stream{false};