Commit 50b329ee9f13e0c615fa8d1d637597ab3929e433

Authored by Masamichi Hosoda
Committed by Jay Berkenbilt
1 parent 5cf4090a

Add QPDFWriter::getWrittenXRefTable()

include/qpdf/QPDFWriter.hh
... ... @@ -470,6 +470,11 @@ class QPDFWriter
470 470 QPDF_DLL
471 471 QPDFObjGen getRenumberedObjGen(QPDFObjGen);
472 472  
  473 + // Return XRef entry that was written into the final file.
  474 + // This method can be used after calling write().
  475 + QPDF_DLL
  476 + std::map<QPDFObjGen, QPDFXRefEntry> getWrittenXRefTable();
  477 +
473 478 private:
474 479 // flags used by unparseObject
475 480 static int const f_stream = 1 << 0;
... ...
libqpdf/QPDFWriter.cc
... ... @@ -2747,6 +2747,23 @@ QPDFWriter::getRenumberedObjGen(QPDFObjGen og)
2747 2747 return QPDFObjGen(this->m->obj_renumber[og], 0);
2748 2748 }
2749 2749  
  2750 +std::map<QPDFObjGen, QPDFXRefEntry>
  2751 +QPDFWriter::getWrittenXRefTable()
  2752 +{
  2753 + std::map<QPDFObjGen, QPDFXRefEntry> result;
  2754 +
  2755 + for (std::map<int, QPDFXRefEntry>::iterator iter = this->m->xref.begin();
  2756 + iter != this->m->xref.end(); ++iter)
  2757 + {
  2758 + if (iter->first != 0 && iter->second.getType() != 0)
  2759 + {
  2760 + result[QPDFObjGen(iter->first, 0)] = iter->second;
  2761 + }
  2762 + }
  2763 +
  2764 + return result;
  2765 +}
  2766 +
2750 2767 void
2751 2768 QPDFWriter::enqueuePart(std::vector<QPDFObjectHandle>& part)
2752 2769 {
... ...
qpdf/test_renumber.cc
... ... @@ -5,6 +5,7 @@
5 5 #include <qpdf/QPDFObjectHandle.hh>
6 6 #include <qpdf/QPDFObjGen.hh>
7 7 #include <qpdf/QPDFWriter.hh>
  8 +#include <qpdf/QPDFXRefEntry.hh>
8 9  
9 10 #include <algorithm>
10 11 #include <iostream>
... ... @@ -158,6 +159,77 @@ bool compare(QPDFObjectHandle a, QPDFObjectHandle b)
158 159 return true;
159 160 }
160 161  
  162 +bool compare_xref_table(std::map<QPDFObjGen, QPDFXRefEntry> a,
  163 + std::map<QPDFObjGen, QPDFXRefEntry> b)
  164 +{
  165 + if (a.size() != b.size())
  166 + {
  167 + std::cerr
  168 + << "different size"
  169 + << std::endl;
  170 + return false;
  171 + }
  172 +
  173 + for (std::map<QPDFObjGen, QPDFXRefEntry>::iterator iter = a.begin();
  174 + iter != a.end(); ++iter)
  175 + {
  176 + std::cout
  177 + << "xref entry for "
  178 + << iter->first.getObj() << "/" << iter->first.getGen()
  179 + << std::endl;
  180 +
  181 + if (b.count(iter->first) == 0)
  182 + {
  183 + std::cerr
  184 + << "not found"
  185 + << std::endl;
  186 + return false;
  187 + }
  188 +
  189 + QPDFXRefEntry xref_a = iter->second;
  190 + QPDFXRefEntry xref_b = b[iter->first];
  191 + if (xref_a.getType() != xref_b.getType())
  192 + {
  193 + std::cerr
  194 + << "different xref entry type"
  195 + << std::endl;
  196 + return false;
  197 + }
  198 +
  199 + switch (xref_a.getType())
  200 + {
  201 + case 0:
  202 + break;
  203 + case 1:
  204 + if (xref_a.getOffset() != xref_a.getOffset())
  205 + {
  206 + std::cerr
  207 + << "different offset"
  208 + << std::endl;
  209 + return false;
  210 + }
  211 + break;
  212 + case 2:
  213 + if (xref_a.getObjStreamNumber() != xref_a.getObjStreamNumber() ||
  214 + xref_a.getObjStreamIndex() != xref_a.getObjStreamIndex())
  215 + {
  216 + std::cerr
  217 + << "different stream number or index"
  218 + << std::endl;
  219 + return false;
  220 + }
  221 + break;
  222 + default:
  223 + std::cerr
  224 + << "unknown xref entry type"
  225 + << std::endl;
  226 + std::exit(2);
  227 + }
  228 + }
  229 +
  230 + return true;
  231 +}
  232 +
161 233 int main(int argc, char *argv[])
162 234 {
163 235 if (argc < 2)
... ... @@ -226,13 +298,20 @@ int main(int argc, char *argv[])
226 298 w.setPreserveUnreferencedObjects(bpreserve_unreferenced);
227 299 w.write();
228 300  
  301 + std::map<QPDFObjGen, QPDFXRefEntry> xrefs_w
  302 + = w.getWrittenXRefTable();
229 303 PointerHolder<Buffer> buf = w.getBuffer();
230 304  
231 305 QPDF qpdf_ren;
232 306 qpdf_ren.processMemoryFile("renumbered",
233 307 reinterpret_cast<char*>(buf->getBuffer()),
234 308 buf->getSize());
  309 + std::map<QPDFObjGen, QPDFXRefEntry> xrefs_ren
  310 + = qpdf_ren.getXRefTable();
235 311  
  312 + std::cout
  313 + << "--- compare between input and renumbered objects ---"
  314 + << std::endl;
236 315 for (std::vector<QPDFObjectHandle>::iterator iter = objs_in.begin();
237 316 iter != objs_in.end(); ++iter)
238 317 {
... ... @@ -260,6 +339,19 @@ int main(int argc, char *argv[])
260 339 std::exit(2);
261 340 }
262 341 }
  342 + std::cout << "complete" << std::endl;
  343 +
  344 + std::cout
  345 + << "--- compare between written and reloaded xref tables ---"
  346 + << std::endl;
  347 + if (!compare_xref_table(xrefs_w, xrefs_ren))
  348 + {
  349 + std::cerr
  350 + << "different"
  351 + << std::endl;
  352 + std::exit(2);
  353 + }
  354 + std::cout << "complete" << std::endl;
263 355  
264 356 std::cout << "succeeded" << std::endl;
265 357 }
... ...