Commit 16a9bb3f6f63497946d0efbf403df92d0ce30745

Authored by Jay Berkenbilt
1 parent b5614f61

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

include/qpdf/QPDFNameTreeObjectHelper.hh
... ... @@ -54,6 +54,12 @@ class QPDFNameTreeObjectHelper: public QPDFObjectHelper
54 54 // structure.
55 55 QPDF_DLL
56 56 QPDFNameTreeObjectHelper(QPDFObjectHandle);
  57 +
  58 + // Create an empty name tree
  59 + QPDF_DLL
  60 + static QPDFNameTreeObjectHelper newEmpty(QPDF&, bool auto_repair = true);
  61 +
  62 + // ABI: = default
57 63 QPDF_DLL
58 64 virtual ~QPDFNameTreeObjectHelper();
59 65  
... ... @@ -112,7 +118,9 @@ class QPDFNameTreeObjectHelper: public QPDFObjectHelper
112 118 };
113 119  
114 120 // The iterator looks like map iterator, so i.first is a string
115   - // and i.second is a QPDFObjectHandle.
  121 + // and i.second is a QPDFObjectHandle. Incrementing end() brings
  122 + // you to the first item. Decrementing end() brings you to the
  123 + // last item.
116 124 QPDF_DLL
117 125 iterator begin() const;
118 126 QPDF_DLL
... ...
include/qpdf/QPDFNumberTreeObjectHelper.hh
... ... @@ -51,11 +51,17 @@ class QPDFNumberTreeObjectHelper: public QPDFObjectHelper
51 51 // structure.
52 52 QPDF_DLL
53 53 QPDFNumberTreeObjectHelper(QPDFObjectHandle);
  54 +
  55 + // ABI: = default
54 56 QPDF_DLL
55 57 virtual ~QPDFNumberTreeObjectHelper()
56 58 {
57 59 }
58 60  
  61 + // Create an empty number tree
  62 + QPDF_DLL
  63 + static QPDFNumberTreeObjectHelper newEmpty(QPDF&, bool auto_repair = true);
  64 +
59 65 typedef long long int numtree_number;
60 66  
61 67 // Return overall minimum and maximum indices
... ... @@ -131,7 +137,9 @@ class QPDFNumberTreeObjectHelper: public QPDFObjectHelper
131 137 };
132 138  
133 139 // The iterator looks like map iterator, so i.first is a string
134   - // and i.second is a QPDFObjectHandle.
  140 + // and i.second is a QPDFObjectHandle. Incrementing end() brings
  141 + // you to the first item. Decrementing end() brings you to the
  142 + // last item.
135 143 QPDF_DLL
136 144 iterator begin() const;
137 145 QPDF_DLL
... ...
libqpdf/NNTree.cc
... ... @@ -103,9 +103,9 @@ NNTreeIterator::increment(bool backward)
103 103 {
104 104 if (this->item_number < 0)
105 105 {
106   - throw std::logic_error(
107   - "attempt made to increment or decrement an invalid"
108   - " name/number tree iterator");
  106 + QTC::TC("qpdf", "NNTree increment end()");
  107 + deepen(impl.oh, ! backward, true);
  108 + return;
109 109 }
110 110 bool found_valid_key = false;
111 111 while (valid() && (! found_valid_key))
... ...
libqpdf/QPDFNameTreeObjectHelper.cc
... ... @@ -56,6 +56,13 @@ QPDFNameTreeObjectHelper::~QPDFNameTreeObjectHelper()
56 56 {
57 57 }
58 58  
  59 +QPDFNameTreeObjectHelper
  60 +QPDFNameTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair)
  61 +{
  62 + return QPDFNameTreeObjectHelper(
  63 + QPDFObjectHandle::parse("<< /Names [] >>"), qpdf, auto_repair);
  64 +}
  65 +
59 66 QPDFNameTreeObjectHelper::iterator::iterator(
60 67 std::shared_ptr<NNTreeIterator> const& i) :
61 68 impl(i)
... ...
libqpdf/QPDFNumberTreeObjectHelper.cc
... ... @@ -52,6 +52,13 @@ QPDFNumberTreeObjectHelper::QPDFNumberTreeObjectHelper(QPDFObjectHandle oh) :
52 52 {
53 53 }
54 54  
  55 +QPDFNumberTreeObjectHelper
  56 +QPDFNumberTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair)
  57 +{
  58 + return QPDFNumberTreeObjectHelper(
  59 + QPDFObjectHandle::parse("<< /Nums [] >>"), qpdf, auto_repair);
  60 +}
  61 +
55 62 QPDFNumberTreeObjectHelper::iterator::iterator(
56 63 std::shared_ptr<NNTreeIterator> const& i) :
57 64 impl(i)
... ...
qpdf/qpdf.testcov
... ... @@ -551,3 +551,4 @@ NNTree -1 in binary search 0
551 551 NNTree bad node during find 0
552 552 NNTree node is not a dictionary 0
553 553 NNTree limits didn't change 0
  554 +NNTree increment end() 0
... ...
qpdf/test_driver.cc
... ... @@ -1776,6 +1776,32 @@ void runtest(int n, char const* filename1, char const* arg2)
1776 1776 assert("six" == oh.getStringValue());
1777 1777 assert(2 == offset);
1778 1778  
  1779 + auto new1 = QPDFNumberTreeObjectHelper::newEmpty(pdf);
  1780 + auto iter1 = new1.begin();
  1781 + assert(iter1 == new1.end());
  1782 + ++iter1;
  1783 + assert(iter1 == new1.end());
  1784 + --iter1;
  1785 + assert(iter1 == new1.end());
  1786 + new1.insert(1, QPDFObjectHandle::newString("1"));
  1787 + ++iter1;
  1788 + assert((*iter1).first == 1);
  1789 + --iter1;
  1790 + assert(iter1 == new1.end());
  1791 + --iter1;
  1792 + assert((*iter1).first == 1);
  1793 + new1.insert(2, QPDFObjectHandle::newString("2"));
  1794 + ++iter1;
  1795 + assert((*iter1).first == 2);
  1796 + ++iter1;
  1797 + assert(iter1 == new1.end());
  1798 + ++iter1;
  1799 + assert((*iter1).first == 1);
  1800 + --iter1;
  1801 + assert(iter1 == new1.end());
  1802 + --iter1;
  1803 + assert((*iter1).first == 2);
  1804 +
1779 1805 // Exercise deprecated API until qpdf 11
1780 1806 std::cout << "/Bad1: deprecated API" << std::endl;
1781 1807 auto bad1 = QPDFNumberTreeObjectHelper(
... ... @@ -1909,6 +1935,32 @@ void runtest(int n, char const* filename1, char const* arg2)
1909 1935 assert((*last).first == "29 twenty-nine");
1910 1936 assert((*last).second.getUTF8Value() == "twenty-nine!");
1911 1937  
  1938 + auto new1 = QPDFNameTreeObjectHelper::newEmpty(pdf);
  1939 + auto iter1 = new1.begin();
  1940 + assert(iter1 == new1.end());
  1941 + ++iter1;
  1942 + assert(iter1 == new1.end());
  1943 + --iter1;
  1944 + assert(iter1 == new1.end());
  1945 + new1.insert("1", QPDFObjectHandle::newString("1"));
  1946 + ++iter1;
  1947 + assert((*iter1).first == "1");
  1948 + --iter1;
  1949 + assert(iter1 == new1.end());
  1950 + --iter1;
  1951 + assert((*iter1).first == "1");
  1952 + new1.insert("2", QPDFObjectHandle::newString("2"));
  1953 + ++iter1;
  1954 + assert((*iter1).first == "2");
  1955 + ++iter1;
  1956 + assert(iter1 == new1.end());
  1957 + ++iter1;
  1958 + assert((*iter1).first == "1");
  1959 + --iter1;
  1960 + assert(iter1 == new1.end());
  1961 + --iter1;
  1962 + assert((*iter1).first == "2");
  1963 +
1912 1964 std::vector<std::string> empties = {"/Empty1", "/Empty2"};
1913 1965 for (auto const& k: empties)
1914 1966 {
... ...