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,33 +63,13 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper | ||
| 63 | { | 63 | { |
| 64 | friend class QPDFOutlineObjectHelper; | 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 | private: | 69 | private: |
| 74 | void initializeByPage(); | 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 | std::shared_ptr<Members> m; | 74 | std::shared_ptr<Members> m; |
| 95 | }; | 75 | }; |
libqpdf/QPDFOutlineDocumentHelper.cc
| @@ -2,22 +2,42 @@ | @@ -2,22 +2,42 @@ | ||
| 2 | 2 | ||
| 3 | #include <qpdf/QTC.hh> | 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 | QPDFOutlineDocumentHelper::QPDFOutlineDocumentHelper(QPDF& qpdf) : | 25 | QPDFOutlineDocumentHelper::QPDFOutlineDocumentHelper(QPDF& qpdf) : |
| 6 | QPDFDocumentHelper(qpdf), | 26 | QPDFDocumentHelper(qpdf), |
| 7 | - m(new Members()) | 27 | + m(std::make_shared<Members>()) |
| 8 | { | 28 | { |
| 9 | QPDFObjectHandle root = qpdf.getRoot(); | 29 | QPDFObjectHandle root = qpdf.getRoot(); |
| 10 | if (!root.hasKey("/Outlines")) { | 30 | if (!root.hasKey("/Outlines")) { |
| 11 | return; | 31 | return; |
| 12 | } | 32 | } |
| 13 | - QPDFObjectHandle outlines = root.getKey("/Outlines"); | 33 | + auto outlines = root.getKey("/Outlines"); |
| 14 | if (!(outlines.isDictionary() && outlines.hasKey("/First"))) { | 34 | if (!(outlines.isDictionary() && outlines.hasKey("/First"))) { |
| 15 | return; | 35 | return; |
| 16 | } | 36 | } |
| 17 | QPDFObjectHandle cur = outlines.getKey("/First"); | 37 | QPDFObjectHandle cur = outlines.getKey("/First"); |
| 18 | QPDFObjGen::set seen; | 38 | QPDFObjGen::set seen; |
| 19 | while (!cur.isNull() && seen.add(cur)) { | 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 | cur = cur.getKey("/Next"); | 41 | cur = cur.getKey("/Next"); |
| 22 | } | 42 | } |
| 23 | } | 43 | } |
| @@ -55,11 +75,10 @@ QPDFOutlineDocumentHelper::getOutlinesForPage(QPDFObjGen og) | @@ -55,11 +75,10 @@ QPDFOutlineDocumentHelper::getOutlinesForPage(QPDFObjGen og) | ||
| 55 | if (m->by_page.empty()) { | 75 | if (m->by_page.empty()) { |
| 56 | initializeByPage(); | 76 | initializeByPage(); |
| 57 | } | 77 | } |
| 58 | - std::vector<QPDFOutlineObjectHelper> result; | ||
| 59 | if (m->by_page.contains(og)) { | 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 | QPDFObjectHandle | 84 | QPDFObjectHandle |
| @@ -70,13 +89,12 @@ QPDFOutlineDocumentHelper::resolveNamedDest(QPDFObjectHandle name) | @@ -70,13 +89,12 @@ QPDFOutlineDocumentHelper::resolveNamedDest(QPDFObjectHandle name) | ||
| 70 | if (!m->dest_dict) { | 89 | if (!m->dest_dict) { |
| 71 | m->dest_dict = qpdf.getRoot().getKey("/Dests"); | 90 | m->dest_dict = qpdf.getRoot().getKey("/Dests"); |
| 72 | } | 91 | } |
| 73 | - QTC::TC("qpdf", "QPDFOutlineDocumentHelper name named dest"); | ||
| 74 | result = m->dest_dict.getKeyIfDict(name.getName()); | 92 | result = m->dest_dict.getKeyIfDict(name.getName()); |
| 75 | } else if (name.isString()) { | 93 | } else if (name.isString()) { |
| 76 | if (!m->names_dest) { | 94 | if (!m->names_dest) { |
| 77 | auto dests = qpdf.getRoot().getKey("/Names").getKeyIfDict("/Dests"); | 95 | auto dests = qpdf.getRoot().getKey("/Names").getKeyIfDict("/Dests"); |
| 78 | if (dests.isDictionary()) { | 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 | if (m->names_dest) { | 100 | if (m->names_dest) { |
| @@ -89,7 +107,6 @@ QPDFOutlineDocumentHelper::resolveNamedDest(QPDFObjectHandle name) | @@ -89,7 +107,6 @@ QPDFOutlineDocumentHelper::resolveNamedDest(QPDFObjectHandle name) | ||
| 89 | return QPDFObjectHandle::newNull(); | 107 | return QPDFObjectHandle::newNull(); |
| 90 | } | 108 | } |
| 91 | if (result.isDictionary()) { | 109 | if (result.isDictionary()) { |
| 92 | - QTC::TC("qpdf", "QPDFOutlineDocumentHelper named dest dictionary"); | ||
| 93 | return result.getKey("/D"); | 110 | return result.getKey("/D"); |
| 94 | } | 111 | } |
| 95 | return result; | 112 | return result; |
qpdf/qpdf.testcov
| @@ -341,9 +341,7 @@ QPDFJob automatically set keep files open 1 | @@ -341,9 +341,7 @@ QPDFJob automatically set keep files open 1 | ||
| 341 | QPDFOutlineObjectHelper direct dest 0 | 341 | QPDFOutlineObjectHelper direct dest 0 |
| 342 | QPDFOutlineObjectHelper action dest 0 | 342 | QPDFOutlineObjectHelper action dest 0 |
| 343 | QPDFOutlineObjectHelper named dest 0 | 343 | QPDFOutlineObjectHelper named dest 0 |
| 344 | -QPDFOutlineDocumentHelper name named dest 0 | ||
| 345 | QPDFOutlineDocumentHelper string named dest 0 | 344 | QPDFOutlineDocumentHelper string named dest 0 |
| 346 | -QPDFOutlineDocumentHelper named dest dictionary 0 | ||
| 347 | QPDFOutlineObjectHelper loop 0 | 345 | QPDFOutlineObjectHelper loop 0 |
| 348 | QPDFObjectHandle merge top type mismatch 0 | 346 | QPDFObjectHandle merge top type mismatch 0 |
| 349 | QPDFObjectHandle merge shallow copy 0 | 347 | QPDFObjectHandle merge shallow copy 0 |