Commit dfb2718c31f97d90c8c890586a0bb2380d8f28fc

Authored by m-holger
1 parent d11553e4

Refactor `QPDFOutlineDocumentHelper::Members` to use `std::unique_ptr` for `name…

…s_dest`, improve memory management, and streamline initialization logic
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