Commit c59c6a7d001a678abd77c3bb2291dfbbcb3a75d2

Authored by m-holger
1 parent 19073b46

Refactor `Streams::Copier`: move implementation to `QPDF_Stream.cc` and improve encapsulation.

libqpdf/QPDF.cc
@@ -112,57 +112,6 @@ namespace @@ -112,57 +112,6 @@ namespace
112 }; 112 };
113 } // namespace 113 } // namespace
114 114
115 -Streams::Copier::Data::Data(Stream& source, QPDFObjectHandle const& dest_dict) :  
116 - encp(source.qpdf()->m->encp),  
117 - file(source.qpdf()->m->file),  
118 - source_og(source.id_gen()),  
119 - offset(source.offset()),  
120 - length(source.getLength()),  
121 - dest_dict(dest_dict),  
122 - is_root_metadata(source.isRootMetadata())  
123 -{  
124 -}  
125 -  
126 -Streams::Copier::Copier(Streams& streams) :  
127 - QPDFObjectHandle::StreamDataProvider(true),  
128 - streams(streams)  
129 -{  
130 -}  
131 -  
132 -bool  
133 -Streams::Copier::provideStreamData(  
134 - QPDFObjGen const& og, Pipeline* pipeline, bool suppress_warnings, bool will_retry)  
135 -{  
136 - auto data = copied_data.find(og);  
137 - if (data != copied_data.end()) {  
138 - auto& fd = data->second;  
139 - QTC::TC("qpdf", "QPDF pipe foreign encrypted stream", fd.encp->encrypted ? 0 : 1);  
140 - if (streams.qpdf().pipeStreamData(  
141 - fd.encp,  
142 - fd.file,  
143 - streams.qpdf(),  
144 - fd.source_og,  
145 - fd.offset,  
146 - fd.length,  
147 - fd.dest_dict,  
148 - fd.is_root_metadata,  
149 - pipeline,  
150 - suppress_warnings,  
151 - will_retry)) {  
152 - return true; // for CI coverage  
153 - } else {  
154 - return false;  
155 - }  
156 - }  
157 - auto stream = copied_streams.find(og);  
158 - if (stream != copied_streams.end() &&  
159 - stream->second.pipeStreamData(  
160 - pipeline, nullptr, 0, qpdf_dl_none, suppress_warnings, will_retry)) {  
161 - return true; // for CI coverage  
162 - }  
163 - return false;  
164 -}  
165 -  
166 QPDF::StringDecrypter::StringDecrypter(QPDF* qpdf, QPDFObjGen og) : 115 QPDF::StringDecrypter::StringDecrypter(QPDF* qpdf, QPDFObjGen og) :
167 qpdf(qpdf), 116 qpdf(qpdf),
168 og(og) 117 og(og)
libqpdf/QPDF_Stream.cc
@@ -33,6 +33,110 @@ Streams::immediate_copy_from() const @@ -33,6 +33,110 @@ Streams::immediate_copy_from() const
33 return qpdf_.m->immediate_copy_from; 33 return qpdf_.m->immediate_copy_from;
34 } 34 }
35 35
  36 +class Streams::Copier final: public QPDFObjectHandle::StreamDataProvider
  37 +{
  38 + class Data
  39 + {
  40 + friend class Streams;
  41 +
  42 + public:
  43 + Data(Stream& source, QPDFObjectHandle const& dest_dict) :
  44 + encp(source.qpdf()->m->encp),
  45 + file(source.qpdf()->m->file),
  46 + source_og(source.id_gen()),
  47 + offset(source.offset()),
  48 + length(source.getLength()),
  49 + dest_dict(dest_dict),
  50 + is_root_metadata(source.isRootMetadata())
  51 + {
  52 + }
  53 +
  54 + private:
  55 + std::shared_ptr<EncryptionParameters> encp;
  56 + std::shared_ptr<InputSource> file;
  57 + QPDFObjGen source_og;
  58 + qpdf_offset_t offset;
  59 + size_t length;
  60 + QPDFObjectHandle dest_dict;
  61 + bool is_root_metadata{false};
  62 + };
  63 +
  64 + public:
  65 + Copier() = delete;
  66 + Copier(StreamDataProvider const&) = delete;
  67 + Copier(StreamDataProvider&&) = delete;
  68 + Copier& operator=(StreamDataProvider const&) = delete;
  69 + Copier& operator=(StreamDataProvider&&) = delete;
  70 + ~Copier() final = default;
  71 +
  72 + Copier(Streams& streams) :
  73 + QPDFObjectHandle::StreamDataProvider(true),
  74 + streams(streams)
  75 + {
  76 + }
  77 +
  78 + bool
  79 + provideStreamData(
  80 + QPDFObjGen const& og, Pipeline* pipeline, bool suppress_warnings, bool will_retry) final
  81 + {
  82 + auto data = copied_data.find(og);
  83 + if (data != copied_data.end()) {
  84 + auto& fd = data->second;
  85 + QTC::TC("qpdf", "QPDF pipe foreign encrypted stream", fd.encp->encrypted ? 0 : 1);
  86 + if (streams.qpdf().pipeStreamData(
  87 + fd.encp,
  88 + fd.file,
  89 + streams.qpdf(),
  90 + fd.source_og,
  91 + fd.offset,
  92 + fd.length,
  93 + fd.dest_dict,
  94 + fd.is_root_metadata,
  95 + pipeline,
  96 + suppress_warnings,
  97 + will_retry)) {
  98 + return true; // for CI coverage
  99 + } else {
  100 + return false;
  101 + }
  102 + }
  103 + auto stream = copied_streams.find(og);
  104 + if (stream != copied_streams.end() &&
  105 + stream->second.pipeStreamData(
  106 + pipeline, nullptr, 0, qpdf_dl_none, suppress_warnings, will_retry)) {
  107 + return true; // for CI coverage
  108 + }
  109 + return false;
  110 + }
  111 +
  112 + void
  113 + register_copy(QPDFObjGen local_og, QPDFObjectHandle const& foreign_stream)
  114 + {
  115 + copied_streams.insert_or_assign(local_og, foreign_stream);
  116 + }
  117 +
  118 + void
  119 + register_copy(
  120 + QPDFObjGen local_og,
  121 + Stream& foreign,
  122 + qpdf_offset_t offset,
  123 + QPDFObjectHandle const& local_dict)
  124 + {
  125 + copied_data.insert_or_assign(local_og, Data(foreign, local_dict));
  126 + }
  127 +
  128 + private:
  129 + Streams& streams;
  130 + std::map<QPDFObjGen, QPDFObjectHandle> copied_streams;
  131 + std::map<QPDFObjGen, Data> copied_data;
  132 +};
  133 +
  134 +Streams::Streams(QPDF& qpdf) :
  135 + qpdf_(qpdf),
  136 + copier_(std::make_shared<Copier>(*this))
  137 +{
  138 +}
  139 +
36 namespace 140 namespace
37 { 141 {
38 class SF_Crypt final: public QPDFStreamFilter 142 class SF_Crypt final: public QPDFStreamFilter
libqpdf/qpdf/QPDF_private.hh
@@ -580,69 +580,10 @@ class QPDF::Doc @@ -580,69 +580,10 @@ class QPDF::Doc
580 { 580 {
581 // Copier manages the copying of streams into this PDF. It is used both for copying 581 // Copier manages the copying of streams into this PDF. It is used both for copying
582 // local and foreign streams. 582 // local and foreign streams.
583 - class Copier final: public QPDFObjectHandle::StreamDataProvider  
584 - {  
585 - class Data  
586 - {  
587 - friend class Streams;  
588 -  
589 - public:  
590 - Data(Stream& source, QPDFObjectHandle const& dest_dict);  
591 -  
592 - private:  
593 - std::shared_ptr<EncryptionParameters> encp;  
594 - std::shared_ptr<InputSource> file;  
595 - QPDFObjGen source_og;  
596 - qpdf_offset_t offset;  
597 - size_t length;  
598 - QPDFObjectHandle dest_dict;  
599 - bool is_root_metadata{false};  
600 - };  
601 -  
602 - public:  
603 - Copier() = delete;  
604 - Copier(StreamDataProvider const&) = delete;  
605 - Copier(StreamDataProvider&&) = delete;  
606 - Copier& operator=(StreamDataProvider const&) = delete;  
607 - Copier& operator=(StreamDataProvider&&) = delete;  
608 -  
609 - Copier(Streams& streams);  
610 - ~Copier() final = default;  
611 -  
612 - bool provideStreamData(  
613 - QPDFObjGen const& og,  
614 - Pipeline* pipeline,  
615 - bool suppress_warnings,  
616 - bool will_retry) final;  
617 -  
618 - void  
619 - register_copy(QPDFObjGen local_og, QPDFObjectHandle const& foreign_stream)  
620 - {  
621 - copied_streams.insert_or_assign(local_og, foreign_stream);  
622 - }  
623 -  
624 - void  
625 - register_copy(  
626 - QPDFObjGen local_og,  
627 - Stream& foreign,  
628 - qpdf_offset_t offset,  
629 - QPDFObjectHandle const& local_dict)  
630 - {  
631 - copied_data.insert_or_assign(local_og, Data(foreign, local_dict));  
632 - }  
633 -  
634 - private:  
635 - Streams& streams;  
636 - std::map<QPDFObjGen, QPDFObjectHandle> copied_streams;  
637 - std::map<QPDFObjGen, Data> copied_data;  
638 - }; 583 + class Copier;
639 584
640 public: 585 public:
641 - Streams(QPDF& qpdf) :  
642 - qpdf_(qpdf),  
643 - copier_(std::make_shared<Copier>(*this))  
644 - {  
645 - } 586 + Streams(QPDF& qpdf);
646 587
647 Streams() = delete; 588 Streams() = delete;
648 Streams(Streams const&) = delete; 589 Streams(Streams const&) = delete;