Commit f110a23c48d74157b999715bf451118c920fa169
1 parent
0d8b0882
Refactor `NNTree::remove`: simplify logic, replace `getArrayItem` and `getArrayN…
…Items` with subscript operators, introduce `std::cmp` utilities, and remove redundant debug traces.
Showing
2 changed files
with
18 additions
and
41 deletions
libqpdf/NNTree.cc
| ... | ... | @@ -422,8 +422,8 @@ NNTreeIterator::remove() |
| 422 | 422 | throw std::logic_error("attempt made to remove an invalid iterator"); |
| 423 | 423 | } |
| 424 | 424 | auto items = node.getKey(impl.details.itemsKey()); |
| 425 | - int nitems = items.getArrayNItems(); | |
| 426 | - if (item_number + 2 > nitems) { | |
| 425 | + int nitems = static_cast<int>(items.size()); | |
| 426 | + if (std::cmp_greater(item_number + 2, nitems)) { | |
| 427 | 427 | impl.error(node, "found short items array while removing an item"); |
| 428 | 428 | } |
| 429 | 429 | |
| ... | ... | @@ -437,20 +437,17 @@ NNTreeIterator::remove() |
| 437 | 437 | if (item_number == 0 || item_number == nitems) { |
| 438 | 438 | // We removed either the first or last item of an items array that remains non-empty, so |
| 439 | 439 | // we have to adjust limits. |
| 440 | - QTC::TC("qpdf", "NNTree remove reset limits"); | |
| 441 | 440 | resetLimits(node, lastPathElement()); |
| 442 | 441 | } |
| 443 | 442 | |
| 444 | 443 | if (item_number == nitems) { |
| 445 | 444 | // We removed the last item of a non-empty items array, so advance to the successor of |
| 446 | 445 | // the previous item. |
| 447 | - QTC::TC("qpdf", "NNTree erased last item"); | |
| 448 | 446 | item_number -= 2; |
| 449 | 447 | increment(false); |
| 450 | 448 | } else if (item_number < nitems) { |
| 451 | 449 | // We don't have to do anything since the removed item's successor now occupies its |
| 452 | 450 | // former location. |
| 453 | - QTC::TC("qpdf", "NNTree erased non-last item"); | |
| 454 | 451 | updateIValue(); |
| 455 | 452 | } else { |
| 456 | 453 | // We already checked to ensure this condition would not happen. |
| ... | ... | @@ -461,61 +458,51 @@ NNTreeIterator::remove() |
| 461 | 458 | |
| 462 | 459 | if (path.empty()) { |
| 463 | 460 | // Special case: if this is the root node, we can leave it empty. |
| 464 | - QTC::TC("qpdf", "NNTree erased all items on leaf/root"); | |
| 465 | 461 | setItemNumber(impl.oh, -1); |
| 466 | 462 | return; |
| 467 | 463 | } |
| 468 | 464 | |
| 469 | - QTC::TC("qpdf", "NNTree items is empty after remove"); | |
| 470 | - | |
| 471 | 465 | // We removed the last item from this items array, so we need to remove this node from the |
| 472 | 466 | // parent on up the tree. Then we need to position ourselves at the removed item's successor. |
| 473 | - bool done = false; | |
| 474 | - while (!done) { | |
| 467 | + while (true) { | |
| 475 | 468 | auto element = lastPathElement(); |
| 476 | 469 | auto parent = element; |
| 477 | 470 | --parent; |
| 478 | 471 | auto kids = element->node.getKey("/Kids"); |
| 479 | 472 | kids.eraseItem(element->kid_number); |
| 480 | - auto nkids = kids.getArrayNItems(); | |
| 473 | + auto nkids = kids.size(); | |
| 481 | 474 | if (nkids > 0) { |
| 482 | 475 | // The logic here is similar to the items case. |
| 483 | - if ((element->kid_number == 0) || (element->kid_number == nkids)) { | |
| 484 | - QTC::TC("qpdf", "NNTree erased first or last kid"); | |
| 476 | + if (element->kid_number == 0 || std::cmp_equal(element->kid_number, nkids)) { | |
| 485 | 477 | resetLimits(element->node, parent); |
| 486 | 478 | } |
| 487 | - if (element->kid_number == nkids) { | |
| 479 | + if (std::cmp_equal(element->kid_number, nkids)) { | |
| 488 | 480 | // Move to the successor of the last child of the previous kid. |
| 489 | - setItemNumber(QPDFObjectHandle(), -1); | |
| 481 | + setItemNumber({}, -1); | |
| 490 | 482 | --element->kid_number; |
| 491 | - deepen(kids.getArrayItem(element->kid_number), false, true); | |
| 483 | + deepen(kids[element->kid_number], false, true); | |
| 492 | 484 | if (valid()) { |
| 493 | 485 | increment(false); |
| 494 | - if (!valid()) { | |
| 495 | - QTC::TC("qpdf", "NNTree erased last item in tree"); | |
| 496 | - } else { | |
| 497 | - QTC::TC("qpdf", "NNTree erased last kid"); | |
| 498 | - } | |
| 486 | + QTC::TC("qpdf", "NNTree erased last kid/item in tree", valid() ? 0 : 1); | |
| 499 | 487 | } |
| 500 | 488 | } else { |
| 501 | 489 | // Next kid is in deleted kid's position |
| 502 | - QTC::TC("qpdf", "NNTree erased non-last kid"); | |
| 503 | 490 | deepen(kids.getArrayItem(element->kid_number), true, true); |
| 504 | 491 | } |
| 505 | - done = true; | |
| 506 | - } else if (parent == path.end()) { | |
| 492 | + return; | |
| 493 | + } | |
| 494 | + | |
| 495 | + if (parent == path.end()) { | |
| 507 | 496 | // We erased the very last item. Convert the root to an empty items array. |
| 508 | - QTC::TC("qpdf", "NNTree non-flat tree is empty after remove"); | |
| 509 | 497 | element->node.removeKey("/Kids"); |
| 510 | 498 | element->node.replaceKey(impl.details.itemsKey(), QPDFObjectHandle::newArray()); |
| 511 | 499 | path.clear(); |
| 512 | 500 | setItemNumber(impl.oh, -1); |
| 513 | - done = true; | |
| 514 | - } else { | |
| 515 | - // Walk up the tree and continue | |
| 516 | - QTC::TC("qpdf", "NNTree remove walking up tree"); | |
| 517 | - path.pop_back(); | |
| 501 | + return; | |
| 518 | 502 | } |
| 503 | + | |
| 504 | + // Walk up the tree and continue | |
| 505 | + path.pop_back(); | |
| 519 | 506 | } |
| 520 | 507 | } |
| 521 | 508 | ... | ... |
qpdf/qpdf.testcov
| ... | ... | @@ -534,17 +534,7 @@ NNTree split second half kid 0 |
| 534 | 534 | NNTree limits didn't change 0 |
| 535 | 535 | NNTree increment end() 0 |
| 536 | 536 | NNTree insertAfter inserts first 0 |
| 537 | -NNTree remove reset limits 0 | |
| 538 | -NNTree erased last item 0 | |
| 539 | -NNTree erased non-last item 0 | |
| 540 | -NNTree items is empty after remove 0 | |
| 541 | -NNTree erased all items on leaf/root 0 | |
| 542 | -NNTree erased first or last kid 0 | |
| 543 | -NNTree erased last kid 0 | |
| 544 | -NNTree erased non-last kid 0 | |
| 545 | -NNTree non-flat tree is empty after remove 0 | |
| 546 | -NNTree remove walking up tree 0 | |
| 547 | -NNTree erased last item in tree 0 | |
| 537 | +NNTree erased last kid/item in tree 1 | |
| 548 | 538 | NNTree remove limits from root 0 |
| 549 | 539 | QPDFPageObjectHelper unresolved names 0 |
| 550 | 540 | QPDFPageObjectHelper resolving unresolved 0 | ... | ... |