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 112 };
113 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 115 QPDF::StringDecrypter::StringDecrypter(QPDF* qpdf, QPDFObjGen og) :
167 116 qpdf(qpdf),
168 117 og(og)
... ...
libqpdf/QPDF_Stream.cc
... ... @@ -33,6 +33,110 @@ Streams::immediate_copy_from() const
33 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 140 namespace
37 141 {
38 142 class SF_Crypt final: public QPDFStreamFilter
... ...
libqpdf/qpdf/QPDF_private.hh
... ... @@ -580,69 +580,10 @@ class QPDF::Doc
580 580 {
581 581 // Copier manages the copying of streams into this PDF. It is used both for copying
582 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 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 588 Streams() = delete;
648 589 Streams(Streams const&) = delete;
... ...