Commit cbeaf5a89e75f883a10bbad1a491969000b552c6

Authored by m-holger
1 parent 722ca8e0

Refactor `BaseDictionary` and `Dictionary` constructors, add `operator[]` for di…

…ctionary key access, and simplify null handling logic.
include/qpdf/ObjectHandle.hh
@@ -83,6 +83,8 @@ namespace qpdf @@ -83,6 +83,8 @@ namespace qpdf
83 QPDFObjectHandle operator[](size_t n) const; 83 QPDFObjectHandle operator[](size_t n) const;
84 QPDFObjectHandle operator[](int n) const; 84 QPDFObjectHandle operator[](int n) const;
85 85
  86 + QPDFObjectHandle const& operator[](std::string const& key) const;
  87 +
86 std::shared_ptr<QPDFObject> copy(bool shallow = false) const; 88 std::shared_ptr<QPDFObject> copy(bool shallow = false) const;
87 // Recursively remove association with any QPDF object. This method may only be called 89 // Recursively remove association with any QPDF object. This method may only be called
88 // during final destruction. 90 // during final destruction.
libqpdf/QPDF_Dictionary.cc
@@ -16,6 +16,19 @@ BaseDictionary::dict() const @@ -16,6 +16,19 @@ BaseDictionary::dict() const
16 return nullptr; // unreachable 16 return nullptr; // unreachable
17 } 17 }
18 18
  19 +QPDFObjectHandle const&
  20 +BaseHandle::operator[](std::string const& key) const
  21 +{
  22 + if (auto d = as<QPDF_Dictionary>()) {
  23 + auto it = d->items.find(key);
  24 + if (it != d->items.end()) {
  25 + return it->second;
  26 + }
  27 + }
  28 + static const QPDFObjectHandle null_obj;
  29 + return null_obj;
  30 +}
  31 +
19 bool 32 bool
20 BaseDictionary::hasKey(std::string const& key) const 33 BaseDictionary::hasKey(std::string const& key) const
21 { 34 {
@@ -78,13 +91,28 @@ BaseDictionary::replaceKey(std::string const&amp; key, QPDFObjectHandle value) @@ -78,13 +91,28 @@ BaseDictionary::replaceKey(std::string const&amp; key, QPDFObjectHandle value)
78 } 91 }
79 } 92 }
80 93
  94 +Dictionary::Dictionary(std::map<std::string, QPDFObjectHandle>&& dict) :
  95 + BaseDictionary(std::move(dict))
  96 +{
  97 +}
  98 +
  99 +Dictionary::Dictionary(std::shared_ptr<QPDFObject> const& obj) :
  100 + BaseDictionary(obj)
  101 +{
  102 +}
  103 +
  104 +Dictionary
  105 +Dictionary::empty()
  106 +{
  107 + return Dictionary(std::map<std::string, QPDFObjectHandle>());
  108 +}
  109 +
81 void 110 void
82 QPDFObjectHandle::checkOwnership(QPDFObjectHandle const& item) const 111 QPDFObjectHandle::checkOwnership(QPDFObjectHandle const& item) const
83 { 112 {
84 auto qpdf = getOwningQPDF(); 113 auto qpdf = getOwningQPDF();
85 auto item_qpdf = item.getOwningQPDF(); 114 auto item_qpdf = item.getOwningQPDF();
86 if (qpdf && item_qpdf && qpdf != item_qpdf) { 115 if (qpdf && item_qpdf && qpdf != item_qpdf) {
87 - QTC::TC("qpdf", "QPDFObjectHandle check ownership");  
88 throw std::logic_error( 116 throw std::logic_error(
89 "Attempting to add an object from a different QPDF. Use " 117 "Attempting to add an object from a different QPDF. Use "
90 "QPDF::copyForeignObject to add objects from another file."); 118 "QPDF::copyForeignObject to add objects from another file.");
libqpdf/qpdf/QPDFObjectHandle_private.hh
@@ -119,6 +119,14 @@ namespace qpdf @@ -119,6 +119,14 @@ namespace qpdf
119 class BaseDictionary: public BaseHandle 119 class BaseDictionary: public BaseHandle
120 { 120 {
121 public: 121 public:
  122 + // The following methods are not part of the public API.
  123 + bool hasKey(std::string const& key) const;
  124 + QPDFObjectHandle getKey(std::string const& key) const;
  125 + std::set<std::string> getKeys();
  126 + std::map<std::string, QPDFObjectHandle> const& getAsMap() const;
  127 + void removeKey(std::string const& key);
  128 + void replaceKey(std::string const& key, QPDFObjectHandle value);
  129 +
122 using iterator = std::map<std::string, QPDFObjectHandle>::iterator; 130 using iterator = std::map<std::string, QPDFObjectHandle>::iterator;
123 using const_iterator = std::map<std::string, QPDFObjectHandle>::const_iterator; 131 using const_iterator = std::map<std::string, QPDFObjectHandle>::const_iterator;
124 using reverse_iterator = std::map<std::string, QPDFObjectHandle>::reverse_iterator; 132 using reverse_iterator = std::map<std::string, QPDFObjectHandle>::reverse_iterator;
@@ -197,41 +205,87 @@ namespace qpdf @@ -197,41 +205,87 @@ namespace qpdf
197 return {}; 205 return {};
198 } 206 }
199 207
200 - // The following methods are not part of the public API.  
201 - bool hasKey(std::string const& key) const;  
202 - QPDFObjectHandle getKey(std::string const& key) const;  
203 - std::set<std::string> getKeys();  
204 - std::map<std::string, QPDFObjectHandle> const& getAsMap() const;  
205 - void removeKey(std::string const& key);  
206 - void replaceKey(std::string const& key, QPDFObjectHandle value);  
207 -  
208 protected: 208 protected:
209 BaseDictionary() = default; 209 BaseDictionary() = default;
210 - BaseDictionary(std::shared_ptr<QPDFObject> const& obj) :  
211 - BaseHandle(obj) {};  
212 - BaseDictionary(std::shared_ptr<QPDFObject>&& obj) :  
213 - BaseHandle(std::move(obj)) {}; 210 +
  211 + explicit BaseDictionary(std::map<std::string, QPDFObjectHandle> const& dict) :
  212 + BaseHandle(QPDFObject::create<QPDF_Dictionary>(dict))
  213 + {
  214 + }
  215 +
  216 + explicit BaseDictionary(std::map<std::string, QPDFObjectHandle>&& dict) :
  217 + BaseHandle(QPDFObject::create<QPDF_Dictionary>(std::move(dict)))
  218 + {
  219 + }
  220 +
  221 + explicit BaseDictionary(std::shared_ptr<QPDFObject> const& obj) :
  222 + BaseHandle(obj)
  223 + {
  224 + }
  225 + explicit BaseDictionary(std::shared_ptr<QPDFObject>&& obj) :
  226 + BaseHandle(std::move(obj))
  227 + {
  228 + }
214 BaseDictionary(BaseDictionary const&) = default; 229 BaseDictionary(BaseDictionary const&) = default;
215 BaseDictionary& operator=(BaseDictionary const&) = default; 230 BaseDictionary& operator=(BaseDictionary const&) = default;
216 BaseDictionary(BaseDictionary&&) = default; 231 BaseDictionary(BaseDictionary&&) = default;
217 BaseDictionary& operator=(BaseDictionary&&) = default; 232 BaseDictionary& operator=(BaseDictionary&&) = default;
  233 +
  234 + explicit BaseDictionary(QPDFObjectHandle const& oh) :
  235 + BaseHandle(oh.resolved_type_code() == ::ot_dictionary ? oh : QPDFObjectHandle())
  236 + {
  237 + }
  238 +
  239 + explicit BaseDictionary(QPDFObjectHandle&& oh) :
  240 + BaseHandle(
  241 + oh.resolved_type_code() == ::ot_dictionary ? std::move(oh) : QPDFObjectHandle())
  242 + {
  243 + }
218 ~BaseDictionary() = default; 244 ~BaseDictionary() = default;
219 245
220 QPDF_Dictionary* dict() const; 246 QPDF_Dictionary* dict() const;
221 }; 247 };
222 248
  249 + // Dictionary only defines con/destructors. All other methods are inherited from BaseDictionary.
223 class Dictionary final: public BaseDictionary 250 class Dictionary final: public BaseDictionary
224 { 251 {
225 public: 252 public:
226 - explicit Dictionary(std::shared_ptr<QPDFObject> const& obj) :  
227 - BaseDictionary(obj) 253 + Dictionary() = default;
  254 + explicit Dictionary(std::map<std::string, QPDFObjectHandle>&& dict);
  255 + explicit Dictionary(std::shared_ptr<QPDFObject> const& obj);
  256 +
  257 + static Dictionary empty();
  258 +
  259 + Dictionary(Dictionary const&) = default;
  260 + Dictionary& operator=(Dictionary const&) = default;
  261 + Dictionary(Dictionary&&) = default;
  262 + Dictionary& operator=(Dictionary&&) = default;
  263 +
  264 + Dictionary(QPDFObjectHandle const& oh) :
  265 + BaseDictionary(oh)
  266 + {
  267 + }
  268 +
  269 + Dictionary&
  270 + operator=(QPDFObjectHandle const& oh)
  271 + {
  272 + assign(::ot_dictionary, oh);
  273 + return *this;
  274 + }
  275 +
  276 + Dictionary(QPDFObjectHandle&& oh) :
  277 + BaseDictionary(std::move(oh))
228 { 278 {
229 } 279 }
230 280
231 - explicit Dictionary(std::shared_ptr<QPDFObject>&& obj) :  
232 - BaseDictionary(std::move(obj)) 281 + Dictionary&
  282 + operator=(QPDFObjectHandle&& oh)
233 { 283 {
  284 + assign(::ot_dictionary, std::move(oh));
  285 + return *this;
234 } 286 }
  287 +
  288 + ~Dictionary() = default;
235 }; 289 };
236 290
237 class Name final: public BaseHandle 291 class Name final: public BaseHandle
qpdf/qpdf.testcov
@@ -537,7 +537,6 @@ QPDFWriter preserve object streams 0 @@ -537,7 +537,6 @@ QPDFWriter preserve object streams 0
537 QPDFWriter preserve object streams preserve unreferenced 0 537 QPDFWriter preserve object streams preserve unreferenced 0
538 QPDFWriter exclude from object stream 0 538 QPDFWriter exclude from object stream 0
539 QPDF_pages findPage not found 0 539 QPDF_pages findPage not found 0
540 -QPDFObjectHandle check ownership 0  
541 QPDFJob weak crypto error 0 540 QPDFJob weak crypto error 0
542 qpdf-c called qpdf_oh_is_initialized 0 541 qpdf-c called qpdf_oh_is_initialized 0
543 qpdf-c registered progress reporter 0 542 qpdf-c registered progress reporter 0