mirror of
https://github.com/qpdf/qpdf.git
synced 2024-11-10 15:20:54 +00:00
Add private methods QPDFObjectHandle::asArray etc
Centralise casting of QPDFObjects and reduce repeated dereferencing.
This commit is contained in:
parent
2a2eebcaea
commit
114bffa089
@ -43,8 +43,18 @@
|
||||
|
||||
class Pipeline;
|
||||
class QPDF;
|
||||
class QPDF_Dictionary;
|
||||
class QPDF_Array;
|
||||
class QPDF_Bool;
|
||||
class QPDF_Dictionary;
|
||||
class QPDF_InlineImage;
|
||||
class QPDF_Integer;
|
||||
class QPDF_Name;
|
||||
class QPDF_Null;
|
||||
class QPDF_Operator;
|
||||
class QPDF_Real;
|
||||
class QPDF_Reserved;
|
||||
class QPDF_Stream;
|
||||
class QPDF_String;
|
||||
class QPDFTokenizer;
|
||||
class QPDFExc;
|
||||
class Pl_QPDFTokenizer;
|
||||
@ -1480,6 +1490,16 @@ class QPDFObjectHandle
|
||||
};
|
||||
return o.obj;
|
||||
}
|
||||
static QPDF_Array*
|
||||
asArray(QPDFObjectHandle& oh)
|
||||
{
|
||||
return oh.asArray();
|
||||
}
|
||||
static QPDF_Stream*
|
||||
asStream(QPDFObjectHandle& oh)
|
||||
{
|
||||
return oh.asStream();
|
||||
}
|
||||
};
|
||||
friend class ObjAccessor;
|
||||
|
||||
@ -1581,6 +1601,20 @@ class QPDFObjectHandle
|
||||
qpdf_offset_t offset,
|
||||
size_t length);
|
||||
|
||||
QPDF_Array* asArray();
|
||||
QPDF_Bool* asBool();
|
||||
QPDF_Dictionary* asDictionary();
|
||||
QPDF_InlineImage* asInlineImage();
|
||||
QPDF_Integer* asInteger();
|
||||
QPDF_Name* asName();
|
||||
QPDF_Null* asNull();
|
||||
QPDF_Operator* asOperator();
|
||||
QPDF_Real* asReal();
|
||||
QPDF_Reserved* asReserved();
|
||||
QPDF_Stream* asStream();
|
||||
QPDF_Stream* asStreamWithAssert();
|
||||
QPDF_String* asString();
|
||||
|
||||
void typeWarning(char const* expected_type, std::string const& warning);
|
||||
void objectWarning(std::string const& warning);
|
||||
void assertType(char const* type_name, bool istype);
|
||||
@ -1881,7 +1915,7 @@ QPDFObjectHandle::setParsedOffset(qpdf_offset_t offset)
|
||||
{
|
||||
// This is called during parsing on newly created direct objects,
|
||||
// so we can't call dereference() here.
|
||||
if (this->obj.get()) {
|
||||
if (initialized) {
|
||||
this->obj->setParsedOffset(offset);
|
||||
}
|
||||
}
|
||||
|
@ -1420,8 +1420,7 @@ QPDF::fixDanglingReferences(bool force)
|
||||
to_check.push_back(iter.second);
|
||||
}
|
||||
} else if (obj.isArray()) {
|
||||
QPDF_Array* arr = dynamic_cast<QPDF_Array*>(
|
||||
QPDFObjectHandle::ObjAccessor::getObject(obj).get());
|
||||
auto arr = QPDFObjectHandle::ObjAccessor::asArray(obj);
|
||||
arr->addExplicitElementsToList(to_check);
|
||||
}
|
||||
for (auto sub: to_check) {
|
||||
@ -2468,12 +2467,12 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
|
||||
QPDFObjGen local_og(result.getObjGen());
|
||||
// Copy information from the foreign stream so we can pipe its
|
||||
// data later without keeping the original QPDF object around.
|
||||
|
||||
QPDF* foreign_stream_qpdf = foreign.getOwningQPDF(
|
||||
false, "unable to retrieve owning qpdf from foreign stream");
|
||||
|
||||
QPDF_Stream* stream = dynamic_cast<QPDF_Stream*>(
|
||||
QPDFObjectHandle::ObjAccessor::getObject(foreign).get());
|
||||
if (!stream) {
|
||||
auto stream = QPDFObjectHandle::ObjAccessor::asStream(foreign);
|
||||
if (stream == nullptr) {
|
||||
throw std::logic_error("unable to retrieve underlying"
|
||||
" stream object from foreign stream");
|
||||
}
|
||||
|
@ -277,24 +277,91 @@ QPDFObjectHandle::getTypeName()
|
||||
return dereference() ? this->obj->getTypeName() : "uninitialized";
|
||||
}
|
||||
|
||||
namespace
|
||||
QPDF_Array*
|
||||
QPDFObjectHandle::asArray()
|
||||
{
|
||||
template <class T>
|
||||
class QPDFObjectTypeAccessor
|
||||
{
|
||||
public:
|
||||
static bool
|
||||
check(std::shared_ptr<QPDFObject> const& o)
|
||||
{
|
||||
return (o && dynamic_cast<T const*>(o.get()));
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
return isArray() ? dynamic_cast<QPDF_Array*>(obj.get()) : nullptr;
|
||||
}
|
||||
|
||||
QPDF_Bool*
|
||||
QPDFObjectHandle::asBool()
|
||||
{
|
||||
return isBool() ? dynamic_cast<QPDF_Bool*>(obj.get()) : nullptr;
|
||||
}
|
||||
|
||||
QPDF_Dictionary*
|
||||
QPDFObjectHandle::asDictionary()
|
||||
{
|
||||
return isDictionary() ? dynamic_cast<QPDF_Dictionary*>(obj.get()) : nullptr;
|
||||
}
|
||||
|
||||
QPDF_InlineImage*
|
||||
QPDFObjectHandle::asInlineImage()
|
||||
{
|
||||
return isInlineImage() ? dynamic_cast<QPDF_InlineImage*>(obj.get())
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
QPDF_Integer*
|
||||
QPDFObjectHandle::asInteger()
|
||||
{
|
||||
return isInteger() ? dynamic_cast<QPDF_Integer*>(obj.get()) : nullptr;
|
||||
}
|
||||
|
||||
QPDF_Name*
|
||||
QPDFObjectHandle::asName()
|
||||
{
|
||||
return isName() ? dynamic_cast<QPDF_Name*>(obj.get()) : nullptr;
|
||||
}
|
||||
|
||||
QPDF_Null*
|
||||
QPDFObjectHandle::asNull()
|
||||
{
|
||||
return isNull() ? dynamic_cast<QPDF_Null*>(obj.get()) : nullptr;
|
||||
}
|
||||
|
||||
QPDF_Operator*
|
||||
QPDFObjectHandle::asOperator()
|
||||
{
|
||||
return isOperator() ? dynamic_cast<QPDF_Operator*>(obj.get()) : nullptr;
|
||||
}
|
||||
|
||||
QPDF_Real*
|
||||
QPDFObjectHandle::asReal()
|
||||
{
|
||||
return isReal() ? dynamic_cast<QPDF_Real*>(obj.get()) : nullptr;
|
||||
}
|
||||
|
||||
QPDF_Reserved*
|
||||
QPDFObjectHandle::asReserved()
|
||||
{
|
||||
return isReserved() ? dynamic_cast<QPDF_Reserved*>(obj.get()) : nullptr;
|
||||
}
|
||||
|
||||
QPDF_Stream*
|
||||
QPDFObjectHandle::asStream()
|
||||
{
|
||||
return isStream() ? dynamic_cast<QPDF_Stream*>(obj.get()) : nullptr;
|
||||
}
|
||||
|
||||
QPDF_Stream*
|
||||
QPDFObjectHandle::asStreamWithAssert()
|
||||
{
|
||||
auto stream = asStream();
|
||||
assertType("stream", stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
QPDF_String*
|
||||
QPDFObjectHandle::asString()
|
||||
{
|
||||
return isString() ? dynamic_cast<QPDF_String*>(obj.get()) : nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::isBool()
|
||||
{
|
||||
return dereference() && QPDFObjectTypeAccessor<QPDF_Bool>::check(obj);
|
||||
return dereference() && (obj->getTypeCode() == QPDFObject::ot_boolean);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -303,26 +370,26 @@ QPDFObjectHandle::isDirectNull() const
|
||||
// Don't call dereference() -- this is a const method, and we know
|
||||
// objid == 0, so there's nothing to resolve.
|
||||
return (
|
||||
this->initialized && (getObjectID() == 0) &&
|
||||
QPDFObjectTypeAccessor<QPDF_Null>::check(obj));
|
||||
initialized && (getObjectID() == 0) &&
|
||||
(obj->getTypeCode() == QPDFObject::ot_null));
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::isNull()
|
||||
{
|
||||
return dereference() && QPDFObjectTypeAccessor<QPDF_Null>::check(obj);
|
||||
return dereference() && (obj->getTypeCode() == QPDFObject::ot_null);
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::isInteger()
|
||||
{
|
||||
return dereference() && QPDFObjectTypeAccessor<QPDF_Integer>::check(obj);
|
||||
return dereference() && (obj->getTypeCode() == QPDFObject::ot_integer);
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::isReal()
|
||||
{
|
||||
return dereference() && QPDFObjectTypeAccessor<QPDF_Real>::check(obj);
|
||||
return dereference() && (obj->getTypeCode() == QPDFObject::ot_real);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -359,51 +426,49 @@ QPDFObjectHandle::getValueAsNumber(double& value)
|
||||
bool
|
||||
QPDFObjectHandle::isName()
|
||||
{
|
||||
return dereference() && QPDFObjectTypeAccessor<QPDF_Name>::check(obj);
|
||||
return dereference() && (obj->getTypeCode() == QPDFObject::ot_name);
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::isString()
|
||||
{
|
||||
return dereference() && QPDFObjectTypeAccessor<QPDF_String>::check(obj);
|
||||
return dereference() && (obj->getTypeCode() == QPDFObject::ot_string);
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::isOperator()
|
||||
{
|
||||
return dereference() && QPDFObjectTypeAccessor<QPDF_Operator>::check(obj);
|
||||
return dereference() && (obj->getTypeCode() == QPDFObject::ot_operator);
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::isInlineImage()
|
||||
{
|
||||
return dereference() &&
|
||||
QPDFObjectTypeAccessor<QPDF_InlineImage>::check(obj);
|
||||
return dereference() && (obj->getTypeCode() == QPDFObject::ot_inlineimage);
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::isArray()
|
||||
{
|
||||
return dereference() && QPDFObjectTypeAccessor<QPDF_Array>::check(obj);
|
||||
return dereference() && (obj->getTypeCode() == QPDFObject::ot_array);
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::isDictionary()
|
||||
{
|
||||
return dereference() && QPDFObjectTypeAccessor<QPDF_Dictionary>::check(obj);
|
||||
return dereference() && (obj->getTypeCode() == QPDFObject::ot_dictionary);
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::isStream()
|
||||
{
|
||||
return dereference() && QPDFObjectTypeAccessor<QPDF_Stream>::check(obj);
|
||||
return dereference() && (obj->getTypeCode() == QPDFObject::ot_stream);
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::isReserved()
|
||||
{
|
||||
// dereference will clear reserved if this has been replaced
|
||||
return dereference() && QPDFObjectTypeAccessor<QPDF_Reserved>::check(obj);
|
||||
return dereference() && (obj->getTypeCode() == QPDFObject::ot_reserved);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -441,8 +506,9 @@ QPDFObjectHandle::isStreamOfType(
|
||||
bool
|
||||
QPDFObjectHandle::getBoolValue()
|
||||
{
|
||||
if (isBool()) {
|
||||
return dynamic_cast<QPDF_Bool*>(obj.get())->getVal();
|
||||
auto boolean = asBool();
|
||||
if (boolean) {
|
||||
return boolean->getVal();
|
||||
} else {
|
||||
typeWarning("boolean", "returning false");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle boolean returning false");
|
||||
@ -453,10 +519,11 @@ QPDFObjectHandle::getBoolValue()
|
||||
bool
|
||||
QPDFObjectHandle::getValueAsBool(bool& value)
|
||||
{
|
||||
if (!isBool()) {
|
||||
auto boolean = asBool();
|
||||
if (boolean == nullptr) {
|
||||
return false;
|
||||
}
|
||||
value = dynamic_cast<QPDF_Bool*>(obj.get())->getVal();
|
||||
value = boolean->getVal();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -465,8 +532,9 @@ QPDFObjectHandle::getValueAsBool(bool& value)
|
||||
long long
|
||||
QPDFObjectHandle::getIntValue()
|
||||
{
|
||||
if (isInteger()) {
|
||||
return dynamic_cast<QPDF_Integer*>(obj.get())->getVal();
|
||||
auto integer = asInteger();
|
||||
if (integer) {
|
||||
return integer->getVal();
|
||||
} else {
|
||||
typeWarning("integer", "returning 0");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle integer returning 0");
|
||||
@ -477,10 +545,11 @@ QPDFObjectHandle::getIntValue()
|
||||
bool
|
||||
QPDFObjectHandle::getValueAsInt(long long& value)
|
||||
{
|
||||
if (!isInteger()) {
|
||||
auto integer = asInteger();
|
||||
if (integer == nullptr) {
|
||||
return false;
|
||||
}
|
||||
value = dynamic_cast<QPDF_Integer*>(obj.get())->getVal();
|
||||
value = integer->getVal();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -576,8 +645,9 @@ QPDFObjectHandle::getValueAsUInt(unsigned int& value)
|
||||
std::string
|
||||
QPDFObjectHandle::getRealValue()
|
||||
{
|
||||
if (isReal()) {
|
||||
return dynamic_cast<QPDF_Real*>(obj.get())->getVal();
|
||||
auto real = asReal();
|
||||
if (real) {
|
||||
return real->getVal();
|
||||
} else {
|
||||
typeWarning("real", "returning 0.0");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle real returning 0.0");
|
||||
@ -588,10 +658,11 @@ QPDFObjectHandle::getRealValue()
|
||||
bool
|
||||
QPDFObjectHandle::getValueAsReal(std::string& value)
|
||||
{
|
||||
if (!isReal()) {
|
||||
auto real = asReal();
|
||||
if (real == nullptr) {
|
||||
return false;
|
||||
}
|
||||
value = dynamic_cast<QPDF_Real*>(obj.get())->getVal();
|
||||
value = real->getVal();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -600,8 +671,9 @@ QPDFObjectHandle::getValueAsReal(std::string& value)
|
||||
std::string
|
||||
QPDFObjectHandle::getName()
|
||||
{
|
||||
if (isName()) {
|
||||
return dynamic_cast<QPDF_Name*>(obj.get())->getName();
|
||||
auto name = asName();
|
||||
if (name) {
|
||||
return name->getName();
|
||||
} else {
|
||||
typeWarning("name", "returning dummy name");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle name returning dummy name");
|
||||
@ -612,10 +684,11 @@ QPDFObjectHandle::getName()
|
||||
bool
|
||||
QPDFObjectHandle::getValueAsName(std::string& value)
|
||||
{
|
||||
if (!isName()) {
|
||||
auto name = asName();
|
||||
if (name == nullptr) {
|
||||
return false;
|
||||
}
|
||||
value = dynamic_cast<QPDF_Name*>(obj.get())->getName();
|
||||
value = name->getName();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -624,8 +697,9 @@ QPDFObjectHandle::getValueAsName(std::string& value)
|
||||
std::string
|
||||
QPDFObjectHandle::getStringValue()
|
||||
{
|
||||
if (isString()) {
|
||||
return dynamic_cast<QPDF_String*>(obj.get())->getVal();
|
||||
auto str = asString();
|
||||
if (str) {
|
||||
return str->getVal();
|
||||
} else {
|
||||
typeWarning("string", "returning empty string");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle string returning empty string");
|
||||
@ -636,18 +710,20 @@ QPDFObjectHandle::getStringValue()
|
||||
bool
|
||||
QPDFObjectHandle::getValueAsString(std::string& value)
|
||||
{
|
||||
if (!isString()) {
|
||||
auto str = asString();
|
||||
if (str == nullptr) {
|
||||
return false;
|
||||
}
|
||||
value = dynamic_cast<QPDF_String*>(obj.get())->getVal();
|
||||
value = str->getVal();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string
|
||||
QPDFObjectHandle::getUTF8Value()
|
||||
{
|
||||
if (isString()) {
|
||||
return dynamic_cast<QPDF_String*>(obj.get())->getUTF8Val();
|
||||
auto str = asString();
|
||||
if (str) {
|
||||
return str->getUTF8Val();
|
||||
} else {
|
||||
typeWarning("string", "returning empty string");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle string returning empty utf8");
|
||||
@ -658,10 +734,11 @@ QPDFObjectHandle::getUTF8Value()
|
||||
bool
|
||||
QPDFObjectHandle::getValueAsUTF8(std::string& value)
|
||||
{
|
||||
if (!isString()) {
|
||||
auto str = asString();
|
||||
if (str == nullptr) {
|
||||
return false;
|
||||
}
|
||||
value = dynamic_cast<QPDF_String*>(obj.get())->getUTF8Val();
|
||||
value = str->getUTF8Val();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -670,8 +747,9 @@ QPDFObjectHandle::getValueAsUTF8(std::string& value)
|
||||
std::string
|
||||
QPDFObjectHandle::getOperatorValue()
|
||||
{
|
||||
if (isOperator()) {
|
||||
return dynamic_cast<QPDF_Operator*>(obj.get())->getVal();
|
||||
auto op = asOperator();
|
||||
if (op) {
|
||||
return op->getVal();
|
||||
} else {
|
||||
typeWarning("operator", "returning fake value");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle operator returning fake value");
|
||||
@ -682,18 +760,20 @@ QPDFObjectHandle::getOperatorValue()
|
||||
bool
|
||||
QPDFObjectHandle::getValueAsOperator(std::string& value)
|
||||
{
|
||||
if (!isOperator()) {
|
||||
auto op = asOperator();
|
||||
if (op == nullptr) {
|
||||
return false;
|
||||
}
|
||||
value = dynamic_cast<QPDF_Operator*>(obj.get())->getVal();
|
||||
value = op->getVal();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string
|
||||
QPDFObjectHandle::getInlineImageValue()
|
||||
{
|
||||
if (isInlineImage()) {
|
||||
return dynamic_cast<QPDF_InlineImage*>(obj.get())->getVal();
|
||||
auto image = asInlineImage();
|
||||
if (image) {
|
||||
return image->getVal();
|
||||
} else {
|
||||
typeWarning("inlineimage", "returning empty data");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle inlineimage returning empty data");
|
||||
@ -704,10 +784,11 @@ QPDFObjectHandle::getInlineImageValue()
|
||||
bool
|
||||
QPDFObjectHandle::getValueAsInlineImage(std::string& value)
|
||||
{
|
||||
if (!isInlineImage()) {
|
||||
auto image = asInlineImage();
|
||||
if (image == nullptr) {
|
||||
return false;
|
||||
}
|
||||
value = dynamic_cast<QPDF_InlineImage*>(obj.get())->getVal();
|
||||
value = image->getVal();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -722,8 +803,9 @@ QPDFObjectHandle::aitems()
|
||||
int
|
||||
QPDFObjectHandle::getArrayNItems()
|
||||
{
|
||||
if (isArray()) {
|
||||
return dynamic_cast<QPDF_Array*>(obj.get())->getNItems();
|
||||
auto array = asArray();
|
||||
if (array) {
|
||||
return array->getNItems();
|
||||
} else {
|
||||
typeWarning("array", "treating as empty");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle array treating as empty");
|
||||
@ -735,11 +817,12 @@ QPDFObjectHandle
|
||||
QPDFObjectHandle::getArrayItem(int n)
|
||||
{
|
||||
QPDFObjectHandle result;
|
||||
if (isArray() && (n < getArrayNItems()) && (n >= 0)) {
|
||||
result = dynamic_cast<QPDF_Array*>(obj.get())->getItem(n);
|
||||
auto array = asArray();
|
||||
if (array && (n < array->getNItems()) && (n >= 0)) {
|
||||
result = array->getItem(n);
|
||||
} else {
|
||||
result = newNull();
|
||||
if (isArray()) {
|
||||
if (array) {
|
||||
objectWarning("returning null for out of bounds array access");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle array bounds");
|
||||
} else {
|
||||
@ -748,7 +831,7 @@ QPDFObjectHandle::getArrayItem(int n)
|
||||
}
|
||||
QPDF* context = nullptr;
|
||||
std::string description;
|
||||
if (this->obj->getDescription(context, description)) {
|
||||
if (obj->getDescription(context, description)) {
|
||||
result.setObjectDescription(
|
||||
context,
|
||||
description + " -> null returned from invalid array access");
|
||||
@ -760,14 +843,12 @@ QPDFObjectHandle::getArrayItem(int n)
|
||||
bool
|
||||
QPDFObjectHandle::isRectangle()
|
||||
{
|
||||
if (!isArray()) {
|
||||
return false;
|
||||
}
|
||||
if (getArrayNItems() != 4) {
|
||||
auto array = asArray();
|
||||
if ((array == nullptr) || (array->getNItems() != 4)) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!getArrayItem(i).isNumber()) {
|
||||
if (!array->getItem(i).isNumber()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -777,14 +858,12 @@ QPDFObjectHandle::isRectangle()
|
||||
bool
|
||||
QPDFObjectHandle::isMatrix()
|
||||
{
|
||||
if (!isArray()) {
|
||||
return false;
|
||||
}
|
||||
if (getArrayNItems() != 6) {
|
||||
auto array = asArray();
|
||||
if ((array == nullptr) || (array->getNItems() != 6)) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
if (!getArrayItem(i).isNumber()) {
|
||||
if (!array->getItem(i).isNumber()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -796,13 +875,14 @@ QPDFObjectHandle::getArrayAsRectangle()
|
||||
{
|
||||
Rectangle result;
|
||||
if (isRectangle()) {
|
||||
auto array = asArray();
|
||||
// Rectangle coordinates are always supposed to be llx, lly,
|
||||
// urx, ury, but files have been found in the wild where
|
||||
// llx > urx or lly > ury.
|
||||
double i0 = getArrayItem(0).getNumericValue();
|
||||
double i1 = getArrayItem(1).getNumericValue();
|
||||
double i2 = getArrayItem(2).getNumericValue();
|
||||
double i3 = getArrayItem(3).getNumericValue();
|
||||
double i0 = array->getItem(0).getNumericValue();
|
||||
double i1 = array->getItem(1).getNumericValue();
|
||||
double i2 = array->getItem(2).getNumericValue();
|
||||
double i3 = array->getItem(3).getNumericValue();
|
||||
result = Rectangle(
|
||||
std::min(i0, i2),
|
||||
std::min(i1, i3),
|
||||
@ -817,13 +897,14 @@ QPDFObjectHandle::getArrayAsMatrix()
|
||||
{
|
||||
Matrix result;
|
||||
if (isMatrix()) {
|
||||
auto array = asArray();
|
||||
result = Matrix(
|
||||
getArrayItem(0).getNumericValue(),
|
||||
getArrayItem(1).getNumericValue(),
|
||||
getArrayItem(2).getNumericValue(),
|
||||
getArrayItem(3).getNumericValue(),
|
||||
getArrayItem(4).getNumericValue(),
|
||||
getArrayItem(5).getNumericValue());
|
||||
array->getItem(0).getNumericValue(),
|
||||
array->getItem(1).getNumericValue(),
|
||||
array->getItem(2).getNumericValue(),
|
||||
array->getItem(3).getNumericValue(),
|
||||
array->getItem(4).getNumericValue(),
|
||||
array->getItem(5).getNumericValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -832,8 +913,9 @@ std::vector<QPDFObjectHandle>
|
||||
QPDFObjectHandle::getArrayAsVector()
|
||||
{
|
||||
std::vector<QPDFObjectHandle> result;
|
||||
if (isArray()) {
|
||||
dynamic_cast<QPDF_Array*>(obj.get())->getAsVector(result);
|
||||
auto array = asArray();
|
||||
if (array) {
|
||||
array->getAsVector(result);
|
||||
} else {
|
||||
typeWarning("array", "treating as empty");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle array treating as empty vector");
|
||||
@ -846,9 +928,10 @@ QPDFObjectHandle::getArrayAsVector()
|
||||
void
|
||||
QPDFObjectHandle::setArrayItem(int n, QPDFObjectHandle const& item)
|
||||
{
|
||||
if (isArray()) {
|
||||
auto array = asArray();
|
||||
if (array) {
|
||||
checkOwnership(item);
|
||||
dynamic_cast<QPDF_Array*>(obj.get())->setItem(n, item);
|
||||
array->setItem(n, item);
|
||||
} else {
|
||||
typeWarning("array", "ignoring attempt to set item");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle array ignoring set item");
|
||||
@ -858,11 +941,12 @@ QPDFObjectHandle::setArrayItem(int n, QPDFObjectHandle const& item)
|
||||
void
|
||||
QPDFObjectHandle::setArrayFromVector(std::vector<QPDFObjectHandle> const& items)
|
||||
{
|
||||
if (isArray()) {
|
||||
auto array = asArray();
|
||||
if (array) {
|
||||
for (auto const& item: items) {
|
||||
checkOwnership(item);
|
||||
}
|
||||
dynamic_cast<QPDF_Array*>(obj.get())->setFromVector(items);
|
||||
array->setFromVector(items);
|
||||
} else {
|
||||
typeWarning("array", "ignoring attempt to replace items");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle array ignoring replace items");
|
||||
@ -872,8 +956,9 @@ QPDFObjectHandle::setArrayFromVector(std::vector<QPDFObjectHandle> const& items)
|
||||
void
|
||||
QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item)
|
||||
{
|
||||
if (isArray()) {
|
||||
dynamic_cast<QPDF_Array*>(obj.get())->insertItem(at, item);
|
||||
auto array = asArray();
|
||||
if (array) {
|
||||
array->insertItem(at, item);
|
||||
} else {
|
||||
typeWarning("array", "ignoring attempt to insert item");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle array ignoring insert item");
|
||||
@ -890,9 +975,10 @@ QPDFObjectHandle::insertItemAndGetNew(int at, QPDFObjectHandle const& item)
|
||||
void
|
||||
QPDFObjectHandle::appendItem(QPDFObjectHandle const& item)
|
||||
{
|
||||
if (isArray()) {
|
||||
auto array = asArray();
|
||||
if (array) {
|
||||
checkOwnership(item);
|
||||
dynamic_cast<QPDF_Array*>(obj.get())->appendItem(item);
|
||||
array->appendItem(item);
|
||||
} else {
|
||||
typeWarning("array", "ignoring attempt to append item");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle array ignoring append item");
|
||||
@ -909,10 +995,11 @@ QPDFObjectHandle::appendItemAndGetNew(QPDFObjectHandle const& item)
|
||||
void
|
||||
QPDFObjectHandle::eraseItem(int at)
|
||||
{
|
||||
if (isArray() && (at < getArrayNItems()) && (at >= 0)) {
|
||||
dynamic_cast<QPDF_Array*>(obj.get())->eraseItem(at);
|
||||
auto array = asArray();
|
||||
if (array && (at < array->getNItems()) && (at >= 0)) {
|
||||
array->eraseItem(at);
|
||||
} else {
|
||||
if (isArray()) {
|
||||
if (array) {
|
||||
objectWarning("ignoring attempt to erase out of bounds array item");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle erase array bounds");
|
||||
} else {
|
||||
@ -926,8 +1013,9 @@ QPDFObjectHandle
|
||||
QPDFObjectHandle::eraseItemAndGetOld(int at)
|
||||
{
|
||||
auto result = QPDFObjectHandle::newNull();
|
||||
if (isArray() && (at < getArrayNItems()) && (at >= 0)) {
|
||||
result = getArrayItem(at);
|
||||
auto array = asArray();
|
||||
if (array && (at < array->getNItems()) && (at >= 0)) {
|
||||
result = array->getItem(at);
|
||||
}
|
||||
eraseItem(at);
|
||||
return result;
|
||||
@ -944,8 +1032,9 @@ QPDFObjectHandle::ditems()
|
||||
bool
|
||||
QPDFObjectHandle::hasKey(std::string const& key)
|
||||
{
|
||||
if (isDictionary()) {
|
||||
return dynamic_cast<QPDF_Dictionary*>(obj.get())->hasKey(key);
|
||||
auto dict = asDictionary();
|
||||
if (dict) {
|
||||
return dict->hasKey(key);
|
||||
} else {
|
||||
typeWarning(
|
||||
"dictionary", "returning false for a key containment request");
|
||||
@ -958,15 +1047,16 @@ QPDFObjectHandle
|
||||
QPDFObjectHandle::getKey(std::string const& key)
|
||||
{
|
||||
QPDFObjectHandle result;
|
||||
if (isDictionary()) {
|
||||
result = dynamic_cast<QPDF_Dictionary*>(obj.get())->getKey(key);
|
||||
auto dict = asDictionary();
|
||||
if (dict) {
|
||||
result = dict->getKey(key);
|
||||
} else {
|
||||
typeWarning("dictionary", "returning null for attempted key retrieval");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle dictionary null for getKey");
|
||||
result = newNull();
|
||||
QPDF* qpdf = nullptr;
|
||||
std::string description;
|
||||
if (this->obj->getDescription(qpdf, description)) {
|
||||
if (obj->getDescription(qpdf, description)) {
|
||||
result.setObjectDescription(
|
||||
qpdf,
|
||||
(description + " -> null returned from getting key " + key +
|
||||
@ -986,8 +1076,9 @@ std::set<std::string>
|
||||
QPDFObjectHandle::getKeys()
|
||||
{
|
||||
std::set<std::string> result;
|
||||
if (isDictionary()) {
|
||||
result = dynamic_cast<QPDF_Dictionary*>(obj.get())->getKeys();
|
||||
auto dict = asDictionary();
|
||||
if (dict) {
|
||||
result = dict->getKeys();
|
||||
} else {
|
||||
typeWarning("dictionary", "treating as empty");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle dictionary empty set for getKeys");
|
||||
@ -999,8 +1090,9 @@ std::map<std::string, QPDFObjectHandle>
|
||||
QPDFObjectHandle::getDictAsMap()
|
||||
{
|
||||
std::map<std::string, QPDFObjectHandle> result;
|
||||
if (isDictionary()) {
|
||||
result = dynamic_cast<QPDF_Dictionary*>(obj.get())->getAsMap();
|
||||
auto dict = asDictionary();
|
||||
if (dict) {
|
||||
result = dict->getAsMap();
|
||||
} else {
|
||||
typeWarning("dictionary", "treating as empty");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle dictionary empty map for asMap");
|
||||
@ -1191,9 +1283,10 @@ void
|
||||
QPDFObjectHandle::replaceKey(
|
||||
std::string const& key, QPDFObjectHandle const& value)
|
||||
{
|
||||
if (isDictionary()) {
|
||||
auto dict = asDictionary();
|
||||
if (dict) {
|
||||
checkOwnership(value);
|
||||
dynamic_cast<QPDF_Dictionary*>(obj.get())->replaceKey(key, value);
|
||||
dict->replaceKey(key, value);
|
||||
} else {
|
||||
typeWarning("dictionary", "ignoring key replacement request");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle dictionary ignoring replaceKey");
|
||||
@ -1220,8 +1313,9 @@ QPDFObjectHandle::replaceKeyAndGetOld(
|
||||
void
|
||||
QPDFObjectHandle::removeKey(std::string const& key)
|
||||
{
|
||||
if (isDictionary()) {
|
||||
dynamic_cast<QPDF_Dictionary*>(obj.get())->removeKey(key);
|
||||
auto dict = asDictionary();
|
||||
if (dict) {
|
||||
dict->removeKey(key);
|
||||
} else {
|
||||
typeWarning("dictionary", "ignoring key removal request");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle dictionary ignoring removeKey");
|
||||
@ -1232,8 +1326,9 @@ QPDFObjectHandle
|
||||
QPDFObjectHandle::removeKeyAndGetOld(std::string const& key)
|
||||
{
|
||||
auto result = QPDFObjectHandle::newNull();
|
||||
if (isDictionary()) {
|
||||
result = getKey(key);
|
||||
auto dict = asDictionary();
|
||||
if (dict) {
|
||||
result = dict->getKey(key);
|
||||
}
|
||||
removeKey(key);
|
||||
return result;
|
||||
@ -1250,50 +1345,43 @@ QPDFObjectHandle::replaceOrRemoveKey(
|
||||
QPDFObjectHandle
|
||||
QPDFObjectHandle::getDict()
|
||||
{
|
||||
assertStream();
|
||||
return dynamic_cast<QPDF_Stream*>(obj.get())->getDict();
|
||||
return asStreamWithAssert()->getDict();
|
||||
}
|
||||
|
||||
void
|
||||
QPDFObjectHandle::setFilterOnWrite(bool val)
|
||||
{
|
||||
assertStream();
|
||||
dynamic_cast<QPDF_Stream*>(obj.get())->setFilterOnWrite(val);
|
||||
asStreamWithAssert()->setFilterOnWrite(val);
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::getFilterOnWrite()
|
||||
{
|
||||
assertStream();
|
||||
return dynamic_cast<QPDF_Stream*>(obj.get())->getFilterOnWrite();
|
||||
return asStreamWithAssert()->getFilterOnWrite();
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::isDataModified()
|
||||
{
|
||||
assertStream();
|
||||
return dynamic_cast<QPDF_Stream*>(obj.get())->isDataModified();
|
||||
return asStreamWithAssert()->isDataModified();
|
||||
}
|
||||
|
||||
void
|
||||
QPDFObjectHandle::replaceDict(QPDFObjectHandle const& new_dict)
|
||||
{
|
||||
assertStream();
|
||||
dynamic_cast<QPDF_Stream*>(obj.get())->replaceDict(new_dict);
|
||||
asStreamWithAssert()->replaceDict(new_dict);
|
||||
}
|
||||
|
||||
std::shared_ptr<Buffer>
|
||||
QPDFObjectHandle::getStreamData(qpdf_stream_decode_level_e level)
|
||||
{
|
||||
assertStream();
|
||||
return dynamic_cast<QPDF_Stream*>(obj.get())->getStreamData(level);
|
||||
return asStreamWithAssert()->getStreamData(level);
|
||||
}
|
||||
|
||||
std::shared_ptr<Buffer>
|
||||
QPDFObjectHandle::getRawStreamData()
|
||||
{
|
||||
assertStream();
|
||||
return dynamic_cast<QPDF_Stream*>(obj.get())->getRawStreamData();
|
||||
return asStreamWithAssert()->getRawStreamData();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1305,8 +1393,7 @@ QPDFObjectHandle::pipeStreamData(
|
||||
bool suppress_warnings,
|
||||
bool will_retry)
|
||||
{
|
||||
assertStream();
|
||||
return dynamic_cast<QPDF_Stream*>(obj.get())->pipeStreamData(
|
||||
return asStreamWithAssert()->pipeStreamData(
|
||||
p,
|
||||
filtering_attempted,
|
||||
encode_flags,
|
||||
@ -1323,9 +1410,8 @@ QPDFObjectHandle::pipeStreamData(
|
||||
bool suppress_warnings,
|
||||
bool will_retry)
|
||||
{
|
||||
assertStream();
|
||||
bool filtering_attempted;
|
||||
dynamic_cast<QPDF_Stream*>(obj.get())->pipeStreamData(
|
||||
asStreamWithAssert()->pipeStreamData(
|
||||
p,
|
||||
&filtering_attempted,
|
||||
encode_flags,
|
||||
@ -1359,9 +1445,7 @@ QPDFObjectHandle::replaceStreamData(
|
||||
QPDFObjectHandle const& filter,
|
||||
QPDFObjectHandle const& decode_parms)
|
||||
{
|
||||
assertStream();
|
||||
dynamic_cast<QPDF_Stream*>(obj.get())->replaceStreamData(
|
||||
data, filter, decode_parms);
|
||||
asStreamWithAssert()->replaceStreamData(data, filter, decode_parms);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1370,14 +1454,12 @@ QPDFObjectHandle::replaceStreamData(
|
||||
QPDFObjectHandle const& filter,
|
||||
QPDFObjectHandle const& decode_parms)
|
||||
{
|
||||
assertStream();
|
||||
auto b = std::make_shared<Buffer>(data.length());
|
||||
unsigned char* bp = b->getBuffer();
|
||||
if (bp) {
|
||||
memcpy(bp, data.c_str(), data.length());
|
||||
}
|
||||
dynamic_cast<QPDF_Stream*>(obj.get())->replaceStreamData(
|
||||
b, filter, decode_parms);
|
||||
asStreamWithAssert()->replaceStreamData(b, filter, decode_parms);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1386,9 +1468,7 @@ QPDFObjectHandle::replaceStreamData(
|
||||
QPDFObjectHandle const& filter,
|
||||
QPDFObjectHandle const& decode_parms)
|
||||
{
|
||||
assertStream();
|
||||
dynamic_cast<QPDF_Stream*>(obj.get())->replaceStreamData(
|
||||
provider, filter, decode_parms);
|
||||
asStreamWithAssert()->replaceStreamData(provider, filter, decode_parms);
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -1437,11 +1517,9 @@ QPDFObjectHandle::replaceStreamData(
|
||||
QPDFObjectHandle const& filter,
|
||||
QPDFObjectHandle const& decode_parms)
|
||||
{
|
||||
assertStream();
|
||||
auto sdp =
|
||||
std::shared_ptr<StreamDataProvider>(new FunctionProvider(provider));
|
||||
dynamic_cast<QPDF_Stream*>(obj.get())->replaceStreamData(
|
||||
sdp, filter, decode_parms);
|
||||
asStreamWithAssert()->replaceStreamData(sdp, filter, decode_parms);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1450,11 +1528,9 @@ QPDFObjectHandle::replaceStreamData(
|
||||
QPDFObjectHandle const& filter,
|
||||
QPDFObjectHandle const& decode_parms)
|
||||
{
|
||||
assertStream();
|
||||
auto sdp =
|
||||
std::shared_ptr<StreamDataProvider>(new FunctionProvider(provider));
|
||||
dynamic_cast<QPDF_Stream*>(obj.get())->replaceStreamData(
|
||||
sdp, filter, decode_parms);
|
||||
asStreamWithAssert()->replaceStreamData(sdp, filter, decode_parms);
|
||||
}
|
||||
|
||||
std::map<std::string, QPDFObjectHandle>
|
||||
@ -1469,10 +1545,11 @@ QPDFObjectHandle::arrayOrStreamToStreamArray(
|
||||
{
|
||||
all_description = description;
|
||||
std::vector<QPDFObjectHandle> result;
|
||||
if (isArray()) {
|
||||
int n_items = getArrayNItems();
|
||||
auto array = asArray();
|
||||
if (array) {
|
||||
int n_items = array->getNItems();
|
||||
for (int i = 0; i < n_items; ++i) {
|
||||
QPDFObjectHandle item = getArrayItem(i);
|
||||
QPDFObjectHandle item = array->getItem(i);
|
||||
if (item.isStream()) {
|
||||
result.push_back(item);
|
||||
} else {
|
||||
@ -1649,8 +1726,9 @@ QPDFObjectHandle::unparseResolved()
|
||||
std::string
|
||||
QPDFObjectHandle::unparseBinary()
|
||||
{
|
||||
if (this->isString()) {
|
||||
return dynamic_cast<QPDF_String*>(this->obj.get())->unparse(true);
|
||||
auto str = asString();
|
||||
if (str) {
|
||||
return str->unparse(true);
|
||||
} else {
|
||||
return unparse();
|
||||
}
|
||||
@ -1666,7 +1744,7 @@ QPDFObjectHandle::getJSON(bool dereference_indirect)
|
||||
JSON
|
||||
QPDFObjectHandle::getJSON(int json_version, bool dereference_indirect)
|
||||
{
|
||||
if ((!dereference_indirect) && this->isIndirect()) {
|
||||
if ((!dereference_indirect) && isIndirect()) {
|
||||
return JSON::makeString(unparse());
|
||||
} else if (!dereference()) {
|
||||
throw std::logic_error(
|
||||
@ -1675,7 +1753,7 @@ QPDFObjectHandle::getJSON(int json_version, bool dereference_indirect)
|
||||
throw std::logic_error(
|
||||
"QPDFObjectHandle: attempting to unparse a reserved object");
|
||||
} else {
|
||||
return this->obj->getJSON(json_version);
|
||||
return obj->getJSON(json_version);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1687,8 +1765,7 @@ QPDFObjectHandle::getStreamJSON(
|
||||
Pipeline* p,
|
||||
std::string const& data_filename)
|
||||
{
|
||||
assertStream();
|
||||
return dynamic_cast<QPDF_Stream*>(obj.get())->getStreamJSON(
|
||||
return asStreamWithAssert()->getStreamJSON(
|
||||
json_version, json_data, decode_level, p, data_filename);
|
||||
}
|
||||
|
||||
@ -1908,8 +1985,7 @@ QPDFObjectHandle::addContentTokenFilter(std::shared_ptr<TokenFilter> filter)
|
||||
void
|
||||
QPDFObjectHandle::addTokenFilter(std::shared_ptr<TokenFilter> filter)
|
||||
{
|
||||
assertStream();
|
||||
return dynamic_cast<QPDF_Stream*>(obj.get())->addTokenFilter(filter);
|
||||
return asStreamWithAssert()->addTokenFilter(filter);
|
||||
}
|
||||
|
||||
QPDFObjectHandle
|
||||
@ -1946,7 +2022,6 @@ QPDFObjectHandle::newIndirect(QPDF* qpdf, QPDFObjGen const& og)
|
||||
QTC::TC("qpdf", "QPDFObjectHandle indirect with 0 objid");
|
||||
return newNull();
|
||||
}
|
||||
|
||||
return QPDFObjectHandle(qpdf, og, QPDF_Unresolved::create());
|
||||
}
|
||||
|
||||
@ -2119,8 +2194,7 @@ QPDFObjectHandle::newStream(QPDF* qpdf)
|
||||
QPDFObjectHandle stream_dict = newDictionary();
|
||||
QPDFObjectHandle result = qpdf->makeIndirectObject(QPDFObjectHandle(
|
||||
QPDF_Stream::create(qpdf, QPDFObjGen(), stream_dict, 0, 0)));
|
||||
result.dereference();
|
||||
QPDF_Stream* stream = dynamic_cast<QPDF_Stream*>(result.obj.get());
|
||||
auto stream = result.asStream();
|
||||
stream->setObjGen(result.getObjGen());
|
||||
return result;
|
||||
}
|
||||
@ -2248,9 +2322,10 @@ QPDFObjectHandle::copyObject(
|
||||
new_obj = obj->shallowCopy();
|
||||
} else if (isArray()) {
|
||||
std::vector<QPDFObjectHandle> items;
|
||||
int n = getArrayNItems();
|
||||
auto array = asArray();
|
||||
int n = array->getNItems();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
items.push_back(getArrayItem(i));
|
||||
items.push_back(array->getItem(i));
|
||||
if ((!first_level_only) &&
|
||||
(cross_indirect || (!items.back().isIndirect()))) {
|
||||
items.back().copyObject(
|
||||
@ -2260,8 +2335,9 @@ QPDFObjectHandle::copyObject(
|
||||
new_obj = QPDF_Array::create(items);
|
||||
} else if (isDictionary()) {
|
||||
std::map<std::string, QPDFObjectHandle> items;
|
||||
auto dict = asDictionary();
|
||||
for (auto const& key: getKeys()) {
|
||||
items[key] = getKey(key);
|
||||
items[key] = dict->getKey(key);
|
||||
if ((!first_level_only) &&
|
||||
(cross_indirect || (!items[key].isIndirect()))) {
|
||||
items[key].copyObject(
|
||||
@ -2309,7 +2385,7 @@ QPDFObjectHandle::makeDirect(bool allow_streams)
|
||||
void
|
||||
QPDFObjectHandle::assertInitialized() const
|
||||
{
|
||||
if (!this->initialized) {
|
||||
if (!initialized) {
|
||||
throw std::logic_error("operation attempted on uninitialized "
|
||||
"QPDFObjectHandle");
|
||||
}
|
||||
@ -2551,7 +2627,6 @@ QPDFObjectHandle::dereference()
|
||||
(getObjectID() &&
|
||||
QPDF::Resolver::objectChanged(this->qpdf, getObjGen(), this->obj))) {
|
||||
this->obj = QPDF::Resolver::resolve(this->qpdf, getObjGen());
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -17,14 +17,16 @@ QPDF_Reserved::shallowCopy()
|
||||
std::string
|
||||
QPDF_Reserved::unparse()
|
||||
{
|
||||
throw std::logic_error("attempt to unparse QPDF_Reserved");
|
||||
throw std::logic_error(
|
||||
"QPDFObjectHandle: attempting to unparse a reserved object");
|
||||
return "";
|
||||
}
|
||||
|
||||
JSON
|
||||
QPDF_Reserved::getJSON(int json_version)
|
||||
{
|
||||
throw std::logic_error("attempt to generate JSON from QPDF_Reserved");
|
||||
throw std::logic_error(
|
||||
"QPDFObjectHandle: attempting to unparse a reserved object");
|
||||
return JSON::makeNull();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user