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,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&amp; item) @@ -239,11 +239,11 @@ QPDF_Array::insertItem(int at, QPDFObjectHandle const&amp; 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&lt;QPDFObject&gt;&amp;&amp; obj) @@ -35,9 +27,9 @@ SparseOHArray::append(std::shared_ptr&lt;QPDFObject&gt;&amp;&amp; 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