Commit 16a9bb3f6f63497946d0efbf403df92d0ce30745
1 parent
b5614f61
name/number trees: newEmpty, increment/decrement end()
Showing
7 changed files
with
88 additions
and
5 deletions
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
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 | { | ... | ... |