Commit 1c14a9e6c49e43aa95f564a89c4456f14c450546
Committed by
GitHub
Merge pull request #959 from m-holger/reserved
Add new method QPDF::newReserved()
Showing
4 changed files
with
33 additions
and
5 deletions
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 |