Commit e80fad86e95af978ada2a6cc5c4b209a1f65f7c0
1 parent
ff73d71e
Add new QPDFObjectHandle methods for more fluent programming
Showing
8 changed files
with
193 additions
and
31 deletions
ChangeLog
| 1 | +2022-04-29 Jay Berkenbilt <ejb@ql.org> | ||
| 2 | + | ||
| 3 | + * QPDFObjectHandle: for the methods insertItem, appendItem, | ||
| 4 | + eraseItem, replaceKey, and removeKey, have the methods return a | ||
| 5 | + reference to the original object, making a fluent interface to | ||
| 6 | + initializing or modifying QPDFObjectHandle possible. Also, for | ||
| 7 | + each one, add a corresponding "AndGet" method (insertItemAndGet, | ||
| 8 | + appendItemAndGet, eraseItemAndGet, replaceKeyAndGet, and | ||
| 9 | + removeKeyAndGet) that returns the newly inserted, replaced, or | ||
| 10 | + removed item. This makes it possible to create a new object, add | ||
| 11 | + it to an array or dictionary, and get a handle to it all in one | ||
| 12 | + line. | ||
| 13 | + | ||
| 1 | 2022-04-24 Jay Berkenbilt <ejb@ql.org> | 14 | 2022-04-24 Jay Berkenbilt <ejb@ql.org> |
| 2 | 15 | ||
| 3 | * Bug fix: "removeAttachment" in the job JSON now takes an array | 16 | * Bug fix: "removeAttachment" in the job JSON now takes an array |
TODO
| @@ -474,13 +474,6 @@ This is a list of changes to make next time there is an ABI change. | @@ -474,13 +474,6 @@ This is a list of changes to make next time there is an ABI change. | ||
| 474 | Comments appear in the code prefixed by "ABI". Always Search for ABI | 474 | Comments appear in the code prefixed by "ABI". Always Search for ABI |
| 475 | in source and header files to find items not listed here. | 475 | in source and header files to find items not listed here. |
| 476 | 476 | ||
| 477 | -* Having QPDFObjectHandle setters return Class& to allow for | ||
| 478 | - use of fluent interfaces. This includes array and dictionary | ||
| 479 | - mutators. | ||
| 480 | - newDictionary().replaceKey("/X", "1"_qpdf).replaceKey("/Y", "(asdf)"_qpdf); | ||
| 481 | -* Add replaceKeyAndGet, appendItemAndGet, setArrayItemAndGet, | ||
| 482 | - insertItemAndGet that return the new item so you can say | ||
| 483 | - auto oh = dict.replaceKeyAndGet("/Key", QPDFObjectHandle::newSomething()); | ||
| 484 | * Add getKeyOrInsert("/X", oh) that returns the existing value or adds | 477 | * Add getKeyOrInsert("/X", oh) that returns the existing value or adds |
| 485 | oh as the new value and returns it. | 478 | oh as the new value and returns it. |
| 486 | * Add default values to the getters, like getIntValue(default_value). | 479 | * Add default values to the getters, like getIntValue(default_value). |
include/qpdf/QPDFObjectHandle.hh
| @@ -990,7 +990,20 @@ class QPDFObjectHandle | @@ -990,7 +990,20 @@ class QPDFObjectHandle | ||
| 990 | QPDF_DLL | 990 | QPDF_DLL |
| 991 | QPDFObjectHandle copyStream(); | 991 | QPDFObjectHandle copyStream(); |
| 992 | 992 | ||
| 993 | - // Mutator methods. Use with caution. | 993 | + // Mutator methods. |
| 994 | + | ||
| 995 | + // Since qpdf 11: when a mutator object returns QPDFObjectHandle&, | ||
| 996 | + // it is a reference to the object itself. This makes it possible | ||
| 997 | + // to use a fluent style. For example: | ||
| 998 | + // | ||
| 999 | + // array.appendItem(i1).appendItem(i2); | ||
| 1000 | + // | ||
| 1001 | + // would append i1 and then i2 to the array. There are also items | ||
| 1002 | + // that end with AndGet and return a QPDFObjectHandle. These | ||
| 1003 | + // return the newly added object. For example: | ||
| 1004 | + // | ||
| 1005 | + // auto new_dict = dict.replaceKeyAndGet( | ||
| 1006 | + // "/New", QPDFObjectHandle::newDictionary()); | ||
| 994 | 1007 | ||
| 995 | // Recursively copy this object, making it direct. An exception is | 1008 | // Recursively copy this object, making it direct. An exception is |
| 996 | // thrown if a loop is detected. With allow_streams true, keep | 1009 | // thrown if a loop is detected. With allow_streams true, keep |
| @@ -1010,31 +1023,54 @@ class QPDFObjectHandle | @@ -1010,31 +1023,54 @@ class QPDFObjectHandle | ||
| 1010 | QPDF_DLL | 1023 | QPDF_DLL |
| 1011 | void setArrayFromVector(std::vector<QPDFObjectHandle> const& items); | 1024 | void setArrayFromVector(std::vector<QPDFObjectHandle> const& items); |
| 1012 | // Insert an item before the item at the given position ("at") so | 1025 | // Insert an item before the item at the given position ("at") so |
| 1013 | - // that it has that position after insertion. If "at" is equal to | ||
| 1014 | - // the size of the array, insert the item at the end. | 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). | ||
| 1029 | + QPDF_DLL | ||
| 1030 | + QPDFObjectHandle& insertItem(int at, QPDFObjectHandle const& item); | ||
| 1031 | + // Like insertItem but return the item that was inserted. | ||
| 1015 | QPDF_DLL | 1032 | QPDF_DLL |
| 1016 | - void insertItem(int at, QPDFObjectHandle const& item); | 1033 | + QPDFObjectHandle insertItemAndGet(int at, QPDFObjectHandle const& item); |
| 1034 | + // Append an item, and return a reference to the original array | ||
| 1035 | + // (not the new item). | ||
| 1017 | QPDF_DLL | 1036 | QPDF_DLL |
| 1018 | - void appendItem(QPDFObjectHandle const& item); | 1037 | + QPDFObjectHandle& appendItem(QPDFObjectHandle const& item); |
| 1038 | + // Append an item, and return the newly added item. | ||
| 1039 | + QPDF_DLL | ||
| 1040 | + QPDFObjectHandle appendItemAndGet(QPDFObjectHandle const& item); | ||
| 1019 | // Remove the item at that position, reducing the size of the | 1041 | // Remove the item at that position, reducing the size of the |
| 1020 | - // array by one. | 1042 | + // array by one. Return a reference the original array (not the |
| 1043 | + // item that was removed). | ||
| 1044 | + QPDF_DLL | ||
| 1045 | + QPDFObjectHandle& eraseItem(int at); | ||
| 1046 | + // Erase and item and return the item that was removed. | ||
| 1021 | QPDF_DLL | 1047 | QPDF_DLL |
| 1022 | - void eraseItem(int at); | 1048 | + QPDFObjectHandle eraseItemAndGet(int at); |
| 1023 | 1049 | ||
| 1024 | // Mutator methods for dictionary objects | 1050 | // Mutator methods for dictionary objects |
| 1025 | 1051 | ||
| 1026 | // Replace value of key, adding it if it does not exist. If value | 1052 | // Replace value of key, adding it if it does not exist. If value |
| 1027 | - // is null, remove the key. | 1053 | + // is null, remove the key. Return a reference to the original |
| 1054 | + // dictionary (not the new item). | ||
| 1055 | + QPDF_DLL | ||
| 1056 | + QPDFObjectHandle& | ||
| 1057 | + replaceKey(std::string const& key, QPDFObjectHandle const& value); | ||
| 1058 | + // Replace value of key and return the value. | ||
| 1028 | QPDF_DLL | 1059 | QPDF_DLL |
| 1029 | - void replaceKey(std::string const& key, QPDFObjectHandle const& value); | ||
| 1030 | - // Remove key, doing nothing if key does not exist | 1060 | + QPDFObjectHandle |
| 1061 | + 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). | ||
| 1031 | QPDF_DLL | 1064 | QPDF_DLL |
| 1032 | - void removeKey(std::string const& key); | 1065 | + QPDFObjectHandle& removeKey(std::string const& key); |
| 1066 | + // Remove key and return the old value. If the old value didn't | ||
| 1067 | + // exist, return a null object. | ||
| 1068 | + QPDF_DLL | ||
| 1069 | + QPDFObjectHandle removeKeyAndGet(std::string const& key); | ||
| 1033 | 1070 | ||
| 1034 | // ABI: Remove in qpdf 12 | 1071 | // ABI: Remove in qpdf 12 |
| 1035 | - [[deprecated("use replaceKey -- it does the same thing")]] | ||
| 1036 | - QPDF_DLL | ||
| 1037 | - void replaceOrRemoveKey(std::string const& key, QPDFObjectHandle const&); | 1072 | + [[deprecated("use replaceKey -- it does the same thing")]] QPDF_DLL void |
| 1073 | + replaceOrRemoveKey(std::string const& key, QPDFObjectHandle const&); | ||
| 1038 | 1074 | ||
| 1039 | // Methods for stream objects | 1075 | // Methods for stream objects |
| 1040 | QPDF_DLL | 1076 | QPDF_DLL |
libqpdf/QPDFObjectHandle.cc
| @@ -959,7 +959,7 @@ QPDFObjectHandle::setArrayFromVector(std::vector<QPDFObjectHandle> const& items) | @@ -959,7 +959,7 @@ QPDFObjectHandle::setArrayFromVector(std::vector<QPDFObjectHandle> const& items) | ||
| 959 | } | 959 | } |
| 960 | } | 960 | } |
| 961 | 961 | ||
| 962 | -void | 962 | +QPDFObjectHandle& |
| 963 | QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item) | 963 | QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item) |
| 964 | { | 964 | { |
| 965 | if (isArray()) { | 965 | if (isArray()) { |
| @@ -968,9 +968,17 @@ QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item) | @@ -968,9 +968,17 @@ QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item) | ||
| 968 | typeWarning("array", "ignoring attempt to insert item"); | 968 | typeWarning("array", "ignoring attempt to insert item"); |
| 969 | QTC::TC("qpdf", "QPDFObjectHandle array ignoring insert item"); | 969 | QTC::TC("qpdf", "QPDFObjectHandle array ignoring insert item"); |
| 970 | } | 970 | } |
| 971 | + return *this; | ||
| 971 | } | 972 | } |
| 972 | 973 | ||
| 973 | -void | 974 | +QPDFObjectHandle |
| 975 | +QPDFObjectHandle::insertItemAndGet(int at, QPDFObjectHandle const& item) | ||
| 976 | +{ | ||
| 977 | + insertItem(at, item); | ||
| 978 | + return item; | ||
| 979 | +} | ||
| 980 | + | ||
| 981 | +QPDFObjectHandle& | ||
| 974 | QPDFObjectHandle::appendItem(QPDFObjectHandle const& item) | 982 | QPDFObjectHandle::appendItem(QPDFObjectHandle const& item) |
| 975 | { | 983 | { |
| 976 | if (isArray()) { | 984 | if (isArray()) { |
| @@ -980,9 +988,17 @@ QPDFObjectHandle::appendItem(QPDFObjectHandle const& item) | @@ -980,9 +988,17 @@ QPDFObjectHandle::appendItem(QPDFObjectHandle const& item) | ||
| 980 | typeWarning("array", "ignoring attempt to append item"); | 988 | typeWarning("array", "ignoring attempt to append item"); |
| 981 | QTC::TC("qpdf", "QPDFObjectHandle array ignoring append item"); | 989 | QTC::TC("qpdf", "QPDFObjectHandle array ignoring append item"); |
| 982 | } | 990 | } |
| 991 | + return *this; | ||
| 983 | } | 992 | } |
| 984 | 993 | ||
| 985 | -void | 994 | +QPDFObjectHandle |
| 995 | +QPDFObjectHandle::appendItemAndGet(QPDFObjectHandle const& item) | ||
| 996 | +{ | ||
| 997 | + appendItem(item); | ||
| 998 | + return item; | ||
| 999 | +} | ||
| 1000 | + | ||
| 1001 | +QPDFObjectHandle& | ||
| 986 | QPDFObjectHandle::eraseItem(int at) | 1002 | QPDFObjectHandle::eraseItem(int at) |
| 987 | { | 1003 | { |
| 988 | if (isArray() && (at < getArrayNItems()) && (at >= 0)) { | 1004 | if (isArray() && (at < getArrayNItems()) && (at >= 0)) { |
| @@ -996,6 +1012,18 @@ QPDFObjectHandle::eraseItem(int at) | @@ -996,6 +1012,18 @@ QPDFObjectHandle::eraseItem(int at) | ||
| 996 | QTC::TC("qpdf", "QPDFObjectHandle array ignoring erase item"); | 1012 | QTC::TC("qpdf", "QPDFObjectHandle array ignoring erase item"); |
| 997 | } | 1013 | } |
| 998 | } | 1014 | } |
| 1015 | + return *this; | ||
| 1016 | +} | ||
| 1017 | + | ||
| 1018 | +QPDFObjectHandle | ||
| 1019 | +QPDFObjectHandle::eraseItemAndGet(int at) | ||
| 1020 | +{ | ||
| 1021 | + auto result = QPDFObjectHandle::newNull(); | ||
| 1022 | + if (isArray() && (at < getArrayNItems()) && (at >= 0)) { | ||
| 1023 | + result = getArrayItem(at); | ||
| 1024 | + } | ||
| 1025 | + eraseItem(at); | ||
| 1026 | + return result; | ||
| 999 | } | 1027 | } |
| 1000 | 1028 | ||
| 1001 | // Dictionary accessors | 1029 | // Dictionary accessors |
| @@ -1267,7 +1295,7 @@ QPDFObjectHandle::getOwningQPDF() | @@ -1267,7 +1295,7 @@ QPDFObjectHandle::getOwningQPDF() | ||
| 1267 | 1295 | ||
| 1268 | // Dictionary mutators | 1296 | // Dictionary mutators |
| 1269 | 1297 | ||
| 1270 | -void | 1298 | +QPDFObjectHandle& |
| 1271 | QPDFObjectHandle::replaceKey( | 1299 | QPDFObjectHandle::replaceKey( |
| 1272 | std::string const& key, QPDFObjectHandle const& value) | 1300 | std::string const& key, QPDFObjectHandle const& value) |
| 1273 | { | 1301 | { |
| @@ -1278,9 +1306,18 @@ QPDFObjectHandle::replaceKey( | @@ -1278,9 +1306,18 @@ QPDFObjectHandle::replaceKey( | ||
| 1278 | typeWarning("dictionary", "ignoring key replacement request"); | 1306 | typeWarning("dictionary", "ignoring key replacement request"); |
| 1279 | QTC::TC("qpdf", "QPDFObjectHandle dictionary ignoring replaceKey"); | 1307 | QTC::TC("qpdf", "QPDFObjectHandle dictionary ignoring replaceKey"); |
| 1280 | } | 1308 | } |
| 1309 | + return *this; | ||
| 1281 | } | 1310 | } |
| 1282 | 1311 | ||
| 1283 | -void | 1312 | +QPDFObjectHandle |
| 1313 | +QPDFObjectHandle::replaceKeyAndGet( | ||
| 1314 | + std::string const& key, QPDFObjectHandle const& value) | ||
| 1315 | +{ | ||
| 1316 | + replaceKey(key, value); | ||
| 1317 | + return value; | ||
| 1318 | +} | ||
| 1319 | + | ||
| 1320 | +QPDFObjectHandle& | ||
| 1284 | QPDFObjectHandle::removeKey(std::string const& key) | 1321 | QPDFObjectHandle::removeKey(std::string const& key) |
| 1285 | { | 1322 | { |
| 1286 | if (isDictionary()) { | 1323 | if (isDictionary()) { |
| @@ -1289,6 +1326,18 @@ QPDFObjectHandle::removeKey(std::string const& key) | @@ -1289,6 +1326,18 @@ QPDFObjectHandle::removeKey(std::string const& key) | ||
| 1289 | typeWarning("dictionary", "ignoring key removal request"); | 1326 | typeWarning("dictionary", "ignoring key removal request"); |
| 1290 | QTC::TC("qpdf", "QPDFObjectHandle dictionary ignoring removeKey"); | 1327 | QTC::TC("qpdf", "QPDFObjectHandle dictionary ignoring removeKey"); |
| 1291 | } | 1328 | } |
| 1329 | + return *this; | ||
| 1330 | +} | ||
| 1331 | + | ||
| 1332 | +QPDFObjectHandle | ||
| 1333 | +QPDFObjectHandle::removeKeyAndGet(std::string const& key) | ||
| 1334 | +{ | ||
| 1335 | + auto result = QPDFObjectHandle::newNull(); | ||
| 1336 | + if (isDictionary()) { | ||
| 1337 | + result = getKey(key); | ||
| 1338 | + } | ||
| 1339 | + removeKey(key); | ||
| 1340 | + return result; | ||
| 1292 | } | 1341 | } |
| 1293 | 1342 | ||
| 1294 | void | 1343 | void |
manual/release-notes.rst
| @@ -73,6 +73,15 @@ For a detailed list of changes, please see the file | @@ -73,6 +73,15 @@ For a detailed list of changes, please see the file | ||
| 73 | ``QPDFNumberTreeObjectHelper`` constructors that don't take a | 73 | ``QPDFNumberTreeObjectHelper`` constructors that don't take a |
| 74 | ``QPDF&`` argument. | 74 | ``QPDF&`` argument. |
| 75 | 75 | ||
| 76 | + - Library Enhancements | ||
| 77 | + | ||
| 78 | + - Support for more fluent programming with ``QPDFObjectHandle``. | ||
| 79 | + The methods ``insertItem``, ``appendItem``, ``eraseItem``, | ||
| 80 | + ``replaceKey``, and ``removeKey`` all return a reference to the | ||
| 81 | + object being modified. New methods ``insertItemAndGet``, | ||
| 82 | + ``appendItemAndGet``, ``eraseItemAndGet``, ``replaceKeyAndGet``, | ||
| 83 | + and ``removeKeyAndGet`` return the newly added or removed object. | ||
| 84 | + | ||
| 76 | - Other changes | 85 | - Other changes |
| 77 | 86 | ||
| 78 | - A new chapter on contributing to qpdf has been added to the | 87 | - A new chapter on contributing to qpdf has been added to the |
qpdf/qtest/qpdf.test
| @@ -1440,13 +1440,16 @@ foreach (my $i = 1; $i <= 3; ++$i) | @@ -1440,13 +1440,16 @@ foreach (my $i = 1; $i <= 3; ++$i) | ||
| 1440 | 1440 | ||
| 1441 | show_ntests(); | 1441 | show_ntests(); |
| 1442 | # ---------- | 1442 | # ---------- |
| 1443 | -$td->notify("--- Dictionary keys ---"); | ||
| 1444 | -$n_tests += 1; | 1443 | +$td->notify("--- Miscellaneous QPDFObjectHandle API ---"); |
| 1444 | +$n_tests += 2; | ||
| 1445 | 1445 | ||
| 1446 | $td->runtest("dictionary keys", | 1446 | $td->runtest("dictionary keys", |
| 1447 | {$td->COMMAND => "test_driver 87 - -"}, | 1447 | {$td->COMMAND => "test_driver 87 - -"}, |
| 1448 | - {$td->STRING => "test 87 done\n", | ||
| 1449 | - $td->EXIT_STATUS => 0}, | 1448 | + {$td->STRING => "test 87 done\n", $td->EXIT_STATUS => 0}, |
| 1449 | + $td->NORMALIZE_NEWLINES); | ||
| 1450 | +$td->runtest("fluent interfaces", | ||
| 1451 | + {$td->COMMAND => "test_driver 88 minimal.pdf -"}, | ||
| 1452 | + {$td->FILE => "test88.out", $td->EXIT_STATUS => 0}, | ||
| 1450 | $td->NORMALIZE_NEWLINES); | 1453 | $td->NORMALIZE_NEWLINES); |
| 1451 | 1454 | ||
| 1452 | show_ntests(); | 1455 | show_ntests(); |
qpdf/qtest/qpdf/test88.out
0 โ 100644
qpdf/test_driver.cc
| @@ -3178,6 +3178,63 @@ test_87(QPDF& pdf, char const* arg2) | @@ -3178,6 +3178,63 @@ test_87(QPDF& pdf, char const* arg2) | ||
| 3178 | assert(dict.getJSON().unparse() == "{\n \"/A\": 2\n}"); | 3178 | assert(dict.getJSON().unparse() == "{\n \"/A\": 2\n}"); |
| 3179 | } | 3179 | } |
| 3180 | 3180 | ||
| 3181 | +static void | ||
| 3182 | +test_88(QPDF& pdf, char const* arg2) | ||
| 3183 | +{ | ||
| 3184 | + // Exercise fluent QPDFObjectHandle mutators and similar methods | ||
| 3185 | + // added for qpdf 11. | ||
| 3186 | + auto dict = QPDFObjectHandle::newDictionary() | ||
| 3187 | + .replaceKey("/One", QPDFObjectHandle::newInteger(1)) | ||
| 3188 | + .replaceKey("/Two", QPDFObjectHandle::newInteger(2)); | ||
| 3189 | + dict.replaceKeyAndGet("/Three", QPDFObjectHandle::newArray()) | ||
| 3190 | + .appendItem("(a)"_qpdf) | ||
| 3191 | + .appendItem("(b)"_qpdf) | ||
| 3192 | + .appendItemAndGet(QPDFObjectHandle::newDictionary()) | ||
| 3193 | + .replaceKey("/Z", "/Y"_qpdf) | ||
| 3194 | + .replaceKey("/X", "/W"_qpdf); | ||
| 3195 | + assert(dict.unparse() == R"( | ||
| 3196 | + << | ||
| 3197 | + /One 1 | ||
| 3198 | + /Two 2 | ||
| 3199 | + /Three [ (a) (b) << /Z /Y /X /W >> ] | ||
| 3200 | + >> | ||
| 3201 | + )"_qpdf.unparse()); | ||
| 3202 | + auto arr = dict.getKey("/Three") | ||
| 3203 | + .insertItem(0, QPDFObjectHandle::newString("0")) | ||
| 3204 | + .insertItem(0, QPDFObjectHandle::newString("00")); | ||
| 3205 | + assert( | ||
| 3206 | + arr.unparse() == | ||
| 3207 | + "[ (00) (0) (a) (b) << /Z /Y /X /W >> ]"_qpdf.unparse()); | ||
| 3208 | + auto new_dict = arr.insertItemAndGet(1, "<< /P /Q /R /S >>"_qpdf); | ||
| 3209 | + arr.eraseItem(2).eraseItem(0); | ||
| 3210 | + assert( | ||
| 3211 | + arr.unparse() == | ||
| 3212 | + "[ << /P /Q /R /S >> (a) (b) << /Z /Y /X /W >> ]"_qpdf.unparse()); | ||
| 3213 | + | ||
| 3214 | + // new_dict shares internals with the one in the array. It has | ||
| 3215 | + // always been this way, and there is code that relies on this | ||
| 3216 | + // behavior. Maybe it would be different if I could start over | ||
| 3217 | + // again... | ||
| 3218 | + new_dict.removeKey("/R").replaceKey("/T", "/U"_qpdf); | ||
| 3219 | + assert( | ||
| 3220 | + arr.unparse() == | ||
| 3221 | + "[ << /P /Q /T /U >> (a) (b) << /Z /Y /X /W >> ]"_qpdf.unparse()); | ||
| 3222 | + auto s = arr.eraseItemAndGet(1); | ||
| 3223 | + assert(s.unparse() == "(a)"); | ||
| 3224 | + assert( | ||
| 3225 | + arr.unparse() == | ||
| 3226 | + "[ << /P /Q /T /U >> (b) << /Z /Y /X /W >> ]"_qpdf.unparse()); | ||
| 3227 | + | ||
| 3228 | + assert(new_dict.removeKeyAndGet("/M").isNull()); | ||
| 3229 | + assert(new_dict.removeKeyAndGet("/P").unparse() == "/Q"); | ||
| 3230 | + assert(new_dict.unparse() == "<< /T /U >>"_qpdf.unparse()); | ||
| 3231 | + | ||
| 3232 | + // Test errors | ||
| 3233 | + auto arr2 = pdf.getRoot().replaceKeyAndGet("/QTest", "[1 2]"_qpdf); | ||
| 3234 | + arr2.setObjectDescription(&pdf, "test array"); | ||
| 3235 | + assert(arr2.eraseItemAndGet(50).isNull()); | ||
| 3236 | +} | ||
| 3237 | + | ||
| 3181 | void | 3238 | void |
| 3182 | runtest(int n, char const* filename1, char const* arg2) | 3239 | runtest(int n, char const* filename1, char const* arg2) |
| 3183 | { | 3240 | { |
| @@ -3280,7 +3337,7 @@ runtest(int n, char const* filename1, char const* arg2) | @@ -3280,7 +3337,7 @@ runtest(int n, char const* filename1, char const* arg2) | ||
| 3280 | {76, test_76}, {77, test_77}, {78, test_78}, {79, test_79}, | 3337 | {76, test_76}, {77, test_77}, {78, test_78}, {79, test_79}, |
| 3281 | {80, test_80}, {81, test_81}, {82, test_82}, {83, test_83}, | 3338 | {80, test_80}, {81, test_81}, {82, test_82}, {83, test_83}, |
| 3282 | {84, test_84}, {85, test_85}, {86, test_86}, {87, test_87}, | 3339 | {84, test_84}, {85, test_85}, {86, test_86}, {87, test_87}, |
| 3283 | - }; | 3340 | + {88, test_88}}; |
| 3284 | 3341 | ||
| 3285 | auto fn = test_functions.find(n); | 3342 | auto fn = test_functions.find(n); |
| 3286 | if (fn == test_functions.end()) { | 3343 | if (fn == test_functions.end()) { |