From e83f3308fbccd34959d325b830118eafe441fe48 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 17 Aug 2019 18:54:24 -0400 Subject: SparseOHArray --- libqpdf/SparseOHArray.cc | 143 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 libqpdf/SparseOHArray.cc (limited to 'libqpdf/SparseOHArray.cc') diff --git a/libqpdf/SparseOHArray.cc b/libqpdf/SparseOHArray.cc new file mode 100644 index 00000000..2c525ca8 --- /dev/null +++ b/libqpdf/SparseOHArray.cc @@ -0,0 +1,143 @@ +#include +#include + +SparseOHArray::SparseOHArray() : + n_elements(0) +{ +} + +size_t +SparseOHArray::size() const +{ + return this->n_elements; +} + +void +SparseOHArray::append(QPDFObjectHandle oh) +{ + if (! oh.isResolvedNull()) + { + this->elements[this->n_elements] = oh; + } + ++this->n_elements; +} + +QPDFObjectHandle +SparseOHArray::at(size_t idx) const +{ + if (idx >= this->n_elements) + { + throw std::logic_error( + "INTERNAL ERROR: bounds error accessing SparseOHArray element"); + } + std::map::const_iterator iter = + this->elements.find(idx); + if (iter == this->elements.end()) + { + return QPDFObjectHandle::newNull(); + } + else + { + return (*iter).second; + } +} + +void +SparseOHArray::remove_last() +{ + if (this->n_elements == 0) + { + throw std::logic_error( + "INTERNAL ERROR: attempt to remove" + " last item from empty SparseOHArray"); + } + --this->n_elements; + this->elements.erase(this->n_elements); +} + +void +SparseOHArray::releaseResolved() +{ + for (std::map::iterator iter = + this->elements.begin(); + iter != this->elements.end(); ++iter) + { + QPDFObjectHandle::ReleaseResolver::releaseResolved((*iter).second); + } +} + +void +SparseOHArray::setAt(size_t idx, QPDFObjectHandle oh) +{ + if (idx >= this->n_elements) + { + throw std::logic_error("bounds error setting item in SparseOHArray"); + } + if (oh.isResolvedNull()) + { + this->elements.erase(idx); + } + else + { + this->elements[idx] = oh; + } +} + +void +SparseOHArray::erase(size_t idx) +{ + if (idx >= this->n_elements) + { + throw std::logic_error("bounds error erasing item from SparseOHArray"); + } + std::map dest; + for (std::map::iterator iter = + this->elements.begin(); + iter != this->elements.end(); ++iter) + { + 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 +SparseOHArray::insert(size_t idx, QPDFObjectHandle oh) +{ + if (idx > this->n_elements) + { + throw std::logic_error("bounds error inserting item to SparseOHArray"); + } + else if (idx == this->n_elements) + { + // Allow inserting to the last position + append(oh); + } + else + { + std::map dest; + for (std::map::iterator iter = + this->elements.begin(); + iter != this->elements.end(); ++iter) + { + if ((*iter).first < idx) + { + dest.insert(*iter); + } + else + { + dest[(*iter).first + 1] = (*iter).second; + } + } + this->elements = dest; + this->elements[idx] = oh; + ++this->n_elements; + } +} -- cgit v1.2.3-54-g00ecf