Commit c1def4ead4c578862ad6fcda35a9ca65be407893

Authored by Jay Berkenbilt
1 parent d12734d7

Implement QPDFObjectHandle equality

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-&gt;runtest(&quot;fluent interfaces&quot;, @@ -24,6 +22,10 @@ $td-&gt;runtest(&quot;fluent interfaces&quot;,
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&amp; pdf, char const* arg2) @@ -3275,6 +3275,33 @@ test_92(QPDF&amp; 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()) {