2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-23 03:18:59 +00:00

Refactor QPDF_Array::eraseItem and rename to erase

This commit is contained in:
m-holger 2022-12-12 13:29:52 +00:00
parent 1bb23d0545
commit 4d37389bef
6 changed files with 28 additions and 29 deletions

View File

@ -972,18 +972,15 @@ QPDFObjectHandle::appendItemAndGetNew(QPDFObjectHandle const& item)
void void
QPDFObjectHandle::eraseItem(int at) QPDFObjectHandle::eraseItem(int at)
{ {
auto array = asArray(); if (auto array = asArray()) {
if (array && at < array->size() && at >= 0) { if (!array->erase(at)) {
array->eraseItem(at);
} else {
if (array) {
objectWarning("ignoring attempt to erase out of bounds array item"); objectWarning("ignoring attempt to erase out of bounds array item");
QTC::TC("qpdf", "QPDFObjectHandle erase array bounds"); QTC::TC("qpdf", "QPDFObjectHandle erase array bounds");
}
} else { } else {
typeWarning("array", "ignoring attempt to erase item"); typeWarning("array", "ignoring attempt to erase item");
QTC::TC("qpdf", "QPDFObjectHandle array ignoring erase item"); QTC::TC("qpdf", "QPDFObjectHandle array ignoring erase item");
} }
}
} }
QPDFObjectHandle QPDFObjectHandle

View File

@ -267,17 +267,16 @@ QPDF_Array::push_back(QPDFObjectHandle const& item)
} }
} }
void bool
QPDF_Array::eraseItem(int at) QPDF_Array::erase(int at)
{ {
if (at < 0 || at >= size()) {
return false;
}
if (sparse) { if (sparse) {
sp_elements.erase(at); sp_elements.erase(at);
} else { } else {
size_t idx = QIntC::to_size(at); elements.erase(elements.cbegin() + at);
if (idx >= elements.size()) {
throw std::logic_error("bounds error erasing item from OHArray");
}
int n = int(idx);
elements.erase(elements.cbegin() + n);
} }
return true;
} }

View File

@ -44,21 +44,22 @@ SparseOHArray::setAt(int idx, QPDFObjectHandle oh)
} }
void void
SparseOHArray::erase(int idx) SparseOHArray::erase(int at)
{ {
if (idx >= this->n_elements) { auto end = elements.end();
throw std::logic_error("bounds error erasing item from SparseOHArray"); if (auto iter = elements.lower_bound(at); iter != end) {
if (iter->first == at) {
iter++;
elements.erase(at);
} }
decltype(this->elements) dest;
for (auto const& iter: this->elements) { while (iter != end) {
if (iter.first < idx) { auto nh = elements.extract(iter++);
dest.insert(iter); --nh.key();
} else if (iter.first > idx) { elements.insert(std::move(nh));
dest[iter.first - 1] = iter.second;
} }
} }
this->elements = dest; --n_elements;
--this->n_elements;
} }
void void

View File

@ -35,7 +35,7 @@ class QPDF_Array: public QPDFValue
void setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& items); void setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& items);
bool insert(int at, QPDFObjectHandle const& item); bool insert(int at, QPDFObjectHandle const& item);
void push_back(QPDFObjectHandle const& item); void push_back(QPDFObjectHandle const& item);
void eraseItem(int at); bool erase(int at);
private: private:
QPDF_Array(std::vector<QPDFObjectHandle> const& items); QPDF_Array(std::vector<QPDFObjectHandle> const& items);

View File

@ -1,2 +1,3 @@
WARNING: test array: ignoring attempt to erase out of bounds array item WARNING: test array: ignoring attempt to erase out of bounds array item
WARNING: minimal.pdf, object 1 0 at offset 19: operation for array attempted on object of type dictionary: ignoring attempt to erase item
test 88 done test 88 done

View File

@ -3283,6 +3283,7 @@ test_88(QPDF& pdf, char const* arg2)
auto arr2 = pdf.getRoot().replaceKeyAndGetNew("/QTest", "[1 2]"_qpdf); auto arr2 = pdf.getRoot().replaceKeyAndGetNew("/QTest", "[1 2]"_qpdf);
arr2.setObjectDescription(&pdf, "test array"); arr2.setObjectDescription(&pdf, "test array");
assert(arr2.eraseItemAndGetOld(50).isNull()); assert(arr2.eraseItemAndGetOld(50).isNull());
assert(pdf.getRoot().eraseItemAndGetOld(0).isNull());
} }
static void static void