Commit 56f1b411feeb58b55e92ee77daffaa49c51b7dad
1 parent
7e7a9c43
Back out fluent QPDFObjectHandle methods. Keep the andGet methods.
I decided these were confusing and inconsistent with how JSON works. They muddle the API rather than improving it.
Showing
16 changed files
with
149 additions
and
164 deletions
ChangeLog
| ... | ... | @@ -86,15 +86,12 @@ |
| 86 | 86 | 2022-04-29 Jay Berkenbilt <ejb@ql.org> |
| 87 | 87 | |
| 88 | 88 | * QPDFObjectHandle: for the methods insertItem, appendItem, |
| 89 | - eraseItem, replaceKey, and removeKey, have the methods return a | |
| 90 | - reference to the original object, making a fluent interface to | |
| 91 | - initializing or modifying QPDFObjectHandle possible. Also, for | |
| 92 | - each one, add a corresponding "AndGet" method (insertItemAndGet, | |
| 93 | - appendItemAndGet, eraseItemAndGet, replaceKeyAndGet, and | |
| 94 | - removeKeyAndGet) that returns the newly inserted, replaced, or | |
| 95 | - removed item. This makes it possible to create a new object, add | |
| 96 | - it to an array or dictionary, and get a handle to it all in one | |
| 97 | - line. | |
| 89 | + eraseItem, replaceKey, and removeKey, add a corresponding "AndGet" | |
| 90 | + method (insertItemAndGet, appendItemAndGet, eraseItemAndGet, | |
| 91 | + replaceKeyAndGet, and removeKeyAndGet) that returns the newly | |
| 92 | + inserted, replaced, or removed item. This makes it possible to | |
| 93 | + create a new object, add it to an array or dictionary, and get a | |
| 94 | + handle to it all in one line. | |
| 98 | 95 | |
| 99 | 96 | 2022-04-24 Jay Berkenbilt <ejb@ql.org> |
| 100 | 97 | ... | ... |
examples/pdf-attach-file.cc
| ... | ... | @@ -106,10 +106,10 @@ process( |
| 106 | 106 | // apdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject")); |
| 107 | 107 | // apdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form")); |
| 108 | 108 | // apdict.replaceKey("/BBox", QPDFObjectHandle::parse("[ 0 0 20 20 ]")); |
| 109 | - apdict.replaceKey("/Resources", "<< >>"_qpdf) | |
| 110 | - .replaceKey("/Type", "/XObject"_qpdf) | |
| 111 | - .replaceKey("/Subtype", "/Form"_qpdf) | |
| 112 | - .replaceKey("/BBox", "[ 0 0 20 20 ]"_qpdf); | |
| 109 | + apdict.replaceKey("/Resources", "<< >>"_qpdf); | |
| 110 | + apdict.replaceKey("/Type", "/XObject"_qpdf); | |
| 111 | + apdict.replaceKey("/Subtype", "/Form"_qpdf); | |
| 112 | + apdict.replaceKey("/BBox", "[ 0 0 20 20 ]"_qpdf); | |
| 113 | 113 | auto annot = q.makeIndirectObject(QPDFObjectHandle::parse( |
| 114 | 114 | &q, |
| 115 | 115 | ("<<" | ... | ... |
examples/pdf-create.cc
| ... | ... | @@ -181,9 +181,9 @@ add_page( |
| 181 | 181 | " /Subtype /Image" |
| 182 | 182 | " /BitsPerComponent 8" |
| 183 | 183 | ">>"_qpdf; |
| 184 | - image_dict.replaceKey("/ColorSpace", newName(color_space)) | |
| 185 | - .replaceKey("/Width", newInteger(width)) | |
| 186 | - .replaceKey("/Height", newInteger(height)); | |
| 184 | + image_dict.replaceKey("/ColorSpace", newName(color_space)); | |
| 185 | + image_dict.replaceKey("/Width", newInteger(width)); | |
| 186 | + image_dict.replaceKey("/Height", newInteger(height)); | |
| 187 | 187 | image.replaceDict(image_dict); |
| 188 | 188 | |
| 189 | 189 | // Provide the stream data. |
| ... | ... | @@ -200,9 +200,9 @@ add_page( |
| 200 | 200 | xobject.replaceKey("/Im1", image); |
| 201 | 201 | |
| 202 | 202 | QPDFObjectHandle resources = QPDFObjectHandle::newDictionary(); |
| 203 | - resources.replaceKey("/ProcSet", procset) | |
| 204 | - .replaceKey("/Font", rfont) | |
| 205 | - .replaceKey("/XObject", xobject); | |
| 203 | + resources.replaceKey("/ProcSet", procset); | |
| 204 | + resources.replaceKey("/Font", rfont); | |
| 205 | + resources.replaceKey("/XObject", xobject); | |
| 206 | 206 | |
| 207 | 207 | // Create the page content stream |
| 208 | 208 | QPDFObjectHandle contents = |
| ... | ... | @@ -213,7 +213,8 @@ add_page( |
| 213 | 213 | " /Type /Page" |
| 214 | 214 | " /MediaBox [0 0 612 392]" |
| 215 | 215 | ">>"_qpdf); |
| 216 | - page.replaceKey("/Contents", contents).replaceKey("/Resources", resources); | |
| 216 | + page.replaceKey("/Contents", contents); | |
| 217 | + page.replaceKey("/Resources", resources); | |
| 217 | 218 | |
| 218 | 219 | // Add the page to the PDF file |
| 219 | 220 | dh.addPage(page, false); | ... | ... |
include/qpdf/QPDFObjectHandle.hh
| ... | ... | @@ -1024,25 +1024,22 @@ class QPDFObjectHandle |
| 1024 | 1024 | void setArrayFromVector(std::vector<QPDFObjectHandle> const& items); |
| 1025 | 1025 | // Insert an item before the item at the given position ("at") so |
| 1026 | 1026 | // that it has that position after insertion. If "at" is equal to |
| 1027 | - // the size of the array, insert the item at the end. Return a | |
| 1028 | - // reference to the array (not the new item). | |
| 1027 | + // the size of the array, insert the item at the end. | |
| 1029 | 1028 | QPDF_DLL |
| 1030 | - QPDFObjectHandle& insertItem(int at, QPDFObjectHandle const& item); | |
| 1029 | + void insertItem(int at, QPDFObjectHandle const& item); | |
| 1031 | 1030 | // Like insertItem but return the item that was inserted. |
| 1032 | 1031 | QPDF_DLL |
| 1033 | 1032 | QPDFObjectHandle insertItemAndGet(int at, QPDFObjectHandle const& item); |
| 1034 | - // Append an item, and return a reference to the original array | |
| 1035 | - // (not the new item). | |
| 1033 | + // Append an item to an array. | |
| 1036 | 1034 | QPDF_DLL |
| 1037 | - QPDFObjectHandle& appendItem(QPDFObjectHandle const& item); | |
| 1035 | + void appendItem(QPDFObjectHandle const& item); | |
| 1038 | 1036 | // Append an item, and return the newly added item. |
| 1039 | 1037 | QPDF_DLL |
| 1040 | 1038 | QPDFObjectHandle appendItemAndGet(QPDFObjectHandle const& item); |
| 1041 | 1039 | // Remove the item at that position, reducing the size of the |
| 1042 | - // array by one. Return a reference the original array (not the | |
| 1043 | - // item that was removed). | |
| 1040 | + // array by one. | |
| 1044 | 1041 | QPDF_DLL |
| 1045 | - QPDFObjectHandle& eraseItem(int at); | |
| 1042 | + void eraseItem(int at); | |
| 1046 | 1043 | // Erase and item and return the item that was removed. |
| 1047 | 1044 | QPDF_DLL |
| 1048 | 1045 | QPDFObjectHandle eraseItemAndGet(int at); |
| ... | ... | @@ -1050,19 +1047,16 @@ class QPDFObjectHandle |
| 1050 | 1047 | // Mutator methods for dictionary objects |
| 1051 | 1048 | |
| 1052 | 1049 | // Replace value of key, adding it if it does not exist. If value |
| 1053 | - // is null, remove the key. Return a reference to the original | |
| 1054 | - // dictionary (not the new item). | |
| 1050 | + // is null, remove the key. | |
| 1055 | 1051 | QPDF_DLL |
| 1056 | - QPDFObjectHandle& | |
| 1057 | - replaceKey(std::string const& key, QPDFObjectHandle const& value); | |
| 1052 | + void replaceKey(std::string const& key, QPDFObjectHandle const& value); | |
| 1058 | 1053 | // Replace value of key and return the value. |
| 1059 | 1054 | QPDF_DLL |
| 1060 | 1055 | QPDFObjectHandle |
| 1061 | 1056 | replaceKeyAndGet(std::string const& key, QPDFObjectHandle const& value); |
| 1062 | - // Remove key, doing nothing if key does not exist. Return the | |
| 1063 | - // original dictionary (not the removed item). | |
| 1057 | + // Remove key, doing nothing if key does not exist. | |
| 1064 | 1058 | QPDF_DLL |
| 1065 | - QPDFObjectHandle& removeKey(std::string const& key); | |
| 1059 | + void removeKey(std::string const& key); | |
| 1066 | 1060 | // Remove key and return the old value. If the old value didn't |
| 1067 | 1061 | // exist, return a null object. |
| 1068 | 1062 | QPDF_DLL | ... | ... |
libqpdf/NNTree.cc
| ... | ... | @@ -208,8 +208,9 @@ NNTreeIterator::resetLimits( |
| 208 | 208 | } |
| 209 | 209 | } |
| 210 | 210 | if (first.isInitialized() && last.isInitialized()) { |
| 211 | - auto limits = | |
| 212 | - QPDFObjectHandle::newArray().appendItem(first).appendItem(last); | |
| 211 | + auto limits = QPDFObjectHandle::newArray(); | |
| 212 | + limits.appendItem(first); | |
| 213 | + limits.appendItem(last); | |
| 213 | 214 | auto olimits = node.getKey("/Limits"); |
| 214 | 215 | if (olimits.isArray() && (olimits.getArrayNItems() == 2)) { |
| 215 | 216 | auto ofirst = olimits.getArrayItem(0); |
| ... | ... | @@ -340,10 +341,9 @@ NNTreeIterator::split( |
| 340 | 341 | first_node.replaceKey(key, first_half); |
| 341 | 342 | QPDFObjectHandle new_kids = QPDFObjectHandle::newArray(); |
| 342 | 343 | new_kids.appendItem(first_node); |
| 343 | - to_split | |
| 344 | - .removeKey("/Limits") // already shouldn't be there for root | |
| 345 | - .removeKey(impl.details.itemsKey()) | |
| 346 | - .replaceKey("/Kids", new_kids); | |
| 344 | + to_split.removeKey("/Limits"); // already shouldn't be there for root | |
| 345 | + to_split.removeKey(impl.details.itemsKey()); | |
| 346 | + to_split.replaceKey("/Kids", new_kids); | |
| 347 | 347 | if (is_leaf) { |
| 348 | 348 | QTC::TC("qpdf", "NNTree split root + leaf"); |
| 349 | 349 | this->node = first_node; |
| ... | ... | @@ -884,8 +884,9 @@ NNTreeImpl::repair() |
| 884 | 884 | for (auto const& i: *this) { |
| 885 | 885 | repl.insert(i.first, i.second); |
| 886 | 886 | } |
| 887 | - this->oh.replaceKey("/Kids", new_node.getKey("/Kids")) | |
| 888 | - .replaceKey(details.itemsKey(), new_node.getKey(details.itemsKey())); | |
| 887 | + this->oh.replaceKey("/Kids", new_node.getKey("/Kids")); | |
| 888 | + this->oh.replaceKey( | |
| 889 | + details.itemsKey(), new_node.getKey(details.itemsKey())); | |
| 889 | 890 | } |
| 890 | 891 | |
| 891 | 892 | NNTreeImpl::iterator | ... | ... |
libqpdf/QPDFAcroFormDocumentHelper.cc
| ... | ... | @@ -733,7 +733,8 @@ QPDFAcroFormDocumentHelper::adjustAppearanceStream( |
| 733 | 733 | auto existing_old = subdict.getKey(old_key); |
| 734 | 734 | if (!existing_old.isNull()) { |
| 735 | 735 | QTC::TC("qpdf", "QPDFAcroFormDocumentHelper ap rename"); |
| 736 | - subdict.replaceKey(new_key, existing_old).removeKey(old_key); | |
| 736 | + subdict.replaceKey(new_key, existing_old); | |
| 737 | + subdict.removeKey(old_key); | |
| 737 | 738 | } |
| 738 | 739 | } |
| 739 | 740 | } | ... | ... |
libqpdf/QPDFFileSpecObjectHelper.cc
| ... | ... | @@ -103,8 +103,8 @@ QPDFFileSpecObjectHelper::createFileSpec( |
| 103 | 103 | QPDFFileSpecObjectHelper result(oh); |
| 104 | 104 | result.setFilename(filename); |
| 105 | 105 | auto ef = QPDFObjectHandle::newDictionary(); |
| 106 | - ef.replaceKey("/F", efsoh.getObjectHandle()) | |
| 107 | - .replaceKey("/UF", efsoh.getObjectHandle()); | |
| 106 | + ef.replaceKey("/F", efsoh.getObjectHandle()); | |
| 107 | + ef.replaceKey("/UF", efsoh.getObjectHandle()); | |
| 108 | 108 | oh.replaceKey("/EF", ef); |
| 109 | 109 | return result; |
| 110 | 110 | } | ... | ... |
libqpdf/QPDFObjectHandle.cc
| ... | ... | @@ -959,7 +959,7 @@ QPDFObjectHandle::setArrayFromVector(std::vector<QPDFObjectHandle> const& items) |
| 959 | 959 | } |
| 960 | 960 | } |
| 961 | 961 | |
| 962 | -QPDFObjectHandle& | |
| 962 | +void | |
| 963 | 963 | QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item) |
| 964 | 964 | { |
| 965 | 965 | if (isArray()) { |
| ... | ... | @@ -968,7 +968,6 @@ QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item) |
| 968 | 968 | typeWarning("array", "ignoring attempt to insert item"); |
| 969 | 969 | QTC::TC("qpdf", "QPDFObjectHandle array ignoring insert item"); |
| 970 | 970 | } |
| 971 | - return *this; | |
| 972 | 971 | } |
| 973 | 972 | |
| 974 | 973 | QPDFObjectHandle |
| ... | ... | @@ -978,7 +977,7 @@ QPDFObjectHandle::insertItemAndGet(int at, QPDFObjectHandle const& item) |
| 978 | 977 | return item; |
| 979 | 978 | } |
| 980 | 979 | |
| 981 | -QPDFObjectHandle& | |
| 980 | +void | |
| 982 | 981 | QPDFObjectHandle::appendItem(QPDFObjectHandle const& item) |
| 983 | 982 | { |
| 984 | 983 | if (isArray()) { |
| ... | ... | @@ -988,7 +987,6 @@ QPDFObjectHandle::appendItem(QPDFObjectHandle const& item) |
| 988 | 987 | typeWarning("array", "ignoring attempt to append item"); |
| 989 | 988 | QTC::TC("qpdf", "QPDFObjectHandle array ignoring append item"); |
| 990 | 989 | } |
| 991 | - return *this; | |
| 992 | 990 | } |
| 993 | 991 | |
| 994 | 992 | QPDFObjectHandle |
| ... | ... | @@ -998,7 +996,7 @@ QPDFObjectHandle::appendItemAndGet(QPDFObjectHandle const& item) |
| 998 | 996 | return item; |
| 999 | 997 | } |
| 1000 | 998 | |
| 1001 | -QPDFObjectHandle& | |
| 999 | +void | |
| 1002 | 1000 | QPDFObjectHandle::eraseItem(int at) |
| 1003 | 1001 | { |
| 1004 | 1002 | if (isArray() && (at < getArrayNItems()) && (at >= 0)) { |
| ... | ... | @@ -1012,7 +1010,6 @@ QPDFObjectHandle::eraseItem(int at) |
| 1012 | 1010 | QTC::TC("qpdf", "QPDFObjectHandle array ignoring erase item"); |
| 1013 | 1011 | } |
| 1014 | 1012 | } |
| 1015 | - return *this; | |
| 1016 | 1013 | } |
| 1017 | 1014 | |
| 1018 | 1015 | QPDFObjectHandle |
| ... | ... | @@ -1289,7 +1286,7 @@ QPDFObjectHandle::getOwningQPDF() |
| 1289 | 1286 | |
| 1290 | 1287 | // Dictionary mutators |
| 1291 | 1288 | |
| 1292 | -QPDFObjectHandle& | |
| 1289 | +void | |
| 1293 | 1290 | QPDFObjectHandle::replaceKey( |
| 1294 | 1291 | std::string const& key, QPDFObjectHandle const& value) |
| 1295 | 1292 | { |
| ... | ... | @@ -1300,7 +1297,6 @@ QPDFObjectHandle::replaceKey( |
| 1300 | 1297 | typeWarning("dictionary", "ignoring key replacement request"); |
| 1301 | 1298 | QTC::TC("qpdf", "QPDFObjectHandle dictionary ignoring replaceKey"); |
| 1302 | 1299 | } |
| 1303 | - return *this; | |
| 1304 | 1300 | } |
| 1305 | 1301 | |
| 1306 | 1302 | QPDFObjectHandle |
| ... | ... | @@ -1311,7 +1307,7 @@ QPDFObjectHandle::replaceKeyAndGet( |
| 1311 | 1307 | return value; |
| 1312 | 1308 | } |
| 1313 | 1309 | |
| 1314 | -QPDFObjectHandle& | |
| 1310 | +void | |
| 1315 | 1311 | QPDFObjectHandle::removeKey(std::string const& key) |
| 1316 | 1312 | { |
| 1317 | 1313 | if (isDictionary()) { |
| ... | ... | @@ -1320,7 +1316,6 @@ QPDFObjectHandle::removeKey(std::string const& key) |
| 1320 | 1316 | typeWarning("dictionary", "ignoring key removal request"); |
| 1321 | 1317 | QTC::TC("qpdf", "QPDFObjectHandle dictionary ignoring removeKey"); |
| 1322 | 1318 | } |
| 1323 | - return *this; | |
| 1324 | 1319 | } |
| 1325 | 1320 | |
| 1326 | 1321 | QPDFObjectHandle | ... | ... |
libqpdf/QPDFPageLabelDocumentHelper.cc
| ... | ... | @@ -44,8 +44,9 @@ QPDFPageLabelDocumentHelper::getLabelForPage(long long page_idx) |
| 44 | 44 | QIntC::range_check(start, offset); |
| 45 | 45 | start += offset; |
| 46 | 46 | result = QPDFObjectHandle::newDictionary(); |
| 47 | - result.replaceKey("/S", S).replaceKey("/P", P).replaceKey( | |
| 48 | - "/St", QPDFObjectHandle::newInteger(start)); | |
| 47 | + result.replaceKey("/S", S); | |
| 48 | + result.replaceKey("/P", P); | |
| 49 | + result.replaceKey("/St", QPDFObjectHandle::newInteger(start)); | |
| 49 | 50 | return result; |
| 50 | 51 | } |
| 51 | 52 | ... | ... |
libqpdf/QPDFPageObjectHelper.cc
| ... | ... | @@ -78,8 +78,8 @@ QPDFObjectHandle |
| 78 | 78 | InlineImageTracker::convertIIDict(QPDFObjectHandle odict) |
| 79 | 79 | { |
| 80 | 80 | QPDFObjectHandle dict = QPDFObjectHandle::newDictionary(); |
| 81 | - dict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject")) | |
| 82 | - .replaceKey("/Subtype", QPDFObjectHandle::newName("/Image")); | |
| 81 | + dict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject")); | |
| 82 | + dict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Image")); | |
| 83 | 83 | std::set<std::string> keys = odict.getKeys(); |
| 84 | 84 | for (auto key: keys) { |
| 85 | 85 | QPDFObjectHandle value = odict.getKey(key); |
| ... | ... | @@ -752,11 +752,11 @@ QPDFPageObjectHelper::getFormXObjectForPage(bool handle_transformations) |
| 752 | 752 | } |
| 753 | 753 | QPDFObjectHandle result = QPDFObjectHandle::newStream(qpdf); |
| 754 | 754 | QPDFObjectHandle newdict = result.getDict(); |
| 755 | - newdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject")) | |
| 756 | - .replaceKey("/Subtype", QPDFObjectHandle::newName("/Form")) | |
| 757 | - .replaceKey( | |
| 758 | - "/Resources", getAttribute("/Resources", false).shallowCopy()) | |
| 759 | - .replaceKey("/Group", getAttribute("/Group", false).shallowCopy()); | |
| 755 | + newdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject")); | |
| 756 | + newdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form")); | |
| 757 | + newdict.replaceKey( | |
| 758 | + "/Resources", getAttribute("/Resources", false).shallowCopy()); | |
| 759 | + newdict.replaceKey("/Group", getAttribute("/Group", false).shallowCopy()); | |
| 760 | 760 | QPDFObjectHandle bbox = getTrimBox(false).shallowCopy(); |
| 761 | 761 | if (!bbox.isRectangle()) { |
| 762 | 762 | this->oh.warnIfPossible("bounding box is invalid; form" | ... | ... |
libqpdf/QPDF_Stream.cc
| ... | ... | @@ -725,8 +725,8 @@ QPDF_Stream::replaceFilterData( |
| 725 | 725 | QPDFObjectHandle const& decode_parms, |
| 726 | 726 | size_t length) |
| 727 | 727 | { |
| 728 | - this->stream_dict.replaceKey("/Filter", filter) | |
| 729 | - .replaceKey("/DecodeParms", decode_parms); | |
| 728 | + this->stream_dict.replaceKey("/Filter", filter); | |
| 729 | + this->stream_dict.replaceKey("/DecodeParms", decode_parms); | |
| 730 | 730 | if (length == 0) { |
| 731 | 731 | QTC::TC("qpdf", "QPDF_Stream unknown stream length"); |
| 732 | 732 | this->stream_dict.removeKey("/Length"); | ... | ... |
libtests/nntree.cc
| ... | ... | @@ -62,15 +62,16 @@ test_bsearch() |
| 62 | 62 | auto mk = [&q](std::vector<int> const& v) { |
| 63 | 63 | auto nums = QPDFObjectHandle::newArray(); |
| 64 | 64 | for (auto i: v) { |
| 65 | - nums.appendItem(QPDFObjectHandle::newInteger(i)) | |
| 66 | - .appendItem(QPDFObjectHandle::newString( | |
| 67 | - "-" + QUtil::int_to_string(i) + "-")); | |
| 65 | + nums.appendItem(QPDFObjectHandle::newInteger(i)); | |
| 66 | + nums.appendItem(QPDFObjectHandle::newString( | |
| 67 | + "-" + QUtil::int_to_string(i) + "-")); | |
| 68 | 68 | } |
| 69 | 69 | auto limits = QPDFObjectHandle::newArray(); |
| 70 | - limits.appendItem(QPDFObjectHandle::newInteger(v.at(0))) | |
| 71 | - .appendItem(QPDFObjectHandle::newInteger(v.at(v.size() - 1))); | |
| 70 | + limits.appendItem(QPDFObjectHandle::newInteger(v.at(0))); | |
| 71 | + limits.appendItem(QPDFObjectHandle::newInteger(v.at(v.size() - 1))); | |
| 72 | 72 | auto node = q.makeIndirectObject(QPDFObjectHandle::newDictionary()); |
| 73 | - node.replaceKey("/Nums", nums).replaceKey("/Limits", limits); | |
| 73 | + node.replaceKey("/Nums", nums); | |
| 74 | + node.replaceKey("/Limits", limits); | |
| 74 | 75 | return node; |
| 75 | 76 | }; |
| 76 | 77 | |
| ... | ... | @@ -168,8 +169,8 @@ test_depth() |
| 168 | 169 | int val = |
| 169 | 170 | (((((i1 * NITEMS) + i2) * NITEMS) + i3) * NITEMS) + i4; |
| 170 | 171 | std::string str = QUtil::int_to_string(10 * val, 6); |
| 171 | - items.appendItem(QPDFObjectHandle::newString(str)) | |
| 172 | - .appendItem(QPDFObjectHandle::newString("val " + str)); | |
| 172 | + items.appendItem(QPDFObjectHandle::newString(str)); | |
| 173 | + items.appendItem(QPDFObjectHandle::newString("val " + str)); | |
| 173 | 174 | if (i4 == 0) { |
| 174 | 175 | first = str; |
| 175 | 176 | } else if (i4 == NITEMS - 1) { |
| ... | ... | @@ -178,23 +179,21 @@ test_depth() |
| 178 | 179 | } |
| 179 | 180 | auto limits = QPDFObjectHandle::newArray(); |
| 180 | 181 | n3.replaceKey("/Limits", limits); |
| 181 | - limits.appendItem(QPDFObjectHandle::newString(first)) | |
| 182 | - .appendItem(QPDFObjectHandle::newString(last)); | |
| 182 | + limits.appendItem(QPDFObjectHandle::newString(first)); | |
| 183 | + limits.appendItem(QPDFObjectHandle::newString(last)); | |
| 183 | 184 | } |
| 184 | 185 | auto limits = QPDFObjectHandle::newArray(); |
| 185 | 186 | n2.replaceKey("/Limits", limits); |
| 186 | - limits | |
| 187 | - .appendItem( | |
| 188 | - k2.getArrayItem(0).getKey("/Limits").getArrayItem(0)) | |
| 189 | - .appendItem(k2.getArrayItem(NITEMS - 1) | |
| 190 | - .getKey("/Limits") | |
| 191 | - .getArrayItem(1)); | |
| 187 | + limits.appendItem( | |
| 188 | + k2.getArrayItem(0).getKey("/Limits").getArrayItem(0)); | |
| 189 | + limits.appendItem( | |
| 190 | + k2.getArrayItem(NITEMS - 1).getKey("/Limits").getArrayItem(1)); | |
| 192 | 191 | } |
| 193 | 192 | auto limits = QPDFObjectHandle::newArray(); |
| 194 | 193 | n1.replaceKey("/Limits", limits); |
| 195 | - limits.appendItem(k1.getArrayItem(0).getKey("/Limits").getArrayItem(0)) | |
| 196 | - .appendItem( | |
| 197 | - k1.getArrayItem(NITEMS - 1).getKey("/Limits").getArrayItem(1)); | |
| 194 | + limits.appendItem(k1.getArrayItem(0).getKey("/Limits").getArrayItem(0)); | |
| 195 | + limits.appendItem( | |
| 196 | + k1.getArrayItem(NITEMS - 1).getKey("/Limits").getArrayItem(1)); | |
| 198 | 197 | } |
| 199 | 198 | |
| 200 | 199 | QPDFNameTreeObjectHelper nh(n0, q); | ... | ... |
manual/release-notes.rst
| ... | ... | @@ -98,12 +98,9 @@ For a detailed list of changes, please see the file |
| 98 | 98 | |
| 99 | 99 | - Library Enhancements |
| 100 | 100 | |
| 101 | - - Support for more fluent programming with ``QPDFObjectHandle``. | |
| 102 | - The methods ``insertItem``, ``appendItem``, ``eraseItem``, | |
| 103 | - ``replaceKey``, and ``removeKey`` all return a reference to the | |
| 104 | - object being modified. New methods ``insertItemAndGet``, | |
| 105 | - ``appendItemAndGet``, ``eraseItemAndGet``, ``replaceKeyAndGet``, | |
| 106 | - and ``removeKeyAndGet`` return the newly added or removed object. | |
| 101 | + - New methods ``insertItemAndGet``, ``appendItemAndGet``, | |
| 102 | + ``eraseItemAndGet``, ``replaceKeyAndGet``, and | |
| 103 | + ``removeKeyAndGet`` return the newly added or removed object. | |
| 107 | 104 | |
| 108 | 105 | - Add new ``Pipeline`` methods to reduce the amount of casting that is |
| 109 | 106 | needed: | ... | ... |
qpdf/pdf_from_scratch.cc
| ... | ... | @@ -60,14 +60,15 @@ runtest(int n) |
| 60 | 60 | rfont.replaceKey("/F1", font); |
| 61 | 61 | |
| 62 | 62 | QPDFObjectHandle resources = QPDFObjectHandle::newDictionary(); |
| 63 | - resources.replaceKey("/ProcSet", procset).replaceKey("/Font", rfont); | |
| 63 | + resources.replaceKey("/ProcSet", procset); | |
| 64 | + resources.replaceKey("/Font", rfont); | |
| 64 | 65 | |
| 65 | 66 | QPDFObjectHandle page = |
| 66 | 67 | pdf.makeIndirectObject(QPDFObjectHandle::newDictionary()); |
| 67 | - page.replaceKey("/Type", newName("/Page")) | |
| 68 | - .replaceKey("/MediaBox", mediabox) | |
| 69 | - .replaceKey("/Contents", contents) | |
| 70 | - .replaceKey("/Resources", resources); | |
| 68 | + page.replaceKey("/Type", newName("/Page")); | |
| 69 | + page.replaceKey("/MediaBox", mediabox); | |
| 70 | + page.replaceKey("/Contents", contents); | |
| 71 | + page.replaceKey("/Resources", resources); | |
| 71 | 72 | |
| 72 | 73 | QPDFPageDocumentHelper(pdf).addPage(page, true); |
| 73 | 74 | ... | ... |
qpdf/test_driver.cc
| ... | ... | @@ -525,7 +525,8 @@ test_9(QPDF& pdf, char const* arg2) |
| 525 | 525 | "data for other stream\n", |
| 526 | 526 | QPDFObjectHandle::newNull(), |
| 527 | 527 | QPDFObjectHandle::newNull()); |
| 528 | - root.replaceKey("/QStream", qstream).replaceKey("/RStream", rstream); | |
| 528 | + root.replaceKey("/QStream", qstream); | |
| 529 | + root.replaceKey("/RStream", rstream); | |
| 529 | 530 | QPDFWriter w(pdf, "a.pdf"); |
| 530 | 531 | w.setStaticID(true); |
| 531 | 532 | w.setStreamDataMode(qpdf_s_preserve); |
| ... | ... | @@ -895,12 +896,15 @@ test_24(QPDF& pdf, char const* arg2) |
| 895 | 896 | QPDFObjectHandle res1 = QPDFObjectHandle::newReserved(&pdf); |
| 896 | 897 | QPDFObjectHandle res2 = QPDFObjectHandle::newReserved(&pdf); |
| 897 | 898 | QPDFObjectHandle trailer = pdf.getTrailer(); |
| 898 | - trailer.replaceKey("Array1", res1).replaceKey("Array2", res2); | |
| 899 | + trailer.replaceKey("Array1", res1); | |
| 900 | + trailer.replaceKey("Array2", res2); | |
| 899 | 901 | |
| 900 | 902 | QPDFObjectHandle array1 = QPDFObjectHandle::newArray(); |
| 901 | 903 | QPDFObjectHandle array2 = QPDFObjectHandle::newArray(); |
| 902 | - array1.appendItem(res2).appendItem(QPDFObjectHandle::newInteger(1)); | |
| 903 | - array2.appendItem(res1).appendItem(QPDFObjectHandle::newInteger(2)); | |
| 904 | + array1.appendItem(res2); | |
| 905 | + array1.appendItem(QPDFObjectHandle::newInteger(1)); | |
| 906 | + array2.appendItem(res1); | |
| 907 | + array2.appendItem(QPDFObjectHandle::newInteger(2)); | |
| 904 | 908 | // Make sure trying to ask questions about a reserved object |
| 905 | 909 | // doesn't break it. |
| 906 | 910 | if (res1.isArray()) { |
| ... | ... | @@ -1065,14 +1069,13 @@ test_27(QPDF& pdf, char const* arg2) |
| 1065 | 1069 | dh.addPage(O3.getKey("/OtherPage"), false); |
| 1066 | 1070 | dh.addPage(O3, false); |
| 1067 | 1071 | QPDFObjectHandle s2 = QPDFObjectHandle::newStream(&oldpdf, "potato\n"); |
| 1068 | - pdf.getTrailer() | |
| 1069 | - .replaceKey("/QTest", pdf.copyForeignObject(qtest)) | |
| 1070 | - .replaceKey("/QTest2", QPDFObjectHandle::newArray()); | |
| 1071 | - pdf.getTrailer() | |
| 1072 | - .getKey("/QTest2") | |
| 1073 | - .appendItem(pdf.copyForeignObject(s1)) | |
| 1074 | - .appendItem(pdf.copyForeignObject(s2)) | |
| 1075 | - .appendItem(pdf.copyForeignObject(s3)); | |
| 1072 | + auto trailer = pdf.getTrailer(); | |
| 1073 | + trailer.replaceKey("/QTest", pdf.copyForeignObject(qtest)); | |
| 1074 | + auto qtest2 = | |
| 1075 | + trailer.replaceKeyAndGet("/QTest2", QPDFObjectHandle::newArray()); | |
| 1076 | + qtest2.appendItem(pdf.copyForeignObject(s1)); | |
| 1077 | + qtest2.appendItem(pdf.copyForeignObject(s2)); | |
| 1078 | + qtest2.appendItem(pdf.copyForeignObject(s3)); | |
| 1076 | 1079 | } |
| 1077 | 1080 | |
| 1078 | 1081 | QPDFWriter w(pdf, "a.pdf"); |
| ... | ... | @@ -2035,12 +2038,6 @@ test_55(QPDF& pdf, char const* arg2) |
| 2035 | 2038 | QPDFPageDocumentHelper(pdf).getAllPages(); |
| 2036 | 2039 | QPDFObjectHandle qtest = QPDFObjectHandle::newArray(); |
| 2037 | 2040 | for (auto& ph: pages) { |
| 2038 | - // Note: using fluent appendItem causes a test failure with | |
| 2039 | - // MSVC 19.31.31107, which appears to evaluate the argument to | |
| 2040 | - // the second appendItem before the first. Since these | |
| 2041 | - // arguments have the side effect of creating objects, the | |
| 2042 | - // object numbers end up being different even though the | |
| 2043 | - // resulting file is semantically correct. | |
| 2044 | 2041 | qtest.appendItem(ph.getFormXObjectForPage()); |
| 2045 | 2042 | qtest.appendItem(ph.getFormXObjectForPage(false)); |
| 2046 | 2043 | } |
| ... | ... | @@ -2196,10 +2193,10 @@ test_60(QPDF& pdf, char const* arg2) |
| 2196 | 2193 | |
| 2197 | 2194 | // The only differences between /QTest and /QTest3 should be |
| 2198 | 2195 | // the direct objects merged from r2. |
| 2199 | - pdf.getTrailer() | |
| 2200 | - .replaceKey("/QTest1", r1) | |
| 2201 | - .replaceKey("/QTest2", r2) | |
| 2202 | - .replaceKey("/QTest3", r3); | |
| 2196 | + auto trailer = pdf.getTrailer(); | |
| 2197 | + trailer.replaceKey("/QTest1", r1); | |
| 2198 | + trailer.replaceKey("/QTest2", r2); | |
| 2199 | + trailer.replaceKey("/QTest3", r3); | |
| 2203 | 2200 | QPDFWriter w(pdf, "a.pdf"); |
| 2204 | 2201 | w.setQDFMode(true); |
| 2205 | 2202 | w.setStaticID(true); |
| ... | ... | @@ -2259,9 +2256,9 @@ test_62(QPDF& pdf, char const* arg2) |
| 2259 | 2256 | long long q2 = QIntC::to_longlong(q2_l); |
| 2260 | 2257 | unsigned int q3_i = UINT_MAX; |
| 2261 | 2258 | long long q3 = QIntC::to_longlong(q3_i); |
| 2262 | - t.replaceKey("/Q1", QPDFObjectHandle::newInteger(q1)) | |
| 2263 | - .replaceKey("/Q2", QPDFObjectHandle::newInteger(q2)) | |
| 2264 | - .replaceKey("/Q3", QPDFObjectHandle::newInteger(q3)); | |
| 2259 | + t.replaceKey("/Q1", QPDFObjectHandle::newInteger(q1)); | |
| 2260 | + t.replaceKey("/Q2", QPDFObjectHandle::newInteger(q2)); | |
| 2261 | + t.replaceKey("/Q3", QPDFObjectHandle::newInteger(q3)); | |
| 2265 | 2262 | assert_compare_numbers(q1, t.getKey("/Q1").getIntValue()); |
| 2266 | 2263 | assert_compare_numbers(q1_l, t.getKey("/Q1").getUIntValue()); |
| 2267 | 2264 | assert_compare_numbers(INT_MAX, t.getKey("/Q1").getIntValueAsInt()); |
| ... | ... | @@ -3120,17 +3117,16 @@ test_87(QPDF& pdf, char const* arg2) |
| 3120 | 3117 | static void |
| 3121 | 3118 | test_88(QPDF& pdf, char const* arg2) |
| 3122 | 3119 | { |
| 3123 | - // Exercise fluent QPDFObjectHandle mutators and similar methods | |
| 3124 | - // added for qpdf 11. | |
| 3125 | - auto dict = QPDFObjectHandle::newDictionary() | |
| 3126 | - .replaceKey("/One", QPDFObjectHandle::newInteger(1)) | |
| 3127 | - .replaceKey("/Two", QPDFObjectHandle::newInteger(2)); | |
| 3128 | - dict.replaceKeyAndGet("/Three", QPDFObjectHandle::newArray()) | |
| 3129 | - .appendItem("(a)"_qpdf) | |
| 3130 | - .appendItem("(b)"_qpdf) | |
| 3131 | - .appendItemAndGet(QPDFObjectHandle::newDictionary()) | |
| 3132 | - .replaceKey("/Z", "/Y"_qpdf) | |
| 3133 | - .replaceKey("/X", "/W"_qpdf); | |
| 3120 | + // Exercise mutate and get methods added for qpdf 11. | |
| 3121 | + auto dict = QPDFObjectHandle::newDictionary(); | |
| 3122 | + dict.replaceKey("/One", QPDFObjectHandle::newInteger(1)); | |
| 3123 | + dict.replaceKey("/Two", QPDFObjectHandle::newInteger(2)); | |
| 3124 | + auto three = dict.replaceKeyAndGet("/Three", QPDFObjectHandle::newArray()); | |
| 3125 | + three.appendItem("(a)"_qpdf); | |
| 3126 | + three.appendItem("(b)"_qpdf); | |
| 3127 | + auto newdict = three.appendItemAndGet(QPDFObjectHandle::newDictionary()); | |
| 3128 | + newdict.replaceKey("/Z", "/Y"_qpdf); | |
| 3129 | + newdict.replaceKey("/X", "/W"_qpdf); | |
| 3134 | 3130 | assert(dict.unparse() == R"( |
| 3135 | 3131 | << |
| 3136 | 3132 | /One 1 |
| ... | ... | @@ -3138,14 +3134,15 @@ test_88(QPDF& pdf, char const* arg2) |
| 3138 | 3134 | /Three [ (a) (b) << /Z /Y /X /W >> ] |
| 3139 | 3135 | >> |
| 3140 | 3136 | )"_qpdf.unparse()); |
| 3141 | - auto arr = dict.getKey("/Three") | |
| 3142 | - .insertItem(0, QPDFObjectHandle::newString("0")) | |
| 3143 | - .insertItem(0, QPDFObjectHandle::newString("00")); | |
| 3137 | + auto arr = dict.getKey("/Three"); | |
| 3138 | + arr.insertItem(0, QPDFObjectHandle::newString("0")); | |
| 3139 | + arr.insertItem(0, QPDFObjectHandle::newString("00")); | |
| 3144 | 3140 | assert( |
| 3145 | 3141 | arr.unparse() == |
| 3146 | 3142 | "[ (00) (0) (a) (b) << /Z /Y /X /W >> ]"_qpdf.unparse()); |
| 3147 | 3143 | auto new_dict = arr.insertItemAndGet(1, "<< /P /Q /R /S >>"_qpdf); |
| 3148 | - arr.eraseItem(2).eraseItem(0); | |
| 3144 | + arr.eraseItem(2); | |
| 3145 | + arr.eraseItem(0); | |
| 3149 | 3146 | assert( |
| 3150 | 3147 | arr.unparse() == |
| 3151 | 3148 | "[ << /P /Q /R /S >> (a) (b) << /Z /Y /X /W >> ]"_qpdf.unparse()); |
| ... | ... | @@ -3154,7 +3151,8 @@ test_88(QPDF& pdf, char const* arg2) |
| 3154 | 3151 | // always been this way, and there is code that relies on this |
| 3155 | 3152 | // behavior. Maybe it would be different if I could start over |
| 3156 | 3153 | // again... |
| 3157 | - new_dict.removeKey("/R").replaceKey("/T", "/U"_qpdf); | |
| 3154 | + new_dict.removeKey("/R"); | |
| 3155 | + new_dict.replaceKey("/T", "/U"_qpdf); | |
| 3158 | 3156 | assert( |
| 3159 | 3157 | arr.unparse() == |
| 3160 | 3158 | "[ << /P /Q /T /U >> (a) (b) << /Z /Y /X /W >> ]"_qpdf.unparse()); | ... | ... |
qpdf/test_large_file.cc
| ... | ... | @@ -187,37 +187,37 @@ create_pdf(char const* filename) |
| 187 | 187 | |
| 188 | 188 | QPDFObjectHandle font = |
| 189 | 189 | pdf.makeIndirectObject(QPDFObjectHandle::newDictionary()); |
| 190 | - font.replaceKey("/Type", newName("/Font")) | |
| 191 | - .replaceKey("/Subtype", newName("/Type1")) | |
| 192 | - .replaceKey("/Name", newName("/F1")) | |
| 193 | - .replaceKey("/BaseFont", newName("/Helvetica")) | |
| 194 | - .replaceKey("/Encoding", newName("/WinAnsiEncoding")); | |
| 190 | + font.replaceKey("/Type", newName("/Font")); | |
| 191 | + font.replaceKey("/Subtype", newName("/Type1")); | |
| 192 | + font.replaceKey("/Name", newName("/F1")); | |
| 193 | + font.replaceKey("/BaseFont", newName("/Helvetica")); | |
| 194 | + font.replaceKey("/Encoding", newName("/WinAnsiEncoding")); | |
| 195 | 195 | |
| 196 | 196 | QPDFObjectHandle procset = |
| 197 | 197 | pdf.makeIndirectObject(QPDFObjectHandle::newArray()); |
| 198 | - procset.appendItem(newName("/PDF")) | |
| 199 | - .appendItem(newName("/Text")) | |
| 200 | - .appendItem(newName("/ImageC")); | |
| 198 | + procset.appendItem(newName("/PDF")); | |
| 199 | + procset.appendItem(newName("/Text")); | |
| 200 | + procset.appendItem(newName("/ImageC")); | |
| 201 | 201 | |
| 202 | 202 | QPDFObjectHandle rfont = QPDFObjectHandle::newDictionary(); |
| 203 | 203 | rfont.replaceKey("/F1", font); |
| 204 | 204 | |
| 205 | 205 | QPDFObjectHandle mediabox = QPDFObjectHandle::newArray(); |
| 206 | - mediabox.appendItem(newInteger(0)) | |
| 207 | - .appendItem(newInteger(0)) | |
| 208 | - .appendItem(newInteger(612)) | |
| 209 | - .appendItem(newInteger(792)); | |
| 206 | + mediabox.appendItem(newInteger(0)); | |
| 207 | + mediabox.appendItem(newInteger(0)); | |
| 208 | + mediabox.appendItem(newInteger(612)); | |
| 209 | + mediabox.appendItem(newInteger(792)); | |
| 210 | 210 | |
| 211 | 211 | QPDFPageDocumentHelper dh(pdf); |
| 212 | 212 | for (size_t pageno = 1; pageno <= npages; ++pageno) { |
| 213 | 213 | QPDFObjectHandle image = QPDFObjectHandle::newStream(&pdf); |
| 214 | 214 | QPDFObjectHandle image_dict = image.getDict(); |
| 215 | - image_dict.replaceKey("/Type", newName("/XObject")) | |
| 216 | - .replaceKey("/Subtype", newName("/Image")) | |
| 217 | - .replaceKey("/ColorSpace", newName("/DeviceGray")) | |
| 218 | - .replaceKey("/BitsPerComponent", newInteger(8)) | |
| 219 | - .replaceKey("/Width", newInteger(width)) | |
| 220 | - .replaceKey("/Height", newInteger(height)); | |
| 215 | + image_dict.replaceKey("/Type", newName("/XObject")); | |
| 216 | + image_dict.replaceKey("/Subtype", newName("/Image")); | |
| 217 | + image_dict.replaceKey("/ColorSpace", newName("/DeviceGray")); | |
| 218 | + image_dict.replaceKey("/BitsPerComponent", newInteger(8)); | |
| 219 | + image_dict.replaceKey("/Width", newInteger(width)); | |
| 220 | + image_dict.replaceKey("/Height", newInteger(height)); | |
| 221 | 221 | ImageProvider* p = new ImageProvider(pageno); |
| 222 | 222 | std::shared_ptr<QPDFObjectHandle::StreamDataProvider> provider(p); |
| 223 | 223 | image.replaceStreamData( |
| ... | ... | @@ -227,18 +227,18 @@ create_pdf(char const* filename) |
| 227 | 227 | xobject.replaceKey("/Im1", image); |
| 228 | 228 | |
| 229 | 229 | QPDFObjectHandle resources = QPDFObjectHandle::newDictionary(); |
| 230 | - resources.replaceKey("/ProcSet", procset) | |
| 231 | - .replaceKey("/Font", rfont) | |
| 232 | - .replaceKey("/XObject", xobject); | |
| 230 | + resources.replaceKey("/ProcSet", procset); | |
| 231 | + resources.replaceKey("/Font", rfont); | |
| 232 | + resources.replaceKey("/XObject", xobject); | |
| 233 | 233 | |
| 234 | 234 | QPDFObjectHandle contents = create_page_contents(pdf, pageno); |
| 235 | 235 | |
| 236 | 236 | QPDFObjectHandle page = |
| 237 | 237 | pdf.makeIndirectObject(QPDFObjectHandle::newDictionary()); |
| 238 | - page.replaceKey("/Type", newName("/Page")) | |
| 239 | - .replaceKey("/MediaBox", mediabox) | |
| 240 | - .replaceKey("/Contents", contents) | |
| 241 | - .replaceKey("/Resources", resources); | |
| 238 | + page.replaceKey("/Type", newName("/Page")); | |
| 239 | + page.replaceKey("/MediaBox", mediabox); | |
| 240 | + page.replaceKey("/Contents", contents); | |
| 241 | + page.replaceKey("/Resources", resources); | |
| 242 | 242 | |
| 243 | 243 | dh.addPage(page, false); |
| 244 | 244 | } | ... | ... |