Commit cbeaf5a89e75f883a10bbad1a491969000b552c6
1 parent
722ca8e0
Refactor `BaseDictionary` and `Dictionary` constructors, add `operator[]` for di…
…ctionary key access, and simplify null handling logic.
Showing
4 changed files
with
101 additions
and
18 deletions
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& key, QPDFObjectHandle value) | @@ -78,13 +91,28 @@ BaseDictionary::replaceKey(std::string const& 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 |