Commit 233e46b55b9e511f5d71f40d6c30aebe7f6ef79c
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.
Showing
2 changed files
with
25 additions
and
30 deletions
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& 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 | ... | ... |