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,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& p) | @@ -524,11 +525,11 @@ QPDFObject::write_json(int json_version, JSON::Writer& 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& p) | @@ -538,11 +539,11 @@ QPDFObject::write_json(int json_version, JSON::Writer& 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& item) const | @@ -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 | 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& oh) | @@ -121,25 +106,14 @@ Array::setAt(int at, QPDFObjectHandle const& 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<QPDFObjectHandle> const& v) | @@ -147,7 +121,7 @@ Array::setFromVector(std::vector<QPDFObjectHandle> const& 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& item) | @@ -190,9 +164,9 @@ Array::push_back(QPDFObjectHandle const& 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); |