2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-11-16 09:37:08 +00:00

Add new method Objects::get

This commit is contained in:
m-holger 2024-10-07 16:39:27 +01:00
parent 83443c116d
commit 6c9903062f
5 changed files with 42 additions and 27 deletions

View File

@ -575,32 +575,25 @@ QPDF::newStream(std::string const& data)
QPDFObjectHandle QPDFObjectHandle
QPDF::getObject(QPDFObjGen const& og) QPDF::getObject(QPDFObjGen const& og)
{ {
if (auto it = m->objects.obj_cache.find(og); it != m->objects.obj_cache.end()) { return m->objects.get(og);
return {it->second.object};
} else if (m->objects.xref_table().initialized() && !m->objects.xref_table().type(og)) {
return QPDF_Null::create();
} else {
auto result = m->objects.obj_cache.try_emplace(og, QPDF_Unresolved::create(this, og));
return {result.first->second.object};
}
} }
QPDFObjectHandle QPDFObjectHandle
QPDF::getObject(int objid, int generation) QPDF::getObject(int id, int gen)
{ {
return getObject(QPDFObjGen(objid, generation)); return m->objects.get(id, gen);
} }
QPDFObjectHandle QPDFObjectHandle
QPDF::getObjectByObjGen(QPDFObjGen const& og) QPDF::getObjectByObjGen(QPDFObjGen const& og)
{ {
return getObject(og); return m->objects.get(og);
} }
QPDFObjectHandle QPDFObjectHandle
QPDF::getObjectByID(int objid, int generation) QPDF::getObjectByID(int id, int gen)
{ {
return getObject(QPDFObjGen(objid, generation)); return m->objects.get(id, gen);
} }
void void

View File

@ -130,7 +130,7 @@ QPDF::isLinearized()
return false; return false;
} }
auto candidate = getObjectByID(lindict_obj, 0); auto candidate = m->objects.get(lindict_obj, 0);
if (!candidate.isDictionary()) { if (!candidate.isDictionary()) {
return false; return false;
} }
@ -563,11 +563,11 @@ QPDF::getLinearizationOffset(QPDFObjGen const& og)
QPDFObjectHandle QPDFObjectHandle
QPDF::getUncompressedObject(QPDFObjectHandle& obj, std::map<int, int> const& object_stream_data) QPDF::getUncompressedObject(QPDFObjectHandle& obj, std::map<int, int> const& object_stream_data)
{ {
if (obj.isNull() || (object_stream_data.count(obj.getObjectID()) == 0)) { if (obj.isNull() || !object_stream_data.count(obj.getObjectID())) {
return obj; return obj;
} else { } else {
int repl = (*(object_stream_data.find(obj.getObjectID()))).second; int repl = (*(object_stream_data.find(obj.getObjectID()))).second;
return getObject(repl, 0); return m->objects.get(repl, 0);
} }
} }
@ -578,7 +578,7 @@ QPDF::getUncompressedObject(QPDFObjectHandle& obj, Objects const& objects)
if (obj.isNull() || objects.xref_table().type(og) != 2) { if (obj.isNull() || objects.xref_table().type(og) != 2) {
return obj; return obj;
} }
return getObject(objects.xref_table().stream_number(og.getObj()), 0); return m->objects.get(objects.xref_table().stream_number(og.getObj()), 0);
} }
QPDFObjectHandle QPDFObjectHandle
@ -586,7 +586,7 @@ QPDF::getUncompressedObject(QPDFObjectHandle& oh, QPDFWriter::ObjTable const& ob
{ {
if (obj.contains(oh)) { if (obj.contains(oh)) {
if (auto id = obj[oh].object_stream; id > 0) { if (auto id = obj[oh].object_stream; id > 0) {
return oh.isNull() ? oh : getObject(id, 0); return oh.isNull() ? oh : m->objects.get(id, 0);
} }
} }
return oh; return oh;
@ -1430,9 +1430,9 @@ QPDF::pushOutlinesToPart(
m->c_outline_data.first_object = outlines_og.getObj(); m->c_outline_data.first_object = outlines_og.getObj();
m->c_outline_data.nobjects = 1; m->c_outline_data.nobjects = 1;
lc_outlines.erase(outlines_og); lc_outlines.erase(outlines_og);
part.push_back(outlines); part.emplace_back(outlines);
for (auto const& og: lc_outlines) { for (auto const& og: lc_outlines) {
part.push_back(getObject(og)); part.emplace_back(m->objects.get(og));
++m->c_outline_data.nobjects; ++m->c_outline_data.nobjects;
} }
} }

View File

@ -201,7 +201,7 @@ Xref_table::reconstruct(QPDFExc& e)
} }
} }
std::vector<std::tuple<int, int, qpdf_offset_t>> objects; std::vector<std::tuple<int, int, qpdf_offset_t>> found_objects;
std::vector<qpdf_offset_t> trailers; std::vector<qpdf_offset_t> trailers;
int max_found = 0; int max_found = 0;
@ -220,7 +220,7 @@ Xref_table::reconstruct(QPDFExc& e)
int obj = QUtil::string_to_int(t1.getValue().c_str()); int obj = QUtil::string_to_int(t1.getValue().c_str());
int gen = QUtil::string_to_int(t2.getValue().c_str()); int gen = QUtil::string_to_int(t2.getValue().c_str());
if (obj <= max_id_) { if (obj <= max_id_) {
objects.emplace_back(obj, gen, token_start); found_objects.emplace_back(obj, gen, token_start);
if (obj > max_found) { if (obj > max_found) {
max_found = obj; max_found = obj;
} }
@ -249,8 +249,8 @@ Xref_table::reconstruct(QPDFExc& e)
check_warnings(); check_warnings();
} }
auto rend = objects.rend(); auto rend = found_objects.rend();
for (auto it = objects.rbegin(); it != rend; it++) { for (auto it = found_objects.rbegin(); it != rend; it++) {
auto [obj, gen, token_start] = *it; auto [obj, gen, token_start] = *it;
insert(obj, 1, token_start, gen); insert(obj, 1, token_start, gen);
check_warnings(); check_warnings();
@ -265,7 +265,7 @@ Xref_table::reconstruct(QPDFExc& e)
if (item.type() != 1) { if (item.type() != 1) {
continue; continue;
} }
auto oh = qpdf.getObject(i, item.gen()); auto oh = objects.get(i, item.gen());
try { try {
if (!oh.isStreamOfType("/XRef")) { if (!oh.isStreamOfType("/XRef")) {
continue; continue;
@ -1598,7 +1598,7 @@ Objects::resolveObjectsInStream(int obj_stream_number)
} }
m->resolved_object_streams.insert(obj_stream_number); m->resolved_object_streams.insert(obj_stream_number);
// Force resolution of object stream // Force resolution of object stream
QPDFObjectHandle obj_stream = qpdf.getObject(obj_stream_number, 0); QPDFObjectHandle obj_stream = get(obj_stream_number, 0);
if (!obj_stream.isStream()) { if (!obj_stream.isStream()) {
throw qpdf.damagedPDF( throw qpdf.damagedPDF(
"supposed object stream " + std::to_string(obj_stream_number) + " is not a stream"); "supposed object stream " + std::to_string(obj_stream_number) + " is not a stream");

View File

@ -905,7 +905,7 @@ qpdf_oh
qpdf_get_object_by_id(qpdf_data qpdf, int objid, int generation) qpdf_get_object_by_id(qpdf_data qpdf, int objid, int generation)
{ {
QTC::TC("qpdf", "qpdf-c called qpdf_get_object_by_id"); QTC::TC("qpdf", "qpdf-c called qpdf_get_object_by_id");
return new_object(qpdf, qpdf->qpdf->getObjectByID(objid, generation)); return new_object(qpdf, qpdf->qpdf->getObject(objid, generation));
} }
template <class RET> template <class RET>

View File

@ -3,6 +3,9 @@
#include <qpdf/QPDF.hh> #include <qpdf/QPDF.hh>
#include <qpdf/QPDF_Null.hh>
#include <qpdf/QPDF_Unresolved.hh>
#include <variant> #include <variant>
// The Objects class is responsible for keeping track of all objects belonging to a QPDF instance, // The Objects class is responsible for keeping track of all objects belonging to a QPDF instance,
@ -419,6 +422,25 @@ class QPDF::Objects
return xref.trailer(); return xref.trailer();
} }
QPDFObjectHandle
get(QPDFObjGen og)
{
if (auto it = obj_cache.find(og); it != obj_cache.end()) {
return {it->second.object};
} else if (xref.initialized() && !xref.type(og)) {
return QPDF_Null::create();
} else {
auto result = obj_cache.try_emplace(og, QPDF_Unresolved::create(&qpdf, og));
return {result.first->second.object};
}
}
QPDFObjectHandle
get(int id, int gen)
{
return get(QPDFObjGen(id, gen));
}
std::map<QPDFObjGen, Entry> obj_cache; std::map<QPDFObjGen, Entry> obj_cache;
QPDFObjectHandle readObjectInStream(std::shared_ptr<InputSource>& input, int obj); QPDFObjectHandle readObjectInStream(std::shared_ptr<InputSource>& input, int obj);