Commit eb6296712e1927ba918986ffed890914f0023ed9

Authored by m-holger
1 parent 8d9b9a1a

Change Array to use std::vector<QPDFObjectHandle> for storage

libqpdf/QPDFObjectHandle.cc
@@ -322,17 +322,18 @@ QPDFObject::copy(bool shallow) @@ -322,17 +322,18 @@ QPDFObject::copy(bool shallow)
322 for (auto const& element: a.sp->elements) { 322 for (auto const& element: a.sp->elements) {
323 auto const& obj = element.second; 323 auto const& obj = element.second;
324 result.sp->elements[element.first] = 324 result.sp->elements[element.first] =
325 - obj->getObjGen().isIndirect() ? obj : obj->copy(); 325 + obj.getObj()->getObjGen().isIndirect() ? obj : obj.getObj()->copy();
326 } 326 }
327 return QPDFObject::create<QPDF_Array>(std::move(result)); 327 return QPDFObject::create<QPDF_Array>(std::move(result));
328 } else { 328 } else {
329 - std::vector<std::shared_ptr<QPDFObject>> result; 329 + std::vector<QPDFObjectHandle> result;
330 result.reserve(a.elements.size()); 330 result.reserve(a.elements.size());
331 for (auto const& element: a.elements) { 331 for (auto const& element: a.elements) {
332 result.push_back( 332 result.push_back(
333 - element  
334 - ? (element->getObjGen().isIndirect() ? element : element->copy())  
335 - : element); 333 + element ? (element.getObj()->getObjGen().isIndirect()
  334 + ? element
  335 + : element.getObj()->copy())
  336 + : element);
336 } 337 }
337 return QPDFObject::create<QPDF_Array>(std::move(result), false); 338 return QPDFObject::create<QPDF_Array>(std::move(result), false);
338 } 339 }
@@ -404,9 +405,9 @@ QPDFObject::unparse() @@ -404,9 +405,9 @@ QPDFObject::unparse()
404 for (int j = next; j < key; ++j) { 405 for (int j = next; j < key; ++j) {
405 result += "null "; 406 result += "null ";
406 } 407 }
407 - auto item_og = item.second->resolved_object()->getObjGen(); 408 + auto item_og = item.second.getObj()->resolved_object()->getObjGen();
408 result += item_og.isIndirect() ? item_og.unparse(' ') + " R " 409 result += item_og.isIndirect() ? item_og.unparse(' ') + " R "
409 - : item.second->unparse() + " "; 410 + : item.second.getObj()->unparse() + " ";
410 next = ++key; 411 next = ++key;
411 } 412 }
412 for (int j = next; j < a.sp->size; ++j) { 413 for (int j = next; j < a.sp->size; ++j) {
@@ -414,9 +415,9 @@ QPDFObject::unparse() @@ -414,9 +415,9 @@ QPDFObject::unparse()
414 } 415 }
415 } else { 416 } else {
416 for (auto const& item: a.elements) { 417 for (auto const& item: a.elements) {
417 - auto item_og = item->resolved_object()->getObjGen();  
418 - result +=  
419 - item_og.isIndirect() ? item_og.unparse(' ') + " R " : item->unparse() + " "; 418 + auto item_og = item.getObj()->resolved_object()->getObjGen();
  419 + result += item_og.isIndirect() ? item_og.unparse(' ') + " R "
  420 + : item.getObj()->unparse() + " ";
420 } 421 }
421 } 422 }
422 result += "]"; 423 result += "]";
@@ -524,11 +525,11 @@ QPDFObject::write_json(int json_version, JSON::Writer&amp; p) @@ -524,11 +525,11 @@ QPDFObject::write_json(int json_version, JSON::Writer&amp; p)
524 p.writeNext() << "null"; 525 p.writeNext() << "null";
525 } 526 }
526 p.writeNext(); 527 p.writeNext();
527 - auto item_og = item.second->getObjGen(); 528 + auto item_og = item.second.getObj()->getObjGen();
528 if (item_og.isIndirect()) { 529 if (item_og.isIndirect()) {
529 p << "\"" << item_og.unparse(' ') << " R\""; 530 p << "\"" << item_og.unparse(' ') << " R\"";
530 } else { 531 } else {
531 - item.second->write_json(json_version, p); 532 + item.second.getObj()->write_json(json_version, p);
532 } 533 }
533 next = ++key; 534 next = ++key;
534 } 535 }
@@ -538,11 +539,11 @@ QPDFObject::write_json(int json_version, JSON::Writer&amp; p) @@ -538,11 +539,11 @@ QPDFObject::write_json(int json_version, JSON::Writer&amp; p)
538 } else { 539 } else {
539 for (auto const& item: a.elements) { 540 for (auto const& item: a.elements) {
540 p.writeNext(); 541 p.writeNext();
541 - auto item_og = item->getObjGen(); 542 + auto item_og = item.getObj()->getObjGen();
542 if (item_og.isIndirect()) { 543 if (item_og.isIndirect()) {
543 p << "\"" << item_og.unparse(' ') << " R\""; 544 p << "\"" << item_og.unparse(' ') << " R\"";
544 } else { 545 } else {
545 - item->write_json(json_version, p); 546 + item.getObj()->write_json(json_version, p);
546 } 547 }
547 } 548 }
548 } 549 }
@@ -598,14 +599,14 @@ QPDFObject::disconnect() @@ -598,14 +599,14 @@ QPDFObject::disconnect()
598 if (a.sp) { 599 if (a.sp) {
599 for (auto& item: a.sp->elements) { 600 for (auto& item: a.sp->elements) {
600 auto& obj = item.second; 601 auto& obj = item.second;
601 - if (!obj->getObjGen().isIndirect()) {  
602 - obj->disconnect(); 602 + if (!obj.getObj()->getObjGen().isIndirect()) {
  603 + obj.getObj()->disconnect();
603 } 604 }
604 } 605 }
605 } else { 606 } else {
606 for (auto& obj: a.elements) { 607 for (auto& obj: a.elements) {
607 - if (!obj->getObjGen().isIndirect()) {  
608 - obj->disconnect(); 608 + if (!obj.getObj()->getObjGen().isIndirect()) {
  609 + obj.getObj()->disconnect();
609 } 610 }
610 } 611 }
611 } 612 }
libqpdf/QPDFParser.cc
@@ -209,8 +209,9 @@ QPDFParser::parseRemainder(bool content_stream) @@ -209,8 +209,9 @@ QPDFParser::parseRemainder(bool content_stream)
209 return {QPDFObject::create<QPDF_Null>()}; 209 return {QPDFObject::create<QPDF_Null>()};
210 } 210 }
211 if (frame->state == st_array) { 211 if (frame->state == st_array) {
212 - auto object = QPDFObject::create<QPDF_Array>(  
213 - std::move(frame->olist), frame->null_count > 100); 212 + auto object = frame->null_count > 100
  213 + ? QPDFObject::create<QPDF_Array>(std::move(frame->olist), true)
  214 + : QPDFObject::create<QPDF_Array>(std::move(frame->olist));
214 setDescription(object, frame->offset - 1); 215 setDescription(object, frame->offset - 1);
215 // The `offset` points to the next of "[". Set the rewind offset to point to the 216 // The `offset` points to the next of "[". Set the rewind offset to point to the
216 // beginning of "[". This has been explicitly tested with whitespace surrounding the 217 // beginning of "[". This has been explicitly tested with whitespace surrounding the
@@ -451,8 +452,8 @@ QPDFParser::fixMissingKeys() @@ -451,8 +452,8 @@ QPDFParser::fixMissingKeys()
451 { 452 {
452 std::set<std::string> names; 453 std::set<std::string> names;
453 for (auto& obj: frame->olist) { 454 for (auto& obj: frame->olist) {
454 - if (obj->getTypeCode() == ::ot_name) {  
455 - names.insert(obj->getStringValue()); 455 + if (obj.getObj()->getTypeCode() == ::ot_name) {
  456 + names.insert(obj.getObj()->getStringValue());
456 } 457 }
457 } 458 }
458 int next_fake_key = 1; 459 int next_fake_key = 1;
libqpdf/QPDF_Array.cc
@@ -8,17 +8,6 @@ using namespace qpdf; @@ -8,17 +8,6 @@ using namespace qpdf;
8 static const QPDFObjectHandle null_oh = QPDFObjectHandle::newNull(); 8 static const QPDFObjectHandle null_oh = QPDFObjectHandle::newNull();
9 9
10 inline void 10 inline void
11 -QPDF_Array::checkOwnership(QPDFObjectHandle const& item) const  
12 -{  
13 - // This is only called from QPDF_Array::setFromVector, which in turn is only called from create.  
14 - // At his point qpdf is a nullptr and therefore the ownership check reduces to an uninitialized  
15 - // check  
16 - if (!item.getObjectPtr()) {  
17 - throw std::logic_error("Attempting to add an uninitialized object to a QPDF_Array.");  
18 - }  
19 -}  
20 -  
21 -inline void  
22 Array::checkOwnership(QPDFObjectHandle const& item) const 11 Array::checkOwnership(QPDFObjectHandle const& item) const
23 { 12 {
24 if (auto o = item.getObjectPtr()) { 13 if (auto o = item.getObjectPtr()) {
@@ -36,17 +25,13 @@ Array::checkOwnership(QPDFObjectHandle const&amp; item) const @@ -36,17 +25,13 @@ Array::checkOwnership(QPDFObjectHandle const&amp; item) const
36 } 25 }
37 } 26 }
38 27
39 -QPDF_Array::QPDF_Array(std::vector<QPDFObjectHandle> const& v)  
40 -{  
41 - setFromVector(v);  
42 -}  
43 -  
44 -QPDF_Array::QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& v, bool sparse) 28 +QPDF_Array::QPDF_Array(std::vector<QPDFObjectHandle>&& v, bool sparse)
45 { 29 {
46 if (sparse) { 30 if (sparse) {
47 sp = std::make_unique<Sparse>(); 31 sp = std::make_unique<Sparse>();
48 for (auto&& item: v) { 32 for (auto&& item: v) {
49 - if (item->getTypeCode() != ::ot_null || item->getObjGen().isIndirect()) { 33 + if (item.getObj()->getTypeCode() != ::ot_null ||
  34 + item.getObj()->getObjGen().isIndirect()) {
50 sp->elements[sp->size] = std::move(item); 35 sp->elements[sp->size] = std::move(item);
51 } 36 }
52 ++sp->size; 37 ++sp->size;
@@ -108,7 +93,7 @@ Array::getAsVector() const @@ -108,7 +93,7 @@ Array::getAsVector() const
108 v.resize(size_t(size()), null_oh); 93 v.resize(size_t(size()), null_oh);
109 return v; 94 return v;
110 } else { 95 } else {
111 - return {a->elements.cbegin(), a->elements.cend()}; 96 + return a->elements;
112 } 97 }
113 } 98 }
114 99
@@ -121,25 +106,14 @@ Array::setAt(int at, QPDFObjectHandle const&amp; oh) @@ -121,25 +106,14 @@ Array::setAt(int at, QPDFObjectHandle const&amp; oh)
121 auto a = array(); 106 auto a = array();
122 checkOwnership(oh); 107 checkOwnership(oh);
123 if (a->sp) { 108 if (a->sp) {
124 - a->sp->elements[at] = oh.getObj(); 109 + a->sp->elements[at] = oh;
125 } else { 110 } else {
126 - a->elements[size_t(at)] = oh.getObj(); 111 + a->elements[size_t(at)] = oh;
127 } 112 }
128 return true; 113 return true;
129 } 114 }
130 115
131 void 116 void
132 -QPDF_Array::setFromVector(std::vector<QPDFObjectHandle> const& v)  
133 -{  
134 - elements.resize(0);  
135 - elements.reserve(v.size());  
136 - for (auto const& item: v) {  
137 - checkOwnership(item);  
138 - elements.push_back(item.getObj());  
139 - }  
140 -}  
141 -  
142 -void  
143 Array::setFromVector(std::vector<QPDFObjectHandle> const& v) 117 Array::setFromVector(std::vector<QPDFObjectHandle> const& v)
144 { 118 {
145 auto a = array(); 119 auto a = array();
@@ -147,7 +121,7 @@ Array::setFromVector(std::vector&lt;QPDFObjectHandle&gt; const&amp; v) @@ -147,7 +121,7 @@ Array::setFromVector(std::vector&lt;QPDFObjectHandle&gt; const&amp; v)
147 a->elements.reserve(v.size()); 121 a->elements.reserve(v.size());
148 for (auto const& item: v) { 122 for (auto const& item: v) {
149 checkOwnership(item); 123 checkOwnership(item);
150 - a->elements.push_back(item.getObj()); 124 + a->elements.emplace_back(item);
151 } 125 }
152 } 126 }
153 127
@@ -190,9 +164,9 @@ Array::push_back(QPDFObjectHandle const&amp; item) @@ -190,9 +164,9 @@ Array::push_back(QPDFObjectHandle const&amp; item)
190 auto a = array(); 164 auto a = array();
191 checkOwnership(item); 165 checkOwnership(item);
192 if (a->sp) { 166 if (a->sp) {
193 - a->sp->elements[(a->sp->size)++] = item.getObj(); 167 + a->sp->elements[(a->sp->size)++] = item;
194 } else { 168 } else {
195 - a->elements.push_back(item.getObj()); 169 + a->elements.emplace_back(item);
196 } 170 }
197 } 171 }
198 172
libqpdf/qpdf/QPDFObject_private.hh
@@ -35,7 +35,7 @@ class QPDF_Array final @@ -35,7 +35,7 @@ class QPDF_Array final
35 struct Sparse 35 struct Sparse
36 { 36 {
37 int size{0}; 37 int size{0};
38 - std::map<int, std::shared_ptr<QPDFObject>> elements; 38 + std::map<int, QPDFObjectHandle> elements;
39 }; 39 };
40 40
41 public: 41 public:
@@ -51,19 +51,25 @@ class QPDF_Array final @@ -51,19 +51,25 @@ class QPDF_Array final
51 private: 51 private:
52 friend class QPDFObject; 52 friend class QPDFObject;
53 friend class qpdf::Array; 53 friend class qpdf::Array;
54 - QPDF_Array(std::vector<QPDFObjectHandle> const& items);  
55 - QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& items, bool sparse); 54 + QPDF_Array(std::vector<QPDFObjectHandle> const& items) :
  55 + elements(items)
  56 + {
  57 + }
  58 + QPDF_Array(std::vector<QPDFObjectHandle>&& items, bool sparse);
  59 +
  60 + QPDF_Array(std::vector<QPDFObjectHandle>&& items) :
  61 + elements(std::move(items))
  62 + {
  63 + }
56 64
57 int 65 int
58 size() const 66 size() const
59 { 67 {
60 return sp ? sp->size : int(elements.size()); 68 return sp ? sp->size : int(elements.size());
61 } 69 }
62 - void setFromVector(std::vector<QPDFObjectHandle> const& items);  
63 - void checkOwnership(QPDFObjectHandle const& item) const;  
64 70
65 std::unique_ptr<Sparse> sp; 71 std::unique_ptr<Sparse> sp;
66 - std::vector<std::shared_ptr<QPDFObject>> elements; 72 + std::vector<QPDFObjectHandle> elements;
67 }; 73 };
68 74
69 class QPDF_Bool final 75 class QPDF_Bool final
@@ -202,9 +208,6 @@ class QPDF_Stream final @@ -202,9 +208,6 @@ class QPDF_Stream final
202 } 208 }
203 209
204 private: 210 private:
205 - void replaceFilterData(  
206 - QPDFObjectHandle const& filter, QPDFObjectHandle const& decode_parms, size_t length);  
207 -  
208 bool filter_on_write{true}; 211 bool filter_on_write{true};
209 QPDFObjectHandle stream_dict; 212 QPDFObjectHandle stream_dict;
210 size_t length{0}; 213 size_t length{0};
libqpdf/qpdf/QPDFParser.hh
@@ -46,7 +46,7 @@ class QPDFParser @@ -46,7 +46,7 @@ class QPDFParser
46 { 46 {
47 } 47 }
48 48
49 - std::vector<std::shared_ptr<QPDFObject>> olist; 49 + std::vector<QPDFObjectHandle> olist;
50 std::map<std::string, QPDFObjectHandle> dict; 50 std::map<std::string, QPDFObjectHandle> dict;
51 parser_state_e state; 51 parser_state_e state;
52 std::string key; 52 std::string key;
libtests/sparse_array.cc
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 int 9 int
10 main() 10 main()
11 { 11 {
12 - auto obj = QPDFObject::create<QPDF_Array>(std::vector<std::shared_ptr<QPDFObject>>(), true); 12 + auto obj = QPDFObject::create<QPDF_Array>(std::vector<QPDFObjectHandle>(), true);
13 auto a = qpdf::Array(obj); 13 auto a = qpdf::Array(obj);
14 14
15 assert(a.size() == 0); 15 assert(a.size() == 0);
@@ -88,7 +88,7 @@ main() @@ -88,7 +88,7 @@ main()
88 pdf.emptyPDF(); 88 pdf.emptyPDF();
89 89
90 obj = QPDFObject::create<QPDF_Array>( 90 obj = QPDFObject::create<QPDF_Array>(
91 - std::vector<std::shared_ptr<QPDFObject>>{10, "null"_qpdf.getObj()}, true); 91 + std::vector<QPDFObjectHandle>{10, "null"_qpdf.getObj()}, true);
92 auto b = qpdf::Array(obj); 92 auto b = qpdf::Array(obj);
93 b.setAt(5, pdf.newIndirectNull()); 93 b.setAt(5, pdf.newIndirectNull());
94 b.setAt(7, "[0 1 2 3]"_qpdf); 94 b.setAt(7, "[0 1 2 3]"_qpdf);