Commit 1c14a9e6c49e43aa95f564a89c4456f14c450546

Authored by Jay Berkenbilt
Committed by GitHub
2 parents 77cc9659 05a49cec

Merge pull request #959 from m-holger/reserved

Add new method QPDF::newReserved()
include/qpdf/QPDF.hh
@@ -413,6 +413,24 @@ class QPDF @@ -413,6 +413,24 @@ class QPDF
413 QPDF_DLL 413 QPDF_DLL
414 QPDFObjectHandle newStream(std::string const& data); 414 QPDFObjectHandle newStream(std::string const& data);
415 415
  416 + // A reserved object is a special sentinel used for qpdf to
  417 + // reserve a spot for an object that is going to be added to the
  418 + // QPDF object. Normally you don't have to use this type since
  419 + // you can just call QPDF::makeIndirectObject. However, in some
  420 + // cases, if you have to create objects with circular references,
  421 + // you may need to create a reserved object so that you can have a
  422 + // reference to it and then replace the object later. Reserved
  423 + // objects have the special property that they can't be resolved
  424 + // to direct objects. This makes it possible to replace a
  425 + // reserved object with a new object while preserving existing
  426 + // references to them. When you are ready to replace a reserved
  427 + // object with its replacement, use QPDF::replaceReserved for this
  428 + // purpose rather than the more general QPDF::replaceObject. It
  429 + // is an error to try to write a QPDF with QPDFWriter if it has
  430 + // any reserved objects in it.
  431 + QPDF_DLL
  432 + QPDFObjectHandle newReserved();
  433 +
416 // Install this object handle as an indirect object and return an 434 // Install this object handle as an indirect object and return an
417 // indirect reference to it. 435 // indirect reference to it.
418 QPDF_DLL 436 QPDF_DLL
include/qpdf/QPDFObjectHandle.hh
@@ -668,7 +668,8 @@ class QPDFObjectHandle @@ -668,7 +668,8 @@ class QPDFObjectHandle
668 // object with its replacement, use QPDF::replaceReserved for this 668 // object with its replacement, use QPDF::replaceReserved for this
669 // purpose rather than the more general QPDF::replaceObject. It 669 // purpose rather than the more general QPDF::replaceObject. It
670 // is an error to try to write a QPDF with QPDFWriter if it has 670 // is an error to try to write a QPDF with QPDFWriter if it has
671 - // any reserved objects in it. 671 + // any reserved objects in it. From QPDF 11.4, you can
  672 + // call QPDF::newReserved() instead.
672 QPDF_DLL 673 QPDF_DLL
673 static QPDFObjectHandle newReserved(QPDF* qpdf); 674 static QPDFObjectHandle newReserved(QPDF* qpdf);
674 675
libqpdf/QPDF.cc
@@ -1985,6 +1985,12 @@ QPDF::makeIndirectObject(QPDFObjectHandle oh) @@ -1985,6 +1985,12 @@ QPDF::makeIndirectObject(QPDFObjectHandle oh)
1985 } 1985 }
1986 1986
1987 QPDFObjectHandle 1987 QPDFObjectHandle
  1988 +QPDF::newReserved()
  1989 +{
  1990 + return makeIndirectFromQPDFObject(QPDF_Reserved::create());
  1991 +}
  1992 +
  1993 +QPDFObjectHandle
1988 QPDF::newStream() 1994 QPDF::newStream()
1989 { 1995 {
1990 return makeIndirectFromQPDFObject(QPDF_Stream::create( 1996 return makeIndirectFromQPDFObject(QPDF_Stream::create(
@@ -2207,9 +2213,8 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) @@ -2207,9 +2213,8 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top)
2207 QTC::TC("qpdf", "QPDF copy indirect"); 2213 QTC::TC("qpdf", "QPDF copy indirect");
2208 if (obj_copier.object_map.count(foreign_og) == 0) { 2214 if (obj_copier.object_map.count(foreign_og) == 0) {
2209 obj_copier.to_copy.push_back(foreign); 2215 obj_copier.to_copy.push_back(foreign);
2210 - obj_copier.object_map[foreign_og] = foreign.isStream()  
2211 - ? newStream()  
2212 - : QPDFObjectHandle::newReserved(this); 2216 + obj_copier.object_map[foreign_og] =
  2217 + foreign.isStream() ? newStream() : newReserved();
2213 } 2218 }
2214 } 2219 }
2215 2220
libqpdf/QPDFObjectHandle.cc
@@ -2128,7 +2128,11 @@ QPDFObjectHandle::newStream(QPDF* qpdf, std::string const& data) @@ -2128,7 +2128,11 @@ QPDFObjectHandle::newStream(QPDF* qpdf, std::string const& data)
2128 QPDFObjectHandle 2128 QPDFObjectHandle
2129 QPDFObjectHandle::newReserved(QPDF* qpdf) 2129 QPDFObjectHandle::newReserved(QPDF* qpdf)
2130 { 2130 {
2131 - return qpdf->makeIndirectObject(QPDFObjectHandle(QPDF_Reserved::create())); 2131 + if (qpdf == nullptr) {
  2132 + throw std::runtime_error(
  2133 + "attempt to create reserved object in null qpdf object");
  2134 + }
  2135 + return qpdf->newReserved();
2132 } 2136 }
2133 2137
2134 void 2138 void