Commit 82419ca013c8baaa50754eac7c71defdc9145dd0

Authored by m-holger
1 parent 742cc7d8

Add new data member QPDF::Xref_table::table

libqpdf/QPDF.cc
@@ -561,13 +561,13 @@ QPDF::Xref_table::reconstruct(QPDFExc& e) @@ -561,13 +561,13 @@ QPDF::Xref_table::reconstruct(QPDFExc& e)
561 561
562 // Delete all references to type 1 (uncompressed) objects 562 // Delete all references to type 1 (uncompressed) objects
563 std::set<QPDFObjGen> to_delete; 563 std::set<QPDFObjGen> to_delete;
564 - for (auto const& iter: *this) { 564 + for (auto const& iter: table) {
565 if (iter.second.getType() == 1) { 565 if (iter.second.getType() == 1) {
566 to_delete.insert(iter.first); 566 to_delete.insert(iter.first);
567 } 567 }
568 } 568 }
569 for (auto const& iter: to_delete) { 569 for (auto const& iter: to_delete) {
570 - erase(iter); 570 + table.erase(iter);
571 } 571 }
572 572
573 file->seek(0, SEEK_END); 573 file->seek(0, SEEK_END);
@@ -609,7 +609,7 @@ QPDF::Xref_table::reconstruct(QPDFExc&amp; e) @@ -609,7 +609,7 @@ QPDF::Xref_table::reconstruct(QPDFExc&amp; e)
609 if (!trailer) { 609 if (!trailer) {
610 qpdf_offset_t max_offset{0}; 610 qpdf_offset_t max_offset{0};
611 // If there are any xref streams, take the last one to appear. 611 // If there are any xref streams, take the last one to appear.
612 - for (auto const& iter: *this) { 612 + for (auto const& iter: table) {
613 auto entry = iter.second; 613 auto entry = iter.second;
614 if (entry.getType() != 1) { 614 if (entry.getType() != 1) {
615 continue; 615 continue;
@@ -647,7 +647,7 @@ QPDF::Xref_table::reconstruct(QPDFExc&amp; e) @@ -647,7 +647,7 @@ QPDF::Xref_table::reconstruct(QPDFExc&amp; e)
647 647
648 throw damaged_pdf("unable to find trailer dictionary while recovering damaged file"); 648 throw damaged_pdf("unable to find trailer dictionary while recovering damaged file");
649 } 649 }
650 - if (empty()) { 650 + if (table.empty()) {
651 // We cannot check for an empty xref table in parse because empty tables are valid when 651 // We cannot check for an empty xref table in parse because empty tables are valid when
652 // creating QPDF objects from JSON. 652 // creating QPDF objects from JSON.
653 throw damaged_pdf("unable to find objects while recovering damaged file"); 653 throw damaged_pdf("unable to find objects while recovering damaged file");
@@ -735,8 +735,8 @@ QPDF::Xref_table::read(qpdf_offset_t xref_offset) @@ -735,8 +735,8 @@ QPDF::Xref_table::read(qpdf_offset_t xref_offset)
735 } 735 }
736 int size = trailer.getKey("/Size").getIntValueAsInt(); 736 int size = trailer.getKey("/Size").getIntValueAsInt();
737 int max_obj = 0; 737 int max_obj = 0;
738 - if (!empty()) {  
739 - max_obj = rbegin()->first.getObj(); 738 + if (!table.empty()) {
  739 + max_obj = table.rbegin()->first.getObj();
740 } 740 }
741 if (!deleted_objects.empty()) { 741 if (!deleted_objects.empty()) {
742 max_obj = std::max(max_obj, *deleted_objects.rbegin()); 742 max_obj = std::max(max_obj, *deleted_objects.rbegin());
@@ -754,10 +754,10 @@ QPDF::Xref_table::read(qpdf_offset_t xref_offset) @@ -754,10 +754,10 @@ QPDF::Xref_table::read(qpdf_offset_t xref_offset)
754 754
755 // Make sure we keep only the highest generation for any object. 755 // Make sure we keep only the highest generation for any object.
756 QPDFObjGen last_og{-1, 0}; 756 QPDFObjGen last_og{-1, 0};
757 - for (auto const& item: *this) { 757 + for (auto const& item: table) {
758 auto id = item.first.getObj(); 758 auto id = item.first.getObj();
759 if (id == last_og.getObj() && id > 0) { 759 if (id == last_og.getObj() && id > 0) {
760 - erase(last_og); 760 + table.erase(last_og);
761 qpdf.removeObject(last_og); 761 qpdf.removeObject(last_og);
762 } 762 }
763 last_og = item.first; 763 last_og = item.first;
@@ -1299,7 +1299,7 @@ QPDF::Xref_table::insert(int obj, int f0, qpdf_offset_t f1, int f2) @@ -1299,7 +1299,7 @@ QPDF::Xref_table::insert(int obj, int f0, qpdf_offset_t f1, int f2)
1299 return; 1299 return;
1300 } 1300 }
1301 1301
1302 - auto [iter, created] = try_emplace(QPDFObjGen(obj, (f0 == 2 ? 0 : f2))); 1302 + auto [iter, created] = table.try_emplace(QPDFObjGen(obj, (f0 == 2 ? 0 : f2)));
1303 if (!created) { 1303 if (!created) {
1304 QTC::TC("qpdf", "QPDF xref reused object"); 1304 QTC::TC("qpdf", "QPDF xref reused object");
1305 return; 1305 return;
@@ -1326,7 +1326,7 @@ QPDF::Xref_table::insert(int obj, int f0, qpdf_offset_t f1, int f2) @@ -1326,7 +1326,7 @@ QPDF::Xref_table::insert(int obj, int f0, qpdf_offset_t f1, int f2)
1326 void 1326 void
1327 QPDF::Xref_table::insert_free(QPDFObjGen og) 1327 QPDF::Xref_table::insert_free(QPDFObjGen og)
1328 { 1328 {
1329 - if (!count(og)) { 1329 + if (!table.count(og)) {
1330 deleted_objects.insert(og.getObj()); 1330 deleted_objects.insert(og.getObj());
1331 } 1331 }
1332 } 1332 }
@@ -1346,7 +1346,7 @@ QPDF::Xref_table::insert_reconstructed(int obj, qpdf_offset_t f1, int f2) @@ -1346,7 +1346,7 @@ QPDF::Xref_table::insert_reconstructed(int obj, qpdf_offset_t f1, int f2)
1346 // deleted_objects stores the uncompressed objects removed from the xref table at the start 1346 // deleted_objects stores the uncompressed objects removed from the xref table at the start
1347 // of recovery. 1347 // of recovery.
1348 QTC::TC("qpdf", "QPDF xref overwrite object"); 1348 QTC::TC("qpdf", "QPDF xref overwrite object");
1349 - insert_or_assign(QPDFObjGen(obj, f2), QPDFXRefEntry(f1)); 1349 + table.insert_or_assign(QPDFObjGen(obj, f2), QPDFXRefEntry(f1));
1350 } 1350 }
1351 } 1351 }
1352 1352
@@ -1360,7 +1360,7 @@ void @@ -1360,7 +1360,7 @@ void
1360 QPDF::Xref_table::show() 1360 QPDF::Xref_table::show()
1361 { 1361 {
1362 auto& cout = *qpdf.m->log->getInfo(); 1362 auto& cout = *qpdf.m->log->getInfo();
1363 - for (auto const& iter: *this) { 1363 + for (auto const& iter: table) {
1364 QPDFObjGen const& og = iter.first; 1364 QPDFObjGen const& og = iter.first;
1365 QPDFXRefEntry const& entry = iter.second; 1365 QPDFXRefEntry const& entry = iter.second;
1366 cout << og.unparse('/') << ": "; 1366 cout << og.unparse('/') << ": ";
@@ -1386,7 +1386,7 @@ bool @@ -1386,7 +1386,7 @@ bool
1386 QPDF::Xref_table::resolve() 1386 QPDF::Xref_table::resolve()
1387 { 1387 {
1388 bool may_change = !reconstructed; 1388 bool may_change = !reconstructed;
1389 - for (auto& iter: *this) { 1389 + for (auto& iter: table) {
1390 if (qpdf.isUnresolved(iter.first)) { 1390 if (qpdf.isUnresolved(iter.first)) {
1391 qpdf.resolve(iter.first); 1391 qpdf.resolve(iter.first);
1392 if (may_change && reconstructed) { 1392 if (may_change && reconstructed) {
@@ -1459,7 +1459,7 @@ QPDF::Xref_table::read_trailer() @@ -1459,7 +1459,7 @@ QPDF::Xref_table::read_trailer()
1459 qpdf_offset_t offset = file->tell(); 1459 qpdf_offset_t offset = file->tell();
1460 bool empty = false; 1460 bool empty = false;
1461 auto object = 1461 auto object =
1462 - QPDFParser(*qpdf.m->file, "trailer", *tokenizer, nullptr, &qpdf, true).parse(empty, false); 1462 + QPDFParser(*file, "trailer", tokenizer, nullptr, &qpdf, true).parse(empty, false);
1463 if (empty) { 1463 if (empty) {
1464 // Nothing in the PDF spec appears to allow empty objects, but they have been encountered in 1464 // Nothing in the PDF spec appears to allow empty objects, but they have been encountered in
1465 // actual PDF files and Adobe Reader appears to ignore them. 1465 // actual PDF files and Adobe Reader appears to ignore them.
libqpdf/qpdf/QPDF_private.hh
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 #include <qpdf/QPDF.hh> 4 #include <qpdf/QPDF.hh>
5 5
6 // Xref_table encapsulates the pdf's xref table and trailer. 6 // Xref_table encapsulates the pdf's xref table and trailer.
7 -class QPDF::Xref_table: std::map<QPDFObjGen, QPDFXRefEntry> 7 +class QPDF::Xref_table
8 { 8 {
9 public: 9 public:
10 Xref_table(QPDF& qpdf, InputSource* const& file) : 10 Xref_table(QPDF& qpdf, InputSource* const& file) :
@@ -23,45 +23,45 @@ class QPDF::Xref_table: std::map&lt;QPDFObjGen, QPDFXRefEntry&gt; @@ -23,45 +23,45 @@ class QPDF::Xref_table: std::map&lt;QPDFObjGen, QPDFXRefEntry&gt;
23 int 23 int
24 type(QPDFObjGen og) const 24 type(QPDFObjGen og) const
25 { 25 {
26 - auto it = find(og);  
27 - return it == end() ? 0 : it->second.getType(); 26 + auto it = table.find(og);
  27 + return it == table.end() ? 0 : it->second.getType();
28 } 28 }
29 29
30 // Returns 0 if og is not in table. 30 // Returns 0 if og is not in table.
31 qpdf_offset_t 31 qpdf_offset_t
32 offset(QPDFObjGen og) const 32 offset(QPDFObjGen og) const
33 { 33 {
34 - auto it = find(og);  
35 - return it == end() ? 0 : it->second.getOffset(); 34 + auto it = table.find(og);
  35 + return it == table.end() ? 0 : it->second.getOffset();
36 } 36 }
37 37
38 // Returns 0 if og is not in table. 38 // Returns 0 if og is not in table.
39 int 39 int
40 stream_number(int id) const 40 stream_number(int id) const
41 { 41 {
42 - auto it = find(QPDFObjGen(id, 0));  
43 - return it == end() ? 0 : it->second.getObjStreamNumber(); 42 + auto it = table.find(QPDFObjGen(id, 0));
  43 + return it == table.end() ? 0 : it->second.getObjStreamNumber();
44 } 44 }
45 45
46 int 46 int
47 stream_index(int id) const 47 stream_index(int id) const
48 { 48 {
49 - auto it = find(QPDFObjGen(id, 0));  
50 - return it == end() ? 0 : it->second.getObjStreamIndex(); 49 + auto it = table.find(QPDFObjGen(id, 0));
  50 + return it == table.end() ? 0 : it->second.getObjStreamIndex();
51 } 51 }
52 52
53 // Temporary access to underlying map 53 // Temporary access to underlying map
54 std::map<QPDFObjGen, QPDFXRefEntry> const& 54 std::map<QPDFObjGen, QPDFXRefEntry> const&
55 as_map() 55 as_map()
56 { 56 {
57 - return *this; 57 + return table;
58 } 58 }
59 59
60 // Temporary access to underlying map size 60 // Temporary access to underlying map size
61 size_t 61 size_t
62 size() const noexcept 62 size() const noexcept
63 { 63 {
64 - return trailer ? std::map<QPDFObjGen, QPDFXRefEntry>::size() : 0; 64 + return trailer ? table.size() : 0;
65 } 65 }
66 66
67 QPDFObjectHandle trailer; 67 QPDFObjectHandle trailer;
@@ -133,6 +133,8 @@ class QPDF::Xref_table: std::map&lt;QPDFObjGen, QPDFXRefEntry&gt; @@ -133,6 +133,8 @@ class QPDF::Xref_table: std::map&lt;QPDFObjGen, QPDFXRefEntry&gt;
133 QPDF& qpdf; 133 QPDF& qpdf;
134 InputSource* const& file; 134 InputSource* const& file;
135 QPDFTokenizer tokenizer; 135 QPDFTokenizer tokenizer;
  136 +
  137 + std::map<QPDFObjGen, QPDFXRefEntry> table;
136 }; 138 };
137 139
138 // Writer class is restricted to QPDFWriter so that only it can call certain methods. 140 // Writer class is restricted to QPDFWriter so that only it can call certain methods.