2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-05-31 17:30:54 +00:00

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.
This commit is contained in:
m-holger 2022-11-16 18:50:13 +00:00
parent ea5164938e
commit e6db8ddeba
3 changed files with 32 additions and 39 deletions

View File

@ -103,8 +103,8 @@ QPDF_Array::unparse()
{
if (sparse) {
std::string result = "[ ";
size_t size = sp_elements.size();
for (size_t i = 0; i < size; ++i) {
int size = sp_elements.size();
for (int i = 0; i < size; ++i) {
result += sp_elements.at(i).unparse();
result += " ";
}
@ -127,8 +127,8 @@ QPDF_Array::getJSON(int json_version)
{
if (sparse) {
JSON j = JSON::makeArray();
size_t size = sp_elements.size();
for (size_t i = 0; i < size; ++i) {
int size = sp_elements.size();
for (int i = 0; i < size; ++i) {
j.addArrayElement(sp_elements.at(i).getJSON(json_version));
}
return j;
@ -162,7 +162,7 @@ QPDF_Array::getItem(int n) const
throw std::logic_error(
"INTERNAL ERROR: bounds error accessing QPDF_Array element");
}
return sp_elements.at(QIntC::to_size(n));
return sp_elements.at(n);
} else {
if ((n < 0) || (n >= QIntC::to_int(elements.size()))) {
throw std::logic_error(
@ -177,8 +177,8 @@ void
QPDF_Array::getAsVector(std::vector<QPDFObjectHandle>& v) const
{
if (sparse) {
size_t size = sp_elements.size();
for (size_t i = 0; i < size; ++i) {
int size = sp_elements.size();
for (int i = 0; i < size; ++i) {
v.push_back(sp_elements.at(i));
}
} else {
@ -190,7 +190,7 @@ void
QPDF_Array::setItem(int n, QPDFObjectHandle const& oh)
{
if (sparse) {
sp_elements.setAt(QIntC::to_size(n), oh);
sp_elements.setAt(n, oh);
} else {
size_t idx = size_t(n);
if (n < 0 || idx >= elements.size()) {
@ -239,11 +239,11 @@ QPDF_Array::insertItem(int at, QPDFObjectHandle const& item)
{
if (sparse) {
// As special case, also allow insert beyond the end
if ((at < 0) || (at > QIntC::to_int(sp_elements.size()))) {
if ((at < 0) || (at > sp_elements.size())) {
throw std::logic_error(
"INTERNAL ERROR: bounds error accessing QPDF_Array element");
}
sp_elements.insert(QIntC::to_size(at), item);
sp_elements.insert(at, item);
} else {
// As special case, also allow insert beyond the end
size_t idx = QIntC::to_size(at);
@ -275,7 +275,7 @@ void
QPDF_Array::eraseItem(int at)
{
if (sparse) {
sp_elements.erase(QIntC::to_size(at));
sp_elements.erase(at);
} else {
size_t idx = QIntC::to_size(at);
if (idx >= elements.size()) {

View File

@ -1,16 +1,8 @@
#include <qpdf/SparseOHArray.hh>
#include <qpdf/QPDFObjectHandle.hh>
#include <qpdf/QPDFObject_private.hh>
#include <stdexcept>
SparseOHArray::SparseOHArray() :
n_elements(0)
{
}
size_t
int
SparseOHArray::size() const
{
return this->n_elements;
@ -20,7 +12,7 @@ void
SparseOHArray::append(QPDFObjectHandle oh)
{
if (!oh.isDirectNull()) {
this->elements[this->n_elements] = oh;
this->elements[this->n_elements] = oh.getObj();
}
++this->n_elements;
}
@ -35,9 +27,9 @@ SparseOHArray::append(std::shared_ptr<QPDFObject>&& obj)
}
QPDFObjectHandle
SparseOHArray::at(size_t idx) const
SparseOHArray::at(int idx) const
{
if (idx >= this->n_elements) {
if (idx < 0 || idx >= this->n_elements) {
throw std::logic_error(
"INTERNAL ERROR: bounds error accessing SparseOHArray element");
}
@ -69,7 +61,7 @@ SparseOHArray::disconnect()
}
void
SparseOHArray::setAt(size_t idx, QPDFObjectHandle oh)
SparseOHArray::setAt(int idx, QPDFObjectHandle oh)
{
if (idx >= this->n_elements) {
throw std::logic_error("bounds error setting item in SparseOHArray");
@ -77,12 +69,12 @@ SparseOHArray::setAt(size_t idx, QPDFObjectHandle oh)
if (oh.isDirectNull()) {
this->elements.erase(idx);
} else {
this->elements[idx] = oh;
this->elements[idx] = oh.getObj();
}
}
void
SparseOHArray::erase(size_t idx)
SparseOHArray::erase(int idx)
{
if (idx >= this->n_elements) {
throw std::logic_error("bounds error erasing item from SparseOHArray");
@ -100,7 +92,7 @@ SparseOHArray::erase(size_t idx)
}
void
SparseOHArray::insert(size_t idx, QPDFObjectHandle oh)
SparseOHArray::insert(int idx, QPDFObjectHandle oh)
{
if (idx > this->n_elements) {
throw std::logic_error("bounds error inserting item to SparseOHArray");
@ -117,7 +109,7 @@ SparseOHArray::insert(size_t idx, QPDFObjectHandle oh)
}
}
this->elements = dest;
this->elements[idx] = oh;
this->elements[idx] = oh.getObj();
++this->n_elements;
}
}
@ -130,7 +122,7 @@ SparseOHArray::copy()
for (auto const& element: this->elements) {
auto value = element.second;
result.elements[element.first] =
value.isIndirect() ? value : value.shallowCopy();
value->getObjGen().isIndirect() ? value : value->copy();
}
return result;
}

View File

@ -2,34 +2,35 @@
#define QPDF_SPARSEOHARRAY_HH
#include <qpdf/QPDFObjectHandle.hh>
#include <unordered_map>
#include <qpdf/QPDFObject_private.hh>
#include <map>
class QPDF_Array;
class SparseOHArray
{
public:
SparseOHArray();
size_t size() const;
SparseOHArray() = default;
int size() const;
void append(QPDFObjectHandle oh);
void append(std::shared_ptr<QPDFObject>&& obj);
QPDFObjectHandle at(size_t idx) const;
QPDFObjectHandle at(int idx) const;
void remove_last();
void setAt(size_t idx, QPDFObjectHandle oh);
void erase(size_t idx);
void insert(size_t idx, QPDFObjectHandle oh);
void setAt(int idx, QPDFObjectHandle oh);
void erase(int idx);
void insert(int idx, QPDFObjectHandle oh);
SparseOHArray copy();
void disconnect();
typedef std::unordered_map<size_t, QPDFObjectHandle>::const_iterator
typedef std::map<int, std::shared_ptr<QPDFObject>>::const_iterator
const_iterator;
const_iterator begin() const;
const_iterator end() const;
private:
friend class QPDF_Array;
std::unordered_map<size_t, QPDFObjectHandle> elements;
size_t n_elements;
std::map<int, std::shared_ptr<QPDFObject>> elements;
int n_elements{0};
};
#endif // QPDF_SPARSEOHARRAY_HH