2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-06-03 19:00:51 +00:00

Performance: remove Members indirection for QPDFObjectHandle

This commit is contained in:
Jay Berkenbilt 2020-04-02 15:14:53 -04:00
parent 31092dc66b
commit 89f19b7099
3 changed files with 124 additions and 167 deletions

View File

@ -1,3 +1,9 @@
2020-04-02 Jay Berkenbilt <ejb@ql.org>
* Remove Members class indirection for QPDFObjectHandle. Those are
copied and assigned too often, and that change caused a very
substantial performance hit.
2020-03-31 Jay Berkenbilt <ejb@ql.org> 2020-03-31 Jay Berkenbilt <ejb@ql.org>
* When detecting unreferenced images during page splitting, if any * When detecting unreferenced images during page splitting, if any

View File

@ -251,10 +251,10 @@ class QPDFObjectHandle
QPDF_DLL QPDF_DLL
QPDFObjectHandle(); QPDFObjectHandle();
QPDF_DLL QPDF_DLL
QPDFObjectHandle(QPDFObjectHandle const&); QPDFObjectHandle(QPDFObjectHandle const&) = default;
QPDF_DLL QPDF_DLL
QPDFObjectHandle& QPDFObjectHandle&
operator=(QPDFObjectHandle const&); operator=(QPDFObjectHandle const&) = default;
QPDF_DLL QPDF_DLL
bool isInitialized() const; bool isInitialized() const;
@ -957,7 +957,7 @@ class QPDFObjectHandle
static PointerHolder<QPDFObject> getObject(QPDFObjectHandle& o) static PointerHolder<QPDFObject> getObject(QPDFObjectHandle& o)
{ {
o.dereference(); o.dereference();
return o.m->obj; return o.obj;
} }
}; };
friend class ObjAccessor; friend class ObjAccessor;
@ -1077,29 +1077,16 @@ class QPDFObjectHandle
std::string const& description, std::string& all_description); std::string const& description, std::string& all_description);
static void warn(QPDF*, QPDFExc const&); static void warn(QPDF*, QPDFExc const&);
class Members bool initialized;
{
friend class ObjAccessor;
friend class QPDFObjectHandle;
public: // Moving members of QPDFObjectHandle into a smart pointer incurs
QPDF_DLL // a substantial performance penalty since QPDFObjectHandle
~Members(); // objects are copied around so frequently.
QPDF* qpdf;
private: int objid; // 0 for direct object
Members(); int generation;
Members(QPDF* qpdf, int objid, int generation); PointerHolder<QPDFObject> obj;
Members(QPDFObject* data); bool reserved;
bool initialized;
QPDF* qpdf;
int objid; // 0 for direct object
int generation;
PointerHolder<QPDFObject> obj;
bool reserved;
};
PointerHolder<Members> m;
}; };
#endif // QPDFOBJECTHANDLE_HH #endif // QPDFOBJECTHANDLE_HH

View File

@ -135,11 +135,7 @@ QPDFObjectHandle::ParserCallbacks::terminateParsing()
throw TerminateParsing(); throw TerminateParsing();
} }
QPDFObjectHandle::Members::~Members() QPDFObjectHandle::QPDFObjectHandle() :
{
}
QPDFObjectHandle::Members::Members() :
initialized(false), initialized(false),
qpdf(0), qpdf(0),
objid(0), objid(0),
@ -148,7 +144,7 @@ QPDFObjectHandle::Members::Members() :
{ {
} }
QPDFObjectHandle::Members::Members(QPDF* qpdf, int objid, int generation) : QPDFObjectHandle::QPDFObjectHandle(QPDF* qpdf, int objid, int generation) :
initialized(true), initialized(true),
qpdf(qpdf), qpdf(qpdf),
objid(objid), objid(objid),
@ -157,7 +153,7 @@ QPDFObjectHandle::Members::Members(QPDF* qpdf, int objid, int generation) :
{ {
} }
QPDFObjectHandle::Members::Members(QPDFObject* data) : QPDFObjectHandle::QPDFObjectHandle(QPDFObject* data) :
initialized(true), initialized(true),
qpdf(0), qpdf(0),
objid(0), objid(0),
@ -167,38 +163,6 @@ QPDFObjectHandle::Members::Members(QPDFObject* data) :
{ {
} }
QPDFObjectHandle::QPDFObjectHandle() :
m(new Members)
{
}
QPDFObjectHandle::QPDFObjectHandle(QPDFObjectHandle const& rhs) :
m(new Members)
{
*m = *rhs.m;
}
QPDFObjectHandle&
QPDFObjectHandle::operator=(QPDFObjectHandle const& rhs)
{
if (this != &rhs)
{
*m = *rhs.m;
}
return *this;
}
QPDFObjectHandle::QPDFObjectHandle(QPDF* qpdf, int objid, int generation) :
m(new Members(qpdf, objid, generation))
{
}
QPDFObjectHandle::QPDFObjectHandle(QPDFObject* data) :
m(new Members(data))
{
}
void void
QPDFObjectHandle::releaseResolved() QPDFObjectHandle::releaseResolved()
{ {
@ -208,14 +172,14 @@ QPDFObjectHandle::releaseResolved()
// destruction. See comments in QPDF::~QPDF(). // destruction. See comments in QPDF::~QPDF().
if (isIndirect()) if (isIndirect())
{ {
if (this->m->obj.getPointer()) if (this->obj.getPointer())
{ {
this->m->obj = 0; this->obj = 0;
} }
} }
else else
{ {
QPDFObject::ObjAccessor::releaseResolved(this->m->obj.getPointer()); QPDFObject::ObjAccessor::releaseResolved(this->obj.getPointer());
} }
} }
@ -234,16 +198,16 @@ QPDFObjectHandle::setObjectDescriptionFromInput(
bool bool
QPDFObjectHandle::isInitialized() const QPDFObjectHandle::isInitialized() const
{ {
return this->m->initialized; return this->initialized;
} }
QPDFObject::object_type_e QPDFObject::object_type_e
QPDFObjectHandle::getTypeCode() QPDFObjectHandle::getTypeCode()
{ {
if (this->m->initialized) if (this->initialized)
{ {
dereference(); dereference();
return this->m->obj->getTypeCode(); return this->obj->getTypeCode();
} }
else else
{ {
@ -254,10 +218,10 @@ QPDFObjectHandle::getTypeCode()
char const* char const*
QPDFObjectHandle::getTypeName() QPDFObjectHandle::getTypeName()
{ {
if (this->m->initialized) if (this->initialized)
{ {
dereference(); dereference();
return this->m->obj->getTypeName(); return this->obj->getTypeName();
} }
else else
{ {
@ -283,35 +247,35 @@ bool
QPDFObjectHandle::isBool() QPDFObjectHandle::isBool()
{ {
dereference(); dereference();
return QPDFObjectTypeAccessor<QPDF_Bool>::check(m->obj.getPointer()); return QPDFObjectTypeAccessor<QPDF_Bool>::check(obj.getPointer());
} }
bool bool
QPDFObjectHandle::isDirectNull() const QPDFObjectHandle::isDirectNull() const
{ {
return (this->m->initialized && (this->m->objid == 0) && return (this->initialized && (this->objid == 0) &&
QPDFObjectTypeAccessor<QPDF_Null>::check(m->obj.getPointer())); QPDFObjectTypeAccessor<QPDF_Null>::check(obj.getPointer()));
} }
bool bool
QPDFObjectHandle::isNull() QPDFObjectHandle::isNull()
{ {
dereference(); dereference();
return QPDFObjectTypeAccessor<QPDF_Null>::check(m->obj.getPointer()); return QPDFObjectTypeAccessor<QPDF_Null>::check(obj.getPointer());
} }
bool bool
QPDFObjectHandle::isInteger() QPDFObjectHandle::isInteger()
{ {
dereference(); dereference();
return QPDFObjectTypeAccessor<QPDF_Integer>::check(m->obj.getPointer()); return QPDFObjectTypeAccessor<QPDF_Integer>::check(obj.getPointer());
} }
bool bool
QPDFObjectHandle::isReal() QPDFObjectHandle::isReal()
{ {
dereference(); dereference();
return QPDFObjectTypeAccessor<QPDF_Real>::check(m->obj.getPointer()); return QPDFObjectTypeAccessor<QPDF_Real>::check(obj.getPointer());
} }
bool bool
@ -344,49 +308,49 @@ bool
QPDFObjectHandle::isName() QPDFObjectHandle::isName()
{ {
dereference(); dereference();
return QPDFObjectTypeAccessor<QPDF_Name>::check(m->obj.getPointer()); return QPDFObjectTypeAccessor<QPDF_Name>::check(obj.getPointer());
} }
bool bool
QPDFObjectHandle::isString() QPDFObjectHandle::isString()
{ {
dereference(); dereference();
return QPDFObjectTypeAccessor<QPDF_String>::check(m->obj.getPointer()); return QPDFObjectTypeAccessor<QPDF_String>::check(obj.getPointer());
} }
bool bool
QPDFObjectHandle::isOperator() QPDFObjectHandle::isOperator()
{ {
dereference(); dereference();
return QPDFObjectTypeAccessor<QPDF_Operator>::check(m->obj.getPointer()); return QPDFObjectTypeAccessor<QPDF_Operator>::check(obj.getPointer());
} }
bool bool
QPDFObjectHandle::isInlineImage() QPDFObjectHandle::isInlineImage()
{ {
dereference(); dereference();
return QPDFObjectTypeAccessor<QPDF_InlineImage>::check(m->obj.getPointer()); return QPDFObjectTypeAccessor<QPDF_InlineImage>::check(obj.getPointer());
} }
bool bool
QPDFObjectHandle::isArray() QPDFObjectHandle::isArray()
{ {
dereference(); dereference();
return QPDFObjectTypeAccessor<QPDF_Array>::check(m->obj.getPointer()); return QPDFObjectTypeAccessor<QPDF_Array>::check(obj.getPointer());
} }
bool bool
QPDFObjectHandle::isDictionary() QPDFObjectHandle::isDictionary()
{ {
dereference(); dereference();
return QPDFObjectTypeAccessor<QPDF_Dictionary>::check(m->obj.getPointer()); return QPDFObjectTypeAccessor<QPDF_Dictionary>::check(obj.getPointer());
} }
bool bool
QPDFObjectHandle::isStream() QPDFObjectHandle::isStream()
{ {
dereference(); dereference();
return QPDFObjectTypeAccessor<QPDF_Stream>::check(m->obj.getPointer()); return QPDFObjectTypeAccessor<QPDF_Stream>::check(obj.getPointer());
} }
bool bool
@ -394,14 +358,14 @@ QPDFObjectHandle::isReserved()
{ {
// dereference will clear reserved if this has been replaced // dereference will clear reserved if this has been replaced
dereference(); dereference();
return this->m->reserved; return this->reserved;
} }
bool bool
QPDFObjectHandle::isIndirect() QPDFObjectHandle::isIndirect()
{ {
assertInitialized(); assertInitialized();
return (this->m->objid != 0); return (this->objid != 0);
} }
bool bool
@ -418,7 +382,7 @@ QPDFObjectHandle::getBoolValue()
{ {
if (isBool()) if (isBool())
{ {
return dynamic_cast<QPDF_Bool*>(m->obj.getPointer())->getVal(); return dynamic_cast<QPDF_Bool*>(obj.getPointer())->getVal();
} }
else else
{ {
@ -435,7 +399,7 @@ QPDFObjectHandle::getIntValue()
{ {
if (isInteger()) if (isInteger())
{ {
return dynamic_cast<QPDF_Integer*>(m->obj.getPointer())->getVal(); return dynamic_cast<QPDF_Integer*>(obj.getPointer())->getVal();
} }
else else
{ {
@ -528,7 +492,7 @@ QPDFObjectHandle::getRealValue()
{ {
if (isReal()) if (isReal())
{ {
return dynamic_cast<QPDF_Real*>(m->obj.getPointer())->getVal(); return dynamic_cast<QPDF_Real*>(obj.getPointer())->getVal();
} }
else else
{ {
@ -545,7 +509,7 @@ QPDFObjectHandle::getName()
{ {
if (isName()) if (isName())
{ {
return dynamic_cast<QPDF_Name*>(m->obj.getPointer())->getName(); return dynamic_cast<QPDF_Name*>(obj.getPointer())->getName();
} }
else else
{ {
@ -562,7 +526,7 @@ QPDFObjectHandle::getStringValue()
{ {
if (isString()) if (isString())
{ {
return dynamic_cast<QPDF_String*>(m->obj.getPointer())->getVal(); return dynamic_cast<QPDF_String*>(obj.getPointer())->getVal();
} }
else else
{ {
@ -577,7 +541,7 @@ QPDFObjectHandle::getUTF8Value()
{ {
if (isString()) if (isString())
{ {
return dynamic_cast<QPDF_String*>(m->obj.getPointer())->getUTF8Val(); return dynamic_cast<QPDF_String*>(obj.getPointer())->getUTF8Val();
} }
else else
{ {
@ -594,7 +558,7 @@ QPDFObjectHandle::getOperatorValue()
{ {
if (isOperator()) if (isOperator())
{ {
return dynamic_cast<QPDF_Operator*>(m->obj.getPointer())->getVal(); return dynamic_cast<QPDF_Operator*>(obj.getPointer())->getVal();
} }
else else
{ {
@ -609,7 +573,7 @@ QPDFObjectHandle::getInlineImageValue()
{ {
if (isInlineImage()) if (isInlineImage())
{ {
return dynamic_cast<QPDF_InlineImage*>(m->obj.getPointer())->getVal(); return dynamic_cast<QPDF_InlineImage*>(obj.getPointer())->getVal();
} }
else else
{ {
@ -626,7 +590,7 @@ QPDFObjectHandle::getArrayNItems()
{ {
if (isArray()) if (isArray())
{ {
return dynamic_cast<QPDF_Array*>(m->obj.getPointer())->getNItems(); return dynamic_cast<QPDF_Array*>(obj.getPointer())->getNItems();
} }
else else
{ {
@ -642,7 +606,7 @@ QPDFObjectHandle::getArrayItem(int n)
QPDFObjectHandle result; QPDFObjectHandle result;
if (isArray() && (n < getArrayNItems()) && (n >= 0)) if (isArray() && (n < getArrayNItems()) && (n >= 0))
{ {
result = dynamic_cast<QPDF_Array*>(m->obj.getPointer())->getItem(n); result = dynamic_cast<QPDF_Array*>(obj.getPointer())->getItem(n);
} }
else else
{ {
@ -659,7 +623,7 @@ QPDFObjectHandle::getArrayItem(int n)
} }
QPDF* context = 0; QPDF* context = 0;
std::string description; std::string description;
if (this->m->obj->getDescription(context, description)) if (this->obj->getDescription(context, description))
{ {
result.setObjectDescription( result.setObjectDescription(
context, context,
@ -755,7 +719,7 @@ QPDFObjectHandle::getArrayAsVector()
std::vector<QPDFObjectHandle> result; std::vector<QPDFObjectHandle> result;
if (isArray()) if (isArray())
{ {
dynamic_cast<QPDF_Array*>(m->obj.getPointer())->getAsVector(result); dynamic_cast<QPDF_Array*>(obj.getPointer())->getAsVector(result);
} }
else else
{ {
@ -772,7 +736,7 @@ QPDFObjectHandle::setArrayItem(int n, QPDFObjectHandle const& item)
{ {
if (isArray()) if (isArray())
{ {
dynamic_cast<QPDF_Array*>(m->obj.getPointer())->setItem(n, item); dynamic_cast<QPDF_Array*>(obj.getPointer())->setItem(n, item);
} }
else else
{ {
@ -786,7 +750,7 @@ QPDFObjectHandle::setArrayFromVector(std::vector<QPDFObjectHandle> const& items)
{ {
if (isArray()) if (isArray())
{ {
dynamic_cast<QPDF_Array*>(m->obj.getPointer())->setFromVector(items); dynamic_cast<QPDF_Array*>(obj.getPointer())->setFromVector(items);
} }
else else
{ {
@ -800,7 +764,7 @@ QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item)
{ {
if (isArray()) if (isArray())
{ {
dynamic_cast<QPDF_Array*>(m->obj.getPointer())->insertItem(at, item); dynamic_cast<QPDF_Array*>(obj.getPointer())->insertItem(at, item);
} }
else else
{ {
@ -814,7 +778,7 @@ QPDFObjectHandle::appendItem(QPDFObjectHandle const& item)
{ {
if (isArray()) if (isArray())
{ {
dynamic_cast<QPDF_Array*>(m->obj.getPointer())->appendItem(item); dynamic_cast<QPDF_Array*>(obj.getPointer())->appendItem(item);
} }
else else
{ {
@ -828,7 +792,7 @@ QPDFObjectHandle::eraseItem(int at)
{ {
if (isArray() && (at < getArrayNItems()) && (at >= 0)) if (isArray() && (at < getArrayNItems()) && (at >= 0))
{ {
dynamic_cast<QPDF_Array*>(m->obj.getPointer())->eraseItem(at); dynamic_cast<QPDF_Array*>(obj.getPointer())->eraseItem(at);
} }
else else
{ {
@ -852,7 +816,7 @@ QPDFObjectHandle::hasKey(std::string const& key)
{ {
if (isDictionary()) if (isDictionary())
{ {
return dynamic_cast<QPDF_Dictionary*>(m->obj.getPointer())->hasKey(key); return dynamic_cast<QPDF_Dictionary*>(obj.getPointer())->hasKey(key);
} }
else else
{ {
@ -870,7 +834,7 @@ QPDFObjectHandle::getKey(std::string const& key)
if (isDictionary()) if (isDictionary())
{ {
result = dynamic_cast<QPDF_Dictionary*>( result = dynamic_cast<QPDF_Dictionary*>(
m->obj.getPointer())->getKey(key); obj.getPointer())->getKey(key);
} }
else else
{ {
@ -880,7 +844,7 @@ QPDFObjectHandle::getKey(std::string const& key)
result = newNull(); result = newNull();
QPDF* qpdf = 0; QPDF* qpdf = 0;
std::string description; std::string description;
if (this->m->obj->getDescription(qpdf, description)) if (this->obj->getDescription(qpdf, description))
{ {
result.setObjectDescription( result.setObjectDescription(
qpdf, qpdf,
@ -898,7 +862,7 @@ QPDFObjectHandle::getKeys()
std::set<std::string> result; std::set<std::string> result;
if (isDictionary()) if (isDictionary())
{ {
result = dynamic_cast<QPDF_Dictionary*>(m->obj.getPointer())->getKeys(); result = dynamic_cast<QPDF_Dictionary*>(obj.getPointer())->getKeys();
} }
else else
{ {
@ -915,7 +879,7 @@ QPDFObjectHandle::getDictAsMap()
if (isDictionary()) if (isDictionary())
{ {
result = dynamic_cast<QPDF_Dictionary*>( result = dynamic_cast<QPDF_Dictionary*>(
m->obj.getPointer())->getAsMap(); obj.getPointer())->getAsMap();
} }
else else
{ {
@ -1082,7 +1046,7 @@ QPDF*
QPDFObjectHandle::getOwningQPDF() QPDFObjectHandle::getOwningQPDF()
{ {
// Will be null for direct objects // Will be null for direct objects
return this->m->qpdf; return this->qpdf;
} }
// Dictionary mutators // Dictionary mutators
@ -1094,7 +1058,7 @@ QPDFObjectHandle::replaceKey(std::string const& key,
if (isDictionary()) if (isDictionary())
{ {
dynamic_cast<QPDF_Dictionary*>( dynamic_cast<QPDF_Dictionary*>(
m->obj.getPointer())->replaceKey(key, value); obj.getPointer())->replaceKey(key, value);
} }
else else
{ {
@ -1108,7 +1072,7 @@ QPDFObjectHandle::removeKey(std::string const& key)
{ {
if (isDictionary()) if (isDictionary())
{ {
dynamic_cast<QPDF_Dictionary*>(m->obj.getPointer())->removeKey(key); dynamic_cast<QPDF_Dictionary*>(obj.getPointer())->removeKey(key);
} }
else else
{ {
@ -1124,7 +1088,7 @@ QPDFObjectHandle::replaceOrRemoveKey(std::string const& key,
if (isDictionary()) if (isDictionary())
{ {
dynamic_cast<QPDF_Dictionary*>( dynamic_cast<QPDF_Dictionary*>(
m->obj.getPointer())->replaceOrRemoveKey(key, value); obj.getPointer())->replaceOrRemoveKey(key, value);
} }
else else
{ {
@ -1138,21 +1102,21 @@ QPDFObjectHandle
QPDFObjectHandle::getDict() QPDFObjectHandle::getDict()
{ {
assertStream(); assertStream();
return dynamic_cast<QPDF_Stream*>(m->obj.getPointer())->getDict(); return dynamic_cast<QPDF_Stream*>(obj.getPointer())->getDict();
} }
bool bool
QPDFObjectHandle::isDataModified() QPDFObjectHandle::isDataModified()
{ {
assertStream(); assertStream();
return dynamic_cast<QPDF_Stream*>(m->obj.getPointer())->isDataModified(); return dynamic_cast<QPDF_Stream*>(obj.getPointer())->isDataModified();
} }
void void
QPDFObjectHandle::replaceDict(QPDFObjectHandle new_dict) QPDFObjectHandle::replaceDict(QPDFObjectHandle new_dict)
{ {
assertStream(); assertStream();
dynamic_cast<QPDF_Stream*>(m->obj.getPointer())->replaceDict(new_dict); dynamic_cast<QPDF_Stream*>(obj.getPointer())->replaceDict(new_dict);
} }
PointerHolder<Buffer> PointerHolder<Buffer>
@ -1160,14 +1124,14 @@ QPDFObjectHandle::getStreamData(qpdf_stream_decode_level_e level)
{ {
assertStream(); assertStream();
return dynamic_cast<QPDF_Stream*>( return dynamic_cast<QPDF_Stream*>(
m->obj.getPointer())->getStreamData(level); obj.getPointer())->getStreamData(level);
} }
PointerHolder<Buffer> PointerHolder<Buffer>
QPDFObjectHandle::getRawStreamData() QPDFObjectHandle::getRawStreamData()
{ {
assertStream(); assertStream();
return dynamic_cast<QPDF_Stream*>(m->obj.getPointer())->getRawStreamData(); return dynamic_cast<QPDF_Stream*>(obj.getPointer())->getRawStreamData();
} }
bool bool
@ -1177,7 +1141,7 @@ QPDFObjectHandle::pipeStreamData(Pipeline* p,
bool suppress_warnings, bool will_retry) bool suppress_warnings, bool will_retry)
{ {
assertStream(); assertStream();
return dynamic_cast<QPDF_Stream*>(m->obj.getPointer())->pipeStreamData( return dynamic_cast<QPDF_Stream*>(obj.getPointer())->pipeStreamData(
p, encode_flags, decode_level, suppress_warnings, will_retry); p, encode_flags, decode_level, suppress_warnings, will_retry);
} }
@ -1208,7 +1172,7 @@ QPDFObjectHandle::replaceStreamData(PointerHolder<Buffer> data,
QPDFObjectHandle const& decode_parms) QPDFObjectHandle const& decode_parms)
{ {
assertStream(); assertStream();
dynamic_cast<QPDF_Stream*>(m->obj.getPointer())->replaceStreamData( dynamic_cast<QPDF_Stream*>(obj.getPointer())->replaceStreamData(
data, filter, decode_parms); data, filter, decode_parms);
} }
@ -1221,7 +1185,7 @@ QPDFObjectHandle::replaceStreamData(std::string const& data,
PointerHolder<Buffer> b = new Buffer(data.length()); PointerHolder<Buffer> b = new Buffer(data.length());
unsigned char* bp = b->getBuffer(); unsigned char* bp = b->getBuffer();
memcpy(bp, data.c_str(), data.length()); memcpy(bp, data.c_str(), data.length());
dynamic_cast<QPDF_Stream*>(m->obj.getPointer())->replaceStreamData( dynamic_cast<QPDF_Stream*>(obj.getPointer())->replaceStreamData(
b, filter, decode_parms); b, filter, decode_parms);
} }
@ -1231,26 +1195,26 @@ QPDFObjectHandle::replaceStreamData(PointerHolder<StreamDataProvider> provider,
QPDFObjectHandle const& decode_parms) QPDFObjectHandle const& decode_parms)
{ {
assertStream(); assertStream();
dynamic_cast<QPDF_Stream*>(m->obj.getPointer())->replaceStreamData( dynamic_cast<QPDF_Stream*>(obj.getPointer())->replaceStreamData(
provider, filter, decode_parms); provider, filter, decode_parms);
} }
QPDFObjGen QPDFObjGen
QPDFObjectHandle::getObjGen() const QPDFObjectHandle::getObjGen() const
{ {
return QPDFObjGen(this->m->objid, this->m->generation); return QPDFObjGen(this->objid, this->generation);
} }
int int
QPDFObjectHandle::getObjectID() const QPDFObjectHandle::getObjectID() const
{ {
return this->m->objid; return this->objid;
} }
int int
QPDFObjectHandle::getGeneration() const QPDFObjectHandle::getGeneration() const
{ {
return this->m->generation; return this->generation;
} }
std::map<std::string, QPDFObjectHandle> std::map<std::string, QPDFObjectHandle>
@ -1352,8 +1316,8 @@ std::vector<QPDFObjectHandle>
QPDFObjectHandle::getPageContents() QPDFObjectHandle::getPageContents()
{ {
std::string description = "page object " + std::string description = "page object " +
QUtil::int_to_string(this->m->objid) + " " + QUtil::int_to_string(this->objid) + " " +
QUtil::int_to_string(this->m->generation); QUtil::int_to_string(this->generation);
std::string all_description; std::string all_description;
return this->getKey("/Contents").arrayOrStreamToStreamArray( return this->getKey("/Contents").arrayOrStreamToStreamArray(
description, all_description); description, all_description);
@ -1480,8 +1444,8 @@ QPDFObjectHandle::unparse()
std::string result; std::string result;
if (this->isIndirect()) if (this->isIndirect())
{ {
result = QUtil::int_to_string(this->m->objid) + " " + result = QUtil::int_to_string(this->objid) + " " +
QUtil::int_to_string(this->m->generation) + " R"; QUtil::int_to_string(this->generation) + " R";
} }
else else
{ {
@ -1493,13 +1457,13 @@ QPDFObjectHandle::unparse()
std::string std::string
QPDFObjectHandle::unparseResolved() QPDFObjectHandle::unparseResolved()
{ {
if (this->m->reserved) if (this->reserved)
{ {
throw std::logic_error( throw std::logic_error(
"QPDFObjectHandle: attempting to unparse a reserved object"); "QPDFObjectHandle: attempting to unparse a reserved object");
} }
dereference(); dereference();
return this->m->obj->unparse(); return this->obj->unparse();
} }
std::string std::string
@ -1508,7 +1472,7 @@ QPDFObjectHandle::unparseBinary()
if (this->isString()) if (this->isString())
{ {
return dynamic_cast<QPDF_String*>( return dynamic_cast<QPDF_String*>(
this->m->obj.getPointer())->unparse(true); this->obj.getPointer())->unparse(true);
} }
else else
{ {
@ -1525,13 +1489,13 @@ QPDFObjectHandle::getJSON(bool dereference_indirect)
} }
else else
{ {
if (this->m->reserved) if (this->reserved)
{ {
throw std::logic_error( throw std::logic_error(
"QPDFObjectHandle: attempting to unparse a reserved object"); "QPDFObjectHandle: attempting to unparse a reserved object");
} }
dereference(); dereference();
return this->m->obj->getJSON(); return this->obj->getJSON();
} }
} }
@ -1577,8 +1541,8 @@ void
QPDFObjectHandle::pipePageContents(Pipeline* p) QPDFObjectHandle::pipePageContents(Pipeline* p)
{ {
std::string description = "page object " + std::string description = "page object " +
QUtil::int_to_string(this->m->objid) + " " + QUtil::int_to_string(this->objid) + " " +
QUtil::int_to_string(this->m->generation); QUtil::int_to_string(this->generation);
std::string all_description; std::string all_description;
this->getKey("/Contents").pipeContentStreams( this->getKey("/Contents").pipeContentStreams(
p, description, all_description); p, description, all_description);
@ -1613,8 +1577,8 @@ void
QPDFObjectHandle::parsePageContents(ParserCallbacks* callbacks) QPDFObjectHandle::parsePageContents(ParserCallbacks* callbacks)
{ {
std::string description = "page object " + std::string description = "page object " +
QUtil::int_to_string(this->m->objid) + " " + QUtil::int_to_string(this->objid) + " " +
QUtil::int_to_string(this->m->generation); QUtil::int_to_string(this->generation);
this->getKey("/Contents").parseContentStream_internal( this->getKey("/Contents").parseContentStream_internal(
description, callbacks); description, callbacks);
} }
@ -1623,8 +1587,8 @@ void
QPDFObjectHandle::filterPageContents(TokenFilter* filter, Pipeline* next) QPDFObjectHandle::filterPageContents(TokenFilter* filter, Pipeline* next)
{ {
std::string description = "token filter for page object " + std::string description = "token filter for page object " +
QUtil::int_to_string(this->m->objid) + " " + QUtil::int_to_string(this->objid) + " " +
QUtil::int_to_string(this->m->generation); QUtil::int_to_string(this->generation);
Pl_QPDFTokenizer token_pipeline(description.c_str(), filter, next); Pl_QPDFTokenizer token_pipeline(description.c_str(), filter, next);
this->pipePageContents(&token_pipeline); this->pipePageContents(&token_pipeline);
} }
@ -1633,8 +1597,8 @@ void
QPDFObjectHandle::filterAsContents(TokenFilter* filter, Pipeline* next) QPDFObjectHandle::filterAsContents(TokenFilter* filter, Pipeline* next)
{ {
std::string description = "token filter for object " + std::string description = "token filter for object " +
QUtil::int_to_string(this->m->objid) + " " + QUtil::int_to_string(this->objid) + " " +
QUtil::int_to_string(this->m->generation); QUtil::int_to_string(this->generation);
Pl_QPDFTokenizer token_pipeline(description.c_str(), filter, next); Pl_QPDFTokenizer token_pipeline(description.c_str(), filter, next);
this->pipeStreamData(&token_pipeline, 0, qpdf_dl_specialized); this->pipeStreamData(&token_pipeline, 0, qpdf_dl_specialized);
} }
@ -1745,7 +1709,7 @@ QPDFObjectHandle::addTokenFilter(PointerHolder<TokenFilter> filter)
{ {
assertStream(); assertStream();
return dynamic_cast<QPDF_Stream*>( return dynamic_cast<QPDF_Stream*>(
m->obj.getPointer())->addTokenFilter(filter); obj.getPointer())->addTokenFilter(filter);
} }
QPDFObjectHandle QPDFObjectHandle
@ -2258,15 +2222,15 @@ qpdf_offset_t
QPDFObjectHandle::getParsedOffset() QPDFObjectHandle::getParsedOffset()
{ {
dereference(); dereference();
return this->m->obj->getParsedOffset(); return this->obj->getParsedOffset();
} }
void void
QPDFObjectHandle::setParsedOffset(qpdf_offset_t offset) QPDFObjectHandle::setParsedOffset(qpdf_offset_t offset)
{ {
if (this->m->obj.getPointer()) if (this->obj.getPointer())
{ {
this->m->obj->setParsedOffset(offset); this->obj->setParsedOffset(offset);
} }
} }
@ -2438,7 +2402,7 @@ QPDFObjectHandle::newStream(QPDF* qpdf)
new QPDF_Stream(qpdf, 0, 0, stream_dict, 0, 0))); new QPDF_Stream(qpdf, 0, 0, stream_dict, 0, 0)));
result.dereference(); result.dereference();
QPDF_Stream* stream = QPDF_Stream* stream =
dynamic_cast<QPDF_Stream*>(result.m->obj.getPointer()); dynamic_cast<QPDF_Stream*>(result.obj.getPointer());
stream->setObjGen(result.getObjectID(), result.getGeneration()); stream->setObjGen(result.getObjectID(), result.getGeneration());
return result; return result;
} }
@ -2469,8 +2433,8 @@ QPDFObjectHandle::newReserved(QPDF* qpdf)
QPDFObjectHandle reserved = qpdf->makeIndirectObject( QPDFObjectHandle reserved = qpdf->makeIndirectObject(
QPDFObjectHandle(new QPDF_Reserved())); QPDFObjectHandle(new QPDF_Reserved()));
QPDFObjectHandle result = QPDFObjectHandle result =
newIndirect(qpdf, reserved.m->objid, reserved.m->generation); newIndirect(qpdf, reserved.objid, reserved.generation);
result.m->reserved = true; result.reserved = true;
return result; return result;
} }
@ -2478,18 +2442,18 @@ void
QPDFObjectHandle::setObjectDescription(QPDF* owning_qpdf, QPDFObjectHandle::setObjectDescription(QPDF* owning_qpdf,
std::string const& object_description) std::string const& object_description)
{ {
if (isInitialized() && this->m->obj.getPointer()) if (isInitialized() && this->obj.getPointer())
{ {
this->m->obj->setDescription(owning_qpdf, object_description); this->obj->setDescription(owning_qpdf, object_description);
} }
} }
bool bool
QPDFObjectHandle::hasObjectDescription() QPDFObjectHandle::hasObjectDescription()
{ {
if (isInitialized() && this->m->obj.getPointer()) if (isInitialized() && this->obj.getPointer())
{ {
return this->m->obj->hasDescription(); return this->obj->hasDescription();
} }
return false; return false;
} }
@ -2511,7 +2475,7 @@ QPDFObjectHandle::shallowCopy()
{ {
QTC::TC("qpdf", "QPDFObjectHandle shallow copy array"); QTC::TC("qpdf", "QPDFObjectHandle shallow copy array");
// No newArray for shallow copying the sparse array // No newArray for shallow copying the sparse array
QPDF_Array* arr = dynamic_cast<QPDF_Array*>(m->obj.getPointer()); QPDF_Array* arr = dynamic_cast<QPDF_Array*>(obj.getPointer());
new_obj = QPDFObjectHandle( new_obj = QPDFObjectHandle(
new QPDF_Array(arr->getElementsForShallowCopy())); new QPDF_Array(arr->getElementsForShallowCopy()));
} }
@ -2544,7 +2508,7 @@ QPDFObjectHandle::copyObject(std::set<QPDFObjGen>& visited,
"attempt to make a stream into a direct object"); "attempt to make a stream into a direct object");
} }
QPDFObjGen cur_og(this->m->objid, this->m->generation); QPDFObjGen cur_og(this->objid, this->generation);
if (cur_og.getObj() != 0) if (cur_og.getObj() != 0)
{ {
if (visited.count(cur_og)) if (visited.count(cur_og))
@ -2565,9 +2529,9 @@ QPDFObjectHandle::copyObject(std::set<QPDFObjGen>& visited,
} }
dereference(); dereference();
this->m->qpdf = 0; this->qpdf = 0;
this->m->objid = 0; this->objid = 0;
this->m->generation = 0; this->generation = 0;
PointerHolder<QPDFObject> new_obj; PointerHolder<QPDFObject> new_obj;
@ -2638,7 +2602,7 @@ QPDFObjectHandle::copyObject(std::set<QPDFObjGen>& visited,
"unknown object type"); "unknown object type");
} }
this->m->obj = new_obj; this->obj = new_obj;
if (cur_og.getObj()) if (cur_og.getObj())
{ {
@ -2656,7 +2620,7 @@ QPDFObjectHandle::makeDirect()
void void
QPDFObjectHandle::assertInitialized() const QPDFObjectHandle::assertInitialized() const
{ {
if (! this->m->initialized) if (! this->initialized)
{ {
throw std::logic_error("operation attempted on uninitialized " throw std::logic_error("operation attempted on uninitialized "
"QPDFObjectHandle"); "QPDFObjectHandle");
@ -2669,7 +2633,7 @@ QPDFObjectHandle::typeWarning(char const* expected_type,
{ {
QPDF* context = 0; QPDF* context = 0;
std::string description; std::string description;
if (this->m->obj->getDescription(context, description)) if (this->obj->getDescription(context, description))
{ {
warn(context, warn(context,
QPDFExc( QPDFExc(
@ -2691,7 +2655,7 @@ QPDFObjectHandle::warnIfPossible(std::string const& warning,
{ {
QPDF* context = 0; QPDF* context = 0;
std::string description; std::string description;
if (this->m->obj->getDescription(context, description)) if (this->obj->getDescription(context, description))
{ {
warn(context, warn(context,
QPDFExc( QPDFExc(
@ -2863,15 +2827,15 @@ QPDFObjectHandle::assertPageObject()
void void
QPDFObjectHandle::dereference() QPDFObjectHandle::dereference()
{ {
if (this->m->obj.getPointer() == 0) if (this->obj.getPointer() == 0)
{ {
PointerHolder<QPDFObject> obj = QPDF::Resolver::resolve( PointerHolder<QPDFObject> obj = QPDF::Resolver::resolve(
this->m->qpdf, this->m->objid, this->m->generation); this->qpdf, this->objid, this->generation);
if (obj.getPointer() == 0) if (obj.getPointer() == 0)
{ {
// QPDF::resolve never returns an uninitialized object, but // QPDF::resolve never returns an uninitialized object, but
// check just in case. // check just in case.
this->m->obj = new QPDF_Null(); this->obj = new QPDF_Null();
} }
else if (dynamic_cast<QPDF_Reserved*>(obj.getPointer())) else if (dynamic_cast<QPDF_Reserved*>(obj.getPointer()))
{ {
@ -2879,8 +2843,8 @@ QPDFObjectHandle::dereference()
} }
else else
{ {
this->m->reserved = false; this->reserved = false;
this->m->obj = obj; this->obj = obj;
} }
} }
} }