2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-10-18 01:46:27 +00:00

Merge pull request #979 from m-holger/const

In FUTURE make various QPDFObjectHandle methods const
This commit is contained in:
m-holger 2024-07-19 10:50:08 +01:00 committed by GitHub
commit 9ce18e41f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 2252 additions and 172 deletions

View File

@ -796,12 +796,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);
} }
}; };
@ -1061,7 +1062,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);

View File

@ -22,23 +22,27 @@
#ifndef QPDFOBJECTHANDLE_HH #ifndef QPDFOBJECTHANDLE_HH
#define QPDFOBJECTHANDLE_HH #define QPDFOBJECTHANDLE_HH
#include <qpdf/Constants.h> #ifdef QPDF_FUTURE
#include <qpdf/DLL.h> # include <qpdf/QPDFObjectHandle_future.hh>
#include <qpdf/Types.h> #else
#include <functional> # include <qpdf/Constants.h>
#include <map> # include <qpdf/DLL.h>
#include <memory> # include <qpdf/Types.h>
#include <set>
#include <string>
#include <vector>
#include <qpdf/Buffer.hh> # include <functional>
#include <qpdf/InputSource.hh> # include <map>
#include <qpdf/JSON.hh> # include <memory>
#include <qpdf/PointerHolder.hh> // unused -- remove in qpdf 12 (see #785) # include <set>
#include <qpdf/QPDFObjGen.hh> # include <string>
#include <qpdf/QPDFTokenizer.hh> # include <vector>
# include <qpdf/Buffer.hh>
# include <qpdf/InputSource.hh>
# include <qpdf/JSON.hh>
# include <qpdf/PointerHolder.hh> // unused -- remove in qpdf 12 (see #785)
# include <qpdf/QPDFObjGen.hh>
# include <qpdf/QPDFTokenizer.hh>
class Pipeline; class Pipeline;
class QPDF; class QPDF;
@ -291,13 +295,6 @@ class QPDFObjectHandle
QPDF_DLL QPDF_DLL
QPDFObjectHandle& operator=(QPDFObjectHandle const&) = default; QPDFObjectHandle& operator=(QPDFObjectHandle const&) = default;
#ifdef QPDF_FUTURE
QPDF_DLL
QPDFObjectHandle(QPDFObjectHandle&&) = default;
QPDF_DLL
QPDFObjectHandle& operator=(QPDFObjectHandle&&) = default;
#endif
QPDF_DLL QPDF_DLL
inline bool isInitialized() const; inline bool isInitialized() const;
@ -1363,24 +1360,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() const;
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) const;
void objectWarning(std::string const& warning); void objectWarning(std::string const& warning) const;
void assertType(char const* type_name, bool istype); void assertType(char const* type_name, bool istype) const;
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);
@ -1400,7 +1396,7 @@ class QPDFObjectHandle
std::shared_ptr<QPDFObject> obj; std::shared_ptr<QPDFObject> obj;
}; };
#ifndef QPDF_NO_QPDF_STRING # ifndef QPDF_NO_QPDF_STRING
// This is short for QPDFObjectHandle::parse, so you can do // This is short for QPDFObjectHandle::parse, so you can do
// auto oh = "<< /Key (value) >>"_qpdf; // auto oh = "<< /Key (value) >>"_qpdf;
@ -1416,7 +1412,7 @@ QPDF_DLL
QPDFObjectHandle operator ""_qpdf(char const* v, size_t len); QPDFObjectHandle operator ""_qpdf(char const* v, size_t len);
/* clang-format on */ /* clang-format on */
#endif // QPDF_NO_QPDF_STRING # endif // QPDF_NO_QPDF_STRING
class QPDFObjectHandle::QPDFDictItems class QPDFObjectHandle::QPDFDictItems
{ {
@ -1638,4 +1634,5 @@ QPDFObjectHandle::isInitialized() const
return obj != nullptr; return obj != nullptr;
} }
#endif // QPDF_FUTURE
#endif // QPDFOBJECTHANDLE_HH #endif // QPDFOBJECTHANDLE_HH

File diff suppressed because it is too large Load Diff

View File

@ -1847,11 +1847,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)) {
@ -1860,7 +1860,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);
@ -1901,6 +1901,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

View File

@ -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()
{ {

File diff suppressed because it is too large Load Diff

View File

@ -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() + " ";
} }
} }

View File

@ -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();
} }

View File

@ -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:

View File

@ -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);