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 83 QPDFObjectHandle operator[](size_t n) const;
84 84 QPDFObjectHandle operator[](int n) const;
85 85  
  86 + QPDFObjectHandle const& operator[](std::string const& key) const;
  87 +
86 88 std::shared_ptr<QPDFObject> copy(bool shallow = false) const;
87 89 // Recursively remove association with any QPDF object. This method may only be called
88 90 // during final destruction.
... ...
libqpdf/QPDF_Dictionary.cc
... ... @@ -16,6 +16,19 @@ BaseDictionary::dict() const
16 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 32 bool
20 33 BaseDictionary::hasKey(std::string const& key) const
21 34 {
... ... @@ -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 110 void
82 111 QPDFObjectHandle::checkOwnership(QPDFObjectHandle const& item) const
83 112 {
84 113 auto qpdf = getOwningQPDF();
85 114 auto item_qpdf = item.getOwningQPDF();
86 115 if (qpdf && item_qpdf && qpdf != item_qpdf) {
87   - QTC::TC("qpdf", "QPDFObjectHandle check ownership");
88 116 throw std::logic_error(
89 117 "Attempting to add an object from a different QPDF. Use "
90 118 "QPDF::copyForeignObject to add objects from another file.");
... ...
libqpdf/qpdf/QPDFObjectHandle_private.hh
... ... @@ -119,6 +119,14 @@ namespace qpdf
119 119 class BaseDictionary: public BaseHandle
120 120 {
121 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 130 using iterator = std::map<std::string, QPDFObjectHandle>::iterator;
123 131 using const_iterator = std::map<std::string, QPDFObjectHandle>::const_iterator;
124 132 using reverse_iterator = std::map<std::string, QPDFObjectHandle>::reverse_iterator;
... ... @@ -197,41 +205,87 @@ namespace qpdf
197 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 208 protected:
209 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 229 BaseDictionary(BaseDictionary const&) = default;
215 230 BaseDictionary& operator=(BaseDictionary const&) = default;
216 231 BaseDictionary(BaseDictionary&&) = default;
217 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 244 ~BaseDictionary() = default;
219 245  
220 246 QPDF_Dictionary* dict() const;
221 247 };
222 248  
  249 + // Dictionary only defines con/destructors. All other methods are inherited from BaseDictionary.
223 250 class Dictionary final: public BaseDictionary
224 251 {
225 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 291 class Name final: public BaseHandle
... ...
qpdf/qpdf.testcov
... ... @@ -537,7 +537,6 @@ QPDFWriter preserve object streams 0
537 537 QPDFWriter preserve object streams preserve unreferenced 0
538 538 QPDFWriter exclude from object stream 0
539 539 QPDF_pages findPage not found 0
540   -QPDFObjectHandle check ownership 0
541 540 QPDFJob weak crypto error 0
542 541 qpdf-c called qpdf_oh_is_initialized 0
543 542 qpdf-c registered progress reporter 0
... ...