diff options
author | m-holger <m-holger@kubitscheck.org> | 2023-03-25 16:30:52 +0100 |
---|---|---|
committer | m-holger <m-holger@kubitscheck.org> | 2023-03-29 12:48:21 +0200 |
commit | 38cf7c16283ec2d476514a54e2b1a7016b0b770a (patch) | |
tree | a741c4c0e5ee636fb8947751ebc50791be7e1aa5 /libqpdf/OHArray.cc | |
parent | de29fd56c487dcf08f2af66f47576f147b20be82 (diff) | |
download | qpdf-38cf7c16283ec2d476514a54e2b1a7016b0b770a.tar.zst |
Add separate sparse mode to QPDF_Array
Add temporary clone of SparseOHArray to implement non-sparse mode.
Diffstat (limited to 'libqpdf/OHArray.cc')
-rw-r--r-- | libqpdf/OHArray.cc | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/libqpdf/OHArray.cc b/libqpdf/OHArray.cc new file mode 100644 index 00000000..436fa4f2 --- /dev/null +++ b/libqpdf/OHArray.cc @@ -0,0 +1,148 @@ +#include <qpdf/OHArray.hh> + +#include <qpdf/QPDFObjectHandle.hh> +#include <qpdf/QPDFObject_private.hh> + +#include <stdexcept> + +OHArray::OHArray() : + n_elements(0) +{ +} + +size_t +OHArray::size() const +{ + return this->n_elements; +} + +void +OHArray::append(QPDFObjectHandle oh) +{ + if (!oh.isDirectNull()) { + this->elements[this->n_elements] = oh; + } + ++this->n_elements; +} + +void +OHArray::append(std::shared_ptr<QPDFObject>&& obj) +{ + if (obj->getTypeCode() != ::ot_null || !obj->getObjGen().isIndirect()) { + this->elements[this->n_elements] = std::move(obj); + } + ++this->n_elements; +} + +QPDFObjectHandle +OHArray::at(size_t idx) const +{ + if (idx >= this->n_elements) { + throw std::logic_error( + "INTERNAL ERROR: bounds error accessing OHArray element"); + } + auto const& iter = this->elements.find(idx); + if (iter == this->elements.end()) { + return QPDFObjectHandle::newNull(); + } else { + return (*iter).second; + } +} + +void +OHArray::remove_last() +{ + if (this->n_elements == 0) { + throw std::logic_error("INTERNAL ERROR: attempt to remove" + " last item from empty OHArray"); + } + --this->n_elements; + this->elements.erase(this->n_elements); +} + +void +OHArray::disconnect() +{ + for (auto& iter: this->elements) { + QPDFObjectHandle::DisconnectAccess::disconnect(iter.second); + } +} + +void +OHArray::setAt(size_t idx, QPDFObjectHandle oh) +{ + if (idx >= this->n_elements) { + throw std::logic_error("bounds error setting item in OHArray"); + } + if (oh.isDirectNull()) { + this->elements.erase(idx); + } else { + this->elements[idx] = oh; + } +} + +void +OHArray::erase(size_t idx) +{ + if (idx >= this->n_elements) { + throw std::logic_error("bounds error erasing item from OHArray"); + } + decltype(this->elements) dest; + for (auto const& iter: this->elements) { + if (iter.first < idx) { + dest.insert(iter); + } else if (iter.first > idx) { + dest[iter.first - 1] = iter.second; + } + } + this->elements = dest; + --this->n_elements; +} + +void +OHArray::insert(size_t idx, QPDFObjectHandle oh) +{ + if (idx > this->n_elements) { + throw std::logic_error("bounds error inserting item to OHArray"); + } else if (idx == this->n_elements) { + // Allow inserting to the last position + append(oh); + } else { + decltype(this->elements) dest; + for (auto const& iter: this->elements) { + if (iter.first < idx) { + dest.insert(iter); + } else { + dest[iter.first + 1] = iter.second; + } + } + this->elements = dest; + this->elements[idx] = oh; + ++this->n_elements; + } +} + +OHArray +OHArray::copy() +{ + OHArray result; + result.n_elements = this->n_elements; + for (auto const& element: this->elements) { + auto value = element.second; + result.elements[element.first] = + value.isIndirect() ? value : value.shallowCopy(); + } + return result; +} + +OHArray::const_iterator +OHArray::begin() const +{ + return this->elements.begin(); +} + +OHArray::const_iterator +OHArray::end() const +{ + return this->elements.end(); +} |