Commit c1def4ead4c578862ad6fcda35a9ca65be407893
1 parent
d12734d7
Implement QPDFObjectHandle equality
Showing
6 changed files
with
63 additions
and
4 deletions
ChangeLog
| 1 | 2022-09-06 Jay Berkenbilt <ejb@ql.org> | 1 | 2022-09-06 Jay Berkenbilt <ejb@ql.org> |
| 2 | 2 | ||
| 3 | + * Add == equality for QPDFObjectHandle. Two QPDFObjectHandle | ||
| 4 | + objects are equal if they point to the same underlying object, | ||
| 5 | + meaning changes to one will be reflected in the other. | ||
| 6 | + | ||
| 3 | * The --show-encryption option now works even if a correct | 7 | * The --show-encryption option now works even if a correct |
| 4 | password is not supplied. If you were using --show-encryption to | 8 | password is not supplied. If you were using --show-encryption to |
| 5 | test whether you have the right password, use --requires-password | 9 | test whether you have the right password, use --requires-password |
include/qpdf/QPDFObjectHandle.hh
| @@ -334,6 +334,15 @@ class QPDFObjectHandle | @@ -334,6 +334,15 @@ class QPDFObjectHandle | ||
| 334 | QPDF_DLL | 334 | QPDF_DLL |
| 335 | inline bool isInitialized() const; | 335 | inline bool isInitialized() const; |
| 336 | 336 | ||
| 337 | + // Two QPDFObjectHandle objects are equal if they point to exactly | ||
| 338 | + // the same underlying object, meaning that changes to one are | ||
| 339 | + // reflected in the other, or "if you paint one, the other one | ||
| 340 | + // changes color." | ||
| 341 | + QPDF_DLL | ||
| 342 | + bool operator==(QPDFObjectHandle const&) const; | ||
| 343 | + QPDF_DLL | ||
| 344 | + bool operator!=(QPDFObjectHandle const&) const; | ||
| 345 | + | ||
| 337 | // Return type code and type name of underlying object. These are | 346 | // Return type code and type name of underlying object. These are |
| 338 | // useful for doing rapid type tests (like switch statements) or | 347 | // useful for doing rapid type tests (like switch statements) or |
| 339 | // for testing and debugging. | 348 | // for testing and debugging. |
libqpdf/QPDFObjectHandle.cc
| @@ -236,6 +236,18 @@ LastChar::getLastChar() | @@ -236,6 +236,18 @@ LastChar::getLastChar() | ||
| 236 | return this->last_char; | 236 | return this->last_char; |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | +bool | ||
| 240 | +QPDFObjectHandle::operator==(QPDFObjectHandle const& rhs) const | ||
| 241 | +{ | ||
| 242 | + return this->obj == rhs.obj; | ||
| 243 | +} | ||
| 244 | + | ||
| 245 | +bool | ||
| 246 | +QPDFObjectHandle::operator!=(QPDFObjectHandle const& rhs) const | ||
| 247 | +{ | ||
| 248 | + return this->obj != rhs.obj; | ||
| 249 | +} | ||
| 250 | + | ||
| 239 | qpdf_object_type_e | 251 | qpdf_object_type_e |
| 240 | QPDFObjectHandle::getTypeCode() | 252 | QPDFObjectHandle::getTypeCode() |
| 241 | { | 253 | { |
manual/release-notes.rst
| @@ -208,6 +208,11 @@ For a detailed list of changes, please see the file | @@ -208,6 +208,11 @@ For a detailed list of changes, please see the file | ||
| 208 | generally not happen for correct code, but at least the | 208 | generally not happen for correct code, but at least the |
| 209 | situation is detectible now. | 209 | situation is detectible now. |
| 210 | 210 | ||
| 211 | + - It is now possible to test ``QPDFObjectHandle`` equality with | ||
| 212 | + ``==`` and ``!=``. Two ``QPDFObjectHandle`` objects are equal if | ||
| 213 | + they point to the same underlying object, meaning changes to one | ||
| 214 | + will be reflected in the other. | ||
| 215 | + | ||
| 211 | - Add new factory method ``QPDF::create()`` that returns a | 216 | - Add new factory method ``QPDF::create()`` that returns a |
| 212 | ``std::shared_ptr<QPDF>``. | 217 | ``std::shared_ptr<QPDF>``. |
| 213 | 218 |
qpdf/qtest/object-handle-api.test
| @@ -14,8 +14,6 @@ cleanup(); | @@ -14,8 +14,6 @@ cleanup(); | ||
| 14 | 14 | ||
| 15 | my $td = new TestDriver('object-handle-api'); | 15 | my $td = new TestDriver('object-handle-api'); |
| 16 | 16 | ||
| 17 | -my $n_tests = 2; | ||
| 18 | - | ||
| 19 | $td->runtest("dictionary keys", | 17 | $td->runtest("dictionary keys", |
| 20 | {$td->COMMAND => "test_driver 87 - -"}, | 18 | {$td->COMMAND => "test_driver 87 - -"}, |
| 21 | {$td->STRING => "test 87 done\n", $td->EXIT_STATUS => 0}, | 19 | {$td->STRING => "test 87 done\n", $td->EXIT_STATUS => 0}, |
| @@ -24,6 +22,10 @@ $td->runtest("fluent interfaces", | @@ -24,6 +22,10 @@ $td->runtest("fluent interfaces", | ||
| 24 | {$td->COMMAND => "test_driver 88 minimal.pdf -"}, | 22 | {$td->COMMAND => "test_driver 88 minimal.pdf -"}, |
| 25 | {$td->FILE => "test88.out", $td->EXIT_STATUS => 0}, | 23 | {$td->FILE => "test88.out", $td->EXIT_STATUS => 0}, |
| 26 | $td->NORMALIZE_NEWLINES); | 24 | $td->NORMALIZE_NEWLINES); |
| 25 | +$td->runtest("equality", | ||
| 26 | + {$td->COMMAND => "test_driver 93 minimal.pdf -"}, | ||
| 27 | + {$td->STRING => "test 93 done\n", $td->EXIT_STATUS => 0}, | ||
| 28 | + $td->NORMALIZE_NEWLINES); | ||
| 27 | 29 | ||
| 28 | cleanup(); | 30 | cleanup(); |
| 29 | -$td->report($n_tests); | 31 | +$td->report(3); |
qpdf/test_driver.cc
| @@ -3275,6 +3275,33 @@ test_92(QPDF& pdf, char const* arg2) | @@ -3275,6 +3275,33 @@ test_92(QPDF& pdf, char const* arg2) | ||
| 3275 | assert(!root.isIndirect()); | 3275 | assert(!root.isIndirect()); |
| 3276 | } | 3276 | } |
| 3277 | 3277 | ||
| 3278 | +static void | ||
| 3279 | +test_93(QPDF& pdf, char const* arg2) | ||
| 3280 | +{ | ||
| 3281 | + // Test QPDFObjectHandle equality. Two QPDFObjectHandle objects | ||
| 3282 | + // are equal if they point to the same underlying object. | ||
| 3283 | + | ||
| 3284 | + auto trailer = pdf.getTrailer(); | ||
| 3285 | + auto root1 = trailer.getKey("/Root"); | ||
| 3286 | + auto root2 = pdf.getRoot(); | ||
| 3287 | + assert(root1 == root2); | ||
| 3288 | + auto oh1 = "<< /One /Two >>"_qpdf; | ||
| 3289 | + auto oh2 = oh1; | ||
| 3290 | + assert(oh1 == oh2); | ||
| 3291 | + auto oh3 = "<< /One /Two >>"_qpdf; | ||
| 3292 | + assert(oh1 != oh3); | ||
| 3293 | + oh2.replaceKey("/One", "/Three"_qpdf); | ||
| 3294 | + assert(oh1 == oh2); | ||
| 3295 | + assert(oh2.unparse() == "<< /One /Three >>"); | ||
| 3296 | + assert(!oh1.isIndirect()); | ||
| 3297 | + auto oh4 = pdf.makeIndirectObject(oh1); | ||
| 3298 | + assert(oh1 == oh4); | ||
| 3299 | + assert(oh1.isIndirect()); | ||
| 3300 | + assert(oh4.isIndirect()); | ||
| 3301 | + trailer.replaceKey("/Potato", oh1); | ||
| 3302 | + assert(trailer.getKey("/Potato") == oh2); | ||
| 3303 | +} | ||
| 3304 | + | ||
| 3278 | void | 3305 | void |
| 3279 | runtest(int n, char const* filename1, char const* arg2) | 3306 | runtest(int n, char const* filename1, char const* arg2) |
| 3280 | { | 3307 | { |
| @@ -3384,7 +3411,7 @@ runtest(int n, char const* filename1, char const* arg2) | @@ -3384,7 +3411,7 @@ runtest(int n, char const* filename1, char const* arg2) | ||
| 3384 | {80, test_80}, {81, test_81}, {82, test_82}, {83, test_83}, | 3411 | {80, test_80}, {81, test_81}, {82, test_82}, {83, test_83}, |
| 3385 | {84, test_84}, {85, test_85}, {86, test_86}, {87, test_87}, | 3412 | {84, test_84}, {85, test_85}, {86, test_86}, {87, test_87}, |
| 3386 | {88, test_88}, {89, test_89}, {90, test_90}, {91, test_91}, | 3413 | {88, test_88}, {89, test_89}, {90, test_90}, {91, test_91}, |
| 3387 | - {92, test_92}}; | 3414 | + {92, test_92}, {93, test_93}}; |
| 3388 | 3415 | ||
| 3389 | auto fn = test_functions.find(n); | 3416 | auto fn = test_functions.find(n); |
| 3390 | if (fn == test_functions.end()) { | 3417 | if (fn == test_functions.end()) { |