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 322 for (auto const& element: a.sp->elements) {
323 323 auto const& obj = element.second;
324 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 327 return QPDFObject::create<QPDF_Array>(std::move(result));
328 328 } else {
329   - std::vector<std::shared_ptr<QPDFObject>> result;
  329 + std::vector<QPDFObjectHandle> result;
330 330 result.reserve(a.elements.size());
331 331 for (auto const& element: a.elements) {
332 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 338 return QPDFObject::create<QPDF_Array>(std::move(result), false);
338 339 }
... ... @@ -404,9 +405,9 @@ QPDFObject::unparse()
404 405 for (int j = next; j < key; ++j) {
405 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 409 result += item_og.isIndirect() ? item_og.unparse(' ') + " R "
409   - : item.second->unparse() + " ";
  410 + : item.second.getObj()->unparse() + " ";
410 411 next = ++key;
411 412 }
412 413 for (int j = next; j < a.sp->size; ++j) {
... ... @@ -414,9 +415,9 @@ QPDFObject::unparse()
414 415 }
415 416 } else {
416 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 423 result += "]";
... ... @@ -524,11 +525,11 @@ QPDFObject::write_json(int json_version, JSON::Writer&amp; p)
524 525 p.writeNext() << "null";
525 526 }
526 527 p.writeNext();
527   - auto item_og = item.second->getObjGen();
  528 + auto item_og = item.second.getObj()->getObjGen();
528 529 if (item_og.isIndirect()) {
529 530 p << "\"" << item_og.unparse(' ') << " R\"";
530 531 } else {
531   - item.second->write_json(json_version, p);
  532 + item.second.getObj()->write_json(json_version, p);
532 533 }
533 534 next = ++key;
534 535 }
... ... @@ -538,11 +539,11 @@ QPDFObject::write_json(int json_version, JSON::Writer&amp; p)
538 539 } else {
539 540 for (auto const& item: a.elements) {
540 541 p.writeNext();
541   - auto item_og = item->getObjGen();
  542 + auto item_og = item.getObj()->getObjGen();
542 543 if (item_og.isIndirect()) {
543 544 p << "\"" << item_og.unparse(' ') << " R\"";
544 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 599 if (a.sp) {
599 600 for (auto& item: a.sp->elements) {
600 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 606 } else {
606 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 209 return {QPDFObject::create<QPDF_Null>()};
210 210 }
211 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 215 setDescription(object, frame->offset - 1);
215 216 // The `offset` points to the next of "[". Set the rewind offset to point to the
216 217 // beginning of "[". This has been explicitly tested with whitespace surrounding the
... ... @@ -451,8 +452,8 @@ QPDFParser::fixMissingKeys()
451 452 {
452 453 std::set<std::string> names;
453 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 459 int next_fake_key = 1;
... ...
libqpdf/QPDF_Array.cc
... ... @@ -8,17 +8,6 @@ using namespace qpdf;
8 8 static const QPDFObjectHandle null_oh = QPDFObjectHandle::newNull();
9 9  
10 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 11 Array::checkOwnership(QPDFObjectHandle const& item) const
23 12 {
24 13 if (auto o = item.getObjectPtr()) {
... ... @@ -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 30 if (sparse) {
47 31 sp = std::make_unique<Sparse>();
48 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 35 sp->elements[sp->size] = std::move(item);
51 36 }
52 37 ++sp->size;
... ... @@ -108,7 +93,7 @@ Array::getAsVector() const
108 93 v.resize(size_t(size()), null_oh);
109 94 return v;
110 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 106 auto a = array();
122 107 checkOwnership(oh);
123 108 if (a->sp) {
124   - a->sp->elements[at] = oh.getObj();
  109 + a->sp->elements[at] = oh;
125 110 } else {
126   - a->elements[size_t(at)] = oh.getObj();
  111 + a->elements[size_t(at)] = oh;
127 112 }
128 113 return true;
129 114 }
130 115  
131 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 117 Array::setFromVector(std::vector<QPDFObjectHandle> const& v)
144 118 {
145 119 auto a = array();
... ... @@ -147,7 +121,7 @@ Array::setFromVector(std::vector&lt;QPDFObjectHandle&gt; const&amp; v)
147 121 a->elements.reserve(v.size());
148 122 for (auto const& item: v) {
149 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 164 auto a = array();
191 165 checkOwnership(item);
192 166 if (a->sp) {
193   - a->sp->elements[(a->sp->size)++] = item.getObj();
  167 + a->sp->elements[(a->sp->size)++] = item;
194 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 35 struct Sparse
36 36 {
37 37 int size{0};
38   - std::map<int, std::shared_ptr<QPDFObject>> elements;
  38 + std::map<int, QPDFObjectHandle> elements;
39 39 };
40 40  
41 41 public:
... ... @@ -51,19 +51,25 @@ class QPDF_Array final
51 51 private:
52 52 friend class QPDFObject;
53 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 65 int
58 66 size() const
59 67 {
60 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 71 std::unique_ptr<Sparse> sp;
66   - std::vector<std::shared_ptr<QPDFObject>> elements;
  72 + std::vector<QPDFObjectHandle> elements;
67 73 };
68 74  
69 75 class QPDF_Bool final
... ... @@ -202,9 +208,6 @@ class QPDF_Stream final
202 208 }
203 209  
204 210 private:
205   - void replaceFilterData(
206   - QPDFObjectHandle const& filter, QPDFObjectHandle const& decode_parms, size_t length);
207   -
208 211 bool filter_on_write{true};
209 212 QPDFObjectHandle stream_dict;
210 213 size_t length{0};
... ...
libqpdf/qpdf/QPDFParser.hh
... ... @@ -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 50 std::map<std::string, QPDFObjectHandle> dict;
51 51 parser_state_e state;
52 52 std::string key;
... ...
libtests/sparse_array.cc
... ... @@ -9,7 +9,7 @@
9 9 int
10 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 13 auto a = qpdf::Array(obj);
14 14  
15 15 assert(a.size() == 0);
... ... @@ -88,7 +88,7 @@ main()
88 88 pdf.emptyPDF();
89 89  
90 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 92 auto b = qpdf::Array(obj);
93 93 b.setAt(5, pdf.newIndirectNull());
94 94 b.setAt(7, "[0 1 2 3]"_qpdf);
... ...