2018-12-18 18:08:55 +00:00
|
|
|
#include <qpdf/QPDFNumberTreeObjectHelper.hh>
|
2022-02-04 21:31:31 +00:00
|
|
|
|
2021-01-16 13:31:56 +00:00
|
|
|
#include <qpdf/NNTree.hh>
|
2021-11-04 17:52:47 +00:00
|
|
|
#include <qpdf/QIntC.hh>
|
2018-12-18 18:08:55 +00:00
|
|
|
|
2022-04-16 17:21:57 +00:00
|
|
|
namespace
|
2018-12-18 18:08:55 +00:00
|
|
|
{
|
2022-04-16 17:21:57 +00:00
|
|
|
class NumberTreeDetails: public NNTreeDetails
|
2018-12-18 18:08:55 +00:00
|
|
|
{
|
2022-04-16 17:21:57 +00:00
|
|
|
public:
|
2023-05-20 12:56:33 +00:00
|
|
|
std::string const&
|
2022-04-16 17:21:57 +00:00
|
|
|
itemsKey() const override
|
|
|
|
{
|
|
|
|
static std::string k("/Nums");
|
|
|
|
return k;
|
|
|
|
}
|
2023-05-20 12:56:33 +00:00
|
|
|
bool
|
2022-04-16 17:21:57 +00:00
|
|
|
keyValid(QPDFObjectHandle oh) const override
|
|
|
|
{
|
|
|
|
return oh.isInteger();
|
|
|
|
}
|
2023-05-20 12:56:33 +00:00
|
|
|
int
|
2022-04-16 17:21:57 +00:00
|
|
|
compareKeys(QPDFObjectHandle a, QPDFObjectHandle b) const override
|
|
|
|
{
|
|
|
|
if (!(keyValid(a) && keyValid(b))) {
|
|
|
|
// We don't call this without calling keyValid first
|
|
|
|
throw std::logic_error("comparing invalid keys");
|
|
|
|
}
|
|
|
|
auto as = a.getIntValue();
|
|
|
|
auto bs = b.getIntValue();
|
|
|
|
return ((as < bs) ? -1 : (as > bs) ? 1 : 0);
|
2018-12-18 18:08:55 +00:00
|
|
|
}
|
2022-04-16 17:21:57 +00:00
|
|
|
};
|
|
|
|
} // namespace
|
2021-01-16 13:31:56 +00:00
|
|
|
|
|
|
|
static NumberTreeDetails number_tree_details;
|
|
|
|
|
2022-08-07 13:09:04 +00:00
|
|
|
QPDFNumberTreeObjectHelper::~QPDFNumberTreeObjectHelper()
|
|
|
|
{
|
|
|
|
// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer. For this specific
|
|
|
|
// class, see github issue #745.
|
|
|
|
}
|
|
|
|
|
2022-04-16 17:12:49 +00:00
|
|
|
QPDFNumberTreeObjectHelper::Members::Members(QPDFObjectHandle& oh, QPDF& q, bool auto_repair) :
|
2021-01-16 23:35:30 +00:00
|
|
|
impl(std::make_shared<NNTreeImpl>(number_tree_details, q, oh, auto_repair))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QPDFNumberTreeObjectHelper::QPDFNumberTreeObjectHelper(
|
|
|
|
QPDFObjectHandle oh, QPDF& q, bool auto_repair) :
|
|
|
|
QPDFObjectHelper(oh),
|
2022-04-16 17:12:49 +00:00
|
|
|
m(new Members(oh, q, auto_repair))
|
2021-01-16 13:31:56 +00:00
|
|
|
{
|
|
|
|
}
|
2018-12-18 18:08:55 +00:00
|
|
|
|
2021-01-24 08:55:18 +00:00
|
|
|
QPDFNumberTreeObjectHelper
|
|
|
|
QPDFNumberTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair)
|
|
|
|
{
|
|
|
|
return QPDFNumberTreeObjectHelper(
|
2022-02-05 14:18:58 +00:00
|
|
|
qpdf.makeIndirectObject("<< /Nums [] >>"_qpdf), qpdf, auto_repair);
|
2021-01-24 08:55:18 +00:00
|
|
|
}
|
|
|
|
|
2021-01-16 17:11:17 +00:00
|
|
|
QPDFNumberTreeObjectHelper::iterator::iterator(std::shared_ptr<NNTreeIterator> const& i) :
|
|
|
|
impl(i)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
QPDFNumberTreeObjectHelper::iterator::valid() const
|
|
|
|
{
|
|
|
|
return impl->valid();
|
|
|
|
}
|
|
|
|
|
|
|
|
QPDFNumberTreeObjectHelper::iterator&
|
|
|
|
QPDFNumberTreeObjectHelper::iterator::operator++()
|
|
|
|
{
|
|
|
|
++(*impl);
|
2021-01-25 13:05:43 +00:00
|
|
|
updateIValue();
|
2021-01-16 17:11:17 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
QPDFNumberTreeObjectHelper::iterator&
|
|
|
|
QPDFNumberTreeObjectHelper::iterator::operator--()
|
|
|
|
{
|
|
|
|
--(*impl);
|
2021-01-25 13:05:43 +00:00
|
|
|
updateIValue();
|
2021-01-16 17:11:17 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2021-01-25 13:05:43 +00:00
|
|
|
void
|
|
|
|
QPDFNumberTreeObjectHelper::iterator::updateIValue()
|
|
|
|
{
|
|
|
|
if (impl->valid()) {
|
|
|
|
auto p = *impl;
|
|
|
|
this->ivalue.first = p->first.getIntValue();
|
|
|
|
this->ivalue.second = p->second;
|
|
|
|
} else {
|
|
|
|
this->ivalue.first = 0;
|
|
|
|
this->ivalue.second = QPDFObjectHandle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-16 17:11:17 +00:00
|
|
|
QPDFNumberTreeObjectHelper::iterator::reference
|
|
|
|
QPDFNumberTreeObjectHelper::iterator::operator*()
|
|
|
|
{
|
2021-01-25 13:05:43 +00:00
|
|
|
updateIValue();
|
|
|
|
return this->ivalue;
|
|
|
|
}
|
|
|
|
|
|
|
|
QPDFNumberTreeObjectHelper::iterator::pointer
|
|
|
|
QPDFNumberTreeObjectHelper::iterator::operator->()
|
|
|
|
{
|
|
|
|
updateIValue();
|
|
|
|
return &this->ivalue;
|
2021-01-16 17:11:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
QPDFNumberTreeObjectHelper::iterator::operator==(iterator const& other) const
|
|
|
|
{
|
|
|
|
return *(impl) == *(other.impl);
|
|
|
|
}
|
|
|
|
|
2021-01-24 09:16:48 +00:00
|
|
|
void
|
|
|
|
QPDFNumberTreeObjectHelper::iterator::insertAfter(numtree_number key, QPDFObjectHandle value)
|
|
|
|
{
|
|
|
|
impl->insertAfter(QPDFObjectHandle::newInteger(key), value);
|
2021-01-25 13:05:43 +00:00
|
|
|
updateIValue();
|
2021-01-24 09:16:48 +00:00
|
|
|
}
|
|
|
|
|
2021-01-24 16:48:46 +00:00
|
|
|
void
|
|
|
|
QPDFNumberTreeObjectHelper::iterator::remove()
|
|
|
|
{
|
|
|
|
impl->remove();
|
2021-01-25 13:05:43 +00:00
|
|
|
updateIValue();
|
2021-01-24 16:48:46 +00:00
|
|
|
}
|
|
|
|
|
2021-01-16 17:11:17 +00:00
|
|
|
QPDFNumberTreeObjectHelper::iterator
|
|
|
|
QPDFNumberTreeObjectHelper::begin() const
|
|
|
|
{
|
|
|
|
return iterator(std::make_shared<NNTreeIterator>(m->impl->begin()));
|
|
|
|
}
|
|
|
|
|
|
|
|
QPDFNumberTreeObjectHelper::iterator
|
|
|
|
QPDFNumberTreeObjectHelper::end() const
|
|
|
|
{
|
|
|
|
return iterator(std::make_shared<NNTreeIterator>(m->impl->end()));
|
|
|
|
}
|
|
|
|
|
|
|
|
QPDFNumberTreeObjectHelper::iterator
|
|
|
|
QPDFNumberTreeObjectHelper::last() const
|
|
|
|
{
|
|
|
|
return iterator(std::make_shared<NNTreeIterator>(m->impl->last()));
|
|
|
|
}
|
|
|
|
|
|
|
|
QPDFNumberTreeObjectHelper::iterator
|
|
|
|
QPDFNumberTreeObjectHelper::find(numtree_number key, bool return_prev_if_not_found)
|
|
|
|
{
|
|
|
|
auto i = m->impl->find(QPDFObjectHandle::newInteger(key), return_prev_if_not_found);
|
|
|
|
return iterator(std::make_shared<NNTreeIterator>(i));
|
|
|
|
}
|
|
|
|
|
2021-01-23 23:33:55 +00:00
|
|
|
QPDFNumberTreeObjectHelper::iterator
|
|
|
|
QPDFNumberTreeObjectHelper::insert(numtree_number key, QPDFObjectHandle value)
|
|
|
|
{
|
|
|
|
auto i = m->impl->insert(QPDFObjectHandle::newInteger(key), value);
|
|
|
|
return iterator(std::make_shared<NNTreeIterator>(i));
|
|
|
|
}
|
|
|
|
|
2021-01-24 16:48:46 +00:00
|
|
|
bool
|
|
|
|
QPDFNumberTreeObjectHelper::remove(numtree_number key, QPDFObjectHandle* value)
|
|
|
|
{
|
|
|
|
return m->impl->remove(QPDFObjectHandle::newInteger(key), value);
|
|
|
|
}
|
|
|
|
|
2018-12-18 18:08:55 +00:00
|
|
|
QPDFNumberTreeObjectHelper::numtree_number
|
|
|
|
QPDFNumberTreeObjectHelper::getMin()
|
|
|
|
{
|
2021-01-16 17:11:17 +00:00
|
|
|
auto i = begin();
|
|
|
|
if (i == end()) {
|
2018-12-18 18:08:55 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2021-01-25 13:05:43 +00:00
|
|
|
return i->first;
|
2018-12-18 18:08:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QPDFNumberTreeObjectHelper::numtree_number
|
|
|
|
QPDFNumberTreeObjectHelper::getMax()
|
|
|
|
{
|
2021-01-16 17:11:17 +00:00
|
|
|
auto i = last();
|
|
|
|
if (i == end()) {
|
2018-12-18 18:08:55 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2021-01-25 13:05:43 +00:00
|
|
|
return i->first;
|
2018-12-18 18:08:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
QPDFNumberTreeObjectHelper::hasIndex(numtree_number idx)
|
|
|
|
{
|
2021-01-16 17:11:17 +00:00
|
|
|
auto i = find(idx);
|
|
|
|
return (i != this->end());
|
2018-12-18 18:08:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
QPDFNumberTreeObjectHelper::findObject(numtree_number idx, QPDFObjectHandle& oh)
|
|
|
|
{
|
2021-01-16 17:11:17 +00:00
|
|
|
auto i = find(idx);
|
|
|
|
if (i == end()) {
|
2018-12-18 18:08:55 +00:00
|
|
|
return false;
|
|
|
|
}
|
2021-01-25 13:05:43 +00:00
|
|
|
oh = i->second;
|
2018-12-18 18:08:55 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
QPDFNumberTreeObjectHelper::findObjectAtOrBelow(
|
|
|
|
numtree_number idx, QPDFObjectHandle& oh, numtree_number& offset)
|
|
|
|
{
|
2021-01-16 17:11:17 +00:00
|
|
|
auto i = find(idx, true);
|
|
|
|
if (i == end()) {
|
2018-12-18 18:08:55 +00:00
|
|
|
return false;
|
|
|
|
}
|
2021-01-25 13:05:43 +00:00
|
|
|
oh = i->second;
|
2021-11-04 17:52:47 +00:00
|
|
|
QIntC::range_check_substract(idx, i->first);
|
2021-01-25 13:05:43 +00:00
|
|
|
offset = idx - i->first;
|
2018-12-18 18:08:55 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-01-23 23:33:55 +00:00
|
|
|
void
|
|
|
|
QPDFNumberTreeObjectHelper::setSplitThreshold(int t)
|
|
|
|
{
|
|
|
|
m->impl->setSplitThreshold(t);
|
|
|
|
}
|
|
|
|
|
2018-12-18 18:08:55 +00:00
|
|
|
std::map<QPDFNumberTreeObjectHelper::numtree_number, QPDFObjectHandle>
|
|
|
|
QPDFNumberTreeObjectHelper::getAsMap() const
|
|
|
|
{
|
|
|
|
std::map<numtree_number, QPDFObjectHandle> result;
|
2021-01-16 17:11:17 +00:00
|
|
|
result.insert(begin(), end());
|
2018-12-18 18:08:55 +00:00
|
|
|
return result;
|
|
|
|
}
|