From 38cf7c16283ec2d476514a54e2b1a7016b0b770a Mon Sep 17 00:00:00 2001 From: m-holger Date: Sat, 25 Mar 2023 15:30:52 +0000 Subject: Add separate sparse mode to QPDF_Array Add temporary clone of SparseOHArray to implement non-sparse mode. --- libqpdf/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'libqpdf/CMakeLists.txt') diff --git a/libqpdf/CMakeLists.txt b/libqpdf/CMakeLists.txt index 5e3a628e..2d857f45 100644 --- a/libqpdf/CMakeLists.txt +++ b/libqpdf/CMakeLists.txt @@ -116,6 +116,7 @@ set(libqpdf_SOURCES SecureRandomDataProvider.cc SF_FlateLzwDecode.cc SparseOHArray.cc + OHArray.cc qpdf-c.cc qpdfjob-c.cc qpdflogger-c.cc) -- cgit v1.2.3-70-g09d2 From ea5164938e77cb968003fe06f98b87f648319bbf Mon Sep 17 00:00:00 2001 From: m-holger Date: Sat, 25 Mar 2023 18:23:39 +0000 Subject: Remove temporary OHArray --- libqpdf/CMakeLists.txt | 1 - libqpdf/OHArray.cc | 5 ----- libqpdf/QPDF_Array.cc | 55 +++++++++++++++++++++------------------------- libqpdf/qpdf/OHArray.hh | 21 ------------------ libqpdf/qpdf/QPDF_Array.hh | 9 ++++---- 5 files changed, 29 insertions(+), 62 deletions(-) delete mode 100644 libqpdf/OHArray.cc delete mode 100644 libqpdf/qpdf/OHArray.hh (limited to 'libqpdf/CMakeLists.txt') diff --git a/libqpdf/CMakeLists.txt b/libqpdf/CMakeLists.txt index 2d857f45..5e3a628e 100644 --- a/libqpdf/CMakeLists.txt +++ b/libqpdf/CMakeLists.txt @@ -116,7 +116,6 @@ set(libqpdf_SOURCES SecureRandomDataProvider.cc SF_FlateLzwDecode.cc SparseOHArray.cc - OHArray.cc qpdf-c.cc qpdfjob-c.cc qpdflogger-c.cc) diff --git a/libqpdf/OHArray.cc b/libqpdf/OHArray.cc deleted file mode 100644 index 377b1a36..00000000 --- a/libqpdf/OHArray.cc +++ /dev/null @@ -1,5 +0,0 @@ -#include - -OHArray::OHArray() -{ -} diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc index c7a9f315..620b75eb 100644 --- a/libqpdf/QPDF_Array.cc +++ b/libqpdf/QPDF_Array.cc @@ -29,7 +29,7 @@ QPDF_Array::QPDF_Array(SparseOHArray const& items) : { } -QPDF_Array::QPDF_Array(OHArray const& items) : +QPDF_Array::QPDF_Array(std::vector> const& items) : QPDFValue(::ot_array, "array"), sparse(false), elements(items) @@ -56,7 +56,7 @@ QPDF_Array::create(SparseOHArray const& items) } std::shared_ptr -QPDF_Array::create(OHArray const& items) +QPDF_Array::create(std::vector> const& items) { return do_create(new QPDF_Array(items)); } @@ -70,10 +70,10 @@ QPDF_Array::copy(bool shallow) if (shallow) { return create(elements); } else { - OHArray result; - result.elements.reserve(elements.elements.size()); - for (auto const& element: elements.elements) { - result.elements.push_back( + std::vector> result; + result.reserve(elements.size()); + for (auto const& element: elements) { + result.push_back( element ? (element->getObjGen().isIndirect() ? element : element->copy()) @@ -90,7 +90,7 @@ QPDF_Array::disconnect() if (sparse) { sp_elements.disconnect(); } else { - for (auto const& iter: elements.elements) { + for (auto const& iter: elements) { if (iter) { QPDFObjectHandle::DisconnectAccess::disconnect(iter); } @@ -112,7 +112,7 @@ QPDF_Array::unparse() return result; } else { std::string result = "[ "; - auto size = elements.elements.size(); + auto size = elements.size(); for (int i = 0; i < int(size); ++i) { result += getItem(i).unparse(); result += " "; @@ -134,7 +134,7 @@ QPDF_Array::getJSON(int json_version) return j; } else { JSON j = JSON::makeArray(); - size_t size = elements.elements.size(); + size_t size = elements.size(); for (int i = 0; i < int(size); ++i) { j.addArrayElement(getItem(i).getJSON(json_version)); } @@ -150,7 +150,7 @@ QPDF_Array::getNItems() const // a lot of code. return QIntC::to_int(sp_elements.size()); } else { - return QIntC::to_int(elements.elements.size()); + return QIntC::to_int(elements.size()); } } @@ -164,11 +164,11 @@ QPDF_Array::getItem(int n) const } return sp_elements.at(QIntC::to_size(n)); } else { - if ((n < 0) || (n >= QIntC::to_int(elements.elements.size()))) { + if ((n < 0) || (n >= QIntC::to_int(elements.size()))) { throw std::logic_error( "INTERNAL ERROR: bounds error accessing QPDF_Array element"); } - auto const& obj = elements.elements.at(size_t(n)); + auto const& obj = elements.at(size_t(n)); return obj ? obj : null_oh; } } @@ -182,8 +182,7 @@ QPDF_Array::getAsVector(std::vector& v) const v.push_back(sp_elements.at(i)); } } else { - v = std::vector( - elements.elements.cbegin(), elements.elements.cend()); + v = std::vector(elements.cbegin(), elements.cend()); } } @@ -194,10 +193,10 @@ QPDF_Array::setItem(int n, QPDFObjectHandle const& oh) sp_elements.setAt(QIntC::to_size(n), oh); } else { size_t idx = size_t(n); - if (n < 0 || idx >= elements.elements.size()) { + if (n < 0 || idx >= elements.size()) { throw std::logic_error("bounds error setting item in QPDF_Array"); } - elements.elements[idx] = oh.getObj(); + elements[idx] = oh.getObj(); } } @@ -210,9 +209,9 @@ QPDF_Array::setFromVector(std::vector const& v) sp_elements.append(iter); } } else { - elements = OHArray(); + elements.resize(0); for (auto const& iter: v) { - elements.elements.push_back(iter.getObj()); + elements.push_back(iter.getObj()); } } } @@ -231,10 +230,7 @@ QPDF_Array::setFromVector(std::vector>&& v) } } } else { - elements = OHArray(); - for (auto&& item: v) { - elements.elements.push_back(std::move(item)); - } + elements = std::move(v); } } @@ -251,17 +247,16 @@ QPDF_Array::insertItem(int at, QPDFObjectHandle const& item) } else { // As special case, also allow insert beyond the end size_t idx = QIntC::to_size(at); - if ((at < 0) || (at > QIntC::to_int(elements.elements.size()))) { + if ((at < 0) || (at > QIntC::to_int(elements.size()))) { throw std::logic_error( "INTERNAL ERROR: bounds error accessing QPDF_Array element"); } - if (idx == elements.elements.size()) { + if (idx == elements.size()) { // Allow inserting to the last position - elements.elements.push_back(item.getObj()); + elements.push_back(item.getObj()); } else { int n = int(idx); - elements.elements.insert( - elements.elements.cbegin() + n, item.getObj()); + elements.insert(elements.cbegin() + n, item.getObj()); } } } @@ -272,7 +267,7 @@ QPDF_Array::appendItem(QPDFObjectHandle const& item) if (sparse) { sp_elements.append(item); } else { - elements.elements.push_back(item.getObj()); + elements.push_back(item.getObj()); } } @@ -283,10 +278,10 @@ QPDF_Array::eraseItem(int at) sp_elements.erase(QIntC::to_size(at)); } else { size_t idx = QIntC::to_size(at); - if (idx >= elements.elements.size()) { + if (idx >= elements.size()) { throw std::logic_error("bounds error erasing item from OHArray"); } int n = int(idx); - elements.elements.erase(elements.elements.cbegin() + n); + elements.erase(elements.cbegin() + n); } } diff --git a/libqpdf/qpdf/OHArray.hh b/libqpdf/qpdf/OHArray.hh deleted file mode 100644 index 563145c2..00000000 --- a/libqpdf/qpdf/OHArray.hh +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef QPDF_OHARRAY_HH -#define QPDF_OHARRAY_HH - -#include -#include - -#include - -class QPDF_Array; - -class OHArray -{ - public: - OHArray(); - - private: - friend class QPDF_Array; - std::vector> elements; -}; - -#endif // QPDF_OHARRAY_HH diff --git a/libqpdf/qpdf/QPDF_Array.hh b/libqpdf/qpdf/QPDF_Array.hh index 00c7f59d..b52efeb6 100644 --- a/libqpdf/qpdf/QPDF_Array.hh +++ b/libqpdf/qpdf/QPDF_Array.hh @@ -3,9 +3,7 @@ #include -#include #include -#include #include class QPDF_Array: public QPDFValue @@ -17,7 +15,8 @@ class QPDF_Array: public QPDFValue static std::shared_ptr create(std::vector>&& items, bool sparse); static std::shared_ptr create(SparseOHArray const& items); - static std::shared_ptr create(OHArray const& items); + static std::shared_ptr + create(std::vector> const& items); virtual std::shared_ptr copy(bool shallow = false); virtual std::string unparse(); virtual JSON getJSON(int json_version); @@ -38,10 +37,10 @@ class QPDF_Array: public QPDFValue QPDF_Array(std::vector const& items); QPDF_Array(std::vector>&& items, bool sparse); QPDF_Array(SparseOHArray const& items); - QPDF_Array(OHArray const& items); + QPDF_Array(std::vector> const& items); bool sparse{false}; SparseOHArray sp_elements; - OHArray elements; + std::vector> elements; }; #endif // QPDF_ARRAY_HH -- cgit v1.2.3-70-g09d2 From a7b6975132eed94905eb784a0e267e575cade2cb Mon Sep 17 00:00:00 2001 From: m-holger Date: Wed, 29 Mar 2023 19:52:03 +0100 Subject: Remove SparseOHArray --- libqpdf/CMakeLists.txt | 1 - libqpdf/QPDFObjectHandle.cc | 1 - libqpdf/QPDF_Array.cc | 107 +++++++++++++++++------------------------- libqpdf/SparseOHArray.cc | 1 - libqpdf/qpdf/QPDF_Array.hh | 14 +++--- libqpdf/qpdf/SparseOHArray.hh | 26 ---------- libtests/sparse_array.cc | 1 + 7 files changed, 51 insertions(+), 100 deletions(-) delete mode 100644 libqpdf/SparseOHArray.cc delete mode 100644 libqpdf/qpdf/SparseOHArray.hh (limited to 'libqpdf/CMakeLists.txt') diff --git a/libqpdf/CMakeLists.txt b/libqpdf/CMakeLists.txt index 5e3a628e..623e05d3 100644 --- a/libqpdf/CMakeLists.txt +++ b/libqpdf/CMakeLists.txt @@ -115,7 +115,6 @@ set(libqpdf_SOURCES ResourceFinder.cc SecureRandomDataProvider.cc SF_FlateLzwDecode.cc - SparseOHArray.cc qpdf-c.cc qpdfjob-c.cc qpdflogger-c.cc) diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index c2bc30f0..b3f208a5 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc index d5cef946..36c5aaea 100644 --- a/libqpdf/QPDF_Array.cc +++ b/libqpdf/QPDF_Array.cc @@ -1,5 +1,6 @@ #include +#include #include static const QPDFObjectHandle null_oh = QPDFObjectHandle::newNull(); @@ -24,6 +25,20 @@ QPDF_Array::checkOwnership(QPDFObjectHandle const& item) const } } +QPDF_Array::QPDF_Array() : + QPDFValue(::ot_array, "array") +{ +} + +QPDF_Array::QPDF_Array(QPDF_Array const& other) : + QPDFValue(::ot_array, "array"), + sparse(other.sparse), + sp_size(other.sp_size), + sp_elements(other.sp_elements), + elements(other.elements) +{ +} + QPDF_Array::QPDF_Array(std::vector const& v) : QPDFValue(::ot_array, "array") { @@ -36,34 +51,18 @@ QPDF_Array::QPDF_Array( sparse(sparse) { if (sparse) { - sp_elements = SparseOHArray(); for (auto&& item: v) { if (item->getTypeCode() != ::ot_null || item->getObjGen().isIndirect()) { - sp_elements.elements[sp_elements.n_elements] = std::move(item); + sp_elements[sp_size] = std::move(item); } - ++sp_elements.n_elements; + ++sp_size; } } else { elements = std::move(v); } } -QPDF_Array::QPDF_Array(SparseOHArray const& items) : - QPDFValue(::ot_array, "array"), - sparse(true), - sp_elements(items) - -{ -} - -QPDF_Array::QPDF_Array(std::vector> const& items) : - QPDFValue(::ot_array, "array"), - sparse(false), - elements(items) -{ -} - std::shared_ptr QPDF_Array::create(std::vector const& items) { @@ -77,37 +76,21 @@ QPDF_Array::create( return do_create(new QPDF_Array(std::move(items), sparse)); } -std::shared_ptr -QPDF_Array::create(SparseOHArray const& items) -{ - return do_create(new QPDF_Array(items)); -} - -std::shared_ptr -QPDF_Array::create(std::vector> const& items) -{ - return do_create(new QPDF_Array(items)); -} - std::shared_ptr QPDF_Array::copy(bool shallow) { if (shallow) { - if (sparse) { - return create(sp_elements); - } else { - return create(elements); - } + return do_create(new QPDF_Array(*this)); } else { if (sparse) { - SparseOHArray result; - result.n_elements = sp_elements.n_elements; - for (auto const& element: sp_elements.elements) { + QPDF_Array* result = new QPDF_Array(); + result->sp_size = sp_size; + for (auto const& element: sp_elements) { auto const& obj = element.second; - result.elements[element.first] = + result->sp_elements[element.first] = obj->getObjGen().isIndirect() ? obj : obj->copy(); } - return create(std::move(result)); + return do_create(result); } else { std::vector> result; result.reserve(elements.size()); @@ -118,7 +101,7 @@ QPDF_Array::copy(bool shallow) : element->copy()) : element); } - return create(std::move(result)); + return create(std::move(result), false); } } } @@ -127,7 +110,7 @@ void QPDF_Array::disconnect() { if (sparse) { - for (auto& item: sp_elements.elements) { + for (auto& item: sp_elements) { auto& obj = item.second; if (!obj->getObjGen().isIndirect()) { obj->disconnect(); @@ -147,8 +130,7 @@ QPDF_Array::unparse() { if (sparse) { std::string result = "[ "; - int size = sp_elements.size(); - for (int i = 0; i < size; ++i) { + for (int i = 0; i < sp_size; ++i) { result += at(i).unparse(); result += " "; } @@ -171,8 +153,7 @@ QPDF_Array::getJSON(int json_version) { if (sparse) { JSON j = JSON::makeArray(); - int size = sp_elements.size(); - for (int i = 0; i < size; ++i) { + for (int i = 0; i < sp_size; ++i) { j.addArrayElement(at(i).getJSON(json_version)); } return j; @@ -192,8 +173,8 @@ QPDF_Array::at(int n) const noexcept if (n < 0 || n >= size()) { return {}; } else if (sparse) { - auto const& iter = sp_elements.elements.find(n); - return iter == sp_elements.elements.end() ? null_oh : (*iter).second; + auto const& iter = sp_elements.find(n); + return iter == sp_elements.end() ? null_oh : (*iter).second; } else { return elements[size_t(n)]; } @@ -205,7 +186,7 @@ QPDF_Array::getAsVector() const if (sparse) { std::vector v; v.reserve(size_t(size())); - for (auto const& item: sp_elements.elements) { + for (auto const& item: sp_elements) { v.resize(size_t(item.first), null_oh); v.push_back(item.second); } @@ -224,7 +205,7 @@ QPDF_Array::setAt(int at, QPDFObjectHandle const& oh) } checkOwnership(oh); if (sparse) { - sp_elements.elements[at] = oh.getObj(); + sp_elements[at] = oh.getObj(); } else { elements[size_t(at)] = oh.getObj(); } @@ -254,19 +235,19 @@ QPDF_Array::insert(int at, QPDFObjectHandle const& item) } else { checkOwnership(item); if (sparse) { - auto iter = sp_elements.elements.crbegin(); - while (iter != sp_elements.elements.crend()) { + auto iter = sp_elements.crbegin(); + while (iter != sp_elements.crend()) { auto key = (iter++)->first; if (key >= at) { - auto nh = sp_elements.elements.extract(key); + auto nh = sp_elements.extract(key); ++nh.key(); - sp_elements.elements.insert(std::move(nh)); + sp_elements.insert(std::move(nh)); } else { break; } } - sp_elements.elements[at] = item.getObj(); - ++sp_elements.n_elements; + sp_elements[at] = item.getObj(); + ++sp_size; } else { elements.insert(elements.cbegin() + at, item.getObj()); } @@ -279,7 +260,7 @@ QPDF_Array::push_back(QPDFObjectHandle const& item) { checkOwnership(item); if (sparse) { - sp_elements.elements[sp_elements.n_elements++] = item.getObj(); + sp_elements[sp_size++] = item.getObj(); } else { elements.push_back(item.getObj()); } @@ -292,20 +273,20 @@ QPDF_Array::erase(int at) return false; } if (sparse) { - auto end = sp_elements.elements.end(); - if (auto iter = sp_elements.elements.lower_bound(at); iter != end) { + auto end = sp_elements.end(); + if (auto iter = sp_elements.lower_bound(at); iter != end) { if (iter->first == at) { iter++; - sp_elements.elements.erase(at); + sp_elements.erase(at); } while (iter != end) { - auto nh = sp_elements.elements.extract(iter++); + auto nh = sp_elements.extract(iter++); --nh.key(); - sp_elements.elements.insert(std::move(nh)); + sp_elements.insert(std::move(nh)); } } - --sp_elements.n_elements; + --sp_size; } else { elements.erase(elements.cbegin() + at); } diff --git a/libqpdf/SparseOHArray.cc b/libqpdf/SparseOHArray.cc deleted file mode 100644 index 8b137891..00000000 --- a/libqpdf/SparseOHArray.cc +++ /dev/null @@ -1 +0,0 @@ - diff --git a/libqpdf/qpdf/QPDF_Array.hh b/libqpdf/qpdf/QPDF_Array.hh index d0138e5c..4762bb6e 100644 --- a/libqpdf/qpdf/QPDF_Array.hh +++ b/libqpdf/qpdf/QPDF_Array.hh @@ -3,7 +3,7 @@ #include -#include +#include #include class QPDF_Array: public QPDFValue @@ -14,9 +14,6 @@ class QPDF_Array: public QPDFValue create(std::vector const& items); static std::shared_ptr create(std::vector>&& items, bool sparse); - static std::shared_ptr create(SparseOHArray const& items); - static std::shared_ptr - create(std::vector> const& items); virtual std::shared_ptr copy(bool shallow = false); virtual std::string unparse(); virtual JSON getJSON(int json_version); @@ -25,7 +22,7 @@ class QPDF_Array: public QPDFValue int size() const noexcept { - return sparse ? sp_elements.size() : int(elements.size()); + return sparse ? sp_size : int(elements.size()); } QPDFObjectHandle at(int n) const noexcept; bool setAt(int n, QPDFObjectHandle const& oh); @@ -36,15 +33,16 @@ class QPDF_Array: public QPDFValue bool erase(int at); private: + QPDF_Array(); + QPDF_Array(QPDF_Array const&); QPDF_Array(std::vector const& items); QPDF_Array(std::vector>&& items, bool sparse); - QPDF_Array(SparseOHArray const& items); - QPDF_Array(std::vector> const& items); void checkOwnership(QPDFObjectHandle const& item) const; bool sparse{false}; - SparseOHArray sp_elements; + int sp_size{0}; + std::map> sp_elements; std::vector> elements; }; diff --git a/libqpdf/qpdf/SparseOHArray.hh b/libqpdf/qpdf/SparseOHArray.hh deleted file mode 100644 index 5760f174..00000000 --- a/libqpdf/qpdf/SparseOHArray.hh +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef QPDF_SPARSEOHARRAY_HH -#define QPDF_SPARSEOHARRAY_HH - -#include -#include -#include - -class QPDF_Array; - -class SparseOHArray -{ - public: - SparseOHArray() = default; - int - size() const noexcept - { - return n_elements; - } - - private: - friend class QPDF_Array; - std::map> elements; - int n_elements{0}; -}; - -#endif // QPDF_SPARSEOHARRAY_HH diff --git a/libtests/sparse_array.cc b/libtests/sparse_array.cc index a970b199..9f31c96f 100644 --- a/libtests/sparse_array.cc +++ b/libtests/sparse_array.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include -- cgit v1.2.3-70-g09d2