Commit 8a3cdfd2af4a95d8daede45bcb36eecdcdc8f964

Authored by Jay Berkenbilt
1 parent 910a373a

Change QPDFObjectHandle == to isSameObjectAs

Replace operator== and operator!=, which were testing for the same
underlying object, with isSameObjectAs. This change was motivated by
the fact that pikepdf internally had its own operator== method for
QPDFObjectHandle that did structural comparison. I backed out qpdf's
operator== as a courtesy to pikepdf (in my own testing) but also
because I think people might naturally assume that operator== does a
structural comparison, and isSameObjectAs is clearer in its intent.
ChangeLog
1 2022-09-09 Jay Berkenbilt <ejb@ql.org> 1 2022-09-09 Jay Berkenbilt <ejb@ql.org>
2 2
  3 + * Add QPDFObjectHandle::isSameObjectAs to test whether two
  4 + QPDFObjectHandle objects point to the same underlying object.
  5 +
3 * Expose ability to create custom loggers and to get and set the 6 * Expose ability to create custom loggers and to get and set the
4 logger for QPDF and QPDFJob through the C API. 7 logger for QPDF and QPDFJob through the C API.
5 8
@@ -29,10 +32,6 @@ @@ -29,10 +32,6 @@
29 * Add new methods getArtBox and getBleedBox to 32 * Add new methods getArtBox and getBleedBox to
30 QPDFPageObjectHelper, completing the set of bounding box methods. 33 QPDFPageObjectHelper, completing the set of bounding box methods.
31 34
32 - * Add == equality for QPDFObjectHandle. Two QPDFObjectHandle  
33 - objects are equal if they point to the same underlying object,  
34 - meaning changes to one will be reflected in the other.  
35 -  
36 * The --show-encryption option now works even if a correct 35 * The --show-encryption option now works even if a correct
37 password is not supplied. If you were using --show-encryption to 36 password is not supplied. If you were using --show-encryption to
38 test whether you have the right password, use --requires-password 37 test whether you have the right password, use --requires-password
include/qpdf/QPDFObjectHandle.hh
@@ -334,14 +334,13 @@ class QPDFObjectHandle @@ -334,14 +334,13 @@ 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." 337 + // This method returns true if the QPDFObjectHandle objects point
  338 + // to exactly the same underlying object, meaning that changes to
  339 + // one are reflected in the other, or "if you paint one, the other
  340 + // one changes color." This does not perform a structural
  341 + // comparison of the contents of the objects.
341 QPDF_DLL 342 QPDF_DLL
342 - bool operator==(QPDFObjectHandle const&) const;  
343 - QPDF_DLL  
344 - bool operator!=(QPDFObjectHandle const&) const; 343 + bool isSameObjectAs(QPDFObjectHandle const&) const;
345 344
346 // Return type code and type name of underlying object. These are 345 // Return type code and type name of underlying object. These are
347 // useful for doing rapid type tests (like switch statements) or 346 // useful for doing rapid type tests (like switch statements) or
libqpdf/QPDFObjectHandle.cc
@@ -237,17 +237,11 @@ LastChar::getLastChar() @@ -237,17 +237,11 @@ LastChar::getLastChar()
237 } 237 }
238 238
239 bool 239 bool
240 -QPDFObjectHandle::operator==(QPDFObjectHandle const& rhs) const 240 +QPDFObjectHandle::isSameObjectAs(QPDFObjectHandle const& rhs) const
241 { 241 {
242 return this->obj == rhs.obj; 242 return this->obj == rhs.obj;
243 } 243 }
244 244
245 -bool  
246 -QPDFObjectHandle::operator!=(QPDFObjectHandle const& rhs) const  
247 -{  
248 - return this->obj != rhs.obj;  
249 -}  
250 -  
251 void 245 void
252 QPDFObjectHandle::disconnect() 246 QPDFObjectHandle::disconnect()
253 { 247 {
manual/release-notes.rst
@@ -231,12 +231,12 @@ For a detailed list of changes, please see the file @@ -231,12 +231,12 @@ For a detailed list of changes, please see the file
231 still valid, but it's also possible to have direct objects that 231 still valid, but it's also possible to have direct objects that
232 don't have an owning ``QPDF``. 232 don't have an owning ``QPDF``.
233 233
234 - - It is now possible to test ``QPDFObjectHandle`` equality with  
235 - ``==`` and ``!=``. Two ``QPDFObjectHandle`` objects are equal if  
236 - they point to the same underlying object, meaning changes to one  
237 - will be reflected in the other. Note that this method does not  
238 - compare the contents of the objects, so two distinct but  
239 - structurally identical objects will not be considered equal. 234 + - Add method ``QPDFObjectHandle::isSameObjectAs`` for testing
  235 + whether two ``QPDFObjectHandle`` objects point to the same
  236 + underlying object, meaning changes to one will be reflected in
  237 + the other. Note that this method does not compare the contents
  238 + of the objects, so two distinct but structurally identical
  239 + objects will not be considered the same object.
240 240
241 - New factory method ``QPDF::create()`` returns a 241 - New factory method ``QPDF::create()`` returns a
242 ``std::shared_ptr<QPDF>``. 242 ``std::shared_ptr<QPDF>``.
qpdf/test_driver.cc
@@ -3340,22 +3340,22 @@ test_93(QPDF&amp; pdf, char const* arg2) @@ -3340,22 +3340,22 @@ test_93(QPDF&amp; pdf, char const* arg2)
3340 auto trailer = pdf.getTrailer(); 3340 auto trailer = pdf.getTrailer();
3341 auto root1 = trailer.getKey("/Root"); 3341 auto root1 = trailer.getKey("/Root");
3342 auto root2 = pdf.getRoot(); 3342 auto root2 = pdf.getRoot();
3343 - assert(root1 == root2); 3343 + assert(root1.isSameObjectAs(root2));
3344 auto oh1 = "<< /One /Two >>"_qpdf; 3344 auto oh1 = "<< /One /Two >>"_qpdf;
3345 auto oh2 = oh1; 3345 auto oh2 = oh1;
3346 - assert(oh1 == oh2); 3346 + assert(oh1.isSameObjectAs(oh2));
3347 auto oh3 = "<< /One /Two >>"_qpdf; 3347 auto oh3 = "<< /One /Two >>"_qpdf;
3348 - assert(oh1 != oh3); 3348 + assert(!oh1.isSameObjectAs(oh3));
3349 oh2.replaceKey("/One", "/Three"_qpdf); 3349 oh2.replaceKey("/One", "/Three"_qpdf);
3350 - assert(oh1 == oh2); 3350 + assert(oh1.isSameObjectAs(oh2));
3351 assert(oh2.unparse() == "<< /One /Three >>"); 3351 assert(oh2.unparse() == "<< /One /Three >>");
3352 assert(!oh1.isIndirect()); 3352 assert(!oh1.isIndirect());
3353 auto oh4 = pdf.makeIndirectObject(oh1); 3353 auto oh4 = pdf.makeIndirectObject(oh1);
3354 - assert(oh1 == oh4); 3354 + assert(oh1.isSameObjectAs(oh4));
3355 assert(oh1.isIndirect()); 3355 assert(oh1.isIndirect());
3356 assert(oh4.isIndirect()); 3356 assert(oh4.isIndirect());
3357 trailer.replaceKey("/Potato", oh1); 3357 trailer.replaceKey("/Potato", oh1);
3358 - assert(trailer.getKey("/Potato") == oh2); 3358 + assert(trailer.getKey("/Potato").isSameObjectAs(oh2));
3359 } 3359 }
3360 3360
3361 static void 3361 static void
@@ -3385,76 +3385,76 @@ test_94(QPDF&amp; pdf, char const* arg2) @@ -3385,76 +3385,76 @@ test_94(QPDF&amp; pdf, char const* arg2)
3385 3385
3386 assert(p1.getObjectHandle().getKey("/MediaBox").isNull()); 3386 assert(p1.getObjectHandle().getKey("/MediaBox").isNull());
3387 // MediaBox not present, so get inherited one 3387 // MediaBox not present, so get inherited one
3388 - assert(p1.getMediaBox(false) == root_media); 3388 + assert(p1.getMediaBox(false).isSameObjectAs(root_media));
3389 // Other boxesBox not present, so fall back to MediaBox 3389 // Other boxesBox not present, so fall back to MediaBox
3390 - assert(p1.getCropBox(false, false) == root_media);  
3391 - assert(p1.getBleedBox(false, false) == root_media);  
3392 - assert(p1.getTrimBox(false, false) == root_media);  
3393 - assert(p1.getArtBox(false, false) == root_media); 3390 + assert(p1.getCropBox(false, false).isSameObjectAs(root_media));
  3391 + assert(p1.getBleedBox(false, false).isSameObjectAs(root_media));
  3392 + assert(p1.getTrimBox(false, false).isSameObjectAs(root_media));
  3393 + assert(p1.getArtBox(false, false).isSameObjectAs(root_media));
3394 // Make copy of artbox 3394 // Make copy of artbox
3395 auto p1_new_art = p1.getArtBox(false, true); 3395 auto p1_new_art = p1.getArtBox(false, true);
3396 assert(p1_new_art.unparse() == root_media_unparse); 3396 assert(p1_new_art.unparse() == root_media_unparse);
3397 - assert(p1_new_art != root_media); 3397 + assert(!p1_new_art.isSameObjectAs(root_media));
3398 // This also copied cropbox 3398 // This also copied cropbox
3399 auto p1_new_crop = p1.getCropBox(false, false); 3399 auto p1_new_crop = p1.getCropBox(false, false);
3400 - assert(p1_new_crop != root_media);  
3401 - assert(p1_new_crop != p1_new_art); 3400 + assert(!p1_new_crop.isSameObjectAs(root_media));
  3401 + assert(!p1_new_crop.isSameObjectAs(p1_new_art));
3402 assert(p1_new_crop.unparse() == root_media_unparse); 3402 assert(p1_new_crop.unparse() == root_media_unparse);
3403 // But it didn't copy Media 3403 // But it didn't copy Media
3404 - assert(p1.getMediaBox(false) == root_media); 3404 + assert(p1.getMediaBox(false).isSameObjectAs(root_media));
3405 // Now fall back to new crop 3405 // Now fall back to new crop
3406 - assert(p1.getTrimBox(false, false) == p1_new_crop); 3406 + assert(p1.getTrimBox(false, false).isSameObjectAs(p1_new_crop));
3407 // Request copy. The value returned has the same structure but is 3407 // Request copy. The value returned has the same structure but is
3408 // a different object. 3408 // a different object.
3409 auto p1_effective_media = p1.getMediaBox(true); 3409 auto p1_effective_media = p1.getMediaBox(true);
3410 assert(p1_effective_media.unparse() == root_media_unparse); 3410 assert(p1_effective_media.unparse() == root_media_unparse);
3411 - assert(p1_effective_media != root_media); 3411 + assert(!p1_effective_media.isSameObjectAs(root_media));
3412 3412
3413 // copy_on_fallback didn't have to copy media to crop 3413 // copy_on_fallback didn't have to copy media to crop
3414 - assert(p2.getMediaBox(false) == root_media); 3414 + assert(p2.getMediaBox(false).isSameObjectAs(root_media));
3415 auto p2_crop = p2.getCropBox(false, false); 3415 auto p2_crop = p2.getCropBox(false, false);
3416 auto p2_new_trim = p2.getTrimBox(false, true); 3416 auto p2_new_trim = p2.getTrimBox(false, true);
3417 assert(p2_new_trim.unparse() == p2_crop.unparse()); 3417 assert(p2_new_trim.unparse() == p2_crop.unparse());
3418 - assert(p2_new_trim != p2_crop);  
3419 - assert(p2.getMediaBox(false) == root_media); 3418 + assert(!p2_new_trim.isSameObjectAs(p2_crop));
  3419 + assert(p2.getMediaBox(false).isSameObjectAs(root_media));
3420 3420
3421 // We didn't need to copy anything 3421 // We didn't need to copy anything
3422 auto p3_media = p3.getMediaBox(false); 3422 auto p3_media = p3.getMediaBox(false);
3423 auto p3_crop = p3.getCropBox(false, false); 3423 auto p3_crop = p3.getCropBox(false, false);
3424 - assert(p3.getMediaBox(true) == p3_media);  
3425 - assert(p3.getCropBox(true, true) == p3_crop); 3424 + assert(p3.getMediaBox(true).isSameObjectAs(p3_media));
  3425 + assert(p3.getCropBox(true, true).isSameObjectAs(p3_crop));
3426 3426
3427 // We didn't have to copy for bleed but we did for art 3427 // We didn't have to copy for bleed but we did for art
3428 auto p4_orig_crop = p4.getObjectHandle().getKey("/CropBox"); 3428 auto p4_orig_crop = p4.getObjectHandle().getKey("/CropBox");
3429 auto p4_crop = p4.getCropBox(false, false); 3429 auto p4_crop = p4.getCropBox(false, false);
3430 - assert(p4_orig_crop == p4_crop); 3430 + assert(p4_orig_crop.isSameObjectAs(p4_crop));
3431 auto p4_bleed1 = p4.getBleedBox(false, false); 3431 auto p4_bleed1 = p4.getBleedBox(false, false);
3432 auto p4_bleed2 = p4.getBleedBox(false, true); 3432 auto p4_bleed2 = p4.getBleedBox(false, true);
3433 - assert(p4_bleed1 != p4_crop);  
3434 - assert(p4_bleed1 == p4_bleed2); 3433 + assert(!p4_bleed1.isSameObjectAs(p4_crop));
  3434 + assert(p4_bleed1.isSameObjectAs(p4_bleed2));
3435 auto p4_art1 = p4.getArtBox(false, false); 3435 auto p4_art1 = p4.getArtBox(false, false);
3436 - assert(p4_art1 == p4_crop); 3436 + assert(p4_art1.isSameObjectAs(p4_crop));
3437 auto p4_art2 = p4.getArtBox(false, true); 3437 auto p4_art2 = p4.getArtBox(false, true);
3438 - assert(p4_art2 != p4_crop); 3438 + assert(!p4_art2.isSameObjectAs(p4_crop));
3439 auto p4_new_crop = p4.getCropBox(true, false); 3439 auto p4_new_crop = p4.getCropBox(true, false);
3440 - assert(p4_new_crop != p4_orig_crop); 3440 + assert(!p4_new_crop.isSameObjectAs(p4_orig_crop));
3441 assert(p4_orig_crop.isIndirect()); 3441 assert(p4_orig_crop.isIndirect());
3442 assert(!p4_new_crop.isIndirect()); 3442 assert(!p4_new_crop.isIndirect());
3443 assert(p4_new_crop.unparse() == p4_orig_crop.unparseResolved()); 3443 assert(p4_new_crop.unparse() == p4_orig_crop.unparseResolved());
3444 3444
3445 // Exercise copying for inheritance and fallback 3445 // Exercise copying for inheritance and fallback
3446 - assert(p5.getMediaBox(false) == root_media);  
3447 - assert(p5.getCropBox(false, false) == root_media);  
3448 - assert(p5.getBleedBox(false, false) == root_media); 3446 + assert(p5.getMediaBox(false).isSameObjectAs(root_media));
  3447 + assert(p5.getCropBox(false, false).isSameObjectAs(root_media));
  3448 + assert(p5.getBleedBox(false, false).isSameObjectAs(root_media));
3449 auto p5_new_bleed = p5.getBleedBox(true, true); 3449 auto p5_new_bleed = p5.getBleedBox(true, true);
3450 auto p5_new_media = p5.getMediaBox(false); 3450 auto p5_new_media = p5.getMediaBox(false);
3451 auto p5_new_crop = p5.getCropBox(false, false); 3451 auto p5_new_crop = p5.getCropBox(false, false);
3452 - assert(p5_new_media != root_media);  
3453 - assert(p5_new_crop != root_media);  
3454 - assert(p5_new_crop != p5_new_media);  
3455 - assert(p5_new_bleed != root_media);  
3456 - assert(p5_new_bleed != p5_new_media);  
3457 - assert(p5_new_bleed != p5_new_crop); 3452 + assert(!p5_new_media.isSameObjectAs(root_media));
  3453 + assert(!p5_new_crop.isSameObjectAs(root_media));
  3454 + assert(!p5_new_crop.isSameObjectAs(p5_new_media));
  3455 + assert(!p5_new_bleed.isSameObjectAs(root_media));
  3456 + assert(!p5_new_bleed.isSameObjectAs(p5_new_media));
  3457 + assert(!p5_new_bleed.isSameObjectAs(p5_new_crop));
3458 assert(p5_new_media.unparse() == root_media_unparse); 3458 assert(p5_new_media.unparse() == root_media_unparse);
3459 assert(p5_new_crop.unparse() == root_media_unparse); 3459 assert(p5_new_crop.unparse() == root_media_unparse);
3460 assert(p5_new_bleed.unparse() == root_media_unparse); 3460 assert(p5_new_bleed.unparse() == root_media_unparse);