From c36b76be772aaf3ed02e4a8d1b097bf0fdc94f9d Mon Sep 17 00:00:00 2001 From: m-holger Date: Sat, 22 Feb 2025 11:52:55 +0000 Subject: [PATCH] Add new methods BaseHandle::id_gen, indirect, qpdf and raw_typecode --- include/qpdf/ObjectHandle.hh | 5 +++++ libqpdf/QPDFObjectHandle.cc | 54 +++++++++++++++++++++++++----------------------------- libqpdf/QPDF_Array.cc | 22 ++++++++-------------- libqpdf/qpdf/QPDFObjectHandle_private.hh | 35 ++++++++++++++++++++++++++++++++++- libqpdf/qpdf/QPDFObject_private.hh | 11 ----------- 5 files changed, 72 insertions(+), 55 deletions(-) diff --git a/include/qpdf/ObjectHandle.hh b/include/qpdf/ObjectHandle.hh index 38073c4..6655322 100644 --- a/include/qpdf/ObjectHandle.hh +++ b/include/qpdf/ObjectHandle.hh @@ -28,6 +28,7 @@ #include #include +class QPDF; class QPDF_Dictionary; class QPDFObject; class QPDFObjectHandle; @@ -53,7 +54,11 @@ namespace qpdf // The rest of the header file is for qpdf internal use only. + inline QPDFObjGen id_gen() const; + inline bool indirect() const; inline bool null() const; + inline QPDF* qpdf() const; + inline qpdf_object_type_e raw_type_code() const; inline qpdf_object_type_e type_code() const; protected: diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 4c8e641..46053e1 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -319,20 +319,16 @@ QPDFObject::copy(bool shallow) QPDF_Array result; result.sp = std::make_unique(); result.sp->size = a.sp->size; - for (auto const& element: a.sp->elements) { - auto const& obj = element.second; - result.sp->elements[element.first] = - obj.getObj()->getObjGen().isIndirect() ? obj : obj.getObj()->copy(); + for (auto const& [idx, oh]: a.sp->elements) { + result.sp->elements[idx] = oh.indirect() ? oh : oh.getObj()->copy(); } return QPDFObject::create(std::move(result)); } else { std::vector result; result.reserve(a.elements.size()); for (auto const& element: a.elements) { - result.push_back( - element ? (element.getObj()->getObjGen().isIndirect() - ? element - : element.getObj()->copy()) + result.emplace_back( + element ? (element.indirect() ? element : element.getObj()->copy()) : element); } return QPDFObject::create(std::move(result), false); @@ -347,7 +343,7 @@ QPDFObject::copy(bool shallow) } else { std::map new_items; for (auto const& [key, val]: d.items) { - new_items[key] = val.isIndirect() ? val : val.getObj()->copy(); + new_items[key] = val.indirect() ? val : val.getObj()->copy(); } return QPDFObject::create(new_items); } @@ -405,7 +401,7 @@ QPDFObject::unparse() for (int j = next; j < key; ++j) { result += "null "; } - auto item_og = item.second.getObj()->resolved_object()->getObjGen(); + auto item_og = item.second.id_gen(); result += item_og.isIndirect() ? item_og.unparse(' ') + " R " : item.second.getObj()->unparse() + " "; next = ++key; @@ -415,7 +411,7 @@ QPDFObject::unparse() } } else { for (auto const& item: a.elements) { - auto item_og = item.getObj()->resolved_object()->getObjGen(); + auto item_og = item.id_gen(); result += item_og.isIndirect() ? item_og.unparse(' ') + " R " : item.getObj()->unparse() + " "; } @@ -428,7 +424,7 @@ QPDFObject::unparse() auto const& items = std::get(value).items; std::string result = "<< "; for (auto& iter: items) { - if (!iter.second.isNull()) { + if (!iter.second.null()) { result += Name::normalize(iter.first) + " " + iter.second.unparse() + " "; } } @@ -555,7 +551,7 @@ QPDFObject::write_json(int json_version, JSON::Writer& p) auto const& d = std::get(value); p.writeStart('{'); for (auto& iter: d.items) { - if (!iter.second.isNull()) { + if (!iter.second.null()) { p.writeNext(); if (json_version == 1) { p << "\"" << JSON::Writer::encode_string(Name::normalize(iter.first)) @@ -599,13 +595,13 @@ QPDFObject::disconnect() if (a.sp) { for (auto& item: a.sp->elements) { auto& obj = item.second; - if (!obj.getObj()->getObjGen().isIndirect()) { + if (!obj.indirect()) { obj.getObj()->disconnect(); } } } else { for (auto& obj: a.elements) { - if (!obj.getObj()->getObjGen().isIndirect()) { + if (!obj.indirect()) { obj.getObj()->disconnect(); } } @@ -701,13 +697,13 @@ QPDFObjectHandle::getTypeName() const bool QPDFObjectHandle::isDestroyed() const { - return obj && obj->getResolvedTypeCode() == ::ot_destroyed; + return type_code() == ::ot_destroyed; } bool QPDFObjectHandle::isBool() const { - return obj && obj->getResolvedTypeCode() == ::ot_boolean; + return type_code() == ::ot_boolean; } bool @@ -715,25 +711,25 @@ QPDFObjectHandle::isDirectNull() const { // Don't call dereference() -- this is a const method, and we know // objid == 0, so there's nothing to resolve. - return (obj && getObjectID() == 0 && obj->getTypeCode() == ::ot_null); + return !indirect() && raw_type_code() == ::ot_null; } bool QPDFObjectHandle::isNull() const { - return obj && obj->getResolvedTypeCode() == ::ot_null; + return type_code() == ::ot_null; } bool QPDFObjectHandle::isInteger() const { - return obj && obj->getResolvedTypeCode() == ::ot_integer; + return type_code() == ::ot_integer; } bool QPDFObjectHandle::isReal() const { - return obj && obj->getResolvedTypeCode() == ::ot_real; + return type_code() == ::ot_real; } bool @@ -769,49 +765,49 @@ QPDFObjectHandle::getValueAsNumber(double& value) const bool QPDFObjectHandle::isName() const { - return obj && obj->getResolvedTypeCode() == ::ot_name; + return type_code() == ::ot_name; } bool QPDFObjectHandle::isString() const { - return obj && obj->getResolvedTypeCode() == ::ot_string; + return type_code() == ::ot_string; } bool QPDFObjectHandle::isOperator() const { - return obj && obj->getResolvedTypeCode() == ::ot_operator; + return type_code() == ::ot_operator; } bool QPDFObjectHandle::isInlineImage() const { - return obj && obj->getResolvedTypeCode() == ::ot_inlineimage; + return type_code() == ::ot_inlineimage; } bool QPDFObjectHandle::isArray() const { - return obj && obj->getResolvedTypeCode() == ::ot_array; + return type_code() == ::ot_array; } bool QPDFObjectHandle::isDictionary() const { - return obj && obj->getResolvedTypeCode() == ::ot_dictionary; + return type_code() == ::ot_dictionary; } bool QPDFObjectHandle::isStream() const { - return obj && obj->getResolvedTypeCode() == ::ot_stream; + return type_code() == ::ot_stream; } bool QPDFObjectHandle::isReserved() const { - return obj && obj->getResolvedTypeCode() == ::ot_reserved; + return type_code() == ::ot_reserved; } bool diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc index 7eec380..7f5c9ae 100644 --- a/libqpdf/QPDF_Array.cc +++ b/libqpdf/QPDF_Array.cc @@ -10,28 +10,22 @@ static const QPDFObjectHandle null_oh = QPDFObjectHandle::newNull(); inline void Array::checkOwnership(QPDFObjectHandle const& item) const { - if (auto o = item.getObjectPtr()) { - if (auto pdf = obj->getQPDF()) { - if (auto item_qpdf = o->getQPDF()) { - if (pdf != item_qpdf) { - throw std::logic_error( - "Attempting to add an object from a different QPDF. Use " - "QPDF::copyForeignObject to add objects from another file."); - } - } - } - } else { + if (!item) { throw std::logic_error("Attempting to add an uninitialized object to a QPDF_Array."); } + if (qpdf() && item.qpdf() && qpdf() != item.qpdf()) { + throw std::logic_error( + "Attempting to add an object from a different QPDF. Use " + "QPDF::copyForeignObject to add objects from another file."); + } } QPDF_Array::QPDF_Array(std::vector&& v, bool sparse) { if (sparse) { sp = std::make_unique(); - for (auto&& item: v) { - if (item.getObj()->getTypeCode() != ::ot_null || - item.getObj()->getObjGen().isIndirect()) { + for (auto& item: v) { + if (item.raw_type_code() != ::ot_null || item.indirect()) { sp->elements[sp->size] = std::move(item); } ++sp->size; diff --git a/libqpdf/qpdf/QPDFObjectHandle_private.hh b/libqpdf/qpdf/QPDFObjectHandle_private.hh index 3f9dc3a..efe276c 100644 --- a/libqpdf/qpdf/QPDFObjectHandle_private.hh +++ b/libqpdf/qpdf/QPDFObjectHandle_private.hh @@ -325,16 +325,49 @@ namespace qpdf return nullptr; } + inline QPDFObjGen + BaseHandle::id_gen() const + { + return obj ? obj->og : QPDFObjGen(); + } + + inline bool + BaseHandle::indirect() const + { + return obj ? obj->og.isIndirect() : false; + } + inline bool BaseHandle::null() const { return !obj || obj->getResolvedTypeCode() == ::ot_null; } + inline QPDF* + BaseHandle::qpdf() const + { + return obj ? obj->qpdf : nullptr; + } + + inline qpdf_object_type_e + BaseHandle::raw_type_code() const + { + return obj ? static_cast(obj->value.index()) : ::ot_uninitialized; + } + inline qpdf_object_type_e BaseHandle::type_code() const { - return obj ? obj->getResolvedTypeCode() : ::ot_uninitialized; + if (!obj) { + return ::ot_uninitialized; + } + if (raw_type_code() == ::ot_unresolved) { + return QPDF::Resolver::resolved(obj->qpdf, obj->og)->getTypeCode(); + } + if (raw_type_code() == ::ot_reference) { + return std::get(obj->value).obj->getResolvedTypeCode(); + } + return raw_type_code(); } } // namespace qpdf diff --git a/libqpdf/qpdf/QPDFObject_private.hh b/libqpdf/qpdf/QPDFObject_private.hh index 4450153..25db481 100644 --- a/libqpdf/qpdf/QPDFObject_private.hh +++ b/libqpdf/qpdf/QPDFObject_private.hh @@ -308,17 +308,6 @@ class QPDFObject { return static_cast(value.index()); } - - QPDF* - getQPDF() const - { - return qpdf; - } - QPDFObjGen - getObjGen() const - { - return og; - } void assign_null() { -- libgit2 0.21.4