aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/SparseOHArray.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2019-08-18 00:54:24 +0200
committerJay Berkenbilt <ejb@ql.org>2019-08-18 05:02:41 +0200
commite83f3308fbccd34959d325b830118eafe441fe48 (patch)
treeb3ac08e39da91a00b67e147bd05f5379789fcbe3 /libqpdf/SparseOHArray.cc
parent04419d7c3269aa29ff669c8b5f3a7999edb44bea (diff)
downloadqpdf-e83f3308fbccd34959d325b830118eafe441fe48.tar.zst
SparseOHArray
Diffstat (limited to 'libqpdf/SparseOHArray.cc')
-rw-r--r--libqpdf/SparseOHArray.cc143
1 files changed, 143 insertions, 0 deletions
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 <qpdf/SparseOHArray.hh>
+#include <stdexcept>
+
+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<size_t, QPDFObjectHandle>::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<size_t, QPDFObjectHandle>::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<size_t, QPDFObjectHandle> dest;
+ for (std::map<size_t, QPDFObjectHandle>::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<size_t, QPDFObjectHandle> dest;
+ for (std::map<size_t, QPDFObjectHandle>::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;
+ }
+}