Commit eb6296712e1927ba918986ffed890914f0023ed9
1 parent
8d9b9a1a
Change Array to use std::vector<QPDFObjectHandle> for storage
Showing
6 changed files
with
48 additions
and
69 deletions
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& 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& 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& 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& 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<QPDFObjectHandle> const& 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& 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
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); | ... | ... |