From 949f2219ac99d6c37212fdb5ee27f5568d3416e4 Mon Sep 17 00:00:00 2001 From: m-holger Date: Tue, 4 Feb 2025 17:39:25 +0000 Subject: [PATCH] Add new class qpdf::BaseHandle --- include/qpdf/ObjectHandle.hh | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/qpdf/QPDFObjectHandle.hh | 46 ++++++++++++++++++++++++++-------------------- libqpdf/QPDFObjectHandle.cc | 8 ++++++++ libqpdf/QPDF_Dictionary.cc | 2 ++ 4 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 include/qpdf/ObjectHandle.hh diff --git a/include/qpdf/ObjectHandle.hh b/include/qpdf/ObjectHandle.hh new file mode 100644 index 0000000..42450d9 --- /dev/null +++ b/include/qpdf/ObjectHandle.hh @@ -0,0 +1,64 @@ +// Copyright (c) 2005-2021 Jay Berkenbilt +// Copyright (c) 2022-2025 Jay Berkenbilt and Manfred Holger +// +// This file is part of qpdf. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the License +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions and limitations under +// the License. +// +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic +// License. At your option, you may continue to consider qpdf to be licensed under those terms. +// Please see the manual for additional information. + +#ifndef OBJECTHANDLE_HH +#define OBJECTHANDLE_HH + +#include +#include +#include + +#include + +class QPDF_Dictionary; +class QPDFObject; +class QPDFObjectHandle; + +namespace qpdf +{ + // Basehandle is only used as a base-class for QPDFObjectHandle like classes. Currently the only + // methods exposed in public API are operators to convert derived objects to QPDFObjectHandle, + // QPDFObjGen and bool. + class BaseHandle + { + public: + explicit inline operator bool() const; + inline operator QPDFObjectHandle() const; + operator QPDFObjGen() const; + + // The rest of the header file is for qpdf internal use only. + + protected: + BaseHandle() = default; + BaseHandle(std::shared_ptr const& obj) : + obj(obj) {}; + BaseHandle(std::shared_ptr&& obj) : + obj(std::move(obj)) {}; + BaseHandle(BaseHandle const&) = default; + BaseHandle& operator=(BaseHandle const&) = default; + BaseHandle(BaseHandle&&) = default; + BaseHandle& operator=(BaseHandle&&) = default; + ~BaseHandle() = default; + + std::shared_ptr obj; + }; + +} // namespace qpdf + +#endif // QPDFOBJECTHANDLE_HH diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index bcc0e55..5e8a2a6 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -55,13 +56,14 @@ class QPDF_Reserved; class QPDF_Stream; class QPDF_String; class QPDFObject; +class QPDFObjectHandle; class QPDFTokenizer; class QPDFExc; class Pl_QPDFTokenizer; class QPDFMatrix; class QPDFParser; -class QPDFObjectHandle +class QPDFObjectHandle final: public qpdf::BaseHandle { friend class QPDFParser; @@ -290,18 +292,12 @@ class QPDFObjectHandle QPDFObjectHandle(QPDFObjectHandle const&) = default; QPDF_DLL QPDFObjectHandle& operator=(QPDFObjectHandle const&) = default; - QPDF_DLL QPDFObjectHandle(QPDFObjectHandle&&) = default; QPDF_DLL QPDFObjectHandle& operator=(QPDFObjectHandle&&) = default; - // Return true if the QPDFObjectHandle is initialized. This allows object handles to be used in - // if statements with initializer. - QPDF_DLL - explicit inline operator bool() const noexcept; - - [[deprecated("use operator bool()")]] QPDF_DLL inline bool isInitialized() const noexcept; + [[deprecated("use operator bool()")]] QPDF_DLL inline bool isInitialized() const; // This method returns true if the QPDFObjectHandle objects point to exactly the same underlying // object, meaning that changes to one are reflected in the other, or "if you paint one, the @@ -1329,7 +1325,11 @@ class QPDFObjectHandle // The following methods do not form part of the public API and are for internal use only. QPDFObjectHandle(std::shared_ptr const& obj) : - obj(obj) + qpdf::BaseHandle(obj) + { + } + QPDFObjectHandle(std::shared_ptr&& obj) : + qpdf::BaseHandle(std::move(obj)) { } std::shared_ptr @@ -1386,10 +1386,6 @@ class QPDFObjectHandle arrayOrStreamToStreamArray(std::string const& description, std::string& all_description); static void warn(QPDF*, QPDFExc const&); void checkOwnership(QPDFObjectHandle const&) const; - - // Moving members of QPDFObjectHandle into a smart pointer incurs a substantial performance - // penalty since QPDFObjectHandle objects are copied around so frequently. - std::shared_ptr obj; }; #ifndef QPDF_NO_QPDF_STRING @@ -1606,6 +1602,22 @@ class QPDFObjectHandle::QPDFArrayItems QPDFObjectHandle oh; }; +namespace qpdf +{ + inline BaseHandle:: + operator bool() const + { + return static_cast(obj); + } + + inline BaseHandle:: + operator QPDFObjectHandle() const + { + return {obj}; + } + +} // namespace qpdf + inline int QPDFObjectHandle::getObjectID() const { @@ -1625,15 +1637,9 @@ QPDFObjectHandle::isIndirect() const } inline bool -QPDFObjectHandle::isInitialized() const noexcept +QPDFObjectHandle::isInitialized() const { return obj != nullptr; } -inline QPDFObjectHandle:: -operator bool() const noexcept -{ - return static_cast(obj); -} - #endif // QPDFOBJECTHANDLE_HH diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 9dad223..30f854b 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -39,6 +39,14 @@ using namespace std::literals; +using namespace qpdf; + +BaseHandle:: +operator QPDFObjGen() const +{ + return obj ? obj->getObjGen() : QPDFObjGen(); +} + namespace { class TerminateParsing diff --git a/libqpdf/QPDF_Dictionary.cc b/libqpdf/QPDF_Dictionary.cc index 9567e3c..2cd6f61 100644 --- a/libqpdf/QPDF_Dictionary.cc +++ b/libqpdf/QPDF_Dictionary.cc @@ -1,12 +1,14 @@ #include #include +#include #include #include #include #include using namespace std::literals; +using namespace qpdf; QPDF_Dictionary::QPDF_Dictionary(std::map const& items) : QPDFValue(::ot_dictionary), -- libgit2 0.21.4