From c59c6a7d001a678abd77c3bb2291dfbbcb3a75d2 Mon Sep 17 00:00:00 2001 From: m-holger Date: Thu, 9 Oct 2025 12:48:36 +0100 Subject: [PATCH] Refactor `Streams::Copier`: move implementation to `QPDF_Stream.cc` and improve encapsulation. --- libqpdf/QPDF.cc | 51 --------------------------------------------------- libqpdf/QPDF_Stream.cc | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ libqpdf/qpdf/QPDF_private.hh | 63 ++------------------------------------------------------------- 3 files changed, 106 insertions(+), 112 deletions(-) diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index e6eb71d..010e101 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -112,57 +112,6 @@ namespace }; } // namespace -Streams::Copier::Data::Data(Stream& source, QPDFObjectHandle const& dest_dict) : - encp(source.qpdf()->m->encp), - file(source.qpdf()->m->file), - source_og(source.id_gen()), - offset(source.offset()), - length(source.getLength()), - dest_dict(dest_dict), - is_root_metadata(source.isRootMetadata()) -{ -} - -Streams::Copier::Copier(Streams& streams) : - QPDFObjectHandle::StreamDataProvider(true), - streams(streams) -{ -} - -bool -Streams::Copier::provideStreamData( - QPDFObjGen const& og, Pipeline* pipeline, bool suppress_warnings, bool will_retry) -{ - auto data = copied_data.find(og); - if (data != copied_data.end()) { - auto& fd = data->second; - QTC::TC("qpdf", "QPDF pipe foreign encrypted stream", fd.encp->encrypted ? 0 : 1); - if (streams.qpdf().pipeStreamData( - fd.encp, - fd.file, - streams.qpdf(), - fd.source_og, - fd.offset, - fd.length, - fd.dest_dict, - fd.is_root_metadata, - pipeline, - suppress_warnings, - will_retry)) { - return true; // for CI coverage - } else { - return false; - } - } - auto stream = copied_streams.find(og); - if (stream != copied_streams.end() && - stream->second.pipeStreamData( - pipeline, nullptr, 0, qpdf_dl_none, suppress_warnings, will_retry)) { - return true; // for CI coverage - } - return false; -} - QPDF::StringDecrypter::StringDecrypter(QPDF* qpdf, QPDFObjGen og) : qpdf(qpdf), og(og) diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc index 20f7d8a..6412e72 100644 --- a/libqpdf/QPDF_Stream.cc +++ b/libqpdf/QPDF_Stream.cc @@ -33,6 +33,110 @@ Streams::immediate_copy_from() const return qpdf_.m->immediate_copy_from; } +class Streams::Copier final: public QPDFObjectHandle::StreamDataProvider +{ + class Data + { + friend class Streams; + + public: + Data(Stream& source, QPDFObjectHandle const& dest_dict) : + encp(source.qpdf()->m->encp), + file(source.qpdf()->m->file), + source_og(source.id_gen()), + offset(source.offset()), + length(source.getLength()), + dest_dict(dest_dict), + is_root_metadata(source.isRootMetadata()) + { + } + + private: + std::shared_ptr encp; + std::shared_ptr file; + QPDFObjGen source_og; + qpdf_offset_t offset; + size_t length; + QPDFObjectHandle dest_dict; + bool is_root_metadata{false}; + }; + + public: + Copier() = delete; + Copier(StreamDataProvider const&) = delete; + Copier(StreamDataProvider&&) = delete; + Copier& operator=(StreamDataProvider const&) = delete; + Copier& operator=(StreamDataProvider&&) = delete; + ~Copier() final = default; + + Copier(Streams& streams) : + QPDFObjectHandle::StreamDataProvider(true), + streams(streams) + { + } + + bool + provideStreamData( + QPDFObjGen const& og, Pipeline* pipeline, bool suppress_warnings, bool will_retry) final + { + auto data = copied_data.find(og); + if (data != copied_data.end()) { + auto& fd = data->second; + QTC::TC("qpdf", "QPDF pipe foreign encrypted stream", fd.encp->encrypted ? 0 : 1); + if (streams.qpdf().pipeStreamData( + fd.encp, + fd.file, + streams.qpdf(), + fd.source_og, + fd.offset, + fd.length, + fd.dest_dict, + fd.is_root_metadata, + pipeline, + suppress_warnings, + will_retry)) { + return true; // for CI coverage + } else { + return false; + } + } + auto stream = copied_streams.find(og); + if (stream != copied_streams.end() && + stream->second.pipeStreamData( + pipeline, nullptr, 0, qpdf_dl_none, suppress_warnings, will_retry)) { + return true; // for CI coverage + } + return false; + } + + void + register_copy(QPDFObjGen local_og, QPDFObjectHandle const& foreign_stream) + { + copied_streams.insert_or_assign(local_og, foreign_stream); + } + + void + register_copy( + QPDFObjGen local_og, + Stream& foreign, + qpdf_offset_t offset, + QPDFObjectHandle const& local_dict) + { + copied_data.insert_or_assign(local_og, Data(foreign, local_dict)); + } + + private: + Streams& streams; + std::map copied_streams; + std::map copied_data; +}; + +Streams::Streams(QPDF& qpdf) : + qpdf_(qpdf), + copier_(std::make_shared(*this)) +{ +} + namespace { class SF_Crypt final: public QPDFStreamFilter diff --git a/libqpdf/qpdf/QPDF_private.hh b/libqpdf/qpdf/QPDF_private.hh index 4f112b7..5c15132 100644 --- a/libqpdf/qpdf/QPDF_private.hh +++ b/libqpdf/qpdf/QPDF_private.hh @@ -580,69 +580,10 @@ class QPDF::Doc { // Copier manages the copying of streams into this PDF. It is used both for copying // local and foreign streams. - class Copier final: public QPDFObjectHandle::StreamDataProvider - { - class Data - { - friend class Streams; - - public: - Data(Stream& source, QPDFObjectHandle const& dest_dict); - - private: - std::shared_ptr encp; - std::shared_ptr file; - QPDFObjGen source_og; - qpdf_offset_t offset; - size_t length; - QPDFObjectHandle dest_dict; - bool is_root_metadata{false}; - }; - - public: - Copier() = delete; - Copier(StreamDataProvider const&) = delete; - Copier(StreamDataProvider&&) = delete; - Copier& operator=(StreamDataProvider const&) = delete; - Copier& operator=(StreamDataProvider&&) = delete; - - Copier(Streams& streams); - ~Copier() final = default; - - bool provideStreamData( - QPDFObjGen const& og, - Pipeline* pipeline, - bool suppress_warnings, - bool will_retry) final; - - void - register_copy(QPDFObjGen local_og, QPDFObjectHandle const& foreign_stream) - { - copied_streams.insert_or_assign(local_og, foreign_stream); - } - - void - register_copy( - QPDFObjGen local_og, - Stream& foreign, - qpdf_offset_t offset, - QPDFObjectHandle const& local_dict) - { - copied_data.insert_or_assign(local_og, Data(foreign, local_dict)); - } - - private: - Streams& streams; - std::map copied_streams; - std::map copied_data; - }; + class Copier; public: - Streams(QPDF& qpdf) : - qpdf_(qpdf), - copier_(std::make_shared(*this)) - { - } + Streams(QPDF& qpdf); Streams() = delete; Streams(Streams const&) = delete; -- libgit2 0.21.4