Commit 233e46b55b9e511f5d71f40d6c30aebe7f6ef79c

Authored by m-holger
1 parent 4c65b0a8

Refactor `NNTree::updateIValue`, `getNextKid`, and `increment`: update to use `D…

…ictionary` APIs, replace `getKey` with subscript operator, streamline logic, and simplify bounds checks.
libqpdf/NNTree.cc
... ... @@ -57,21 +57,21 @@ NNTreeIterator::updateIValue(bool allow_invalid)
57 57 // we must call updateIValue as well. These cases are handled, and for good measure, we also
58 58 // call updateIValue in operator* and operator->.
59 59  
  60 + Array items = node[impl.itemsKey()];
  61 + ivalue.first = items[item_number];
  62 + ivalue.second = items[item_number + 1];
  63 + if (ivalue.second) {
  64 + return;
  65 + }
  66 +
60 67 if (item_number < 0 || !node.isDictionary()) {
61 68 if (!allow_invalid) {
62 69 throw std::logic_error(
63 70 "attempt made to dereference an invalid name/number tree iterator");
64 71 }
65   - ivalue.first = QPDFObjectHandle();
66   - ivalue.second = QPDFObjectHandle();
67 72 return;
68 73 }
69   - Array items = node.getKey(impl.itemsKey());
70   - if (!std::cmp_less(item_number + 1, items.size())) {
71   - impl.error(node, "update ivalue: items array is too short");
72   - }
73   - ivalue.first = items[item_number];
74   - ivalue.second = items[1 + item_number];
  74 + impl.error(node, "update ivalue: items array is too short");
75 75 }
76 76  
77 77 NNTreeIterator::PathElement::PathElement(QPDFObjectHandle const& node, int kid_number) :
... ... @@ -80,24 +80,19 @@ NNTreeIterator::PathElement::PathElement(QPDFObjectHandle const&amp; node, int kid_n
80 80 {
81 81 }
82 82  
83   -QPDFObjectHandle
  83 +Dictionary
84 84 NNTreeIterator::getNextKid(PathElement& pe, bool backward)
85 85 {
86 86 while (true) {
87 87 pe.kid_number += backward ? -1 : 1;
88   - Array kids = pe.node.getKey("/Kids");
89   - if (pe.kid_number >= 0 && std::cmp_less(pe.kid_number, kids.size())) {
90   - auto result = kids[pe.kid_number];
91   - if (result.isDictionary() &&
92   - (result.hasKey("/Kids") || result.hasKey(impl.itemsKey()))) {
93   - return result;
94   - } else {
95   - impl.warn(
96   - pe.node, "skipping over invalid kid at index " + std::to_string(pe.kid_number));
97   - }
98   - } else {
99   - return QPDFObjectHandle::newNull();
  88 + Dictionary result = pe.node["/Kids"][pe.kid_number];
  89 + if (result.contains("/Kids") || result.contains(impl.itemsKey())) {
  90 + return result;
100 91 }
  92 + if (pe.kid_number < 0 || std::cmp_greater_equal(pe.kid_number, pe.node["/Kids"].size())) {
  93 + return {};
  94 + }
  95 + impl.warn(pe.node, "skipping over invalid kid at index " + std::to_string(pe.kid_number));
101 96 }
102 97 }
103 98 void
... ... @@ -110,22 +105,22 @@ NNTreeIterator::increment(bool backward)
110 105  
111 106 while (valid()) {
112 107 item_number += backward ? -2 : 2;
113   - Array items = node.getKey(impl.itemsKey());
  108 + Array items = node[impl.itemsKey()];
114 109 if (item_number < 0 || std::cmp_greater_equal(item_number, items.size())) {
115   - bool found = false;
116 110 setItemNumber(QPDFObjectHandle(), -1);
117   - while (!(found || path.empty())) {
  111 + while (!path.empty()) {
118 112 auto& element = path.back();
119   - auto pe_node = getNextKid(element, backward);
120   - if (pe_node.null()) {
121   - path.pop_back();
  113 + if (auto pe_node = getNextKid(element, backward)) {
  114 + if (deepen(pe_node, !backward, false)) {
  115 + break;
  116 + }
122 117 } else {
123   - found = deepen(pe_node, !backward, false);
  118 + path.pop_back();
124 119 }
125 120 }
126 121 }
127 122 if (item_number >= 0) {
128   - items = node.getKey(impl.itemsKey());
  123 + items = node[impl.itemsKey()];
129 124 if (std::cmp_greater_equal(item_number + 1, items.size())) {
130 125 impl.warn(node, "items array doesn't have enough elements");
131 126 } else if (!impl.keyValid(items[item_number])) {
... ...
libqpdf/qpdf/NNTree.hh
... ... @@ -105,7 +105,7 @@ class NNTreeIterator final
105 105 {
106 106 path.emplace_back(a_node, kid_number);
107 107 }
108   - QPDFObjectHandle getNextKid(PathElement& element, bool backward);
  108 + qpdf::Dictionary getNextKid(PathElement& element, bool backward);
109 109 void increment(bool backward);
110 110 void resetLimits(QPDFObjectHandle node, std::list<PathElement>::iterator parent);
111 111  
... ...