Commit 4d37389befc705b671d8fa7a1da2b7117b50f454

Authored by m-holger
1 parent 1bb23d05

Refactor QPDF_Array::eraseItem and rename to erase

libqpdf/QPDFObjectHandle.cc
... ... @@ -972,17 +972,14 @@ QPDFObjectHandle::appendItemAndGetNew(QPDFObjectHandle const& item)
972 972 void
973 973 QPDFObjectHandle::eraseItem(int at)
974 974 {
975   - auto array = asArray();
976   - if (array && at < array->size() && at >= 0) {
977   - array->eraseItem(at);
978   - } else {
979   - if (array) {
  975 + if (auto array = asArray()) {
  976 + if (!array->erase(at)) {
980 977 objectWarning("ignoring attempt to erase out of bounds array item");
981 978 QTC::TC("qpdf", "QPDFObjectHandle erase array bounds");
982   - } else {
983   - typeWarning("array", "ignoring attempt to erase item");
984   - QTC::TC("qpdf", "QPDFObjectHandle array ignoring erase item");
985 979 }
  980 + } else {
  981 + typeWarning("array", "ignoring attempt to erase item");
  982 + QTC::TC("qpdf", "QPDFObjectHandle array ignoring erase item");
986 983 }
987 984 }
988 985  
... ...
libqpdf/QPDF_Array.cc
... ... @@ -267,17 +267,16 @@ QPDF_Array::push_back(QPDFObjectHandle const&amp; item)
267 267 }
268 268 }
269 269  
270   -void
271   -QPDF_Array::eraseItem(int at)
  270 +bool
  271 +QPDF_Array::erase(int at)
272 272 {
  273 + if (at < 0 || at >= size()) {
  274 + return false;
  275 + }
273 276 if (sparse) {
274 277 sp_elements.erase(at);
275 278 } else {
276   - size_t idx = QIntC::to_size(at);
277   - if (idx >= elements.size()) {
278   - throw std::logic_error("bounds error erasing item from OHArray");
279   - }
280   - int n = int(idx);
281   - elements.erase(elements.cbegin() + n);
  279 + elements.erase(elements.cbegin() + at);
282 280 }
  281 + return true;
283 282 }
... ...
libqpdf/SparseOHArray.cc
... ... @@ -44,21 +44,22 @@ SparseOHArray::setAt(int idx, QPDFObjectHandle oh)
44 44 }
45 45  
46 46 void
47   -SparseOHArray::erase(int idx)
  47 +SparseOHArray::erase(int at)
48 48 {
49   - if (idx >= this->n_elements) {
50   - throw std::logic_error("bounds error erasing item from SparseOHArray");
51   - }
52   - decltype(this->elements) dest;
53   - for (auto const& iter: this->elements) {
54   - if (iter.first < idx) {
55   - dest.insert(iter);
56   - } else if (iter.first > idx) {
57   - dest[iter.first - 1] = iter.second;
  49 + auto end = elements.end();
  50 + if (auto iter = elements.lower_bound(at); iter != end) {
  51 + if (iter->first == at) {
  52 + iter++;
  53 + elements.erase(at);
  54 + }
  55 +
  56 + while (iter != end) {
  57 + auto nh = elements.extract(iter++);
  58 + --nh.key();
  59 + elements.insert(std::move(nh));
58 60 }
59 61 }
60   - this->elements = dest;
61   - --this->n_elements;
  62 + --n_elements;
62 63 }
63 64  
64 65 void
... ...
libqpdf/qpdf/QPDF_Array.hh
... ... @@ -35,7 +35,7 @@ class QPDF_Array: public QPDFValue
35 35 void setFromVector(std::vector<std::shared_ptr<QPDFObject>>&& items);
36 36 bool insert(int at, QPDFObjectHandle const& item);
37 37 void push_back(QPDFObjectHandle const& item);
38   - void eraseItem(int at);
  38 + bool erase(int at);
39 39  
40 40 private:
41 41 QPDF_Array(std::vector<QPDFObjectHandle> const& items);
... ...
qpdf/qtest/qpdf/test88.out
1 1 WARNING: test array: ignoring attempt to erase out of bounds array item
  2 +WARNING: minimal.pdf, object 1 0 at offset 19: operation for array attempted on object of type dictionary: ignoring attempt to erase item
2 3 test 88 done
... ...
qpdf/test_driver.cc
... ... @@ -3283,6 +3283,7 @@ test_88(QPDF&amp; pdf, char const* arg2)
3283 3283 auto arr2 = pdf.getRoot().replaceKeyAndGetNew("/QTest", "[1 2]"_qpdf);
3284 3284 arr2.setObjectDescription(&pdf, "test array");
3285 3285 assert(arr2.eraseItemAndGetOld(50).isNull());
  3286 + assert(pdf.getRoot().eraseItemAndGetOld(0).isNull());
3286 3287 }
3287 3288  
3288 3289 static void
... ...