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,6 +54,12 @@ class QPDFNameTreeObjectHelper: public QPDFObjectHelper
54 // structure. 54 // structure.
55 QPDF_DLL 55 QPDF_DLL
56 QPDFNameTreeObjectHelper(QPDFObjectHandle); 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 QPDF_DLL 63 QPDF_DLL
58 virtual ~QPDFNameTreeObjectHelper(); 64 virtual ~QPDFNameTreeObjectHelper();
59 65
@@ -112,7 +118,9 @@ class QPDFNameTreeObjectHelper: public QPDFObjectHelper @@ -112,7 +118,9 @@ class QPDFNameTreeObjectHelper: public QPDFObjectHelper
112 }; 118 };
113 119
114 // The iterator looks like map iterator, so i.first is a string 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 QPDF_DLL 124 QPDF_DLL
117 iterator begin() const; 125 iterator begin() const;
118 QPDF_DLL 126 QPDF_DLL
include/qpdf/QPDFNumberTreeObjectHelper.hh
@@ -51,11 +51,17 @@ class QPDFNumberTreeObjectHelper: public QPDFObjectHelper @@ -51,11 +51,17 @@ class QPDFNumberTreeObjectHelper: public QPDFObjectHelper
51 // structure. 51 // structure.
52 QPDF_DLL 52 QPDF_DLL
53 QPDFNumberTreeObjectHelper(QPDFObjectHandle); 53 QPDFNumberTreeObjectHelper(QPDFObjectHandle);
  54 +
  55 + // ABI: = default
54 QPDF_DLL 56 QPDF_DLL
55 virtual ~QPDFNumberTreeObjectHelper() 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 typedef long long int numtree_number; 65 typedef long long int numtree_number;
60 66
61 // Return overall minimum and maximum indices 67 // Return overall minimum and maximum indices
@@ -131,7 +137,9 @@ class QPDFNumberTreeObjectHelper: public QPDFObjectHelper @@ -131,7 +137,9 @@ class QPDFNumberTreeObjectHelper: public QPDFObjectHelper
131 }; 137 };
132 138
133 // The iterator looks like map iterator, so i.first is a string 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 QPDF_DLL 143 QPDF_DLL
136 iterator begin() const; 144 iterator begin() const;
137 QPDF_DLL 145 QPDF_DLL
libqpdf/NNTree.cc
@@ -103,9 +103,9 @@ NNTreeIterator::increment(bool backward) @@ -103,9 +103,9 @@ NNTreeIterator::increment(bool backward)
103 { 103 {
104 if (this->item_number < 0) 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 bool found_valid_key = false; 110 bool found_valid_key = false;
111 while (valid() && (! found_valid_key)) 111 while (valid() && (! found_valid_key))
libqpdf/QPDFNameTreeObjectHelper.cc
@@ -56,6 +56,13 @@ QPDFNameTreeObjectHelper::~QPDFNameTreeObjectHelper() @@ -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 QPDFNameTreeObjectHelper::iterator::iterator( 66 QPDFNameTreeObjectHelper::iterator::iterator(
60 std::shared_ptr<NNTreeIterator> const& i) : 67 std::shared_ptr<NNTreeIterator> const& i) :
61 impl(i) 68 impl(i)
libqpdf/QPDFNumberTreeObjectHelper.cc
@@ -52,6 +52,13 @@ QPDFNumberTreeObjectHelper::QPDFNumberTreeObjectHelper(QPDFObjectHandle oh) : @@ -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 QPDFNumberTreeObjectHelper::iterator::iterator( 62 QPDFNumberTreeObjectHelper::iterator::iterator(
56 std::shared_ptr<NNTreeIterator> const& i) : 63 std::shared_ptr<NNTreeIterator> const& i) :
57 impl(i) 64 impl(i)
qpdf/qpdf.testcov
@@ -551,3 +551,4 @@ NNTree -1 in binary search 0 @@ -551,3 +551,4 @@ NNTree -1 in binary search 0
551 NNTree bad node during find 0 551 NNTree bad node during find 0
552 NNTree node is not a dictionary 0 552 NNTree node is not a dictionary 0
553 NNTree limits didn't change 0 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,6 +1776,32 @@ void runtest(int n, char const* filename1, char const* arg2)
1776 assert("six" == oh.getStringValue()); 1776 assert("six" == oh.getStringValue());
1777 assert(2 == offset); 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 // Exercise deprecated API until qpdf 11 1805 // Exercise deprecated API until qpdf 11
1780 std::cout << "/Bad1: deprecated API" << std::endl; 1806 std::cout << "/Bad1: deprecated API" << std::endl;
1781 auto bad1 = QPDFNumberTreeObjectHelper( 1807 auto bad1 = QPDFNumberTreeObjectHelper(
@@ -1909,6 +1935,32 @@ void runtest(int n, char const* filename1, char const* arg2) @@ -1909,6 +1935,32 @@ void runtest(int n, char const* filename1, char const* arg2)
1909 assert((*last).first == "29 twenty-nine"); 1935 assert((*last).first == "29 twenty-nine");
1910 assert((*last).second.getUTF8Value() == "twenty-nine!"); 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 std::vector<std::string> empties = {"/Empty1", "/Empty2"}; 1964 std::vector<std::string> empties = {"/Empty1", "/Empty2"};
1913 for (auto const& k: empties) 1965 for (auto const& k: empties)
1914 { 1966 {