From 873562f46bcc61e29f696477d41914fdeb050ea8 Mon Sep 17 00:00:00 2001 From: m-holger Date: Fri, 21 Feb 2025 11:55:04 +0000 Subject: [PATCH] Move QPDFObject::as to BaseHandle --- include/qpdf/ObjectHandle.hh | 3 +++ include/qpdf/QPDF.hh | 5 +++-- include/qpdf/QPDFObjectHandle.hh | 14 -------------- libqpdf/QPDF.cc | 10 +++++----- libqpdf/QPDFObjectHandle.cc | 56 ++++++++++++++++---------------------------------------- libqpdf/QPDF_Array.cc | 7 +++---- libqpdf/QPDF_Dictionary.cc | 6 ++---- libqpdf/qpdf/QPDFObjectHandle_private.hh | 29 +++++++++++++++++++++++++---- libqpdf/qpdf/QPDFObject_private.hh | 22 ++++------------------ 9 files changed, 61 insertions(+), 91 deletions(-) diff --git a/include/qpdf/ObjectHandle.hh b/include/qpdf/ObjectHandle.hh index 4fd9d8a..c7ce939 100644 --- a/include/qpdf/ObjectHandle.hh +++ b/include/qpdf/ObjectHandle.hh @@ -67,6 +67,9 @@ namespace qpdf BaseHandle& operator=(BaseHandle&&) = default; ~BaseHandle() = default; + template + T* as() const; + std::shared_ptr obj; }; diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index 089cc59..528a679 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -798,9 +798,10 @@ class QPDF { friend class QPDFObject; friend class QPDF_Unresolved; + friend class qpdf::BaseHandle; private: - static QPDFObject* + static std::shared_ptr const& resolved(QPDF* qpdf, QPDFObjGen og) { return qpdf->resolve(og); @@ -1072,7 +1073,7 @@ class QPDF QPDFObjGen exp_og, QPDFObjGen& og, bool skip_cache_if_in_xref); - QPDFObject* resolve(QPDFObjGen og); + std::shared_ptr const& resolve(QPDFObjGen og); void resolveObjectsInStream(int obj_stream_number); void stopOnError(std::string const& message); QPDFObjGen nextObjGen(); diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index c525e77..d3ea1f0 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -1359,20 +1359,6 @@ class QPDFObjectHandle final: public qpdf::BaseHandle inline qpdf::Stream as_stream(qpdf::typed options = qpdf::typed::strict) const; private: - QPDF_Array* asArray() const; - QPDF_Bool* asBool() const; - QPDF_Dictionary* asDictionary() const; - QPDF_InlineImage* asInlineImage() const; - QPDF_Integer* asInteger() const; - QPDF_Name* asName() const; - QPDF_Null* asNull() const; - QPDF_Operator* asOperator() const; - QPDF_Real* asReal() const; - QPDF_Reserved* asReserved() const; - QPDF_Stream* asStream() const; - QPDF_Stream* asStreamWithAssert() const; - QPDF_String* asString() const; - void typeWarning(char const* expected_type, std::string const& warning) const; void objectWarning(std::string const& warning) const; void assertType(char const* type_name, bool istype) const; diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 3c6324c..e89c48b 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -1867,11 +1867,11 @@ QPDF::readObjectAtOffset( return oh; } -QPDFObject* +std::shared_ptr const& QPDF::resolve(QPDFObjGen og) { if (!isUnresolved(og)) { - return m->obj_cache[og].object.get(); + return m->obj_cache[og].object; } if (m->resolving.count(og)) { @@ -1880,7 +1880,7 @@ QPDF::resolve(QPDFObjGen og) QTC::TC("qpdf", "QPDF recursion loop in resolve"); warn(damagedPDF("", "loop detected resolving object " + og.unparse(' '))); updateCache(og, QPDFObject::create(), -1, -1); - return m->obj_cache[og].object.get(); + return m->obj_cache[og].object; } ResolveRecorder rr(this, og); @@ -1919,9 +1919,9 @@ QPDF::resolve(QPDFObjGen og) updateCache(og, QPDFObject::create(), -1, -1); } - auto result(m->obj_cache[og].object); + auto& result(m->obj_cache[og].object); result->setDefaultDescription(this, og); - return result.get(); + return result; } void diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index db6f35f..304c0bb 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -697,24 +697,6 @@ QPDFObjectHandle::getTypeName() const return obj ? tn[getTypeCode()] : "uninitialized"; } -QPDF_Bool* -QPDFObjectHandle::asBool() const -{ - return obj ? obj->as() : nullptr; -} - -QPDF_Integer* -QPDFObjectHandle::asInteger() const -{ - return obj ? obj->as() : nullptr; -} - -QPDF_String* -QPDFObjectHandle::asString() const -{ - return obj ? obj->as() : nullptr; -} - bool QPDFObjectHandle::isDestroyed() const { @@ -861,8 +843,7 @@ QPDFObjectHandle::isStreamOfType(std::string const& type, std::string const& sub bool QPDFObjectHandle::getBoolValue() const { - auto boolean = asBool(); - if (boolean) { + if (auto boolean = as()) { return boolean->val; } else { typeWarning("boolean", "returning false"); @@ -874,12 +855,11 @@ QPDFObjectHandle::getBoolValue() const bool QPDFObjectHandle::getValueAsBool(bool& value) const { - auto boolean = asBool(); - if (boolean == nullptr) { - return false; + if (auto boolean = as()) { + value = boolean->val; + return true; } - value = boolean->val; - return true; + return false; } // Integer accessors @@ -887,8 +867,7 @@ QPDFObjectHandle::getValueAsBool(bool& value) const long long QPDFObjectHandle::getIntValue() const { - auto integer = asInteger(); - if (integer) { + if (auto integer = as()) { return integer->val; } else { typeWarning("integer", "returning 0"); @@ -900,12 +879,11 @@ QPDFObjectHandle::getIntValue() const bool QPDFObjectHandle::getValueAsInt(long long& value) const { - auto integer = asInteger(); - if (integer == nullptr) { - return false; + if (auto integer = as()) { + value = integer->val; + return true; } - value = integer->val; - return true; + return false; } int @@ -1062,8 +1040,7 @@ QPDFObjectHandle::getValueAsString(std::string& value) const std::string QPDFObjectHandle::getUTF8Value() const { - auto str = asString(); - if (str) { + if (auto str = as()) { return str->getUTF8Val(); } else { typeWarning("string", "returning empty string"); @@ -1075,12 +1052,11 @@ QPDFObjectHandle::getUTF8Value() const bool QPDFObjectHandle::getValueAsUTF8(std::string& value) const { - auto str = asString(); - if (str == nullptr) { - return false; + if (auto str = as()) { + value = str->getUTF8Val(); + return true; } - value = str->getUTF8Val(); - return true; + return false; } // Operator and Inline Image accessors @@ -1487,7 +1463,7 @@ QPDFObjectHandle::unparseResolved() const std::string QPDFObjectHandle::unparseBinary() const { - if (auto str = asString()) { + if (auto str = as()) { return str->unparse(true); } else { return unparse(); diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc index 8ca7ed9..3ef8012 100644 --- a/libqpdf/QPDF_Array.cc +++ b/libqpdf/QPDF_Array.cc @@ -59,11 +59,10 @@ QPDF_Array::QPDF_Array(std::vector>&& v, bool sparse QPDF_Array* Array::array() const { - if (obj) { - if (auto a = obj->as()) { - return a; - } + if (auto a = as()) { + return a; } + throw std::runtime_error("Expected an array but found a non-array object"); return nullptr; // unreachable } diff --git a/libqpdf/QPDF_Dictionary.cc b/libqpdf/QPDF_Dictionary.cc index 256e01e..e28d30a 100644 --- a/libqpdf/QPDF_Dictionary.cc +++ b/libqpdf/QPDF_Dictionary.cc @@ -9,10 +9,8 @@ using namespace qpdf; QPDF_Dictionary* BaseDictionary::dict() const { - if (obj) { - if (auto d = obj->as()) { - return d; - } + if (auto d = as()) { + return d; } throw std::runtime_error("Expected a dictionary but found a non-dictionary object"); return nullptr; // unreachable diff --git a/libqpdf/qpdf/QPDFObjectHandle_private.hh b/libqpdf/qpdf/QPDFObjectHandle_private.hh index cd4e8ff..d55cd78 100644 --- a/libqpdf/qpdf/QPDFObjectHandle_private.hh +++ b/libqpdf/qpdf/QPDFObjectHandle_private.hh @@ -204,12 +204,13 @@ namespace qpdf QPDF_Stream::Members* stream() const { - if (obj) { - if (auto s = obj->as()) { - return s->m.get(); + if (auto s = as()) { + if (auto ptr = s->m.get()) { + return ptr; } + throw std::logic_error("QPDF_Stream: unexpected nullptr"); } - throw std::runtime_error("operation for stream attempted on object of type dictionary"); + throw std::runtime_error("operation for stream attempted on non-stream object"); return nullptr; // unreachable } bool filterable( @@ -226,6 +227,26 @@ namespace qpdf filter_factories; }; + template + T* + BaseHandle::as() const + { + if (!obj) { + return nullptr; + } + if (std::holds_alternative(obj->value)) { + return &std::get(obj->value); + } + if (std::holds_alternative(obj->value)) { + return BaseHandle(QPDF::Resolver::resolved(obj->qpdf, obj->og)).as(); + } + if (std::holds_alternative(obj->value)) { + // see comment in QPDF_Reference. + return BaseHandle(std::get(obj->value).obj).as(); + } + return nullptr; + } + inline qpdf_object_type_e BaseHandle::type_code() const { diff --git a/libqpdf/qpdf/QPDFObject_private.hh b/libqpdf/qpdf/QPDFObject_private.hh index 501485b..ab897ee 100644 --- a/libqpdf/qpdf/QPDFObject_private.hh +++ b/libqpdf/qpdf/QPDFObject_private.hh @@ -172,6 +172,7 @@ class QPDF_Reference // objects that are an indirect reference we will need to support multiple levels of // indirection, including the possibility of circular references. friend class QPDFObject; + friend class qpdf::BaseHandle; QPDF_Reference(std::shared_ptr obj) : obj(std::move(obj)) @@ -366,7 +367,7 @@ class QPDFObject const QPDFObject* resolved_object() const { - return isUnresolved() ? QPDF::Resolver::resolved(qpdf, og) : this; + return isUnresolved() ? QPDF::Resolver::resolved(qpdf, og).get() : this; } struct JSON_Descr @@ -461,25 +462,10 @@ class QPDFObject return og; } - template - T* - as() - { - if (std::holds_alternative(value)) { - return &std::get(value); - } - if (std::holds_alternative(value)) { - return QPDF::Resolver::resolved(qpdf, og)->as(); - } - if (std::holds_alternative(value)) { - // see comment in QPDF_Reference. - return std::get(value).obj->as(); - } - return nullptr; - } - private: friend class QPDF_Stream; + friend class qpdf::BaseHandle; + typedef std::variant< std::monostate, QPDF_Reserved, -- libgit2 0.21.4