aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2019-08-18 04:13:37 +0200
committerJay Berkenbilt <ejb@ql.org>2019-08-18 05:02:41 +0200
commite5f504b6c5dc34337cc0b316b4a7b1fca7e614b1 (patch)
tree603494c6a8cf784ad1715bfd763787ef4a0cce26
parenta89d8a0677f726ea029a67db164e0116971ffafc (diff)
downloadqpdf-e5f504b6c5dc34337cc0b316b4a7b1fca7e614b1.tar.zst
Use SparseOHArray in QPDF_Array
-rw-r--r--include/qpdf/QPDFObjectHandle.hh5
-rw-r--r--libqpdf/QPDF_Array.cc47
-rw-r--r--libqpdf/qpdf/QPDF_Array.hh5
3 files changed, 29 insertions, 28 deletions
diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh
index ad542c09..4f18cbda 100644
--- a/include/qpdf/QPDFObjectHandle.hh
+++ b/include/qpdf/QPDFObjectHandle.hh
@@ -544,6 +544,10 @@ class QPDFObjectHandle
int getArrayNItems();
QPDF_DLL
QPDFObjectHandle getArrayItem(int n);
+ // Note: QPDF arrays internally optimize memory for arrays
+ // containing lots of nulls. Calling getArrayAsVector may cause a
+ // lot of memory to be allocated for very large arrays with lots
+ // of nulls.
QPDF_DLL
std::vector<QPDFObjectHandle> getArrayAsVector();
QPDF_DLL
@@ -932,7 +936,6 @@ class QPDFObjectHandle
class ReleaseResolver
{
friend class QPDF_Dictionary;
- friend class QPDF_Array;
friend class QPDF_Stream;
friend class SparseOHArray;
private:
diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc
index a912b2bd..45635f8a 100644
--- a/libqpdf/QPDF_Array.cc
+++ b/libqpdf/QPDF_Array.cc
@@ -8,6 +8,11 @@ QPDF_Array::QPDF_Array(std::vector<QPDFObjectHandle> const& v)
setFromVector(v);
}
+QPDF_Array::QPDF_Array(SparseOHArray const& items) :
+ elements(items)
+{
+}
+
QPDF_Array::~QPDF_Array()
{
}
@@ -15,21 +20,17 @@ QPDF_Array::~QPDF_Array()
void
QPDF_Array::releaseResolved()
{
- for (std::vector<QPDFObjectHandle>::iterator iter = this->items.begin();
- iter != this->items.end(); ++iter)
- {
- QPDFObjectHandle::ReleaseResolver::releaseResolved(*iter);
- }
+ this->elements.releaseResolved();
}
std::string
QPDF_Array::unparse()
{
std::string result = "[ ";
- size_t size = this->items.size();
+ size_t size = this->elements.size();
for (size_t i = 0; i < size; ++i)
{
- result += this->items.at(i).unparse();
+ result += this->elements.at(i).unparse();
result += " ";
}
result += "]";
@@ -40,10 +41,10 @@ JSON
QPDF_Array::getJSON()
{
JSON j = JSON::makeArray();
- size_t size = this->items.size();
+ size_t size = this->elements.size();
for (size_t i = 0; i < size; ++i)
{
- j.addArrayElement(this->items.at(i).getJSON());
+ j.addArrayElement(this->elements.at(i).getJSON());
}
return j;
}
@@ -71,46 +72,44 @@ QPDF_Array::getNItems() const
{
// This should really return a size_t, but changing it would break
// a lot of code.
- return QIntC::to_int(this->items.size());
+ return QIntC::to_int(this->elements.size());
}
QPDFObjectHandle
QPDF_Array::getItem(int n) const
{
- if ((n < 0) || (n >= QIntC::to_int(this->items.size())))
+ if ((n < 0) || (n >= QIntC::to_int(elements.size())))
{
throw std::logic_error(
"INTERNAL ERROR: bounds error accessing QPDF_Array element");
}
- return this->items.at(QIntC::to_size(n));
+ return this->elements.at(QIntC::to_size(n));
}
void
QPDF_Array::getAsVector(std::vector<QPDFObjectHandle>& v) const
{
- size_t size = this->items.size();
+ size_t size = this->elements.size();
for (size_t i = 0; i < size; ++i)
{
- v.push_back(this->items.at(i));
+ v.push_back(this->elements.at(i));
}
}
void
QPDF_Array::setItem(int n, QPDFObjectHandle const& oh)
{
- // Call getItem for bounds checking
- (void) getItem(n);
- this->items.at(QIntC::to_size(n)) = oh;
+ this->elements.setAt(QIntC::to_size(n), oh);
}
void
QPDF_Array::setFromVector(std::vector<QPDFObjectHandle> const& v)
{
- this->items.clear();
+ this->elements = SparseOHArray();
for (std::vector<QPDFObjectHandle>::const_iterator iter = v.begin();
iter != v.end(); ++iter)
{
- this->items.push_back(*iter);
+ this->elements.append(*iter);
}
}
@@ -118,24 +117,22 @@ void
QPDF_Array::insertItem(int at, QPDFObjectHandle const& item)
{
// As special case, also allow insert beyond the end
- if ((at < 0) || (at > QIntC::to_int(this->items.size())))
+ if ((at < 0) || (at > QIntC::to_int(this->elements.size())))
{
throw std::logic_error(
"INTERNAL ERROR: bounds error accessing QPDF_Array element");
}
- this->items.insert(this->items.begin() + at, item);
+ this->elements.insert(QIntC::to_size(at), item);
}
void
QPDF_Array::appendItem(QPDFObjectHandle const& item)
{
- this->items.push_back(item);
+ this->elements.append(item);
}
void
QPDF_Array::eraseItem(int at)
{
- // Call getItem for bounds checking
- (void) getItem(at);
- this->items.erase(this->items.begin() + at);
+ this->elements.erase(QIntC::to_size(at));
}
diff --git a/libqpdf/qpdf/QPDF_Array.hh b/libqpdf/qpdf/QPDF_Array.hh
index 4d2cb005..08a5a608 100644
--- a/libqpdf/qpdf/QPDF_Array.hh
+++ b/libqpdf/qpdf/QPDF_Array.hh
@@ -4,12 +4,13 @@
#include <qpdf/QPDFObject.hh>
#include <vector>
-#include <qpdf/QPDFObjectHandle.hh>
+#include <qpdf/SparseOHArray.hh>
class QPDF_Array: public QPDFObject
{
public:
QPDF_Array(std::vector<QPDFObjectHandle> const& items);
+ QPDF_Array(SparseOHArray const& items);
virtual ~QPDF_Array();
virtual std::string unparse();
virtual JSON getJSON();
@@ -31,7 +32,7 @@ class QPDF_Array: public QPDFObject
virtual void releaseResolved();
private:
- std::vector<QPDFObjectHandle> items;
+ SparseOHArray elements;
};
#endif // QPDF_ARRAY_HH