Commit e6db8ddeba560cd472f34be2e20e31ea2f4bfee3

Authored by m-holger
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.
libqpdf/QPDF_Array.cc
... ... @@ -103,8 +103,8 @@ QPDF_Array::unparse()
103 103 {
104 104 if (sparse) {
105 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 108 result += sp_elements.at(i).unparse();
109 109 result += " ";
110 110 }
... ... @@ -127,8 +127,8 @@ QPDF_Array::getJSON(int json_version)
127 127 {
128 128 if (sparse) {
129 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 132 j.addArrayElement(sp_elements.at(i).getJSON(json_version));
133 133 }
134 134 return j;
... ... @@ -162,7 +162,7 @@ QPDF_Array::getItem(int n) const
162 162 throw std::logic_error(
163 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 166 } else {
167 167 if ((n < 0) || (n >= QIntC::to_int(elements.size()))) {
168 168 throw std::logic_error(
... ... @@ -177,8 +177,8 @@ void
177 177 QPDF_Array::getAsVector(std::vector<QPDFObjectHandle>& v) const
178 178 {
179 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 182 v.push_back(sp_elements.at(i));
183 183 }
184 184 } else {
... ... @@ -190,7 +190,7 @@ void
190 190 QPDF_Array::setItem(int n, QPDFObjectHandle const& oh)
191 191 {
192 192 if (sparse) {
193   - sp_elements.setAt(QIntC::to_size(n), oh);
  193 + sp_elements.setAt(n, oh);
194 194 } else {
195 195 size_t idx = size_t(n);
196 196 if (n < 0 || idx >= elements.size()) {
... ... @@ -239,11 +239,11 @@ QPDF_Array::insertItem(int at, QPDFObjectHandle const&amp; item)
239 239 {
240 240 if (sparse) {
241 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 243 throw std::logic_error(
244 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 247 } else {
248 248 // As special case, also allow insert beyond the end
249 249 size_t idx = QIntC::to_size(at);
... ... @@ -275,7 +275,7 @@ void
275 275 QPDF_Array::eraseItem(int at)
276 276 {
277 277 if (sparse) {
278   - sp_elements.erase(QIntC::to_size(at));
  278 + sp_elements.erase(at);
279 279 } else {
280 280 size_t idx = QIntC::to_size(at);
281 281 if (idx >= elements.size()) {
... ...
libqpdf/SparseOHArray.cc
1 1 #include <qpdf/SparseOHArray.hh>
2 2  
3   -#include <qpdf/QPDFObjectHandle.hh>
4   -#include <qpdf/QPDFObject_private.hh>
5   -
6 3 #include <stdexcept>
7 4  
8   -SparseOHArray::SparseOHArray() :
9   - n_elements(0)
10   -{
11   -}
12   -
13   -size_t
  5 +int
14 6 SparseOHArray::size() const
15 7 {
16 8 return this->n_elements;
... ... @@ -20,7 +12,7 @@ void
20 12 SparseOHArray::append(QPDFObjectHandle oh)
21 13 {
22 14 if (!oh.isDirectNull()) {
23   - this->elements[this->n_elements] = oh;
  15 + this->elements[this->n_elements] = oh.getObj();
24 16 }
25 17 ++this->n_elements;
26 18 }
... ... @@ -35,9 +27,9 @@ SparseOHArray::append(std::shared_ptr&lt;QPDFObject&gt;&amp;&amp; obj)
35 27 }
36 28  
37 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 33 throw std::logic_error(
42 34 "INTERNAL ERROR: bounds error accessing SparseOHArray element");
43 35 }
... ... @@ -69,7 +61,7 @@ SparseOHArray::disconnect()
69 61 }
70 62  
71 63 void
72   -SparseOHArray::setAt(size_t idx, QPDFObjectHandle oh)
  64 +SparseOHArray::setAt(int idx, QPDFObjectHandle oh)
73 65 {
74 66 if (idx >= this->n_elements) {
75 67 throw std::logic_error("bounds error setting item in SparseOHArray");
... ... @@ -77,12 +69,12 @@ SparseOHArray::setAt(size_t idx, QPDFObjectHandle oh)
77 69 if (oh.isDirectNull()) {
78 70 this->elements.erase(idx);
79 71 } else {
80   - this->elements[idx] = oh;
  72 + this->elements[idx] = oh.getObj();
81 73 }
82 74 }
83 75  
84 76 void
85   -SparseOHArray::erase(size_t idx)
  77 +SparseOHArray::erase(int idx)
86 78 {
87 79 if (idx >= this->n_elements) {
88 80 throw std::logic_error("bounds error erasing item from SparseOHArray");
... ... @@ -100,7 +92,7 @@ SparseOHArray::erase(size_t idx)
100 92 }
101 93  
102 94 void
103   -SparseOHArray::insert(size_t idx, QPDFObjectHandle oh)
  95 +SparseOHArray::insert(int idx, QPDFObjectHandle oh)
104 96 {
105 97 if (idx > this->n_elements) {
106 98 throw std::logic_error("bounds error inserting item to SparseOHArray");
... ... @@ -117,7 +109,7 @@ SparseOHArray::insert(size_t idx, QPDFObjectHandle oh)
117 109 }
118 110 }
119 111 this->elements = dest;
120   - this->elements[idx] = oh;
  112 + this->elements[idx] = oh.getObj();
121 113 ++this->n_elements;
122 114 }
123 115 }
... ... @@ -130,7 +122,7 @@ SparseOHArray::copy()
130 122 for (auto const& element: this->elements) {
131 123 auto value = element.second;
132 124 result.elements[element.first] =
133   - value.isIndirect() ? value : value.shallowCopy();
  125 + value->getObjGen().isIndirect() ? value : value->copy();
134 126 }
135 127 return result;
136 128 }
... ...
libqpdf/qpdf/SparseOHArray.hh
... ... @@ -2,34 +2,35 @@
2 2 #define QPDF_SPARSEOHARRAY_HH
3 3  
4 4 #include <qpdf/QPDFObjectHandle.hh>
5   -#include <unordered_map>
  5 +#include <qpdf/QPDFObject_private.hh>
  6 +#include <map>
6 7  
7 8 class QPDF_Array;
8 9  
9 10 class SparseOHArray
10 11 {
11 12 public:
12   - SparseOHArray();
13   - size_t size() const;
  13 + SparseOHArray() = default;
  14 + int size() const;
14 15 void append(QPDFObjectHandle oh);
15 16 void append(std::shared_ptr<QPDFObject>&& obj);
16   - QPDFObjectHandle at(size_t idx) const;
  17 + QPDFObjectHandle at(int idx) const;
17 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 22 SparseOHArray copy();
22 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 26 const_iterator;
26 27 const_iterator begin() const;
27 28 const_iterator end() const;
28 29  
29 30 private:
30 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 36 #endif // QPDF_SPARSEOHARRAY_HH
... ...