From c1def4ead4c578862ad6fcda35a9ca65be407893 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Tue, 6 Sep 2022 18:30:31 -0400 Subject: Implement QPDFObjectHandle equality --- ChangeLog | 4 ++++ include/qpdf/QPDFObjectHandle.hh | 9 +++++++++ libqpdf/QPDFObjectHandle.cc | 12 ++++++++++++ manual/release-notes.rst | 5 +++++ qpdf/qtest/object-handle-api.test | 8 +++++--- qpdf/test_driver.cc | 29 ++++++++++++++++++++++++++++- 6 files changed, 63 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index de16280e..6ce558d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2022-09-06 Jay Berkenbilt + * Add == equality for QPDFObjectHandle. Two QPDFObjectHandle + objects are equal if they point to the same underlying object, + meaning changes to one will be reflected in the other. + * The --show-encryption option now works even if a correct password is not supplied. If you were using --show-encryption to test whether you have the right password, use --requires-password diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index f26a7648..0730d8a3 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -334,6 +334,15 @@ class QPDFObjectHandle QPDF_DLL inline bool isInitialized() const; + // Two QPDFObjectHandle objects are equal if they point to exactly + // the same underlying object, meaning that changes to one are + // reflected in the other, or "if you paint one, the other one + // changes color." + QPDF_DLL + bool operator==(QPDFObjectHandle const&) const; + QPDF_DLL + bool operator!=(QPDFObjectHandle const&) const; + // Return type code and type name of underlying object. These are // useful for doing rapid type tests (like switch statements) or // for testing and debugging. diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 838d389f..885abf3c 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -236,6 +236,18 @@ LastChar::getLastChar() return this->last_char; } +bool +QPDFObjectHandle::operator==(QPDFObjectHandle const& rhs) const +{ + return this->obj == rhs.obj; +} + +bool +QPDFObjectHandle::operator!=(QPDFObjectHandle const& rhs) const +{ + return this->obj != rhs.obj; +} + qpdf_object_type_e QPDFObjectHandle::getTypeCode() { diff --git a/manual/release-notes.rst b/manual/release-notes.rst index 60e90e12..d5ee4013 100644 --- a/manual/release-notes.rst +++ b/manual/release-notes.rst @@ -208,6 +208,11 @@ For a detailed list of changes, please see the file generally not happen for correct code, but at least the situation is detectible now. + - It is now possible to test ``QPDFObjectHandle`` equality with + ``==`` and ``!=``. Two ``QPDFObjectHandle`` objects are equal if + they point to the same underlying object, meaning changes to one + will be reflected in the other. + - Add new factory method ``QPDF::create()`` that returns a ``std::shared_ptr``. diff --git a/qpdf/qtest/object-handle-api.test b/qpdf/qtest/object-handle-api.test index 3de5f909..0d233bcc 100644 --- a/qpdf/qtest/object-handle-api.test +++ b/qpdf/qtest/object-handle-api.test @@ -14,8 +14,6 @@ cleanup(); my $td = new TestDriver('object-handle-api'); -my $n_tests = 2; - $td->runtest("dictionary keys", {$td->COMMAND => "test_driver 87 - -"}, {$td->STRING => "test 87 done\n", $td->EXIT_STATUS => 0}, @@ -24,6 +22,10 @@ $td->runtest("fluent interfaces", {$td->COMMAND => "test_driver 88 minimal.pdf -"}, {$td->FILE => "test88.out", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); +$td->runtest("equality", + {$td->COMMAND => "test_driver 93 minimal.pdf -"}, + {$td->STRING => "test 93 done\n", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); cleanup(); -$td->report($n_tests); +$td->report(3); diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc index 16b65d8d..812d6c07 100644 --- a/qpdf/test_driver.cc +++ b/qpdf/test_driver.cc @@ -3275,6 +3275,33 @@ test_92(QPDF& pdf, char const* arg2) assert(!root.isIndirect()); } +static void +test_93(QPDF& pdf, char const* arg2) +{ + // Test QPDFObjectHandle equality. Two QPDFObjectHandle objects + // are equal if they point to the same underlying object. + + auto trailer = pdf.getTrailer(); + auto root1 = trailer.getKey("/Root"); + auto root2 = pdf.getRoot(); + assert(root1 == root2); + auto oh1 = "<< /One /Two >>"_qpdf; + auto oh2 = oh1; + assert(oh1 == oh2); + auto oh3 = "<< /One /Two >>"_qpdf; + assert(oh1 != oh3); + oh2.replaceKey("/One", "/Three"_qpdf); + assert(oh1 == oh2); + assert(oh2.unparse() == "<< /One /Three >>"); + assert(!oh1.isIndirect()); + auto oh4 = pdf.makeIndirectObject(oh1); + assert(oh1 == oh4); + assert(oh1.isIndirect()); + assert(oh4.isIndirect()); + trailer.replaceKey("/Potato", oh1); + assert(trailer.getKey("/Potato") == oh2); +} + void runtest(int n, char const* filename1, char const* arg2) { @@ -3384,7 +3411,7 @@ runtest(int n, char const* filename1, char const* arg2) {80, test_80}, {81, test_81}, {82, test_82}, {83, test_83}, {84, test_84}, {85, test_85}, {86, test_86}, {87, test_87}, {88, test_88}, {89, test_89}, {90, test_90}, {91, test_91}, - {92, test_92}}; + {92, test_92}, {93, test_93}}; auto fn = test_functions.find(n); if (fn == test_functions.end()) { -- cgit v1.2.3-54-g00ecf