Commit e6db8ddeba560cd472f34be2e20e31ea2f4bfee3
1 parent
ea516493
Change SparseOHArray index type to int and elements type to map
There are no reasons other than historical to use size_t. On balance, using map is more efficient. Hold shared pointers to QPDFObjects rather than QPDFObjectHandles for consistencey with QPDF_Array.
Showing
3 changed files
with
32 additions
and
39 deletions
libqpdf/QPDF_Array.cc
| @@ -103,8 +103,8 @@ QPDF_Array::unparse() | @@ -103,8 +103,8 @@ QPDF_Array::unparse() | ||
| 103 | { | 103 | { |
| 104 | if (sparse) { | 104 | if (sparse) { |
| 105 | std::string result = "[ "; | 105 | std::string result = "[ "; |
| 106 | - size_t size = sp_elements.size(); | ||
| 107 | - for (size_t i = 0; i < size; ++i) { | 106 | + int size = sp_elements.size(); |
| 107 | + for (int i = 0; i < size; ++i) { | ||
| 108 | result += sp_elements.at(i).unparse(); | 108 | result += sp_elements.at(i).unparse(); |
| 109 | result += " "; | 109 | result += " "; |
| 110 | } | 110 | } |
| @@ -127,8 +127,8 @@ QPDF_Array::getJSON(int json_version) | @@ -127,8 +127,8 @@ QPDF_Array::getJSON(int json_version) | ||
| 127 | { | 127 | { |
| 128 | if (sparse) { | 128 | if (sparse) { |
| 129 | JSON j = JSON::makeArray(); | 129 | JSON j = JSON::makeArray(); |
| 130 | - size_t size = sp_elements.size(); | ||
| 131 | - for (size_t i = 0; i < size; ++i) { | 130 | + int size = sp_elements.size(); |
| 131 | + for (int i = 0; i < size; ++i) { | ||
| 132 | j.addArrayElement(sp_elements.at(i).getJSON(json_version)); | 132 | j.addArrayElement(sp_elements.at(i).getJSON(json_version)); |
| 133 | } | 133 | } |
| 134 | return j; | 134 | return j; |
| @@ -162,7 +162,7 @@ QPDF_Array::getItem(int n) const | @@ -162,7 +162,7 @@ QPDF_Array::getItem(int n) const | ||
| 162 | throw std::logic_error( | 162 | throw std::logic_error( |
| 163 | "INTERNAL ERROR: bounds error accessing QPDF_Array element"); | 163 | "INTERNAL ERROR: bounds error accessing QPDF_Array element"); |
| 164 | } | 164 | } |
| 165 | - return sp_elements.at(QIntC::to_size(n)); | 165 | + return sp_elements.at(n); |
| 166 | } else { | 166 | } else { |
| 167 | if ((n < 0) || (n >= QIntC::to_int(elements.size()))) { | 167 | if ((n < 0) || (n >= QIntC::to_int(elements.size()))) { |
| 168 | throw std::logic_error( | 168 | throw std::logic_error( |
| @@ -177,8 +177,8 @@ void | @@ -177,8 +177,8 @@ void | ||
| 177 | QPDF_Array::getAsVector(std::vector<QPDFObjectHandle>& v) const | 177 | QPDF_Array::getAsVector(std::vector<QPDFObjectHandle>& v) const |
| 178 | { | 178 | { |
| 179 | if (sparse) { | 179 | if (sparse) { |
| 180 | - size_t size = sp_elements.size(); | ||
| 181 | - for (size_t i = 0; i < size; ++i) { | 180 | + int size = sp_elements.size(); |
| 181 | + for (int i = 0; i < size; ++i) { | ||
| 182 | v.push_back(sp_elements.at(i)); | 182 | v.push_back(sp_elements.at(i)); |
| 183 | } | 183 | } |
| 184 | } else { | 184 | } else { |
| @@ -190,7 +190,7 @@ void | @@ -190,7 +190,7 @@ void | ||
| 190 | QPDF_Array::setItem(int n, QPDFObjectHandle const& oh) | 190 | QPDF_Array::setItem(int n, QPDFObjectHandle const& oh) |
| 191 | { | 191 | { |
| 192 | if (sparse) { | 192 | if (sparse) { |
| 193 | - sp_elements.setAt(QIntC::to_size(n), oh); | 193 | + sp_elements.setAt(n, oh); |
| 194 | } else { | 194 | } else { |
| 195 | size_t idx = size_t(n); | 195 | size_t idx = size_t(n); |
| 196 | if (n < 0 || idx >= elements.size()) { | 196 | if (n < 0 || idx >= elements.size()) { |
| @@ -239,11 +239,11 @@ QPDF_Array::insertItem(int at, QPDFObjectHandle const& item) | @@ -239,11 +239,11 @@ QPDF_Array::insertItem(int at, QPDFObjectHandle const& item) | ||
| 239 | { | 239 | { |
| 240 | if (sparse) { | 240 | if (sparse) { |
| 241 | // As special case, also allow insert beyond the end | 241 | // As special case, also allow insert beyond the end |
| 242 | - if ((at < 0) || (at > QIntC::to_int(sp_elements.size()))) { | 242 | + if ((at < 0) || (at > sp_elements.size())) { |
| 243 | throw std::logic_error( | 243 | throw std::logic_error( |
| 244 | "INTERNAL ERROR: bounds error accessing QPDF_Array element"); | 244 | "INTERNAL ERROR: bounds error accessing QPDF_Array element"); |
| 245 | } | 245 | } |
| 246 | - sp_elements.insert(QIntC::to_size(at), item); | 246 | + sp_elements.insert(at, item); |
| 247 | } else { | 247 | } else { |
| 248 | // As special case, also allow insert beyond the end | 248 | // As special case, also allow insert beyond the end |
| 249 | size_t idx = QIntC::to_size(at); | 249 | size_t idx = QIntC::to_size(at); |
| @@ -275,7 +275,7 @@ void | @@ -275,7 +275,7 @@ void | ||
| 275 | QPDF_Array::eraseItem(int at) | 275 | QPDF_Array::eraseItem(int at) |
| 276 | { | 276 | { |
| 277 | if (sparse) { | 277 | if (sparse) { |
| 278 | - sp_elements.erase(QIntC::to_size(at)); | 278 | + sp_elements.erase(at); |
| 279 | } else { | 279 | } else { |
| 280 | size_t idx = QIntC::to_size(at); | 280 | size_t idx = QIntC::to_size(at); |
| 281 | if (idx >= elements.size()) { | 281 | if (idx >= elements.size()) { |
libqpdf/SparseOHArray.cc
| 1 | #include <qpdf/SparseOHArray.hh> | 1 | #include <qpdf/SparseOHArray.hh> |
| 2 | 2 | ||
| 3 | -#include <qpdf/QPDFObjectHandle.hh> | ||
| 4 | -#include <qpdf/QPDFObject_private.hh> | ||
| 5 | - | ||
| 6 | #include <stdexcept> | 3 | #include <stdexcept> |
| 7 | 4 | ||
| 8 | -SparseOHArray::SparseOHArray() : | ||
| 9 | - n_elements(0) | ||
| 10 | -{ | ||
| 11 | -} | ||
| 12 | - | ||
| 13 | -size_t | 5 | +int |
| 14 | SparseOHArray::size() const | 6 | SparseOHArray::size() const |
| 15 | { | 7 | { |
| 16 | return this->n_elements; | 8 | return this->n_elements; |
| @@ -20,7 +12,7 @@ void | @@ -20,7 +12,7 @@ void | ||
| 20 | SparseOHArray::append(QPDFObjectHandle oh) | 12 | SparseOHArray::append(QPDFObjectHandle oh) |
| 21 | { | 13 | { |
| 22 | if (!oh.isDirectNull()) { | 14 | if (!oh.isDirectNull()) { |
| 23 | - this->elements[this->n_elements] = oh; | 15 | + this->elements[this->n_elements] = oh.getObj(); |
| 24 | } | 16 | } |
| 25 | ++this->n_elements; | 17 | ++this->n_elements; |
| 26 | } | 18 | } |
| @@ -35,9 +27,9 @@ SparseOHArray::append(std::shared_ptr<QPDFObject>&& obj) | @@ -35,9 +27,9 @@ SparseOHArray::append(std::shared_ptr<QPDFObject>&& obj) | ||
| 35 | } | 27 | } |
| 36 | 28 | ||
| 37 | QPDFObjectHandle | 29 | QPDFObjectHandle |
| 38 | -SparseOHArray::at(size_t idx) const | 30 | +SparseOHArray::at(int idx) const |
| 39 | { | 31 | { |
| 40 | - if (idx >= this->n_elements) { | 32 | + if (idx < 0 || idx >= this->n_elements) { |
| 41 | throw std::logic_error( | 33 | throw std::logic_error( |
| 42 | "INTERNAL ERROR: bounds error accessing SparseOHArray element"); | 34 | "INTERNAL ERROR: bounds error accessing SparseOHArray element"); |
| 43 | } | 35 | } |
| @@ -69,7 +61,7 @@ SparseOHArray::disconnect() | @@ -69,7 +61,7 @@ SparseOHArray::disconnect() | ||
| 69 | } | 61 | } |
| 70 | 62 | ||
| 71 | void | 63 | void |
| 72 | -SparseOHArray::setAt(size_t idx, QPDFObjectHandle oh) | 64 | +SparseOHArray::setAt(int idx, QPDFObjectHandle oh) |
| 73 | { | 65 | { |
| 74 | if (idx >= this->n_elements) { | 66 | if (idx >= this->n_elements) { |
| 75 | throw std::logic_error("bounds error setting item in SparseOHArray"); | 67 | throw std::logic_error("bounds error setting item in SparseOHArray"); |
| @@ -77,12 +69,12 @@ SparseOHArray::setAt(size_t idx, QPDFObjectHandle oh) | @@ -77,12 +69,12 @@ SparseOHArray::setAt(size_t idx, QPDFObjectHandle oh) | ||
| 77 | if (oh.isDirectNull()) { | 69 | if (oh.isDirectNull()) { |
| 78 | this->elements.erase(idx); | 70 | this->elements.erase(idx); |
| 79 | } else { | 71 | } else { |
| 80 | - this->elements[idx] = oh; | 72 | + this->elements[idx] = oh.getObj(); |
| 81 | } | 73 | } |
| 82 | } | 74 | } |
| 83 | 75 | ||
| 84 | void | 76 | void |
| 85 | -SparseOHArray::erase(size_t idx) | 77 | +SparseOHArray::erase(int idx) |
| 86 | { | 78 | { |
| 87 | if (idx >= this->n_elements) { | 79 | if (idx >= this->n_elements) { |
| 88 | throw std::logic_error("bounds error erasing item from SparseOHArray"); | 80 | throw std::logic_error("bounds error erasing item from SparseOHArray"); |
| @@ -100,7 +92,7 @@ SparseOHArray::erase(size_t idx) | @@ -100,7 +92,7 @@ SparseOHArray::erase(size_t idx) | ||
| 100 | } | 92 | } |
| 101 | 93 | ||
| 102 | void | 94 | void |
| 103 | -SparseOHArray::insert(size_t idx, QPDFObjectHandle oh) | 95 | +SparseOHArray::insert(int idx, QPDFObjectHandle oh) |
| 104 | { | 96 | { |
| 105 | if (idx > this->n_elements) { | 97 | if (idx > this->n_elements) { |
| 106 | throw std::logic_error("bounds error inserting item to SparseOHArray"); | 98 | throw std::logic_error("bounds error inserting item to SparseOHArray"); |
| @@ -117,7 +109,7 @@ SparseOHArray::insert(size_t idx, QPDFObjectHandle oh) | @@ -117,7 +109,7 @@ SparseOHArray::insert(size_t idx, QPDFObjectHandle oh) | ||
| 117 | } | 109 | } |
| 118 | } | 110 | } |
| 119 | this->elements = dest; | 111 | this->elements = dest; |
| 120 | - this->elements[idx] = oh; | 112 | + this->elements[idx] = oh.getObj(); |
| 121 | ++this->n_elements; | 113 | ++this->n_elements; |
| 122 | } | 114 | } |
| 123 | } | 115 | } |
| @@ -130,7 +122,7 @@ SparseOHArray::copy() | @@ -130,7 +122,7 @@ SparseOHArray::copy() | ||
| 130 | for (auto const& element: this->elements) { | 122 | for (auto const& element: this->elements) { |
| 131 | auto value = element.second; | 123 | auto value = element.second; |
| 132 | result.elements[element.first] = | 124 | result.elements[element.first] = |
| 133 | - value.isIndirect() ? value : value.shallowCopy(); | 125 | + value->getObjGen().isIndirect() ? value : value->copy(); |
| 134 | } | 126 | } |
| 135 | return result; | 127 | return result; |
| 136 | } | 128 | } |
libqpdf/qpdf/SparseOHArray.hh
| @@ -2,34 +2,35 @@ | @@ -2,34 +2,35 @@ | ||
| 2 | #define QPDF_SPARSEOHARRAY_HH | 2 | #define QPDF_SPARSEOHARRAY_HH |
| 3 | 3 | ||
| 4 | #include <qpdf/QPDFObjectHandle.hh> | 4 | #include <qpdf/QPDFObjectHandle.hh> |
| 5 | -#include <unordered_map> | 5 | +#include <qpdf/QPDFObject_private.hh> |
| 6 | +#include <map> | ||
| 6 | 7 | ||
| 7 | class QPDF_Array; | 8 | class QPDF_Array; |
| 8 | 9 | ||
| 9 | class SparseOHArray | 10 | class SparseOHArray |
| 10 | { | 11 | { |
| 11 | public: | 12 | public: |
| 12 | - SparseOHArray(); | ||
| 13 | - size_t size() const; | 13 | + SparseOHArray() = default; |
| 14 | + int size() const; | ||
| 14 | void append(QPDFObjectHandle oh); | 15 | void append(QPDFObjectHandle oh); |
| 15 | void append(std::shared_ptr<QPDFObject>&& obj); | 16 | void append(std::shared_ptr<QPDFObject>&& obj); |
| 16 | - QPDFObjectHandle at(size_t idx) const; | 17 | + QPDFObjectHandle at(int idx) const; |
| 17 | void remove_last(); | 18 | void remove_last(); |
| 18 | - void setAt(size_t idx, QPDFObjectHandle oh); | ||
| 19 | - void erase(size_t idx); | ||
| 20 | - void insert(size_t idx, QPDFObjectHandle oh); | 19 | + void setAt(int idx, QPDFObjectHandle oh); |
| 20 | + void erase(int idx); | ||
| 21 | + void insert(int idx, QPDFObjectHandle oh); | ||
| 21 | SparseOHArray copy(); | 22 | SparseOHArray copy(); |
| 22 | void disconnect(); | 23 | void disconnect(); |
| 23 | 24 | ||
| 24 | - typedef std::unordered_map<size_t, QPDFObjectHandle>::const_iterator | 25 | + typedef std::map<int, std::shared_ptr<QPDFObject>>::const_iterator |
| 25 | const_iterator; | 26 | const_iterator; |
| 26 | const_iterator begin() const; | 27 | const_iterator begin() const; |
| 27 | const_iterator end() const; | 28 | const_iterator end() const; |
| 28 | 29 | ||
| 29 | private: | 30 | private: |
| 30 | friend class QPDF_Array; | 31 | friend class QPDF_Array; |
| 31 | - std::unordered_map<size_t, QPDFObjectHandle> elements; | ||
| 32 | - size_t n_elements; | 32 | + std::map<int, std::shared_ptr<QPDFObject>> elements; |
| 33 | + int n_elements{0}; | ||
| 33 | }; | 34 | }; |
| 34 | 35 | ||
| 35 | #endif // QPDF_SPARSEOHARRAY_HH | 36 | #endif // QPDF_SPARSEOHARRAY_HH |