Commit dfb2718c31f97d90c8c890586a0bb2380d8f28fc
1 parent
d11553e4
Refactor `QPDFOutlineDocumentHelper::Members` to use `std::unique_ptr` for `name…
…s_dest`, improve memory management, and streamline initialization logic
Showing
3 changed files
with
28 additions
and
33 deletions
include/qpdf/QPDFOutlineDocumentHelper.hh
| ... | ... | @@ -63,33 +63,13 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper |
| 63 | 63 | { |
| 64 | 64 | friend class QPDFOutlineObjectHelper; |
| 65 | 65 | |
| 66 | - static bool | |
| 67 | - checkSeen(QPDFOutlineDocumentHelper& dh, QPDFObjGen og) | |
| 68 | - { | |
| 69 | - return !dh.m->seen.add(og); | |
| 70 | - } | |
| 66 | + static bool checkSeen(QPDFOutlineDocumentHelper& dh, QPDFObjGen og); | |
| 71 | 67 | }; |
| 72 | 68 | |
| 73 | 69 | private: |
| 74 | 70 | void initializeByPage(); |
| 75 | 71 | |
| 76 | - class Members | |
| 77 | - { | |
| 78 | - friend class QPDFOutlineDocumentHelper; | |
| 79 | - | |
| 80 | - public: | |
| 81 | - ~Members() = default; | |
| 82 | - | |
| 83 | - private: | |
| 84 | - Members() = default; | |
| 85 | - Members(Members const&) = delete; | |
| 86 | - | |
| 87 | - std::vector<QPDFOutlineObjectHelper> outlines; | |
| 88 | - QPDFObjGen::set seen; | |
| 89 | - QPDFObjectHandle dest_dict; | |
| 90 | - std::shared_ptr<QPDFNameTreeObjectHelper> names_dest; | |
| 91 | - std::map<QPDFObjGen, std::vector<QPDFOutlineObjectHelper>> by_page; | |
| 92 | - }; | |
| 72 | + class Members; | |
| 93 | 73 | |
| 94 | 74 | std::shared_ptr<Members> m; |
| 95 | 75 | }; | ... | ... |
libqpdf/QPDFOutlineDocumentHelper.cc
| ... | ... | @@ -2,22 +2,42 @@ |
| 2 | 2 | |
| 3 | 3 | #include <qpdf/QTC.hh> |
| 4 | 4 | |
| 5 | +class QPDFOutlineDocumentHelper::Members | |
| 6 | +{ | |
| 7 | + public: | |
| 8 | + Members() = default; | |
| 9 | + Members(Members const&) = delete; | |
| 10 | + ~Members() = default; | |
| 11 | + | |
| 12 | + std::vector<QPDFOutlineObjectHelper> outlines; | |
| 13 | + QPDFObjGen::set seen; | |
| 14 | + QPDFObjectHandle dest_dict; | |
| 15 | + std::unique_ptr<QPDFNameTreeObjectHelper> names_dest; | |
| 16 | + std::map<QPDFObjGen, std::vector<QPDFOutlineObjectHelper>> by_page; | |
| 17 | +}; | |
| 18 | + | |
| 19 | +bool | |
| 20 | +QPDFOutlineDocumentHelper::Accessor::checkSeen(QPDFOutlineDocumentHelper& dh, QPDFObjGen og) | |
| 21 | +{ | |
| 22 | + return !dh.m->seen.add(og); | |
| 23 | +} | |
| 24 | + | |
| 5 | 25 | QPDFOutlineDocumentHelper::QPDFOutlineDocumentHelper(QPDF& qpdf) : |
| 6 | 26 | QPDFDocumentHelper(qpdf), |
| 7 | - m(new Members()) | |
| 27 | + m(std::make_shared<Members>()) | |
| 8 | 28 | { |
| 9 | 29 | QPDFObjectHandle root = qpdf.getRoot(); |
| 10 | 30 | if (!root.hasKey("/Outlines")) { |
| 11 | 31 | return; |
| 12 | 32 | } |
| 13 | - QPDFObjectHandle outlines = root.getKey("/Outlines"); | |
| 33 | + auto outlines = root.getKey("/Outlines"); | |
| 14 | 34 | if (!(outlines.isDictionary() && outlines.hasKey("/First"))) { |
| 15 | 35 | return; |
| 16 | 36 | } |
| 17 | 37 | QPDFObjectHandle cur = outlines.getKey("/First"); |
| 18 | 38 | QPDFObjGen::set seen; |
| 19 | 39 | while (!cur.isNull() && seen.add(cur)) { |
| 20 | - m->outlines.push_back(QPDFOutlineObjectHelper::Accessor::create(cur, *this, 1)); | |
| 40 | + m->outlines.emplace_back(QPDFOutlineObjectHelper::Accessor::create(cur, *this, 1)); | |
| 21 | 41 | cur = cur.getKey("/Next"); |
| 22 | 42 | } |
| 23 | 43 | } |
| ... | ... | @@ -55,11 +75,10 @@ QPDFOutlineDocumentHelper::getOutlinesForPage(QPDFObjGen og) |
| 55 | 75 | if (m->by_page.empty()) { |
| 56 | 76 | initializeByPage(); |
| 57 | 77 | } |
| 58 | - std::vector<QPDFOutlineObjectHelper> result; | |
| 59 | 78 | if (m->by_page.contains(og)) { |
| 60 | - result = m->by_page[og]; | |
| 79 | + return m->by_page[og]; | |
| 61 | 80 | } |
| 62 | - return result; | |
| 81 | + return {}; | |
| 63 | 82 | } |
| 64 | 83 | |
| 65 | 84 | QPDFObjectHandle |
| ... | ... | @@ -70,13 +89,12 @@ QPDFOutlineDocumentHelper::resolveNamedDest(QPDFObjectHandle name) |
| 70 | 89 | if (!m->dest_dict) { |
| 71 | 90 | m->dest_dict = qpdf.getRoot().getKey("/Dests"); |
| 72 | 91 | } |
| 73 | - QTC::TC("qpdf", "QPDFOutlineDocumentHelper name named dest"); | |
| 74 | 92 | result = m->dest_dict.getKeyIfDict(name.getName()); |
| 75 | 93 | } else if (name.isString()) { |
| 76 | 94 | if (!m->names_dest) { |
| 77 | 95 | auto dests = qpdf.getRoot().getKey("/Names").getKeyIfDict("/Dests"); |
| 78 | 96 | if (dests.isDictionary()) { |
| 79 | - m->names_dest = std::make_shared<QPDFNameTreeObjectHelper>(dests, qpdf); | |
| 97 | + m->names_dest = std::make_unique<QPDFNameTreeObjectHelper>(dests, qpdf); | |
| 80 | 98 | } |
| 81 | 99 | } |
| 82 | 100 | if (m->names_dest) { |
| ... | ... | @@ -89,7 +107,6 @@ QPDFOutlineDocumentHelper::resolveNamedDest(QPDFObjectHandle name) |
| 89 | 107 | return QPDFObjectHandle::newNull(); |
| 90 | 108 | } |
| 91 | 109 | if (result.isDictionary()) { |
| 92 | - QTC::TC("qpdf", "QPDFOutlineDocumentHelper named dest dictionary"); | |
| 93 | 110 | return result.getKey("/D"); |
| 94 | 111 | } |
| 95 | 112 | return result; | ... | ... |
qpdf/qpdf.testcov
| ... | ... | @@ -341,9 +341,7 @@ QPDFJob automatically set keep files open 1 |
| 341 | 341 | QPDFOutlineObjectHelper direct dest 0 |
| 342 | 342 | QPDFOutlineObjectHelper action dest 0 |
| 343 | 343 | QPDFOutlineObjectHelper named dest 0 |
| 344 | -QPDFOutlineDocumentHelper name named dest 0 | |
| 345 | 344 | QPDFOutlineDocumentHelper string named dest 0 |
| 346 | -QPDFOutlineDocumentHelper named dest dictionary 0 | |
| 347 | 345 | QPDFOutlineObjectHelper loop 0 |
| 348 | 346 | QPDFObjectHandle merge top type mismatch 0 |
| 349 | 347 | QPDFObjectHandle merge shallow copy 0 | ... | ... |