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 742 static std::string const qpdf_version;
743 743  
744 744 class ObjCache;
745   - class ObjCopier;
746 745 class EncryptionParameters;
747 746 class ForeignStreamData;
748 747 class CopiedStreamDataProvider;
... ...
libqpdf/QPDF.cc
... ... @@ -167,8 +167,7 @@ QPDF::Members::Members(QPDF& qpdf) :
167 167 pages(doc.pages()),
168 168 log(QPDFLogger::defaultLogger()),
169 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 473 QPDFObjectHandle
475 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 482 if (!foreign.isIndirect()) {
484 483 throw std::logic_error("QPDF::copyForeign called with direct object handle");
... ... @@ -491,7 +490,7 @@ QPDF::ObjCopier::copier(QPDFObjectHandle const&amp; foreign)
491 490 }
492 491  
493 492 QPDFObjectHandle
494   -QPDF::ObjCopier::Copier::copied(QPDFObjectHandle const& foreign)
  493 +Objects::Foreign::Copier::copied(QPDFObjectHandle const& foreign)
495 494 {
496 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 500 // references to the corresponding object in the local file.
502 501 //
503 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 504 // mapping from the foreign ObjGen to the local QPDFObjectHandle.
506 505 //
507 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 560 }
562 561  
563 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 565 auto foreign_tc = foreign.type_code();
567 566 util::assertion(
... ... @@ -609,7 +608,7 @@ QPDF::ObjCopier::Copier::reserve_objects(QPDFObjectHandle const&amp; foreign, bool t
609 608 }
610 609  
611 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 613 auto foreign_tc = foreign.type_code();
615 614  
... ...
libqpdf/qpdf/QPDF_private.hh
... ... @@ -44,55 +44,6 @@ class QPDF::ObjCache
44 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 47 class QPDF::EncryptionParameters
97 48 {
98 49 friend class QPDF;
... ... @@ -619,6 +570,57 @@ class QPDF::Doc
619 570 class Objects
620 571 {
621 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 624 Objects() = delete;
623 625 Objects(Objects const&) = delete;
624 626 Objects(Objects&&) = delete;
... ... @@ -628,8 +630,15 @@ class QPDF::Doc
628 630  
629 631 Objects(QPDF& qpdf, QPDF::Members* m) :
630 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 644 void parse(char const* password);
... ... @@ -704,9 +713,10 @@ class QPDF::Doc
704 713 bool isUnresolved(QPDFObjGen og);
705 714 void setLastObjectDescription(std::string const& description, QPDFObjGen og);
706 715  
707   - private:
708 716 QPDF& qpdf;
709 717 QPDF::Members* m;
  718 +
  719 + Foreign foreign_;
710 720 }; // class QPDF::Doc::Objects
711 721  
712 722 // This class is used to represent a PDF Pages tree.
... ... @@ -888,7 +898,6 @@ class QPDF::Members
888 898 bool ever_pushed_inherited_attributes_to_pages{false};
889 899 bool ever_called_get_all_pages{false};
890 900 std::vector<QPDFExc> warnings;
891   - QPDF::ObjCopier obj_copier;
892 901 std::shared_ptr<CopiedStreamDataProvider> copied_stream_data_provider;
893 902 bool reconstructed_xref{false};
894 903 bool in_read_xref_stream{false};
... ...