mirror of
https://github.com/qpdf/qpdf.git
synced 2024-11-08 06:15:23 +00:00
Refactor resolving of objects
This commit is contained in:
parent
ce5b864c53
commit
9641626cae
@ -792,12 +792,13 @@ class QPDF
|
|||||||
class Resolver
|
class Resolver
|
||||||
{
|
{
|
||||||
friend class QPDFObject;
|
friend class QPDFObject;
|
||||||
|
friend class QPDF_Unresolved;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void
|
static QPDFObject*
|
||||||
resolve(QPDF* qpdf, QPDFObjGen const& og)
|
resolved(QPDF* qpdf, QPDFObjGen og)
|
||||||
{
|
{
|
||||||
qpdf->resolve(og);
|
return qpdf->resolve(og);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1056,7 +1057,7 @@ class QPDF
|
|||||||
QPDFObjGen exp_og,
|
QPDFObjGen exp_og,
|
||||||
QPDFObjGen& og,
|
QPDFObjGen& og,
|
||||||
bool skip_cache_if_in_xref);
|
bool skip_cache_if_in_xref);
|
||||||
void resolve(QPDFObjGen og);
|
QPDFObject* resolve(QPDFObjGen og);
|
||||||
void resolveObjectsInStream(int obj_stream_number);
|
void resolveObjectsInStream(int obj_stream_number);
|
||||||
void stopOnError(std::string const& message);
|
void stopOnError(std::string const& message);
|
||||||
QPDFObjectHandle reserveObjectIfNotExists(QPDFObjGen const& og);
|
QPDFObjectHandle reserveObjectIfNotExists(QPDFObjGen const& og);
|
||||||
|
@ -1363,24 +1363,23 @@ class QPDFObjectHandle
|
|||||||
void writeJSON(int json_version, JSON::Writer& p, bool dereference_indirect = false);
|
void writeJSON(int json_version, JSON::Writer& p, bool dereference_indirect = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPDF_Array* asArray();
|
QPDF_Array* asArray() const;
|
||||||
QPDF_Bool* asBool();
|
QPDF_Bool* asBool() const;
|
||||||
QPDF_Dictionary* asDictionary();
|
QPDF_Dictionary* asDictionary() const;
|
||||||
QPDF_InlineImage* asInlineImage();
|
QPDF_InlineImage* asInlineImage() const;
|
||||||
QPDF_Integer* asInteger();
|
QPDF_Integer* asInteger() const;
|
||||||
QPDF_Name* asName();
|
QPDF_Name* asName() const;
|
||||||
QPDF_Null* asNull();
|
QPDF_Null* asNull() const;
|
||||||
QPDF_Operator* asOperator();
|
QPDF_Operator* asOperator() const;
|
||||||
QPDF_Real* asReal();
|
QPDF_Real* asReal() const;
|
||||||
QPDF_Reserved* asReserved();
|
QPDF_Reserved* asReserved() const;
|
||||||
QPDF_Stream* asStream();
|
QPDF_Stream* asStream() const;
|
||||||
QPDF_Stream* asStreamWithAssert();
|
QPDF_Stream* asStreamWithAssert();
|
||||||
QPDF_String* asString();
|
QPDF_String* asString() const;
|
||||||
|
|
||||||
void typeWarning(char const* expected_type, std::string const& warning);
|
void typeWarning(char const* expected_type, std::string const& warning);
|
||||||
void objectWarning(std::string const& warning);
|
void objectWarning(std::string const& warning);
|
||||||
void assertType(char const* type_name, bool istype);
|
void assertType(char const* type_name, bool istype);
|
||||||
inline bool dereference();
|
|
||||||
void makeDirect(QPDFObjGen::set& visited, bool stop_at_streams);
|
void makeDirect(QPDFObjGen::set& visited, bool stop_at_streams);
|
||||||
void disconnect();
|
void disconnect();
|
||||||
void setParsedOffset(qpdf_offset_t offset);
|
void setParsedOffset(qpdf_offset_t offset);
|
||||||
|
@ -1728,11 +1728,11 @@ QPDF::readObjectAtOffset(
|
|||||||
return oh;
|
return oh;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
QPDFObject*
|
||||||
QPDF::resolve(QPDFObjGen og)
|
QPDF::resolve(QPDFObjGen og)
|
||||||
{
|
{
|
||||||
if (!isUnresolved(og)) {
|
if (!isUnresolved(og)) {
|
||||||
return;
|
return m->obj_cache[og].object.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m->resolving.count(og)) {
|
if (m->resolving.count(og)) {
|
||||||
@ -1741,7 +1741,7 @@ QPDF::resolve(QPDFObjGen og)
|
|||||||
QTC::TC("qpdf", "QPDF recursion loop in resolve");
|
QTC::TC("qpdf", "QPDF recursion loop in resolve");
|
||||||
warn(damagedPDF("", "loop detected resolving object " + og.unparse(' ')));
|
warn(damagedPDF("", "loop detected resolving object " + og.unparse(' ')));
|
||||||
updateCache(og, QPDF_Null::create(), -1, -1);
|
updateCache(og, QPDF_Null::create(), -1, -1);
|
||||||
return;
|
return m->obj_cache[og].object.get();
|
||||||
}
|
}
|
||||||
ResolveRecorder rr(this, og);
|
ResolveRecorder rr(this, og);
|
||||||
|
|
||||||
@ -1782,6 +1782,7 @@ QPDF::resolve(QPDFObjGen og)
|
|||||||
|
|
||||||
auto result(m->obj_cache[og].object);
|
auto result(m->obj_cache[og].object);
|
||||||
result->setDefaultDescription(this, og);
|
result->setDefaultDescription(this, og);
|
||||||
|
return result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -3,13 +3,6 @@
|
|||||||
#include <qpdf/QPDF.hh>
|
#include <qpdf/QPDF.hh>
|
||||||
#include <qpdf/QPDF_Destroyed.hh>
|
#include <qpdf/QPDF_Destroyed.hh>
|
||||||
|
|
||||||
void
|
|
||||||
QPDFObject::doResolve()
|
|
||||||
{
|
|
||||||
auto og = value->og;
|
|
||||||
QPDF::Resolver::resolve(value->qpdf, og);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
QPDFObject::destroy()
|
QPDFObject::destroy()
|
||||||
{
|
{
|
||||||
|
@ -240,79 +240,79 @@ QPDFObjectHandle::disconnect()
|
|||||||
qpdf_object_type_e
|
qpdf_object_type_e
|
||||||
QPDFObjectHandle::getTypeCode()
|
QPDFObjectHandle::getTypeCode()
|
||||||
{
|
{
|
||||||
return dereference() ? this->obj->getTypeCode() : ::ot_uninitialized;
|
return obj ? obj->getResolvedTypeCode() : ::ot_uninitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
char const*
|
char const*
|
||||||
QPDFObjectHandle::getTypeName()
|
QPDFObjectHandle::getTypeName()
|
||||||
{
|
{
|
||||||
return dereference() ? this->obj->getTypeName() : "uninitialized";
|
return obj ? obj->getTypeName() : "uninitialized";
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF_Array*
|
QPDF_Array*
|
||||||
QPDFObjectHandle::asArray()
|
QPDFObjectHandle::asArray() const
|
||||||
{
|
{
|
||||||
return dereference() ? obj->as<QPDF_Array>() : nullptr;
|
return obj ? obj->as<QPDF_Array>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF_Bool*
|
QPDF_Bool*
|
||||||
QPDFObjectHandle::asBool()
|
QPDFObjectHandle::asBool() const
|
||||||
{
|
{
|
||||||
return dereference() ? obj->as<QPDF_Bool>() : nullptr;
|
return obj ? obj->as<QPDF_Bool>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF_Dictionary*
|
QPDF_Dictionary*
|
||||||
QPDFObjectHandle::asDictionary()
|
QPDFObjectHandle::asDictionary() const
|
||||||
{
|
{
|
||||||
return dereference() ? obj->as<QPDF_Dictionary>() : nullptr;
|
return obj ? obj->as<QPDF_Dictionary>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF_InlineImage*
|
QPDF_InlineImage*
|
||||||
QPDFObjectHandle::asInlineImage()
|
QPDFObjectHandle::asInlineImage() const
|
||||||
{
|
{
|
||||||
return dereference() ? obj->as<QPDF_InlineImage>() : nullptr;
|
return obj ? obj->as<QPDF_InlineImage>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF_Integer*
|
QPDF_Integer*
|
||||||
QPDFObjectHandle::asInteger()
|
QPDFObjectHandle::asInteger() const
|
||||||
{
|
{
|
||||||
return dereference() ? obj->as<QPDF_Integer>() : nullptr;
|
return obj ? obj->as<QPDF_Integer>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF_Name*
|
QPDF_Name*
|
||||||
QPDFObjectHandle::asName()
|
QPDFObjectHandle::asName() const
|
||||||
{
|
{
|
||||||
return dereference() ? obj->as<QPDF_Name>() : nullptr;
|
return obj ? obj->as<QPDF_Name>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF_Null*
|
QPDF_Null*
|
||||||
QPDFObjectHandle::asNull()
|
QPDFObjectHandle::asNull() const
|
||||||
{
|
{
|
||||||
return dereference() ? obj->as<QPDF_Null>() : nullptr;
|
return obj ? obj->as<QPDF_Null>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF_Operator*
|
QPDF_Operator*
|
||||||
QPDFObjectHandle::asOperator()
|
QPDFObjectHandle::asOperator() const
|
||||||
{
|
{
|
||||||
return dereference() ? obj->as<QPDF_Operator>() : nullptr;
|
return obj ? obj->as<QPDF_Operator>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF_Real*
|
QPDF_Real*
|
||||||
QPDFObjectHandle::asReal()
|
QPDFObjectHandle::asReal() const
|
||||||
{
|
{
|
||||||
return dereference() ? obj->as<QPDF_Real>() : nullptr;
|
return obj ? obj->as<QPDF_Real>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF_Reserved*
|
QPDF_Reserved*
|
||||||
QPDFObjectHandle::asReserved()
|
QPDFObjectHandle::asReserved() const
|
||||||
{
|
{
|
||||||
return dereference() ? obj->as<QPDF_Reserved>() : nullptr;
|
return obj ? obj->as<QPDF_Reserved>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF_Stream*
|
QPDF_Stream*
|
||||||
QPDFObjectHandle::asStream()
|
QPDFObjectHandle::asStream() const
|
||||||
{
|
{
|
||||||
return dereference() ? obj->as<QPDF_Stream>() : nullptr;
|
return obj ? obj->as<QPDF_Stream>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF_Stream*
|
QPDF_Stream*
|
||||||
@ -324,21 +324,21 @@ QPDFObjectHandle::asStreamWithAssert()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QPDF_String*
|
QPDF_String*
|
||||||
QPDFObjectHandle::asString()
|
QPDFObjectHandle::asString() const
|
||||||
{
|
{
|
||||||
return dereference() ? obj->as<QPDF_String>() : nullptr;
|
return obj ? obj->as<QPDF_String>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isDestroyed()
|
QPDFObjectHandle::isDestroyed()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_destroyed);
|
return obj && obj->getResolvedTypeCode() == ::ot_destroyed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isBool()
|
QPDFObjectHandle::isBool()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_boolean);
|
return obj && obj->getResolvedTypeCode() == ::ot_boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -346,25 +346,25 @@ QPDFObjectHandle::isDirectNull() const
|
|||||||
{
|
{
|
||||||
// Don't call dereference() -- this is a const method, and we know
|
// Don't call dereference() -- this is a const method, and we know
|
||||||
// objid == 0, so there's nothing to resolve.
|
// objid == 0, so there's nothing to resolve.
|
||||||
return (isInitialized() && (getObjectID() == 0) && (obj->getTypeCode() == ::ot_null));
|
return (obj && getObjectID() == 0 && obj->getTypeCode() == ::ot_null);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isNull()
|
QPDFObjectHandle::isNull()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_null);
|
return obj && obj->getResolvedTypeCode() == ::ot_null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isInteger()
|
QPDFObjectHandle::isInteger()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_integer);
|
return obj && obj->getResolvedTypeCode() == ::ot_integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isReal()
|
QPDFObjectHandle::isReal()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_real);
|
return obj && obj->getResolvedTypeCode() == ::ot_real;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -401,49 +401,49 @@ QPDFObjectHandle::getValueAsNumber(double& value)
|
|||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isName()
|
QPDFObjectHandle::isName()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_name);
|
return obj && obj->getResolvedTypeCode() == ::ot_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isString()
|
QPDFObjectHandle::isString()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_string);
|
return obj && obj->getResolvedTypeCode() == ::ot_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isOperator()
|
QPDFObjectHandle::isOperator()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_operator);
|
return obj && obj->getResolvedTypeCode() == ::ot_operator;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isInlineImage()
|
QPDFObjectHandle::isInlineImage()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_inlineimage);
|
return obj && obj->getResolvedTypeCode() == ::ot_inlineimage;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isArray()
|
QPDFObjectHandle::isArray()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_array);
|
return obj && obj->getResolvedTypeCode() == ::ot_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isDictionary()
|
QPDFObjectHandle::isDictionary()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_dictionary);
|
return obj && obj->getResolvedTypeCode() == ::ot_dictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isStream()
|
QPDFObjectHandle::isStream()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_stream);
|
return obj && obj->getResolvedTypeCode() == ::ot_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
QPDFObjectHandle::isReserved()
|
QPDFObjectHandle::isReserved()
|
||||||
{
|
{
|
||||||
return dereference() && (obj->getTypeCode() == ::ot_reserved);
|
return obj && obj->getResolvedTypeCode() == ::ot_reserved;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -1586,7 +1586,7 @@ QPDFObjectHandle::unparse()
|
|||||||
std::string
|
std::string
|
||||||
QPDFObjectHandle::unparseResolved()
|
QPDFObjectHandle::unparseResolved()
|
||||||
{
|
{
|
||||||
if (!dereference()) {
|
if (!obj) {
|
||||||
throw std::logic_error("attempted to dereference an uninitialized QPDFObjectHandle");
|
throw std::logic_error("attempted to dereference an uninitialized QPDFObjectHandle");
|
||||||
}
|
}
|
||||||
return obj->unparse();
|
return obj->unparse();
|
||||||
@ -1615,7 +1615,7 @@ QPDFObjectHandle::getJSON(int json_version, bool dereference_indirect)
|
|||||||
{
|
{
|
||||||
if ((!dereference_indirect) && isIndirect()) {
|
if ((!dereference_indirect) && isIndirect()) {
|
||||||
return JSON::makeString(unparse());
|
return JSON::makeString(unparse());
|
||||||
} else if (!dereference()) {
|
} else if (!obj) {
|
||||||
throw std::logic_error("attempted to dereference an uninitialized QPDFObjectHandle");
|
throw std::logic_error("attempted to dereference an uninitialized QPDFObjectHandle");
|
||||||
} else {
|
} else {
|
||||||
Pl_Buffer p{"json"};
|
Pl_Buffer p{"json"};
|
||||||
@ -1631,7 +1631,7 @@ QPDFObjectHandle::writeJSON(int json_version, JSON::Writer& p, bool dereference_
|
|||||||
{
|
{
|
||||||
if (!dereference_indirect && isIndirect()) {
|
if (!dereference_indirect && isIndirect()) {
|
||||||
p << "\"" << getObjGen().unparse(' ') << " R\"";
|
p << "\"" << getObjGen().unparse(' ') << " R\"";
|
||||||
} else if (!dereference()) {
|
} else if (!obj) {
|
||||||
throw std::logic_error("attempted to dereference an uninitialized QPDFObjectHandle");
|
throw std::logic_error("attempted to dereference an uninitialized QPDFObjectHandle");
|
||||||
} else {
|
} else {
|
||||||
obj->writeJSON(json_version, p);
|
obj->writeJSON(json_version, p);
|
||||||
@ -1874,11 +1874,7 @@ QPDFObjectHandle::parse(
|
|||||||
qpdf_offset_t
|
qpdf_offset_t
|
||||||
QPDFObjectHandle::getParsedOffset()
|
QPDFObjectHandle::getParsedOffset()
|
||||||
{
|
{
|
||||||
if (dereference()) {
|
return obj ? obj->getParsedOffset() : -1;
|
||||||
return this->obj->getParsedOffset();
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDFObjectHandle
|
QPDFObjectHandle
|
||||||
@ -2055,9 +2051,7 @@ QPDFObjectHandle::newReserved(QPDF* qpdf)
|
|||||||
void
|
void
|
||||||
QPDFObjectHandle::setObjectDescription(QPDF* owning_qpdf, std::string const& object_description)
|
QPDFObjectHandle::setObjectDescription(QPDF* owning_qpdf, std::string const& object_description)
|
||||||
{
|
{
|
||||||
// This is called during parsing on newly created direct objects, so we can't call dereference()
|
if (obj) {
|
||||||
// here.
|
|
||||||
if (isInitialized() && obj.get()) {
|
|
||||||
auto descr = std::make_shared<QPDFValue::Description>(object_description);
|
auto descr = std::make_shared<QPDFValue::Description>(object_description);
|
||||||
obj->setDescription(owning_qpdf, descr);
|
obj->setDescription(owning_qpdf, descr);
|
||||||
}
|
}
|
||||||
@ -2066,13 +2060,13 @@ QPDFObjectHandle::setObjectDescription(QPDF* owning_qpdf, std::string const& obj
|
|||||||
bool
|
bool
|
||||||
QPDFObjectHandle::hasObjectDescription()
|
QPDFObjectHandle::hasObjectDescription()
|
||||||
{
|
{
|
||||||
return dereference() && obj.get() && obj->hasDescription();
|
return obj && obj->hasDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDFObjectHandle
|
QPDFObjectHandle
|
||||||
QPDFObjectHandle::shallowCopy()
|
QPDFObjectHandle::shallowCopy()
|
||||||
{
|
{
|
||||||
if (!dereference()) {
|
if (!obj) {
|
||||||
throw std::logic_error("operation attempted on uninitialized QPDFObjectHandle");
|
throw std::logic_error("operation attempted on uninitialized QPDFObjectHandle");
|
||||||
}
|
}
|
||||||
return {obj->copy()};
|
return {obj->copy()};
|
||||||
@ -2081,7 +2075,7 @@ QPDFObjectHandle::shallowCopy()
|
|||||||
QPDFObjectHandle
|
QPDFObjectHandle
|
||||||
QPDFObjectHandle::unsafeShallowCopy()
|
QPDFObjectHandle::unsafeShallowCopy()
|
||||||
{
|
{
|
||||||
if (!dereference()) {
|
if (!obj) {
|
||||||
throw std::logic_error("operation attempted on uninitialized QPDFObjectHandle");
|
throw std::logic_error("operation attempted on uninitialized QPDFObjectHandle");
|
||||||
}
|
}
|
||||||
return {obj->copy(true)};
|
return {obj->copy(true)};
|
||||||
@ -2172,10 +2166,10 @@ QPDFObjectHandle::typeWarning(char const* expected_type, std::string const& warn
|
|||||||
std::string description;
|
std::string description;
|
||||||
// Type checks above guarantee that the object has been dereferenced. Nevertheless, dereference
|
// Type checks above guarantee that the object has been dereferenced. Nevertheless, dereference
|
||||||
// throws exceptions in the test suite
|
// throws exceptions in the test suite
|
||||||
if (!dereference()) {
|
if (!obj) {
|
||||||
throw std::logic_error("attempted to dereference an uninitialized QPDFObjectHandle");
|
throw std::logic_error("attempted to dereference an uninitialized QPDFObjectHandle");
|
||||||
}
|
}
|
||||||
this->obj->getDescription(context, description);
|
obj->getDescription(context, description);
|
||||||
// Null context handled by warn
|
// Null context handled by warn
|
||||||
warn(
|
warn(
|
||||||
context,
|
context,
|
||||||
@ -2193,7 +2187,7 @@ QPDFObjectHandle::warnIfPossible(std::string const& warning)
|
|||||||
{
|
{
|
||||||
QPDF* context = nullptr;
|
QPDF* context = nullptr;
|
||||||
std::string description;
|
std::string description;
|
||||||
if (dereference() && obj->getDescription(context, description)) {
|
if (obj && obj->getDescription(context, description)) {
|
||||||
warn(context, QPDFExc(qpdf_e_damaged_pdf, "", description, 0, warning));
|
warn(context, QPDFExc(qpdf_e_damaged_pdf, "", description, 0, warning));
|
||||||
} else {
|
} else {
|
||||||
*QPDFLogger::defaultLogger()->getError() << warning << "\n";
|
*QPDFLogger::defaultLogger()->getError() << warning << "\n";
|
||||||
@ -2205,8 +2199,8 @@ QPDFObjectHandle::objectWarning(std::string const& warning)
|
|||||||
{
|
{
|
||||||
QPDF* context = nullptr;
|
QPDF* context = nullptr;
|
||||||
std::string description;
|
std::string description;
|
||||||
// Type checks above guarantee that the object has been dereferenced.
|
// Type checks above guarantee that the object is initialized.
|
||||||
this->obj->getDescription(context, description);
|
obj->getDescription(context, description);
|
||||||
// Null context handled by warn
|
// Null context handled by warn
|
||||||
warn(context, QPDFExc(qpdf_e_object, "", description, 0, warning));
|
warn(context, QPDFExc(qpdf_e_object, "", description, 0, warning));
|
||||||
}
|
}
|
||||||
@ -2372,16 +2366,6 @@ QPDFObjectHandle::assertPageObject()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
|
||||||
QPDFObjectHandle::dereference()
|
|
||||||
{
|
|
||||||
if (!isInitialized()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
this->obj->resolve();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
QPDFObjectHandle::warn(QPDF* qpdf, QPDFExc const& e)
|
QPDFObjectHandle::warn(QPDF* qpdf, QPDFExc const& e)
|
||||||
{
|
{
|
||||||
|
@ -130,8 +130,7 @@ QPDF_Array::unparse()
|
|||||||
for (int j = next; j < key; ++j) {
|
for (int j = next; j < key; ++j) {
|
||||||
result += "null ";
|
result += "null ";
|
||||||
}
|
}
|
||||||
item.second->resolve();
|
auto og = item.second->resolved_object()->getObjGen();
|
||||||
auto og = item.second->getObjGen();
|
|
||||||
result += og.isIndirect() ? og.unparse(' ') + " R " : item.second->unparse() + " ";
|
result += og.isIndirect() ? og.unparse(' ') + " R " : item.second->unparse() + " ";
|
||||||
next = ++key;
|
next = ++key;
|
||||||
}
|
}
|
||||||
@ -140,8 +139,7 @@ QPDF_Array::unparse()
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto const& item: elements) {
|
for (auto const& item: elements) {
|
||||||
item->resolve();
|
auto og = item->resolved_object()->getObjGen();
|
||||||
auto og = item->getObjGen();
|
|
||||||
result += og.isIndirect() ? og.unparse(' ') + " R " : item->unparse() + " ";
|
result += og.isIndirect() ? og.unparse(' ') + " R " : item->unparse() + " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <qpdf/QPDF_Unresolved.hh>
|
#include <qpdf/QPDF_Unresolved.hh>
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <qpdf/QPDF.hh>
|
||||||
|
#include <qpdf/QPDFObject_private.hh>
|
||||||
|
|
||||||
QPDF_Unresolved::QPDF_Unresolved(QPDF* qpdf, QPDFObjGen const& og) :
|
QPDF_Unresolved::QPDF_Unresolved(QPDF* qpdf, QPDFObjGen const& og) :
|
||||||
QPDFValue(::ot_unresolved, "unresolved", qpdf, og)
|
QPDFValue(::ot_unresolved, "unresolved", qpdf, og)
|
||||||
@ -16,19 +17,23 @@ QPDF_Unresolved::create(QPDF* qpdf, QPDFObjGen const& og)
|
|||||||
std::shared_ptr<QPDFObject>
|
std::shared_ptr<QPDFObject>
|
||||||
QPDF_Unresolved::copy(bool shallow)
|
QPDF_Unresolved::copy(bool shallow)
|
||||||
{
|
{
|
||||||
throw std::logic_error("attempted to shallow copy an unresolved QPDFObjectHandle");
|
return QPDF::Resolver::resolved(qpdf, og)->copy(shallow);
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
QPDF_Unresolved::unparse()
|
QPDF_Unresolved::unparse()
|
||||||
{
|
{
|
||||||
throw std::logic_error("attempted to unparse an unresolved QPDFObjectHandle");
|
return QPDF::Resolver::resolved(qpdf, og)->unparse();
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QPDF_Unresolved::writeJSON(int json_version, JSON::Writer& p)
|
QPDF_Unresolved::writeJSON(int json_version, JSON::Writer& p)
|
||||||
{
|
{
|
||||||
throw std::logic_error("attempted to get JSON from an unresolved QPDFObjectHandle");
|
QPDF::Resolver::resolved(qpdf, og)->writeJSON(json_version, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
QPDF_Unresolved::getStringValue() const
|
||||||
|
{
|
||||||
|
return QPDF::Resolver::resolved(qpdf, og)->getStringValue();
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
// include/qpdf/QPDFObject.hh. See comments there for an explanation.
|
// include/qpdf/QPDFObject.hh. See comments there for an explanation.
|
||||||
|
|
||||||
#include <qpdf/Constants.h>
|
#include <qpdf/Constants.h>
|
||||||
#include <qpdf/DLL.h>
|
|
||||||
#include <qpdf/JSON.hh>
|
#include <qpdf/JSON.hh>
|
||||||
|
#include <qpdf/QPDF.hh>
|
||||||
#include <qpdf/QPDFValue.hh>
|
#include <qpdf/QPDFValue.hh>
|
||||||
#include <qpdf/Types.h>
|
#include <qpdf/Types.h>
|
||||||
|
|
||||||
@ -43,18 +43,26 @@ class QPDFObject
|
|||||||
{
|
{
|
||||||
return value->getStringValue();
|
return value->getStringValue();
|
||||||
}
|
}
|
||||||
|
// Return a unique type code for the resolved object
|
||||||
|
qpdf_object_type_e
|
||||||
|
getResolvedTypeCode() const
|
||||||
|
{
|
||||||
|
auto tc = value->type_code;
|
||||||
|
return tc == ::ot_unresolved
|
||||||
|
? QPDF::Resolver::resolved(value->qpdf, value->og)->value->type_code
|
||||||
|
: tc;
|
||||||
|
}
|
||||||
// Return a unique type code for the object
|
// Return a unique type code for the object
|
||||||
qpdf_object_type_e
|
qpdf_object_type_e
|
||||||
getTypeCode() const
|
getTypeCode() const noexcept
|
||||||
{
|
{
|
||||||
return value->type_code;
|
return value->type_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a string literal that describes the type, useful for debugging and testing
|
// Return a string literal that describes the type, useful for debugging and testing
|
||||||
char const*
|
char const*
|
||||||
getTypeName() const
|
getTypeName() const
|
||||||
{
|
{
|
||||||
return value->type_name;
|
return resolved_object()->value->type_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDF*
|
QPDF*
|
||||||
@ -157,20 +165,23 @@ class QPDFObject
|
|||||||
{
|
{
|
||||||
return value->type_code == ::ot_unresolved;
|
return value->type_code == ::ot_unresolved;
|
||||||
}
|
}
|
||||||
void
|
const QPDFObject*
|
||||||
resolve()
|
resolved_object() const
|
||||||
{
|
{
|
||||||
if (isUnresolved()) {
|
return isUnresolved() ? QPDF::Resolver::resolved(value->qpdf, value->og) : this;
|
||||||
doResolve();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void doResolve();
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T*
|
T*
|
||||||
as()
|
as() const
|
||||||
{
|
{
|
||||||
return dynamic_cast<T*>(value.get());
|
if (auto result = dynamic_cast<T*>(value.get())) {
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return isUnresolved()
|
||||||
|
? dynamic_cast<T*>(QPDF::Resolver::resolved(value->qpdf, value->og)->value.get())
|
||||||
|
: nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -11,6 +11,7 @@ class QPDF_Unresolved: public QPDFValue
|
|||||||
std::shared_ptr<QPDFObject> copy(bool shallow = false) override;
|
std::shared_ptr<QPDFObject> copy(bool shallow = false) override;
|
||||||
std::string unparse() override;
|
std::string unparse() override;
|
||||||
void writeJSON(int json_version, JSON::Writer& p) override;
|
void writeJSON(int json_version, JSON::Writer& p) override;
|
||||||
|
std::string getStringValue() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPDF_Unresolved(QPDF* qpdf, QPDFObjGen const& og);
|
QPDF_Unresolved(QPDF* qpdf, QPDFObjGen const& og);
|
||||||
|
Loading…
Reference in New Issue
Block a user