Commit 38cf7c16283ec2d476514a54e2b1a7016b0b770a
1 parent
de29fd56
Add separate sparse mode to QPDF_Array
Add temporary clone of SparseOHArray to implement non-sparse mode.
Showing
6 changed files
with
331 additions
and
42 deletions
include/qpdf/QPDFObjectHandle.hh
| @@ -1497,6 +1497,7 @@ class QPDFObjectHandle | @@ -1497,6 +1497,7 @@ class QPDFObjectHandle | ||
| 1497 | friend class QPDF_Dictionary; | 1497 | friend class QPDF_Dictionary; |
| 1498 | friend class QPDF_Stream; | 1498 | friend class QPDF_Stream; |
| 1499 | friend class SparseOHArray; | 1499 | friend class SparseOHArray; |
| 1500 | + friend class OHArray; | ||
| 1500 | 1501 | ||
| 1501 | private: | 1502 | private: |
| 1502 | static void | 1503 | static void |
libqpdf/CMakeLists.txt
| @@ -116,6 +116,7 @@ set(libqpdf_SOURCES | @@ -116,6 +116,7 @@ set(libqpdf_SOURCES | ||
| 116 | SecureRandomDataProvider.cc | 116 | SecureRandomDataProvider.cc |
| 117 | SF_FlateLzwDecode.cc | 117 | SF_FlateLzwDecode.cc |
| 118 | SparseOHArray.cc | 118 | SparseOHArray.cc |
| 119 | + OHArray.cc | ||
| 119 | qpdf-c.cc | 120 | qpdf-c.cc |
| 120 | qpdfjob-c.cc | 121 | qpdfjob-c.cc |
| 121 | qpdflogger-c.cc) | 122 | qpdflogger-c.cc) |
libqpdf/OHArray.cc
0 → 100644
| 1 | +#include <qpdf/OHArray.hh> | ||
| 2 | + | ||
| 3 | +#include <qpdf/QPDFObjectHandle.hh> | ||
| 4 | +#include <qpdf/QPDFObject_private.hh> | ||
| 5 | + | ||
| 6 | +#include <stdexcept> | ||
| 7 | + | ||
| 8 | +OHArray::OHArray() : | ||
| 9 | + n_elements(0) | ||
| 10 | +{ | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +size_t | ||
| 14 | +OHArray::size() const | ||
| 15 | +{ | ||
| 16 | + return this->n_elements; | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +void | ||
| 20 | +OHArray::append(QPDFObjectHandle oh) | ||
| 21 | +{ | ||
| 22 | + if (!oh.isDirectNull()) { | ||
| 23 | + this->elements[this->n_elements] = oh; | ||
| 24 | + } | ||
| 25 | + ++this->n_elements; | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +void | ||
| 29 | +OHArray::append(std::shared_ptr<QPDFObject>&& obj) | ||
| 30 | +{ | ||
| 31 | + if (obj->getTypeCode() != ::ot_null || !obj->getObjGen().isIndirect()) { | ||
| 32 | + this->elements[this->n_elements] = std::move(obj); | ||
| 33 | + } | ||
| 34 | + ++this->n_elements; | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +QPDFObjectHandle | ||
| 38 | +OHArray::at(size_t idx) const | ||
| 39 | +{ | ||
| 40 | + if (idx >= this->n_elements) { | ||
| 41 | + throw std::logic_error( | ||
| 42 | + "INTERNAL ERROR: bounds error accessing OHArray element"); | ||
| 43 | + } | ||
| 44 | + auto const& iter = this->elements.find(idx); | ||
| 45 | + if (iter == this->elements.end()) { | ||
| 46 | + return QPDFObjectHandle::newNull(); | ||
| 47 | + } else { | ||
| 48 | + return (*iter).second; | ||
| 49 | + } | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +void | ||
| 53 | +OHArray::remove_last() | ||
| 54 | +{ | ||
| 55 | + if (this->n_elements == 0) { | ||
| 56 | + throw std::logic_error("INTERNAL ERROR: attempt to remove" | ||
| 57 | + " last item from empty OHArray"); | ||
| 58 | + } | ||
| 59 | + --this->n_elements; | ||
| 60 | + this->elements.erase(this->n_elements); | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +void | ||
| 64 | +OHArray::disconnect() | ||
| 65 | +{ | ||
| 66 | + for (auto& iter: this->elements) { | ||
| 67 | + QPDFObjectHandle::DisconnectAccess::disconnect(iter.second); | ||
| 68 | + } | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +void | ||
| 72 | +OHArray::setAt(size_t idx, QPDFObjectHandle oh) | ||
| 73 | +{ | ||
| 74 | + if (idx >= this->n_elements) { | ||
| 75 | + throw std::logic_error("bounds error setting item in OHArray"); | ||
| 76 | + } | ||
| 77 | + if (oh.isDirectNull()) { | ||
| 78 | + this->elements.erase(idx); | ||
| 79 | + } else { | ||
| 80 | + this->elements[idx] = oh; | ||
| 81 | + } | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +void | ||
| 85 | +OHArray::erase(size_t idx) | ||
| 86 | +{ | ||
| 87 | + if (idx >= this->n_elements) { | ||
| 88 | + throw std::logic_error("bounds error erasing item from OHArray"); | ||
| 89 | + } | ||
| 90 | + decltype(this->elements) dest; | ||
| 91 | + for (auto const& iter: this->elements) { | ||
| 92 | + if (iter.first < idx) { | ||
| 93 | + dest.insert(iter); | ||
| 94 | + } else if (iter.first > idx) { | ||
| 95 | + dest[iter.first - 1] = iter.second; | ||
| 96 | + } | ||
| 97 | + } | ||
| 98 | + this->elements = dest; | ||
| 99 | + --this->n_elements; | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | +void | ||
| 103 | +OHArray::insert(size_t idx, QPDFObjectHandle oh) | ||
| 104 | +{ | ||
| 105 | + if (idx > this->n_elements) { | ||
| 106 | + throw std::logic_error("bounds error inserting item to OHArray"); | ||
| 107 | + } else if (idx == this->n_elements) { | ||
| 108 | + // Allow inserting to the last position | ||
| 109 | + append(oh); | ||
| 110 | + } else { | ||
| 111 | + decltype(this->elements) dest; | ||
| 112 | + for (auto const& iter: this->elements) { | ||
| 113 | + if (iter.first < idx) { | ||
| 114 | + dest.insert(iter); | ||
| 115 | + } else { | ||
| 116 | + dest[iter.first + 1] = iter.second; | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + this->elements = dest; | ||
| 120 | + this->elements[idx] = oh; | ||
| 121 | + ++this->n_elements; | ||
| 122 | + } | ||
| 123 | +} | ||
| 124 | + | ||
| 125 | +OHArray | ||
| 126 | +OHArray::copy() | ||
| 127 | +{ | ||
| 128 | + OHArray result; | ||
| 129 | + result.n_elements = this->n_elements; | ||
| 130 | + for (auto const& element: this->elements) { | ||
| 131 | + auto value = element.second; | ||
| 132 | + result.elements[element.first] = | ||
| 133 | + value.isIndirect() ? value : value.shallowCopy(); | ||
| 134 | + } | ||
| 135 | + return result; | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | +OHArray::const_iterator | ||
| 139 | +OHArray::begin() const | ||
| 140 | +{ | ||
| 141 | + return this->elements.begin(); | ||
| 142 | +} | ||
| 143 | + | ||
| 144 | +OHArray::const_iterator | ||
| 145 | +OHArray::end() const | ||
| 146 | +{ | ||
| 147 | + return this->elements.end(); | ||
| 148 | +} |
libqpdf/QPDF_Array.cc
| @@ -19,6 +19,13 @@ QPDF_Array::QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& v) : | @@ -19,6 +19,13 @@ QPDF_Array::QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& v) : | ||
| 19 | 19 | ||
| 20 | QPDF_Array::QPDF_Array(SparseOHArray const& items) : | 20 | QPDF_Array::QPDF_Array(SparseOHArray const& items) : |
| 21 | QPDFValue(::ot_array, "array"), | 21 | QPDFValue(::ot_array, "array"), |
| 22 | + sp_elements(items) | ||
| 23 | +{ | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +QPDF_Array::QPDF_Array(OHArray const& items) : | ||
| 27 | + QPDFValue(::ot_array, "array"), | ||
| 28 | + sparse(false), | ||
| 22 | elements(items) | 29 | elements(items) |
| 23 | { | 30 | { |
| 24 | } | 31 | } |
| @@ -42,92 +49,167 @@ QPDF_Array::create(SparseOHArray const& items) | @@ -42,92 +49,167 @@ QPDF_Array::create(SparseOHArray const& items) | ||
| 42 | } | 49 | } |
| 43 | 50 | ||
| 44 | std::shared_ptr<QPDFObject> | 51 | std::shared_ptr<QPDFObject> |
| 52 | +QPDF_Array::create(OHArray const& items) | ||
| 53 | +{ | ||
| 54 | + return do_create(new QPDF_Array(items)); | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +std::shared_ptr<QPDFObject> | ||
| 45 | QPDF_Array::copy(bool shallow) | 58 | QPDF_Array::copy(bool shallow) |
| 46 | { | 59 | { |
| 47 | - return create(shallow ? elements : elements.copy()); | 60 | + if (sparse) { |
| 61 | + return create(shallow ? sp_elements : sp_elements.copy()); | ||
| 62 | + } else { | ||
| 63 | + return create(shallow ? elements : elements.copy()); | ||
| 64 | + } | ||
| 48 | } | 65 | } |
| 49 | 66 | ||
| 50 | void | 67 | void |
| 51 | QPDF_Array::disconnect() | 68 | QPDF_Array::disconnect() |
| 52 | { | 69 | { |
| 53 | - elements.disconnect(); | 70 | + if (sparse) { |
| 71 | + sp_elements.disconnect(); | ||
| 72 | + } else { | ||
| 73 | + elements.disconnect(); | ||
| 74 | + } | ||
| 54 | } | 75 | } |
| 55 | 76 | ||
| 56 | std::string | 77 | std::string |
| 57 | QPDF_Array::unparse() | 78 | QPDF_Array::unparse() |
| 58 | { | 79 | { |
| 59 | - std::string result = "[ "; | ||
| 60 | - size_t size = this->elements.size(); | ||
| 61 | - for (size_t i = 0; i < size; ++i) { | ||
| 62 | - result += this->elements.at(i).unparse(); | ||
| 63 | - result += " "; | 80 | + if (sparse) { |
| 81 | + std::string result = "[ "; | ||
| 82 | + size_t size = sp_elements.size(); | ||
| 83 | + for (size_t i = 0; i < size; ++i) { | ||
| 84 | + result += sp_elements.at(i).unparse(); | ||
| 85 | + result += " "; | ||
| 86 | + } | ||
| 87 | + result += "]"; | ||
| 88 | + return result; | ||
| 89 | + } else { | ||
| 90 | + std::string result = "[ "; | ||
| 91 | + size_t size = elements.size(); | ||
| 92 | + for (size_t i = 0; i < size; ++i) { | ||
| 93 | + result += elements.at(i).unparse(); | ||
| 94 | + result += " "; | ||
| 95 | + } | ||
| 96 | + result += "]"; | ||
| 97 | + return result; | ||
| 64 | } | 98 | } |
| 65 | - result += "]"; | ||
| 66 | - return result; | ||
| 67 | } | 99 | } |
| 68 | 100 | ||
| 69 | JSON | 101 | JSON |
| 70 | QPDF_Array::getJSON(int json_version) | 102 | QPDF_Array::getJSON(int json_version) |
| 71 | { | 103 | { |
| 72 | - JSON j = JSON::makeArray(); | ||
| 73 | - size_t size = this->elements.size(); | ||
| 74 | - for (size_t i = 0; i < size; ++i) { | ||
| 75 | - j.addArrayElement(this->elements.at(i).getJSON(json_version)); | 104 | + if (sparse) { |
| 105 | + JSON j = JSON::makeArray(); | ||
| 106 | + size_t size = sp_elements.size(); | ||
| 107 | + for (size_t i = 0; i < size; ++i) { | ||
| 108 | + j.addArrayElement(sp_elements.at(i).getJSON(json_version)); | ||
| 109 | + } | ||
| 110 | + return j; | ||
| 111 | + } else { | ||
| 112 | + JSON j = JSON::makeArray(); | ||
| 113 | + size_t size = elements.size(); | ||
| 114 | + for (size_t i = 0; i < size; ++i) { | ||
| 115 | + j.addArrayElement(elements.at(i).getJSON(json_version)); | ||
| 116 | + } | ||
| 117 | + return j; | ||
| 76 | } | 118 | } |
| 77 | - return j; | ||
| 78 | } | 119 | } |
| 79 | 120 | ||
| 80 | int | 121 | int |
| 81 | QPDF_Array::getNItems() const | 122 | QPDF_Array::getNItems() const |
| 82 | { | 123 | { |
| 83 | - // This should really return a size_t, but changing it would break | ||
| 84 | - // a lot of code. | ||
| 85 | - return QIntC::to_int(this->elements.size()); | 124 | + if (sparse) { |
| 125 | + // This should really return a size_t, but changing it would break | ||
| 126 | + // a lot of code. | ||
| 127 | + return QIntC::to_int(sp_elements.size()); | ||
| 128 | + } else { | ||
| 129 | + return QIntC::to_int(elements.size()); | ||
| 130 | + } | ||
| 86 | } | 131 | } |
| 87 | 132 | ||
| 88 | QPDFObjectHandle | 133 | QPDFObjectHandle |
| 89 | QPDF_Array::getItem(int n) const | 134 | QPDF_Array::getItem(int n) const |
| 90 | { | 135 | { |
| 91 | - if ((n < 0) || (n >= QIntC::to_int(elements.size()))) { | ||
| 92 | - throw std::logic_error( | ||
| 93 | - "INTERNAL ERROR: bounds error accessing QPDF_Array element"); | 136 | + if (sparse) { |
| 137 | + if ((n < 0) || (n >= QIntC::to_int(sp_elements.size()))) { | ||
| 138 | + throw std::logic_error( | ||
| 139 | + "INTERNAL ERROR: bounds error accessing QPDF_Array element"); | ||
| 140 | + } | ||
| 141 | + return sp_elements.at(QIntC::to_size(n)); | ||
| 142 | + } else { | ||
| 143 | + if ((n < 0) || (n >= QIntC::to_int(elements.size()))) { | ||
| 144 | + throw std::logic_error( | ||
| 145 | + "INTERNAL ERROR: bounds error accessing QPDF_Array element"); | ||
| 146 | + } | ||
| 147 | + return elements.at(QIntC::to_size(n)); | ||
| 94 | } | 148 | } |
| 95 | - return this->elements.at(QIntC::to_size(n)); | ||
| 96 | } | 149 | } |
| 97 | 150 | ||
| 98 | void | 151 | void |
| 99 | QPDF_Array::getAsVector(std::vector<QPDFObjectHandle>& v) const | 152 | QPDF_Array::getAsVector(std::vector<QPDFObjectHandle>& v) const |
| 100 | { | 153 | { |
| 101 | - size_t size = this->elements.size(); | ||
| 102 | - for (size_t i = 0; i < size; ++i) { | ||
| 103 | - v.push_back(this->elements.at(i)); | 154 | + if (sparse) { |
| 155 | + size_t size = sp_elements.size(); | ||
| 156 | + for (size_t i = 0; i < size; ++i) { | ||
| 157 | + v.push_back(sp_elements.at(i)); | ||
| 158 | + } | ||
| 159 | + } else { | ||
| 160 | + size_t size = elements.size(); | ||
| 161 | + for (size_t i = 0; i < size; ++i) { | ||
| 162 | + v.push_back(elements.at(i)); | ||
| 163 | + } | ||
| 104 | } | 164 | } |
| 105 | } | 165 | } |
| 106 | 166 | ||
| 107 | void | 167 | void |
| 108 | QPDF_Array::setItem(int n, QPDFObjectHandle const& oh) | 168 | QPDF_Array::setItem(int n, QPDFObjectHandle const& oh) |
| 109 | { | 169 | { |
| 110 | - this->elements.setAt(QIntC::to_size(n), oh); | 170 | + if (sparse) { |
| 171 | + sp_elements.setAt(QIntC::to_size(n), oh); | ||
| 172 | + } else { | ||
| 173 | + elements.setAt(QIntC::to_size(n), oh); | ||
| 174 | + } | ||
| 111 | } | 175 | } |
| 112 | 176 | ||
| 113 | void | 177 | void |
| 114 | QPDF_Array::setFromVector(std::vector<QPDFObjectHandle> const& v) | 178 | QPDF_Array::setFromVector(std::vector<QPDFObjectHandle> const& v) |
| 115 | { | 179 | { |
| 116 | - this->elements = SparseOHArray(); | ||
| 117 | - for (auto const& iter: v) { | ||
| 118 | - this->elements.append(iter); | 180 | + if (sparse) { |
| 181 | + sp_elements = SparseOHArray(); | ||
| 182 | + for (auto const& iter: v) { | ||
| 183 | + sp_elements.append(iter); | ||
| 184 | + } | ||
| 185 | + } else { | ||
| 186 | + elements = OHArray(); | ||
| 187 | + for (auto const& iter: v) { | ||
| 188 | + elements.append(iter); | ||
| 189 | + } | ||
| 119 | } | 190 | } |
| 120 | } | 191 | } |
| 121 | 192 | ||
| 122 | void | 193 | void |
| 123 | QPDF_Array::setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& v) | 194 | QPDF_Array::setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& v) |
| 124 | { | 195 | { |
| 125 | - this->elements = SparseOHArray(); | ||
| 126 | - for (auto&& item: v) { | ||
| 127 | - if (item) { | ||
| 128 | - this->elements.append(item); | ||
| 129 | - } else { | ||
| 130 | - ++this->elements.n_elements; | 196 | + if (sparse) { |
| 197 | + sp_elements = SparseOHArray(); | ||
| 198 | + for (auto&& item: v) { | ||
| 199 | + if (item) { | ||
| 200 | + sp_elements.append(item); | ||
| 201 | + } else { | ||
| 202 | + ++sp_elements.n_elements; | ||
| 203 | + } | ||
| 204 | + } | ||
| 205 | + } else { | ||
| 206 | + elements = OHArray(); | ||
| 207 | + for (auto&& item: v) { | ||
| 208 | + if (item) { | ||
| 209 | + elements.append(item); | ||
| 210 | + } else { | ||
| 211 | + ++elements.n_elements; | ||
| 212 | + } | ||
| 131 | } | 213 | } |
| 132 | } | 214 | } |
| 133 | } | 215 | } |
| @@ -135,22 +217,39 @@ QPDF_Array::setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& v) | @@ -135,22 +217,39 @@ QPDF_Array::setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& v) | ||
| 135 | void | 217 | void |
| 136 | QPDF_Array::insertItem(int at, QPDFObjectHandle const& item) | 218 | QPDF_Array::insertItem(int at, QPDFObjectHandle const& item) |
| 137 | { | 219 | { |
| 138 | - // As special case, also allow insert beyond the end | ||
| 139 | - if ((at < 0) || (at > QIntC::to_int(this->elements.size()))) { | ||
| 140 | - throw std::logic_error( | ||
| 141 | - "INTERNAL ERROR: bounds error accessing QPDF_Array element"); | 220 | + if (sparse) { |
| 221 | + // As special case, also allow insert beyond the end | ||
| 222 | + if ((at < 0) || (at > QIntC::to_int(sp_elements.size()))) { | ||
| 223 | + throw std::logic_error( | ||
| 224 | + "INTERNAL ERROR: bounds error accessing QPDF_Array element"); | ||
| 225 | + } | ||
| 226 | + sp_elements.insert(QIntC::to_size(at), item); | ||
| 227 | + } else { | ||
| 228 | + // As special case, also allow insert beyond the end | ||
| 229 | + if ((at < 0) || (at > QIntC::to_int(elements.size()))) { | ||
| 230 | + throw std::logic_error( | ||
| 231 | + "INTERNAL ERROR: bounds error accessing QPDF_Array element"); | ||
| 232 | + } | ||
| 233 | + elements.insert(QIntC::to_size(at), item); | ||
| 142 | } | 234 | } |
| 143 | - this->elements.insert(QIntC::to_size(at), item); | ||
| 144 | } | 235 | } |
| 145 | 236 | ||
| 146 | void | 237 | void |
| 147 | QPDF_Array::appendItem(QPDFObjectHandle const& item) | 238 | QPDF_Array::appendItem(QPDFObjectHandle const& item) |
| 148 | { | 239 | { |
| 149 | - this->elements.append(item); | 240 | + if (sparse) { |
| 241 | + sp_elements.append(item); | ||
| 242 | + } else { | ||
| 243 | + elements.append(item); | ||
| 244 | + } | ||
| 150 | } | 245 | } |
| 151 | 246 | ||
| 152 | void | 247 | void |
| 153 | QPDF_Array::eraseItem(int at) | 248 | QPDF_Array::eraseItem(int at) |
| 154 | { | 249 | { |
| 155 | - this->elements.erase(QIntC::to_size(at)); | 250 | + if (sparse) { |
| 251 | + sp_elements.erase(QIntC::to_size(at)); | ||
| 252 | + } else { | ||
| 253 | + elements.erase(QIntC::to_size(at)); | ||
| 254 | + } | ||
| 156 | } | 255 | } |
libqpdf/qpdf/OHArray.hh
0 → 100644
| 1 | +#ifndef QPDF_OHARRAY_HH | ||
| 2 | +#define QPDF_OHARRAY_HH | ||
| 3 | + | ||
| 4 | +#include <qpdf/QPDFObjectHandle.hh> | ||
| 5 | +#include <unordered_map> | ||
| 6 | + | ||
| 7 | +class QPDF_Array; | ||
| 8 | + | ||
| 9 | +class OHArray | ||
| 10 | +{ | ||
| 11 | + public: | ||
| 12 | + OHArray(); | ||
| 13 | + size_t size() const; | ||
| 14 | + void append(QPDFObjectHandle oh); | ||
| 15 | + void append(std::shared_ptr<QPDFObject>&& obj); | ||
| 16 | + QPDFObjectHandle at(size_t idx) const; | ||
| 17 | + 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); | ||
| 21 | + OHArray copy(); | ||
| 22 | + void disconnect(); | ||
| 23 | + | ||
| 24 | + typedef std::unordered_map<size_t, QPDFObjectHandle>::const_iterator | ||
| 25 | + const_iterator; | ||
| 26 | + const_iterator begin() const; | ||
| 27 | + const_iterator end() const; | ||
| 28 | + | ||
| 29 | + private: | ||
| 30 | + friend class QPDF_Array; | ||
| 31 | + std::unordered_map<size_t, QPDFObjectHandle> elements; | ||
| 32 | + size_t n_elements; | ||
| 33 | +}; | ||
| 34 | + | ||
| 35 | +#endif // QPDF_OHARRAY_HH |
libqpdf/qpdf/QPDF_Array.hh
| @@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
| 3 | 3 | ||
| 4 | #include <qpdf/QPDFValue.hh> | 4 | #include <qpdf/QPDFValue.hh> |
| 5 | 5 | ||
| 6 | +#include <qpdf/OHArray.hh> | ||
| 6 | #include <qpdf/SparseOHArray.hh> | 7 | #include <qpdf/SparseOHArray.hh> |
| 7 | #include <list> | 8 | #include <list> |
| 8 | #include <vector> | 9 | #include <vector> |
| @@ -16,6 +17,7 @@ class QPDF_Array: public QPDFValue | @@ -16,6 +17,7 @@ class QPDF_Array: public QPDFValue | ||
| 16 | static std::shared_ptr<QPDFObject> | 17 | static std::shared_ptr<QPDFObject> |
| 17 | create(std::vector<std::shared_ptr<QPDFObject>>&& items); | 18 | create(std::vector<std::shared_ptr<QPDFObject>>&& items); |
| 18 | static std::shared_ptr<QPDFObject> create(SparseOHArray const& items); | 19 | static std::shared_ptr<QPDFObject> create(SparseOHArray const& items); |
| 20 | + static std::shared_ptr<QPDFObject> create(OHArray const& items); | ||
| 19 | virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); | 21 | virtual std::shared_ptr<QPDFObject> copy(bool shallow = false); |
| 20 | virtual std::string unparse(); | 22 | virtual std::string unparse(); |
| 21 | virtual JSON getJSON(int json_version); | 23 | virtual JSON getJSON(int json_version); |
| @@ -36,7 +38,10 @@ class QPDF_Array: public QPDFValue | @@ -36,7 +38,10 @@ class QPDF_Array: public QPDFValue | ||
| 36 | QPDF_Array(std::vector<QPDFObjectHandle> const& items); | 38 | QPDF_Array(std::vector<QPDFObjectHandle> const& items); |
| 37 | QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& items); | 39 | QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& items); |
| 38 | QPDF_Array(SparseOHArray const& items); | 40 | QPDF_Array(SparseOHArray const& items); |
| 39 | - SparseOHArray elements; | 41 | + QPDF_Array(OHArray const& items); |
| 42 | + bool sparse{false}; | ||
| 43 | + SparseOHArray sp_elements; | ||
| 44 | + OHArray elements; | ||
| 40 | }; | 45 | }; |
| 41 | 46 | ||
| 42 | #endif // QPDF_ARRAY_HH | 47 | #endif // QPDF_ARRAY_HH |