2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-05-28 16:00:53 +00:00

Use SparseOHArray in QPDF_Array

This commit is contained in:
Jay Berkenbilt 2019-08-17 22:13:37 -04:00
parent a89d8a0677
commit e5f504b6c5
3 changed files with 29 additions and 28 deletions

View File

@ -544,6 +544,10 @@ class QPDFObjectHandle
int getArrayNItems(); int getArrayNItems();
QPDF_DLL QPDF_DLL
QPDFObjectHandle getArrayItem(int n); 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 QPDF_DLL
std::vector<QPDFObjectHandle> getArrayAsVector(); std::vector<QPDFObjectHandle> getArrayAsVector();
QPDF_DLL QPDF_DLL
@ -932,7 +936,6 @@ class QPDFObjectHandle
class ReleaseResolver class ReleaseResolver
{ {
friend class QPDF_Dictionary; friend class QPDF_Dictionary;
friend class QPDF_Array;
friend class QPDF_Stream; friend class QPDF_Stream;
friend class SparseOHArray; friend class SparseOHArray;
private: private:

View File

@ -8,6 +8,11 @@ QPDF_Array::QPDF_Array(std::vector<QPDFObjectHandle> const& v)
setFromVector(v); setFromVector(v);
} }
QPDF_Array::QPDF_Array(SparseOHArray const& items) :
elements(items)
{
}
QPDF_Array::~QPDF_Array() QPDF_Array::~QPDF_Array()
{ {
} }
@ -15,21 +20,17 @@ QPDF_Array::~QPDF_Array()
void void
QPDF_Array::releaseResolved() QPDF_Array::releaseResolved()
{ {
for (std::vector<QPDFObjectHandle>::iterator iter = this->items.begin(); this->elements.releaseResolved();
iter != this->items.end(); ++iter)
{
QPDFObjectHandle::ReleaseResolver::releaseResolved(*iter);
}
} }
std::string std::string
QPDF_Array::unparse() QPDF_Array::unparse()
{ {
std::string result = "[ "; std::string result = "[ ";
size_t size = this->items.size(); size_t size = this->elements.size();
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
{ {
result += this->items.at(i).unparse(); result += this->elements.at(i).unparse();
result += " "; result += " ";
} }
result += "]"; result += "]";
@ -40,10 +41,10 @@ JSON
QPDF_Array::getJSON() QPDF_Array::getJSON()
{ {
JSON j = JSON::makeArray(); JSON j = JSON::makeArray();
size_t size = this->items.size(); size_t size = this->elements.size();
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
{ {
j.addArrayElement(this->items.at(i).getJSON()); j.addArrayElement(this->elements.at(i).getJSON());
} }
return j; return j;
} }
@ -71,46 +72,44 @@ QPDF_Array::getNItems() const
{ {
// This should really return a size_t, but changing it would break // This should really return a size_t, but changing it would break
// a lot of code. // a lot of code.
return QIntC::to_int(this->items.size()); return QIntC::to_int(this->elements.size());
} }
QPDFObjectHandle QPDFObjectHandle
QPDF_Array::getItem(int n) const 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( throw std::logic_error(
"INTERNAL ERROR: bounds error accessing QPDF_Array element"); "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 void
QPDF_Array::getAsVector(std::vector<QPDFObjectHandle>& v) const 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) for (size_t i = 0; i < size; ++i)
{ {
v.push_back(this->items.at(i)); v.push_back(this->elements.at(i));
} }
} }
void void
QPDF_Array::setItem(int n, QPDFObjectHandle const& oh) QPDF_Array::setItem(int n, QPDFObjectHandle const& oh)
{ {
// Call getItem for bounds checking this->elements.setAt(QIntC::to_size(n), oh);
(void) getItem(n);
this->items.at(QIntC::to_size(n)) = oh;
} }
void void
QPDF_Array::setFromVector(std::vector<QPDFObjectHandle> const& v) QPDF_Array::setFromVector(std::vector<QPDFObjectHandle> const& v)
{ {
this->items.clear(); this->elements = SparseOHArray();
for (std::vector<QPDFObjectHandle>::const_iterator iter = v.begin(); for (std::vector<QPDFObjectHandle>::const_iterator iter = v.begin();
iter != v.end(); ++iter) 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) QPDF_Array::insertItem(int at, QPDFObjectHandle const& item)
{ {
// As special case, also allow insert beyond the end // 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( throw std::logic_error(
"INTERNAL ERROR: bounds error accessing QPDF_Array element"); "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 void
QPDF_Array::appendItem(QPDFObjectHandle const& item) QPDF_Array::appendItem(QPDFObjectHandle const& item)
{ {
this->items.push_back(item); this->elements.append(item);
} }
void void
QPDF_Array::eraseItem(int at) QPDF_Array::eraseItem(int at)
{ {
// Call getItem for bounds checking this->elements.erase(QIntC::to_size(at));
(void) getItem(at);
this->items.erase(this->items.begin() + at);
} }

View File

@ -4,12 +4,13 @@
#include <qpdf/QPDFObject.hh> #include <qpdf/QPDFObject.hh>
#include <vector> #include <vector>
#include <qpdf/QPDFObjectHandle.hh> #include <qpdf/SparseOHArray.hh>
class QPDF_Array: public QPDFObject class QPDF_Array: public QPDFObject
{ {
public: public:
QPDF_Array(std::vector<QPDFObjectHandle> const& items); QPDF_Array(std::vector<QPDFObjectHandle> const& items);
QPDF_Array(SparseOHArray const& items);
virtual ~QPDF_Array(); virtual ~QPDF_Array();
virtual std::string unparse(); virtual std::string unparse();
virtual JSON getJSON(); virtual JSON getJSON();
@ -31,7 +32,7 @@ class QPDF_Array: public QPDFObject
virtual void releaseResolved(); virtual void releaseResolved();
private: private:
std::vector<QPDFObjectHandle> items; SparseOHArray elements;
}; };
#endif // QPDF_ARRAY_HH #endif // QPDF_ARRAY_HH