mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-03 15:17:29 +00:00
name/number trees: insertAfter
This commit is contained in:
parent
16a9bb3f6f
commit
5816fb44b8
@ -112,6 +112,19 @@ class QPDFNameTreeObjectHelper: public QPDFObjectHelper
|
|||||||
return ! operator==(other);
|
return ! operator==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DANGER: this method can create inconsistent trees if not
|
||||||
|
// used properly! Insert a new item immediately after the
|
||||||
|
// current iterator and increment so that it points to the new
|
||||||
|
// item. If the current iterator is end(), insert at the
|
||||||
|
// beginning. This method does not check for proper ordering,
|
||||||
|
// so if you use it, you must ensure that the item you are
|
||||||
|
// inserting belongs where you are putting it. The reason for
|
||||||
|
// this method is that it is more efficient than insert() and
|
||||||
|
// can be used safely when you are creating a new tree and
|
||||||
|
// inserting items in sorted order.
|
||||||
|
QPDF_DLL
|
||||||
|
void insertAfter(std::string const& key, QPDFObjectHandle value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
iterator(std::shared_ptr<NNTreeIterator> const&);
|
iterator(std::shared_ptr<NNTreeIterator> const&);
|
||||||
std::shared_ptr<NNTreeIterator> impl;
|
std::shared_ptr<NNTreeIterator> impl;
|
||||||
|
@ -131,6 +131,19 @@ class QPDFNumberTreeObjectHelper: public QPDFObjectHelper
|
|||||||
return ! operator==(other);
|
return ! operator==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DANGER: this method can create inconsistent trees if not
|
||||||
|
// used properly! Insert a new item immediately after the
|
||||||
|
// current iterator and increment so that it points to the new
|
||||||
|
// item. If the current iterator is end(), insert at the
|
||||||
|
// beginning. This method does not check for proper ordering,
|
||||||
|
// so if you use it, you must ensure that the item you are
|
||||||
|
// inserting belongs where you are putting it. The reason for
|
||||||
|
// this method is that it is more efficient than insert() and
|
||||||
|
// can be used safely when you are creating a new tree and
|
||||||
|
// inserting items in sorted order.
|
||||||
|
QPDF_DLL
|
||||||
|
void insertAfter(numtree_number key, QPDFObjectHandle value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
iterator(std::shared_ptr<NNTreeIterator> const&);
|
iterator(std::shared_ptr<NNTreeIterator> const&);
|
||||||
std::shared_ptr<NNTreeIterator> impl;
|
std::shared_ptr<NNTreeIterator> impl;
|
||||||
|
@ -444,6 +444,14 @@ NNTreeIterator::lastPathElement()
|
|||||||
void
|
void
|
||||||
NNTreeIterator::insertAfter(QPDFObjectHandle key, QPDFObjectHandle value)
|
NNTreeIterator::insertAfter(QPDFObjectHandle key, QPDFObjectHandle value)
|
||||||
{
|
{
|
||||||
|
if (! valid())
|
||||||
|
{
|
||||||
|
QTC::TC("qpdf", "NNTree insertAfter inserts first");
|
||||||
|
impl.insertFirst(key, value);
|
||||||
|
deepen(impl.oh, true, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto items = this->node.getKey(impl.details.itemsKey());
|
auto items = this->node.getKey(impl.details.itemsKey());
|
||||||
if (! items.isArray())
|
if (! items.isArray())
|
||||||
{
|
{
|
||||||
@ -457,6 +465,7 @@ NNTreeIterator::insertAfter(QPDFObjectHandle key, QPDFObjectHandle value)
|
|||||||
items.insertItem(this->item_number + 3, value);
|
items.insertItem(this->item_number + 3, value);
|
||||||
resetLimits(this->node, lastPathElement());
|
resetLimits(this->node, lastPathElement());
|
||||||
split(this->node, lastPathElement());
|
split(this->node, lastPathElement());
|
||||||
|
increment(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
NNTreeIterator&
|
NNTreeIterator&
|
||||||
@ -968,7 +977,6 @@ NNTreeImpl::insert(QPDFObjectHandle key, QPDFObjectHandle value)
|
|||||||
{
|
{
|
||||||
QTC::TC("qpdf", "NNTree insert inserts after");
|
QTC::TC("qpdf", "NNTree insert inserts after");
|
||||||
iter.insertAfter(key, value);
|
iter.insertAfter(key, value);
|
||||||
++iter;
|
|
||||||
}
|
}
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,13 @@ QPDFNameTreeObjectHelper::iterator::operator==(iterator const& other) const
|
|||||||
return *(impl) == *(other.impl);
|
return *(impl) == *(other.impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDFNameTreeObjectHelper::iterator::insertAfter(
|
||||||
|
std::string const& key, QPDFObjectHandle value)
|
||||||
|
{
|
||||||
|
impl->insertAfter(QPDFObjectHandle::newUnicodeString(key), value);
|
||||||
|
}
|
||||||
|
|
||||||
QPDFNameTreeObjectHelper::iterator
|
QPDFNameTreeObjectHelper::iterator
|
||||||
QPDFNameTreeObjectHelper::begin() const
|
QPDFNameTreeObjectHelper::begin() const
|
||||||
{
|
{
|
||||||
|
@ -98,6 +98,13 @@ QPDFNumberTreeObjectHelper::iterator::operator==(iterator const& other) const
|
|||||||
return *(impl) == *(other.impl);
|
return *(impl) == *(other.impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDFNumberTreeObjectHelper::iterator::insertAfter(
|
||||||
|
numtree_number key, QPDFObjectHandle value)
|
||||||
|
{
|
||||||
|
impl->insertAfter(QPDFObjectHandle::newInteger(key), value);
|
||||||
|
}
|
||||||
|
|
||||||
QPDFNumberTreeObjectHelper::iterator
|
QPDFNumberTreeObjectHelper::iterator
|
||||||
QPDFNumberTreeObjectHelper::begin() const
|
QPDFNumberTreeObjectHelper::begin() const
|
||||||
{
|
{
|
||||||
|
@ -552,3 +552,4 @@ NNTree bad node during find 0
|
|||||||
NNTree node is not a dictionary 0
|
NNTree node is not a dictionary 0
|
||||||
NNTree limits didn't change 0
|
NNTree limits didn't change 0
|
||||||
NNTree increment end() 0
|
NNTree increment end() 0
|
||||||
|
NNTree insertAfter inserts first 0
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
20 twenty -> twenty.
|
20 twenty -> twenty.
|
||||||
22 twenty-two -> twenty-two!
|
22 twenty-two -> twenty-two!
|
||||||
29 twenty-nine -> twenty-nine!
|
29 twenty-nine -> twenty-nine!
|
||||||
|
insertAfter
|
||||||
|
3 (3!)
|
||||||
|
4 (4!)
|
||||||
/Empty1
|
/Empty1
|
||||||
/Empty2
|
/Empty2
|
||||||
/Bad1: deprecated API
|
/Bad1: deprecated API
|
||||||
|
@ -26,6 +26,9 @@
|
|||||||
22 twenty-two
|
22 twenty-two
|
||||||
23 twenty-three
|
23 twenty-three
|
||||||
29 twenty-nine
|
29 twenty-nine
|
||||||
|
insertAfter
|
||||||
|
3 (3!)
|
||||||
|
4 (4!)
|
||||||
/Bad1: deprecated API
|
/Bad1: deprecated API
|
||||||
/Bad1
|
/Bad1
|
||||||
WARNING: number-tree.pdf (Name/Number tree node (object 14)): name/number tree node has neither non-empty /Nums nor /Kids
|
WARNING: number-tree.pdf (Name/Number tree node (object 14)): name/number tree node has neither non-empty /Nums nor /Kids
|
||||||
|
@ -1802,6 +1802,19 @@ void runtest(int n, char const* filename1, char const* arg2)
|
|||||||
--iter1;
|
--iter1;
|
||||||
assert((*iter1).first == 2);
|
assert((*iter1).first == 2);
|
||||||
|
|
||||||
|
std::cout << "insertAfter" << std::endl;
|
||||||
|
auto new2 = QPDFNumberTreeObjectHelper::newEmpty(pdf);
|
||||||
|
auto iter2 = new2.begin();
|
||||||
|
assert(iter2 == new2.end());
|
||||||
|
iter2.insertAfter(3, QPDFObjectHandle::newString("3!"));
|
||||||
|
assert((*iter2).first == 3);
|
||||||
|
iter2.insertAfter(4, QPDFObjectHandle::newString("4!"));
|
||||||
|
assert((*iter2).first == 4);
|
||||||
|
for (auto i: new2)
|
||||||
|
{
|
||||||
|
std::cout << i.first << " " << i.second.unparse() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
// Exercise deprecated API until qpdf 11
|
// Exercise deprecated API until qpdf 11
|
||||||
std::cout << "/Bad1: deprecated API" << std::endl;
|
std::cout << "/Bad1: deprecated API" << std::endl;
|
||||||
auto bad1 = QPDFNumberTreeObjectHelper(
|
auto bad1 = QPDFNumberTreeObjectHelper(
|
||||||
@ -1961,6 +1974,19 @@ void runtest(int n, char const* filename1, char const* arg2)
|
|||||||
--iter1;
|
--iter1;
|
||||||
assert((*iter1).first == "2");
|
assert((*iter1).first == "2");
|
||||||
|
|
||||||
|
std::cout << "insertAfter" << std::endl;
|
||||||
|
auto new2 = QPDFNameTreeObjectHelper::newEmpty(pdf);
|
||||||
|
auto iter2 = new2.begin();
|
||||||
|
assert(iter2 == new2.end());
|
||||||
|
iter2.insertAfter("3", QPDFObjectHandle::newString("3!"));
|
||||||
|
assert((*iter2).first == "3");
|
||||||
|
iter2.insertAfter("4", QPDFObjectHandle::newString("4!"));
|
||||||
|
assert((*iter2).first == "4");
|
||||||
|
for (auto i: new2)
|
||||||
|
{
|
||||||
|
std::cout << i.first << " " << i.second.unparse() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> empties = {"/Empty1", "/Empty2"};
|
std::vector<std::string> empties = {"/Empty1", "/Empty2"};
|
||||||
for (auto const& k: empties)
|
for (auto const& k: empties)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user