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
QPDF::getObject(QPDFObjGen const& og)
{
if (auto it = m->objects.obj_cache.find(og); it != m->objects.obj_cache.end()) {
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};
}
return m->objects.get(og);
}
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
QPDF::getObjectByObjGen(QPDFObjGen const& og)
{
return getObject(og);
return m->objects.get(og);
}
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

View File

@ -130,7 +130,7 @@ QPDF::isLinearized()
return false;
}
auto candidate = getObjectByID(lindict_obj, 0);
auto candidate = m->objects.get(lindict_obj, 0);
if (!candidate.isDictionary()) {
return false;
}
@ -563,11 +563,11 @@ QPDF::getLinearizationOffset(QPDFObjGen const& og)
QPDFObjectHandle
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;
} else {
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) {
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
@ -586,7 +586,7 @@ QPDF::getUncompressedObject(QPDFObjectHandle& oh, QPDFWriter::ObjTable const& ob
{
if (obj.contains(oh)) {
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;
@ -1430,9 +1430,9 @@ QPDF::pushOutlinesToPart(
m->c_outline_data.first_object = outlines_og.getObj();
m->c_outline_data.nobjects = 1;
lc_outlines.erase(outlines_og);
part.push_back(outlines);
part.emplace_back(outlines);
for (auto const& og: lc_outlines) {
part.push_back(getObject(og));
part.emplace_back(m->objects.get(og));
++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;
int max_found = 0;
@ -220,7 +220,7 @@ Xref_table::reconstruct(QPDFExc& e)
int obj = QUtil::string_to_int(t1.getValue().c_str());
int gen = QUtil::string_to_int(t2.getValue().c_str());
if (obj <= max_id_) {
objects.emplace_back(obj, gen, token_start);
found_objects.emplace_back(obj, gen, token_start);
if (obj > max_found) {
max_found = obj;
}
@ -249,8 +249,8 @@ Xref_table::reconstruct(QPDFExc& e)
check_warnings();
}
auto rend = objects.rend();
for (auto it = objects.rbegin(); it != rend; it++) {
auto rend = found_objects.rend();
for (auto it = found_objects.rbegin(); it != rend; it++) {
auto [obj, gen, token_start] = *it;
insert(obj, 1, token_start, gen);
check_warnings();
@ -265,7 +265,7 @@ Xref_table::reconstruct(QPDFExc& e)
if (item.type() != 1) {
continue;
}
auto oh = qpdf.getObject(i, item.gen());
auto oh = objects.get(i, item.gen());
try {
if (!oh.isStreamOfType("/XRef")) {
continue;
@ -1598,7 +1598,7 @@ Objects::resolveObjectsInStream(int obj_stream_number)
}
m->resolved_object_streams.insert(obj_stream_number);
// 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()) {
throw qpdf.damagedPDF(
"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)
{
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>

View File

@ -3,6 +3,9 @@
#include <qpdf/QPDF.hh>
#include <qpdf/QPDF_Null.hh>
#include <qpdf/QPDF_Unresolved.hh>
#include <variant>
// 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();
}
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;
QPDFObjectHandle readObjectInStream(std::shared_ptr<InputSource>& input, int obj);