2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 19:08:59 +00:00

Refactor QPDF_Array::getItem and rename to at

This commit is contained in:
m-holger 2023-03-24 15:01:40 +00:00
parent 51d350c98c
commit a1a8f35b63
5 changed files with 74 additions and 88 deletions

View File

@ -801,90 +801,88 @@ QPDFObjectHandle::getArrayNItems()
QPDFObjectHandle QPDFObjectHandle
QPDFObjectHandle::getArrayItem(int n) QPDFObjectHandle::getArrayItem(int n)
{ {
auto array = asArray(); if (auto array = asArray()) {
if (array && n < array->size() && n >= 0) { if (auto result = array->at(n); result.obj != nullptr) {
return array->getItem(n); return result;
} else { } else {
if (array) {
objectWarning("returning null for out of bounds array access"); objectWarning("returning null for out of bounds array access");
QTC::TC("qpdf", "QPDFObjectHandle array bounds"); QTC::TC("qpdf", "QPDFObjectHandle array bounds");
} else {
typeWarning("array", "returning null");
QTC::TC("qpdf", "QPDFObjectHandle array null for non-array");
} }
static auto constexpr msg = } else {
" -> null returned from invalid array access"sv; typeWarning("array", "returning null");
return QPDF_Null::create(obj, msg, ""); QTC::TC("qpdf", "QPDFObjectHandle array null for non-array");
} }
static auto constexpr msg = " -> null returned from invalid array access"sv;
return QPDF_Null::create(obj, msg, "");
} }
bool bool
QPDFObjectHandle::isRectangle() QPDFObjectHandle::isRectangle()
{ {
auto array = asArray(); if (auto array = asArray()) {
if (array == nullptr || array->size() != 4) { for (int i = 0; i < 4; ++i) {
return false; if (auto item = array->at(i); !(item.obj && item.isNumber())) {
} return false;
for (int i = 0; i < 4; ++i) { }
if (!array->getItem(i).isNumber()) {
return false;
} }
return array->size() == 4;
} }
return true; return false;
} }
bool bool
QPDFObjectHandle::isMatrix() QPDFObjectHandle::isMatrix()
{ {
auto array = asArray(); if (auto array = asArray()) {
if (array == nullptr || array->size() != 6) { for (int i = 0; i < 6; ++i) {
return false; if (auto item = array->at(i); !(item.obj && item.isNumber())) {
} return false;
for (int i = 0; i < 6; ++i) { }
if (!array->getItem(i).isNumber()) {
return false;
} }
return array->size() == 6;
} }
return true; return false;
} }
QPDFObjectHandle::Rectangle QPDFObjectHandle::Rectangle
QPDFObjectHandle::getArrayAsRectangle() QPDFObjectHandle::getArrayAsRectangle()
{ {
Rectangle result; if (auto array = asArray()) {
if (isRectangle()) { if (array->size() != 4) {
auto array = asArray(); return {};
// Rectangle coordinates are always supposed to be llx, lly, }
// urx, ury, but files have been found in the wild where double items[4];
// llx > urx or lly > ury. for (int i = 0; i < 4; ++i) {
double i0 = array->getItem(0).getNumericValue(); if (!array->at(i).getValueAsNumber(items[i])) {
double i1 = array->getItem(1).getNumericValue(); return {};
double i2 = array->getItem(2).getNumericValue(); }
double i3 = array->getItem(3).getNumericValue(); }
result = Rectangle( return Rectangle(
std::min(i0, i2), std::min(items[0], items[2]),
std::min(i1, i3), std::min(items[1], items[3]),
std::max(i0, i2), std::max(items[0], items[2]),
std::max(i1, i3)); std::max(items[1], items[3]));
} }
return result; return {};
} }
QPDFObjectHandle::Matrix QPDFObjectHandle::Matrix
QPDFObjectHandle::getArrayAsMatrix() QPDFObjectHandle::getArrayAsMatrix()
{ {
Matrix result; if (auto array = asArray()) {
if (isMatrix()) { if (array->size() != 6) {
auto array = asArray(); return {};
result = Matrix( }
array->getItem(0).getNumericValue(), double items[6];
array->getItem(1).getNumericValue(), for (int i = 0; i < 6; ++i) {
array->getItem(2).getNumericValue(), if (!array->at(i).getValueAsNumber(items[i])) {
array->getItem(3).getNumericValue(), return {};
array->getItem(4).getNumericValue(), }
array->getItem(5).getNumericValue()); }
return Matrix(
items[0], items[1], items[2], items[3], items[4], items[5]);
} }
return result; return {};
} }
std::vector<QPDFObjectHandle> std::vector<QPDFObjectHandle>
@ -991,8 +989,8 @@ QPDFObjectHandle
QPDFObjectHandle::eraseItemAndGetOld(int at) QPDFObjectHandle::eraseItemAndGetOld(int at)
{ {
auto array = asArray(); auto array = asArray();
auto result = (array && at < array->size() && at >= 0) ? array->getItem(at) auto result =
: newNull(); (array && at < array->size() && at >= 0) ? array->at(at) : newNull();
eraseItem(at); eraseItem(at);
return result; return result;
} }
@ -1515,7 +1513,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray(
if (auto array = asArray()) { if (auto array = asArray()) {
int n_items = array->size(); int n_items = array->size();
for (int i = 0; i < n_items; ++i) { for (int i = 0; i < n_items; ++i) {
QPDFObjectHandle item = array->getItem(i); QPDFObjectHandle item = array->at(i);
if (item.isStream()) { if (item.isStream()) {
result.push_back(item); result.push_back(item);
} else { } else {
@ -2215,7 +2213,7 @@ QPDFObjectHandle::makeDirect(
auto array = asArray(); auto array = asArray();
int n = array->size(); int n = array->size();
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
items.push_back(array->getItem(i)); items.push_back(array->at(i));
items.back().makeDirect(visited, stop_at_streams); items.back().makeDirect(visited, stop_at_streams);
} }
this->obj = QPDF_Array::create(items); this->obj = QPDF_Array::create(items);

View File

@ -105,7 +105,7 @@ QPDF_Array::unparse()
std::string result = "[ "; std::string result = "[ ";
int size = sp_elements.size(); int size = sp_elements.size();
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
result += sp_elements.at(i).unparse(); result += at(i).unparse();
result += " "; result += " ";
} }
result += "]"; result += "]";
@ -114,7 +114,7 @@ QPDF_Array::unparse()
std::string result = "[ "; std::string result = "[ ";
auto size = elements.size(); auto size = elements.size();
for (int i = 0; i < int(size); ++i) { for (int i = 0; i < int(size); ++i) {
result += getItem(i).unparse(); result += at(i).unparse();
result += " "; result += " ";
} }
result += "]"; result += "]";
@ -129,35 +129,29 @@ QPDF_Array::getJSON(int json_version)
JSON j = JSON::makeArray(); JSON j = JSON::makeArray();
int size = sp_elements.size(); int size = sp_elements.size();
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
j.addArrayElement(sp_elements.at(i).getJSON(json_version)); j.addArrayElement(at(i).getJSON(json_version));
} }
return j; return j;
} else { } else {
JSON j = JSON::makeArray(); JSON j = JSON::makeArray();
size_t size = elements.size(); size_t size = elements.size();
for (int i = 0; i < int(size); ++i) { for (int i = 0; i < int(size); ++i) {
j.addArrayElement(getItem(i).getJSON(json_version)); j.addArrayElement(at(i).getJSON(json_version));
} }
return j; return j;
} }
} }
QPDFObjectHandle QPDFObjectHandle
QPDF_Array::getItem(int n) const QPDF_Array::at(int n) const noexcept
{ {
if (sparse) { if (n < 0 || n >= size()) {
if ((n < 0) || (n >= QIntC::to_int(sp_elements.size()))) { return {};
throw std::logic_error( } else if (sparse) {
"INTERNAL ERROR: bounds error accessing QPDF_Array element"); auto const& iter = sp_elements.elements.find(n);
} return iter == sp_elements.elements.end() ? null_oh : (*iter).second;
return sp_elements.at(n);
} else { } else {
if ((n < 0) || (n >= QIntC::to_int(elements.size()))) { return elements[size_t(n)];
throw std::logic_error(
"INTERNAL ERROR: bounds error accessing QPDF_Array element");
}
auto const& obj = elements.at(size_t(n));
return obj ? obj : null_oh;
} }
} }
@ -167,7 +161,7 @@ QPDF_Array::getAsVector(std::vector<QPDFObjectHandle>& v) const
if (sparse) { if (sparse) {
int size = sp_elements.size(); int size = sp_elements.size();
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
v.push_back(sp_elements.at(i)); v.push_back(at(i));
} }
} else { } else {
v = std::vector<QPDFObjectHandle>(elements.cbegin(), elements.cend()); v = std::vector<QPDFObjectHandle>(elements.cbegin(), elements.cend());

View File

@ -2,6 +2,8 @@
#include <stdexcept> #include <stdexcept>
static const QPDFObjectHandle null_oh = QPDFObjectHandle::newNull();
void void
SparseOHArray::append(QPDFObjectHandle oh) SparseOHArray::append(QPDFObjectHandle oh)
{ {
@ -23,16 +25,8 @@ SparseOHArray::append(std::shared_ptr<QPDFObject>&& obj)
QPDFObjectHandle QPDFObjectHandle
SparseOHArray::at(int idx) const SparseOHArray::at(int idx) const
{ {
if (idx < 0 || idx >= this->n_elements) { auto const& iter = elements.find(idx);
throw std::logic_error( return iter == elements.end() ? null_oh : (*iter).second;
"INTERNAL ERROR: bounds error accessing SparseOHArray element");
}
auto const& iter = this->elements.find(idx);
if (iter == this->elements.end()) {
return QPDFObjectHandle::newNull();
} else {
return (*iter).second;
}
} }
void void

View File

@ -27,7 +27,7 @@ class QPDF_Array: public QPDFValue
{ {
return sparse ? sp_elements.size() : int(elements.size()); return sparse ? sp_elements.size() : int(elements.size());
} }
QPDFObjectHandle getItem(int n) const; QPDFObjectHandle at(int n) const noexcept;
void getAsVector(std::vector<QPDFObjectHandle>&) const; void getAsVector(std::vector<QPDFObjectHandle>&) const;
void setItem(int, QPDFObjectHandle const&); void setItem(int, QPDFObjectHandle const&);

View File

@ -12,7 +12,7 @@ class SparseOHArray
public: public:
SparseOHArray() = default; SparseOHArray() = default;
int int
size() const size() const noexcept
{ {
return n_elements; return n_elements;
} }