diff options
author | Masamichi Hosoda <trueroad@trueroad.jp> | 2019-10-01 16:53:50 +0200 |
---|---|---|
committer | Jay Berkenbilt <ejb@ql.org> | 2019-10-22 22:16:16 +0200 |
commit | 50b329ee9f13e0c615fa8d1d637597ab3929e433 (patch) | |
tree | 29c574c80d47a8583280a3e7c1ed57a38aeeb8d9 | |
parent | 5cf4090aee4a269186e13d902f91e6af3411f4a6 (diff) | |
download | qpdf-50b329ee9f13e0c615fa8d1d637597ab3929e433.tar.zst |
Add QPDFWriter::getWrittenXRefTable()
-rw-r--r-- | include/qpdf/QPDFWriter.hh | 5 | ||||
-rw-r--r-- | libqpdf/QPDFWriter.cc | 17 | ||||
-rw-r--r-- | qpdf/test_renumber.cc | 92 |
3 files changed, 114 insertions, 0 deletions
diff --git a/include/qpdf/QPDFWriter.hh b/include/qpdf/QPDFWriter.hh index eebc84c3..06de6a56 100644 --- a/include/qpdf/QPDFWriter.hh +++ b/include/qpdf/QPDFWriter.hh @@ -470,6 +470,11 @@ class QPDFWriter QPDF_DLL QPDFObjGen getRenumberedObjGen(QPDFObjGen); + // Return XRef entry that was written into the final file. + // This method can be used after calling write(). + QPDF_DLL + std::map<QPDFObjGen, QPDFXRefEntry> getWrittenXRefTable(); + private: // flags used by unparseObject static int const f_stream = 1 << 0; diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc index 247a1ac5..e7eae5c6 100644 --- a/libqpdf/QPDFWriter.cc +++ b/libqpdf/QPDFWriter.cc @@ -2747,6 +2747,23 @@ QPDFWriter::getRenumberedObjGen(QPDFObjGen og) return QPDFObjGen(this->m->obj_renumber[og], 0); } +std::map<QPDFObjGen, QPDFXRefEntry> +QPDFWriter::getWrittenXRefTable() +{ + std::map<QPDFObjGen, QPDFXRefEntry> result; + + for (std::map<int, QPDFXRefEntry>::iterator iter = this->m->xref.begin(); + iter != this->m->xref.end(); ++iter) + { + if (iter->first != 0 && iter->second.getType() != 0) + { + result[QPDFObjGen(iter->first, 0)] = iter->second; + } + } + + return result; +} + void QPDFWriter::enqueuePart(std::vector<QPDFObjectHandle>& part) { diff --git a/qpdf/test_renumber.cc b/qpdf/test_renumber.cc index 1c1954cb..5e68c280 100644 --- a/qpdf/test_renumber.cc +++ b/qpdf/test_renumber.cc @@ -5,6 +5,7 @@ #include <qpdf/QPDFObjectHandle.hh> #include <qpdf/QPDFObjGen.hh> #include <qpdf/QPDFWriter.hh> +#include <qpdf/QPDFXRefEntry.hh> #include <algorithm> #include <iostream> @@ -158,6 +159,77 @@ bool compare(QPDFObjectHandle a, QPDFObjectHandle b) return true; } +bool compare_xref_table(std::map<QPDFObjGen, QPDFXRefEntry> a, + std::map<QPDFObjGen, QPDFXRefEntry> b) +{ + if (a.size() != b.size()) + { + std::cerr + << "different size" + << std::endl; + return false; + } + + for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter = a.begin(); + iter != a.end(); ++iter) + { + std::cout + << "xref entry for " + << iter->first.getObj() << "/" << iter->first.getGen() + << std::endl; + + if (b.count(iter->first) == 0) + { + std::cerr + << "not found" + << std::endl; + return false; + } + + QPDFXRefEntry xref_a = iter->second; + QPDFXRefEntry xref_b = b[iter->first]; + if (xref_a.getType() != xref_b.getType()) + { + std::cerr + << "different xref entry type" + << std::endl; + return false; + } + + switch (xref_a.getType()) + { + case 0: + break; + case 1: + if (xref_a.getOffset() != xref_a.getOffset()) + { + std::cerr + << "different offset" + << std::endl; + return false; + } + break; + case 2: + if (xref_a.getObjStreamNumber() != xref_a.getObjStreamNumber() || + xref_a.getObjStreamIndex() != xref_a.getObjStreamIndex()) + { + std::cerr + << "different stream number or index" + << std::endl; + return false; + } + break; + default: + std::cerr + << "unknown xref entry type" + << std::endl; + std::exit(2); + } + } + + return true; +} + int main(int argc, char *argv[]) { if (argc < 2) @@ -226,13 +298,20 @@ int main(int argc, char *argv[]) w.setPreserveUnreferencedObjects(bpreserve_unreferenced); w.write(); + std::map<QPDFObjGen, QPDFXRefEntry> xrefs_w + = w.getWrittenXRefTable(); PointerHolder<Buffer> buf = w.getBuffer(); QPDF qpdf_ren; qpdf_ren.processMemoryFile("renumbered", reinterpret_cast<char*>(buf->getBuffer()), buf->getSize()); + std::map<QPDFObjGen, QPDFXRefEntry> xrefs_ren + = qpdf_ren.getXRefTable(); + std::cout + << "--- compare between input and renumbered objects ---" + << std::endl; for (std::vector<QPDFObjectHandle>::iterator iter = objs_in.begin(); iter != objs_in.end(); ++iter) { @@ -260,6 +339,19 @@ int main(int argc, char *argv[]) std::exit(2); } } + std::cout << "complete" << std::endl; + + std::cout + << "--- compare between written and reloaded xref tables ---" + << std::endl; + if (!compare_xref_table(xrefs_w, xrefs_ren)) + { + std::cerr + << "different" + << std::endl; + std::exit(2); + } + std::cout << "complete" << std::endl; std::cout << "succeeded" << std::endl; } |