2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-05-29 16:30:53 +00:00

name/number trees: newEmpty, increment/decrement end()

This commit is contained in:
Jay Berkenbilt 2021-01-24 03:55:18 -05:00
parent b5614f611d
commit 16a9bb3f6f
7 changed files with 88 additions and 5 deletions

View File

@ -54,6 +54,12 @@ class QPDFNameTreeObjectHelper: public QPDFObjectHelper
// structure.
QPDF_DLL
QPDFNameTreeObjectHelper(QPDFObjectHandle);
// Create an empty name tree
QPDF_DLL
static QPDFNameTreeObjectHelper newEmpty(QPDF&, bool auto_repair = true);
// ABI: = default
QPDF_DLL
virtual ~QPDFNameTreeObjectHelper();
@ -112,7 +118,9 @@ class QPDFNameTreeObjectHelper: public QPDFObjectHelper
};
// The iterator looks like map iterator, so i.first is a string
// and i.second is a QPDFObjectHandle.
// and i.second is a QPDFObjectHandle. Incrementing end() brings
// you to the first item. Decrementing end() brings you to the
// last item.
QPDF_DLL
iterator begin() const;
QPDF_DLL

View File

@ -51,11 +51,17 @@ class QPDFNumberTreeObjectHelper: public QPDFObjectHelper
// structure.
QPDF_DLL
QPDFNumberTreeObjectHelper(QPDFObjectHandle);
// ABI: = default
QPDF_DLL
virtual ~QPDFNumberTreeObjectHelper()
{
}
// Create an empty number tree
QPDF_DLL
static QPDFNumberTreeObjectHelper newEmpty(QPDF&, bool auto_repair = true);
typedef long long int numtree_number;
// Return overall minimum and maximum indices
@ -131,7 +137,9 @@ class QPDFNumberTreeObjectHelper: public QPDFObjectHelper
};
// The iterator looks like map iterator, so i.first is a string
// and i.second is a QPDFObjectHandle.
// and i.second is a QPDFObjectHandle. Incrementing end() brings
// you to the first item. Decrementing end() brings you to the
// last item.
QPDF_DLL
iterator begin() const;
QPDF_DLL

View File

@ -103,9 +103,9 @@ NNTreeIterator::increment(bool backward)
{
if (this->item_number < 0)
{
throw std::logic_error(
"attempt made to increment or decrement an invalid"
" name/number tree iterator");
QTC::TC("qpdf", "NNTree increment end()");
deepen(impl.oh, ! backward, true);
return;
}
bool found_valid_key = false;
while (valid() && (! found_valid_key))

View File

@ -56,6 +56,13 @@ QPDFNameTreeObjectHelper::~QPDFNameTreeObjectHelper()
{
}
QPDFNameTreeObjectHelper
QPDFNameTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair)
{
return QPDFNameTreeObjectHelper(
QPDFObjectHandle::parse("<< /Names [] >>"), qpdf, auto_repair);
}
QPDFNameTreeObjectHelper::iterator::iterator(
std::shared_ptr<NNTreeIterator> const& i) :
impl(i)

View File

@ -52,6 +52,13 @@ QPDFNumberTreeObjectHelper::QPDFNumberTreeObjectHelper(QPDFObjectHandle oh) :
{
}
QPDFNumberTreeObjectHelper
QPDFNumberTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair)
{
return QPDFNumberTreeObjectHelper(
QPDFObjectHandle::parse("<< /Nums [] >>"), qpdf, auto_repair);
}
QPDFNumberTreeObjectHelper::iterator::iterator(
std::shared_ptr<NNTreeIterator> const& i) :
impl(i)

View File

@ -551,3 +551,4 @@ NNTree -1 in binary search 0
NNTree bad node during find 0
NNTree node is not a dictionary 0
NNTree limits didn't change 0
NNTree increment end() 0

View File

@ -1776,6 +1776,32 @@ void runtest(int n, char const* filename1, char const* arg2)
assert("six" == oh.getStringValue());
assert(2 == offset);
auto new1 = QPDFNumberTreeObjectHelper::newEmpty(pdf);
auto iter1 = new1.begin();
assert(iter1 == new1.end());
++iter1;
assert(iter1 == new1.end());
--iter1;
assert(iter1 == new1.end());
new1.insert(1, QPDFObjectHandle::newString("1"));
++iter1;
assert((*iter1).first == 1);
--iter1;
assert(iter1 == new1.end());
--iter1;
assert((*iter1).first == 1);
new1.insert(2, QPDFObjectHandle::newString("2"));
++iter1;
assert((*iter1).first == 2);
++iter1;
assert(iter1 == new1.end());
++iter1;
assert((*iter1).first == 1);
--iter1;
assert(iter1 == new1.end());
--iter1;
assert((*iter1).first == 2);
// Exercise deprecated API until qpdf 11
std::cout << "/Bad1: deprecated API" << std::endl;
auto bad1 = QPDFNumberTreeObjectHelper(
@ -1909,6 +1935,32 @@ void runtest(int n, char const* filename1, char const* arg2)
assert((*last).first == "29 twenty-nine");
assert((*last).second.getUTF8Value() == "twenty-nine!");
auto new1 = QPDFNameTreeObjectHelper::newEmpty(pdf);
auto iter1 = new1.begin();
assert(iter1 == new1.end());
++iter1;
assert(iter1 == new1.end());
--iter1;
assert(iter1 == new1.end());
new1.insert("1", QPDFObjectHandle::newString("1"));
++iter1;
assert((*iter1).first == "1");
--iter1;
assert(iter1 == new1.end());
--iter1;
assert((*iter1).first == "1");
new1.insert("2", QPDFObjectHandle::newString("2"));
++iter1;
assert((*iter1).first == "2");
++iter1;
assert(iter1 == new1.end());
++iter1;
assert((*iter1).first == "1");
--iter1;
assert(iter1 == new1.end());
--iter1;
assert((*iter1).first == "2");
std::vector<std::string> empties = {"/Empty1", "/Empty2"};
for (auto const& k: empties)
{