Commit 16f4f94cd99b4d0f633596074e8d9358db135517
1 parent
a9fbbd5d
Prepare code for JSON v2
Update getJSON() methods and calls to them
Showing
55 changed files
with
177 additions
and
99 deletions
TODO
| @@ -50,8 +50,6 @@ Output JSON v2 | @@ -50,8 +50,6 @@ Output JSON v2 | ||
| 50 | 50 | ||
| 51 | General things to remember: | 51 | General things to remember: |
| 52 | 52 | ||
| 53 | -* deprecate getJSON without a version | ||
| 54 | - | ||
| 55 | * Make sure all the information from --check and other informational | 53 | * Make sure all the information from --check and other informational |
| 56 | options (--show-linearization, --show-encryption, --show-xref, | 54 | options (--show-linearization, --show-encryption, --show-xref, |
| 57 | --list-attachments, --show-npages) is available in the json output. | 55 | --list-attachments, --show-npages) is available in the json output. |
fuzz/qpdf_fuzzer.cc
| @@ -142,7 +142,7 @@ FuzzHelper::testPages() | @@ -142,7 +142,7 @@ FuzzHelper::testPages() | ||
| 142 | page.getImages(); | 142 | page.getImages(); |
| 143 | pldh.getLabelForPage(pageno); | 143 | pldh.getLabelForPage(pageno); |
| 144 | QPDFObjectHandle page_obj(page.getObjectHandle()); | 144 | QPDFObjectHandle page_obj(page.getObjectHandle()); |
| 145 | - page_obj.getJSON(true).unparse(); | 145 | + page_obj.getJSON(JSON::LATEST, true).unparse(); |
| 146 | odh.getOutlinesForPage(page_obj.getObjGen()); | 146 | odh.getOutlinesForPage(page_obj.getObjGen()); |
| 147 | 147 | ||
| 148 | std::vector<QPDFAnnotationObjectHelper> annotations = | 148 | std::vector<QPDFAnnotationObjectHelper> annotations = |
include/qpdf/JSON.hh
include/qpdf/QPDFJob.hh
| @@ -26,6 +26,7 @@ | @@ -26,6 +26,7 @@ | ||
| 26 | #include <qpdf/DLL.h> | 26 | #include <qpdf/DLL.h> |
| 27 | #include <qpdf/PDFVersion.hh> | 27 | #include <qpdf/PDFVersion.hh> |
| 28 | #include <qpdf/QPDF.hh> | 28 | #include <qpdf/QPDF.hh> |
| 29 | +#include <qpdf/QPDFOutlineObjectHelper.hh> | ||
| 29 | #include <qpdf/QPDFPageObjectHelper.hh> | 30 | #include <qpdf/QPDFPageObjectHelper.hh> |
| 30 | 31 | ||
| 31 | #include <functional> | 32 | #include <functional> |
| @@ -520,6 +521,10 @@ class QPDFJob | @@ -520,6 +521,10 @@ class QPDFJob | ||
| 520 | void doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf); | 521 | void doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf); |
| 521 | void doJSONEncrypt(Pipeline* p, bool& first, QPDF& pdf); | 522 | void doJSONEncrypt(Pipeline* p, bool& first, QPDF& pdf); |
| 522 | void doJSONAttachments(Pipeline* p, bool& first, QPDF& pdf); | 523 | void doJSONAttachments(Pipeline* p, bool& first, QPDF& pdf); |
| 524 | + void addOutlinesToJson( | ||
| 525 | + std::vector<QPDFOutlineObjectHelper> outlines, | ||
| 526 | + JSON& j, | ||
| 527 | + std::map<QPDFObjGen, int>& page_numbers); | ||
| 523 | 528 | ||
| 524 | enum remove_unref_e { re_auto, re_yes, re_no }; | 529 | enum remove_unref_e { re_auto, re_yes, re_no }; |
| 525 | 530 |
include/qpdf/QPDFObject.hh
| @@ -64,7 +64,7 @@ class QPDFObject | @@ -64,7 +64,7 @@ class QPDFObject | ||
| 64 | 64 | ||
| 65 | virtual ~QPDFObject() = default; | 65 | virtual ~QPDFObject() = default; |
| 66 | virtual std::string unparse() = 0; | 66 | virtual std::string unparse() = 0; |
| 67 | - virtual JSON getJSON() = 0; | 67 | + virtual JSON getJSON(int json_version) = 0; |
| 68 | 68 | ||
| 69 | // Return a unique type code for the object | 69 | // Return a unique type code for the object |
| 70 | virtual object_type_e getTypeCode() const = 0; | 70 | virtual object_type_e getTypeCode() const = 0; |
include/qpdf/QPDFObjectHandle.hh
| @@ -1304,15 +1304,40 @@ class QPDFObjectHandle | @@ -1304,15 +1304,40 @@ class QPDFObjectHandle | ||
| 1304 | QPDF_DLL | 1304 | QPDF_DLL |
| 1305 | std::string unparseBinary(); | 1305 | std::string unparseBinary(); |
| 1306 | 1306 | ||
| 1307 | - // Return encoded as JSON. For most object types, there is an | ||
| 1308 | - // obvious mapping. The JSON is generated as follows: | ||
| 1309 | - // * Names are encoded as strings representing the normalized name | ||
| 1310 | - // in PDF syntax as returned by unparse() | 1307 | + // Return encoded as JSON. The constant JSON::LATEST can be used |
| 1308 | + // to specify the latest available JSON version. The JSON is | ||
| 1309 | + // generated as follows: | ||
| 1310 | + // * Arrays, dictionaries, booleans, nulls, integers, and real | ||
| 1311 | + // numbers are represented by their native JSON types. | ||
| 1312 | + // * Names are encoded as strings representing the canonical | ||
| 1313 | + // representation (after parsing #xx) and preceded by a slash, | ||
| 1314 | + // just as unparse() returns. For example, the JSON for the | ||
| 1315 | + // PDF-syntax name /Text#2fPlain would be "/Text/Plain". | ||
| 1311 | // * Indirect references are encoded as strings containing "obj gen R" | 1316 | // * Indirect references are encoded as strings containing "obj gen R" |
| 1312 | - // * Strings are encoded as UTF-8 strings with unrepresentable binary | ||
| 1313 | - // characters encoded as \uHHHH | ||
| 1314 | - // * Encoding streams just encodes the stream's dictionary; the stream | ||
| 1315 | - // data is not represented | 1317 | + // * Strings |
| 1318 | + // * JSON v1: Strings are encoded as UTF-8 strings with | ||
| 1319 | + // unrepresentable binary characters encoded as \uHHHH. | ||
| 1320 | + // Characters in PDF Doc encoding that don't have | ||
| 1321 | + // bidirectional unicode mappings are not reversible. There is | ||
| 1322 | + // no way to tell the difference between a string that looks | ||
| 1323 | + // like a name or indirect object from an actual name or | ||
| 1324 | + // indirect object. | ||
| 1325 | + // * JSON v2: | ||
| 1326 | + // * Unicode strings and strings encoded with PDF Doc encoding | ||
| 1327 | + // that can be bidrectionally mapped two Unicode (which is | ||
| 1328 | + // all strings without undefined characters) are represented | ||
| 1329 | + // as "u:" followed by the UTF-8 encoded string. Example: | ||
| 1330 | + // "u:potato". | ||
| 1331 | + // * All other strings are represented as "b:" followed by a | ||
| 1332 | + // hexadecimal encoding of the string. Example: "b:0102cacb" | ||
| 1333 | + // * Streams | ||
| 1334 | + // * JSON v1: Only the stream's dictionary is encoded. There is | ||
| 1335 | + // no way tell a stream from a dictionary other than context. | ||
| 1336 | + // * JSON v2: A stream is encoded as {"dict": {...}} with the | ||
| 1337 | + // value being the encoding of the stream's dictionary. Since | ||
| 1338 | + // "dict" does not otherwise represent anything, this is | ||
| 1339 | + // unambiguous. The getStreamJSON() call can be used to add | ||
| 1340 | + // encoding of the stream's data. | ||
| 1316 | // * Object types that are only valid in content streams (inline | 1341 | // * Object types that are only valid in content streams (inline |
| 1317 | // image, operator) as well as "reserved" objects are not | 1342 | // image, operator) as well as "reserved" objects are not |
| 1318 | // representable and will be serialized as "null". | 1343 | // representable and will be serialized as "null". |
| @@ -1321,6 +1346,12 @@ class QPDFObjectHandle | @@ -1321,6 +1346,12 @@ class QPDFObjectHandle | ||
| 1321 | // dereference_indirect applies only to this object. It is not | 1346 | // dereference_indirect applies only to this object. It is not |
| 1322 | // recursive. | 1347 | // recursive. |
| 1323 | QPDF_DLL | 1348 | QPDF_DLL |
| 1349 | + JSON getJSON(int json_version, bool dereference_indirect = false); | ||
| 1350 | + | ||
| 1351 | + // Deprecated version uses v1 for backward compatibility. | ||
| 1352 | + // ABI: remove for qpdf 12 | ||
| 1353 | + [[deprecated("Use getJSON(int version)")]] | ||
| 1354 | + QPDF_DLL | ||
| 1324 | JSON getJSON(bool dereference_indirect = false); | 1355 | JSON getJSON(bool dereference_indirect = false); |
| 1325 | 1356 | ||
| 1326 | // Legacy helper methods for commonly performed operations on | 1357 | // Legacy helper methods for commonly performed operations on |
job.sums
| @@ -6,12 +6,12 @@ include/qpdf/auto_job_c_enc.hh 28446f3c32153a52afa239ea40503e6cc8ac2c026813526a3 | @@ -6,12 +6,12 @@ include/qpdf/auto_job_c_enc.hh 28446f3c32153a52afa239ea40503e6cc8ac2c026813526a3 | ||
| 6 | include/qpdf/auto_job_c_main.hh 940aa6f1ead18ed08ba33f11254e9f042348262c85b91de742f0427094412a80 | 6 | include/qpdf/auto_job_c_main.hh 940aa6f1ead18ed08ba33f11254e9f042348262c85b91de742f0427094412a80 |
| 7 | include/qpdf/auto_job_c_pages.hh b3cc0f21029f6d89efa043dcdbfa183cb59325b6506001c18911614fe8e568ec | 7 | include/qpdf/auto_job_c_pages.hh b3cc0f21029f6d89efa043dcdbfa183cb59325b6506001c18911614fe8e568ec |
| 8 | include/qpdf/auto_job_c_uo.hh ae21b69a1efa9333050f4833d465f6daff87e5b38e5106e49bbef5d4132e4ed1 | 8 | include/qpdf/auto_job_c_uo.hh ae21b69a1efa9333050f4833d465f6daff87e5b38e5106e49bbef5d4132e4ed1 |
| 9 | -job.yml 3c130913b3546f272c06b334ece9aa70450449539db10e39673b5ee79d863f48 | 9 | +job.yml e3d9752ea8810872447190b0b2b913f591ae03dfdd876945adf1bbb76942cd0f |
| 10 | libqpdf/qpdf/auto_job_decl.hh 74df4d7fdbdf51ecd0d58ce1e9844bb5525b9adac5a45f7c9a787ecdda2868df | 10 | libqpdf/qpdf/auto_job_decl.hh 74df4d7fdbdf51ecd0d58ce1e9844bb5525b9adac5a45f7c9a787ecdda2868df |
| 11 | libqpdf/qpdf/auto_job_help.hh a3d1a326a3f8ff61a7d451176acde3bb6c8ad66c1ea7a0b8c5d789917ad3a9ee | 11 | libqpdf/qpdf/auto_job_help.hh a3d1a326a3f8ff61a7d451176acde3bb6c8ad66c1ea7a0b8c5d789917ad3a9ee |
| 12 | -libqpdf/qpdf/auto_job_init.hh c8477a597f037d7de5fd131b008a75f1fe435bba248261abe422e8bfb24c8755 | 12 | +libqpdf/qpdf/auto_job_init.hh 1dcefadac02bb4b3a5d112912483902ad46489b1cacefefd3ebe4f64fc1b8a29 |
| 13 | libqpdf/qpdf/auto_job_json_decl.hh 06caa46eaf71db8a50c046f91866baa8087745a9474319fb7c86d92634cc8297 | 13 | libqpdf/qpdf/auto_job_json_decl.hh 06caa46eaf71db8a50c046f91866baa8087745a9474319fb7c86d92634cc8297 |
| 14 | -libqpdf/qpdf/auto_job_json_init.hh e7047a7c83737adfaae49abc295a579bb9b9e0a4644e911d1656a604cb202208 | 14 | +libqpdf/qpdf/auto_job_json_init.hh 784ff973e7efbf589f6a9b3ad22b3aada5c5393e9c5cd31845b8fe4af6e03f98 |
| 15 | libqpdf/qpdf/auto_job_schema.hh cbbcae166cfecbdbdeb40c5a30870e03604a019a8b4f7a217d554a82431d2e5f | 15 | libqpdf/qpdf/auto_job_schema.hh cbbcae166cfecbdbdeb40c5a30870e03604a019a8b4f7a217d554a82431d2e5f |
| 16 | manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580 | 16 | manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580 |
| 17 | manual/cli.rst 8684ca1f601f2832cded52d1b2f74730f97b7b85b57e31a399231731fbe80d26 | 17 | manual/cli.rst 8684ca1f601f2832cded52d1b2f74730f97b7b85b57e31a399231731fbe80d26 |
job.yml
| @@ -38,6 +38,7 @@ choices: | @@ -38,6 +38,7 @@ choices: | ||
| 38 | - screen | 38 | - screen |
| 39 | json_version: | 39 | json_version: |
| 40 | - 1 | 40 | - 1 |
| 41 | + - 2 | ||
| 41 | - latest | 42 | - latest |
| 42 | json_key: | 43 | json_key: |
| 43 | # The list of selectable top-level keys id duplicated in the | 44 | # The list of selectable top-level keys id duplicated in the |
libqpdf/QPDFJob.cc
| @@ -1053,12 +1053,20 @@ QPDFJob::doJSONObjects(Pipeline* p, bool& first, QPDF& pdf) | @@ -1053,12 +1053,20 @@ QPDFJob::doJSONObjects(Pipeline* p, bool& first, QPDF& pdf) | ||
| 1053 | for (auto& obj: objects) { | 1053 | for (auto& obj: objects) { |
| 1054 | if (all_objects || wanted_og.count(obj.getObjGen())) { | 1054 | if (all_objects || wanted_og.count(obj.getObjGen())) { |
| 1055 | JSON::writeDictionaryItem( | 1055 | JSON::writeDictionaryItem( |
| 1056 | - p, first_object, obj.unparse(), obj.getJSON(true), 1); | 1056 | + p, |
| 1057 | + first_object, | ||
| 1058 | + obj.unparse(), | ||
| 1059 | + obj.getJSON(this->m->json_version, true), | ||
| 1060 | + 1); | ||
| 1057 | } | 1061 | } |
| 1058 | } | 1062 | } |
| 1059 | if (all_objects || m->json_objects.count("trailer")) { | 1063 | if (all_objects || m->json_objects.count("trailer")) { |
| 1060 | JSON::writeDictionaryItem( | 1064 | JSON::writeDictionaryItem( |
| 1061 | - p, first_object, "trailer", pdf.getTrailer().getJSON(true), 1); | 1065 | + p, |
| 1066 | + first_object, | ||
| 1067 | + "trailer", | ||
| 1068 | + pdf.getTrailer().getJSON(this->m->json_version, true), | ||
| 1069 | + 1); | ||
| 1062 | } | 1070 | } |
| 1063 | JSON::writeDictionaryClose(p, first_object, 1); | 1071 | JSON::writeDictionaryClose(p, first_object, 1); |
| 1064 | } | 1072 | } |
| @@ -1080,11 +1088,13 @@ QPDFJob::doJSONObjectinfo(Pipeline* p, bool& first, QPDF& pdf) | @@ -1080,11 +1088,13 @@ QPDFJob::doJSONObjectinfo(Pipeline* p, bool& first, QPDF& pdf) | ||
| 1080 | j_stream.addDictionaryMember("is", JSON::makeBool(is_stream)); | 1088 | j_stream.addDictionaryMember("is", JSON::makeBool(is_stream)); |
| 1081 | j_stream.addDictionaryMember( | 1089 | j_stream.addDictionaryMember( |
| 1082 | "length", | 1090 | "length", |
| 1083 | - (is_stream ? obj.getDict().getKey("/Length").getJSON(true) | 1091 | + (is_stream ? obj.getDict().getKey("/Length").getJSON( |
| 1092 | + this->m->json_version, true) | ||
| 1084 | : JSON::makeNull())); | 1093 | : JSON::makeNull())); |
| 1085 | j_stream.addDictionaryMember( | 1094 | j_stream.addDictionaryMember( |
| 1086 | "filter", | 1095 | "filter", |
| 1087 | - (is_stream ? obj.getDict().getKey("/Filter").getJSON(true) | 1096 | + (is_stream ? obj.getDict().getKey("/Filter").getJSON( |
| 1097 | + this->m->json_version, true) | ||
| 1088 | : JSON::makeNull())); | 1098 | : JSON::makeNull())); |
| 1089 | JSON::writeDictionaryItem( | 1099 | JSON::writeDictionaryItem( |
| 1090 | p, first_object, obj.unparse(), j_details, 1); | 1100 | p, first_object, obj.unparse(), j_details, 1); |
| @@ -1108,7 +1118,8 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) | @@ -1108,7 +1118,8 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) | ||
| 1108 | ++pageno; | 1118 | ++pageno; |
| 1109 | JSON j_page = JSON::makeDictionary(); | 1119 | JSON j_page = JSON::makeDictionary(); |
| 1110 | QPDFObjectHandle page = ph.getObjectHandle(); | 1120 | QPDFObjectHandle page = ph.getObjectHandle(); |
| 1111 | - j_page.addDictionaryMember("object", page.getJSON()); | 1121 | + j_page.addDictionaryMember( |
| 1122 | + "object", page.getJSON(this->m->json_version)); | ||
| 1112 | JSON j_images = j_page.addDictionaryMember("images", JSON::makeArray()); | 1123 | JSON j_images = j_page.addDictionaryMember("images", JSON::makeArray()); |
| 1113 | std::map<std::string, QPDFObjectHandle> images = ph.getImages(); | 1124 | std::map<std::string, QPDFObjectHandle> images = ph.getImages(); |
| 1114 | for (auto const& iter2: images) { | 1125 | for (auto const& iter2: images) { |
| @@ -1116,17 +1127,23 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) | @@ -1116,17 +1127,23 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) | ||
| 1116 | j_image.addDictionaryMember("name", JSON::makeString(iter2.first)); | 1127 | j_image.addDictionaryMember("name", JSON::makeString(iter2.first)); |
| 1117 | QPDFObjectHandle image = iter2.second; | 1128 | QPDFObjectHandle image = iter2.second; |
| 1118 | QPDFObjectHandle dict = image.getDict(); | 1129 | QPDFObjectHandle dict = image.getDict(); |
| 1119 | - j_image.addDictionaryMember("object", image.getJSON()); | ||
| 1120 | j_image.addDictionaryMember( | 1130 | j_image.addDictionaryMember( |
| 1121 | - "width", dict.getKey("/Width").getJSON()); | 1131 | + "object", image.getJSON(this->m->json_version)); |
| 1132 | + j_image.addDictionaryMember( | ||
| 1133 | + "width", dict.getKey("/Width").getJSON(this->m->json_version)); | ||
| 1122 | j_image.addDictionaryMember( | 1134 | j_image.addDictionaryMember( |
| 1123 | - "height", dict.getKey("/Height").getJSON()); | 1135 | + "height", |
| 1136 | + dict.getKey("/Height").getJSON(this->m->json_version)); | ||
| 1124 | j_image.addDictionaryMember( | 1137 | j_image.addDictionaryMember( |
| 1125 | - "colorspace", dict.getKey("/ColorSpace").getJSON()); | 1138 | + "colorspace", |
| 1139 | + dict.getKey("/ColorSpace").getJSON(this->m->json_version)); | ||
| 1126 | j_image.addDictionaryMember( | 1140 | j_image.addDictionaryMember( |
| 1127 | - "bitspercomponent", dict.getKey("/BitsPerComponent").getJSON()); | 1141 | + "bitspercomponent", |
| 1142 | + dict.getKey("/BitsPerComponent") | ||
| 1143 | + .getJSON(this->m->json_version)); | ||
| 1128 | QPDFObjectHandle filters = dict.getKey("/Filter").wrapInArray(); | 1144 | QPDFObjectHandle filters = dict.getKey("/Filter").wrapInArray(); |
| 1129 | - j_image.addDictionaryMember("filter", filters.getJSON()); | 1145 | + j_image.addDictionaryMember( |
| 1146 | + "filter", filters.getJSON(this->m->json_version)); | ||
| 1130 | QPDFObjectHandle decode_parms = dict.getKey("/DecodeParms"); | 1147 | QPDFObjectHandle decode_parms = dict.getKey("/DecodeParms"); |
| 1131 | QPDFObjectHandle dp_array; | 1148 | QPDFObjectHandle dp_array; |
| 1132 | if (decode_parms.isArray()) { | 1149 | if (decode_parms.isArray()) { |
| @@ -1137,7 +1154,8 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) | @@ -1137,7 +1154,8 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) | ||
| 1137 | dp_array.appendItem(decode_parms); | 1154 | dp_array.appendItem(decode_parms); |
| 1138 | } | 1155 | } |
| 1139 | } | 1156 | } |
| 1140 | - j_image.addDictionaryMember("decodeparms", dp_array.getJSON()); | 1157 | + j_image.addDictionaryMember( |
| 1158 | + "decodeparms", dp_array.getJSON(this->m->json_version)); | ||
| 1141 | j_image.addDictionaryMember( | 1159 | j_image.addDictionaryMember( |
| 1142 | "filterable", | 1160 | "filterable", |
| 1143 | JSON::makeBool( | 1161 | JSON::makeBool( |
| @@ -1148,10 +1166,11 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) | @@ -1148,10 +1166,11 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) | ||
| 1148 | j_page.addDictionaryMember("contents", JSON::makeArray()); | 1166 | j_page.addDictionaryMember("contents", JSON::makeArray()); |
| 1149 | std::vector<QPDFObjectHandle> content = ph.getPageContents(); | 1167 | std::vector<QPDFObjectHandle> content = ph.getPageContents(); |
| 1150 | for (auto& iter2: content) { | 1168 | for (auto& iter2: content) { |
| 1151 | - j_contents.addArrayElement(iter2.getJSON()); | 1169 | + j_contents.addArrayElement(iter2.getJSON(this->m->json_version)); |
| 1152 | } | 1170 | } |
| 1153 | j_page.addDictionaryMember( | 1171 | j_page.addDictionaryMember( |
| 1154 | - "label", pldh.getLabelForPage(pageno).getJSON()); | 1172 | + "label", |
| 1173 | + pldh.getLabelForPage(pageno).getJSON(this->m->json_version)); | ||
| 1155 | JSON j_outlines = | 1174 | JSON j_outlines = |
| 1156 | j_page.addDictionaryMember("outlines", JSON::makeArray()); | 1175 | j_page.addDictionaryMember("outlines", JSON::makeArray()); |
| 1157 | std::vector<QPDFOutlineObjectHelper> outlines = | 1176 | std::vector<QPDFOutlineObjectHelper> outlines = |
| @@ -1159,11 +1178,12 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) | @@ -1159,11 +1178,12 @@ QPDFJob::doJSONPages(Pipeline* p, bool& first, QPDF& pdf) | ||
| 1159 | for (auto& oiter: outlines) { | 1178 | for (auto& oiter: outlines) { |
| 1160 | JSON j_outline = j_outlines.addArrayElement(JSON::makeDictionary()); | 1179 | JSON j_outline = j_outlines.addArrayElement(JSON::makeDictionary()); |
| 1161 | j_outline.addDictionaryMember( | 1180 | j_outline.addDictionaryMember( |
| 1162 | - "object", oiter.getObjectHandle().getJSON()); | 1181 | + "object", |
| 1182 | + oiter.getObjectHandle().getJSON(this->m->json_version)); | ||
| 1163 | j_outline.addDictionaryMember( | 1183 | j_outline.addDictionaryMember( |
| 1164 | "title", JSON::makeString(oiter.getTitle())); | 1184 | "title", JSON::makeString(oiter.getTitle())); |
| 1165 | j_outline.addDictionaryMember( | 1185 | j_outline.addDictionaryMember( |
| 1166 | - "dest", oiter.getDest().getJSON(true)); | 1186 | + "dest", oiter.getDest().getJSON(this->m->json_version, true)); |
| 1167 | } | 1187 | } |
| 1168 | j_page.addDictionaryMember("pageposfrom1", JSON::makeInt(1 + pageno)); | 1188 | j_page.addDictionaryMember("pageposfrom1", JSON::makeInt(1 + pageno)); |
| 1169 | JSON::writeArrayItem(p, first_page, j_page, 1); | 1189 | JSON::writeArrayItem(p, first_page, j_page, 1); |
| @@ -1192,25 +1212,29 @@ QPDFJob::doJSONPageLabels(Pipeline* p, bool& first, QPDF& pdf) | @@ -1192,25 +1212,29 @@ QPDFJob::doJSONPageLabels(Pipeline* p, bool& first, QPDF& pdf) | ||
| 1192 | break; | 1212 | break; |
| 1193 | } | 1213 | } |
| 1194 | JSON j_label = j_labels.addArrayElement(JSON::makeDictionary()); | 1214 | JSON j_label = j_labels.addArrayElement(JSON::makeDictionary()); |
| 1195 | - j_label.addDictionaryMember("index", (*iter).getJSON()); | 1215 | + j_label.addDictionaryMember( |
| 1216 | + "index", (*iter).getJSON(this->m->json_version)); | ||
| 1196 | ++iter; | 1217 | ++iter; |
| 1197 | - j_label.addDictionaryMember("label", (*iter).getJSON()); | 1218 | + j_label.addDictionaryMember( |
| 1219 | + "label", (*iter).getJSON(this->m->json_version)); | ||
| 1198 | } | 1220 | } |
| 1199 | } | 1221 | } |
| 1200 | JSON::writeDictionaryItem(p, first, "pagelabels", j_labels, 0); | 1222 | JSON::writeDictionaryItem(p, first, "pagelabels", j_labels, 0); |
| 1201 | } | 1223 | } |
| 1202 | 1224 | ||
| 1203 | -static void | ||
| 1204 | -add_outlines_to_json( | 1225 | +void |
| 1226 | +QPDFJob::addOutlinesToJson( | ||
| 1205 | std::vector<QPDFOutlineObjectHelper> outlines, | 1227 | std::vector<QPDFOutlineObjectHelper> outlines, |
| 1206 | JSON& j, | 1228 | JSON& j, |
| 1207 | std::map<QPDFObjGen, int>& page_numbers) | 1229 | std::map<QPDFObjGen, int>& page_numbers) |
| 1208 | { | 1230 | { |
| 1209 | for (auto& ol: outlines) { | 1231 | for (auto& ol: outlines) { |
| 1210 | JSON jo = j.addArrayElement(JSON::makeDictionary()); | 1232 | JSON jo = j.addArrayElement(JSON::makeDictionary()); |
| 1211 | - jo.addDictionaryMember("object", ol.getObjectHandle().getJSON()); | 1233 | + jo.addDictionaryMember( |
| 1234 | + "object", ol.getObjectHandle().getJSON(this->m->json_version)); | ||
| 1212 | jo.addDictionaryMember("title", JSON::makeString(ol.getTitle())); | 1235 | jo.addDictionaryMember("title", JSON::makeString(ol.getTitle())); |
| 1213 | - jo.addDictionaryMember("dest", ol.getDest().getJSON(true)); | 1236 | + jo.addDictionaryMember( |
| 1237 | + "dest", ol.getDest().getJSON(this->m->json_version, true)); | ||
| 1214 | jo.addDictionaryMember("open", JSON::makeBool(ol.getCount() >= 0)); | 1238 | jo.addDictionaryMember("open", JSON::makeBool(ol.getCount() >= 0)); |
| 1215 | QPDFObjectHandle page = ol.getDestPage(); | 1239 | QPDFObjectHandle page = ol.getDestPage(); |
| 1216 | JSON j_destpage = JSON::makeNull(); | 1240 | JSON j_destpage = JSON::makeNull(); |
| @@ -1222,7 +1246,7 @@ add_outlines_to_json( | @@ -1222,7 +1246,7 @@ add_outlines_to_json( | ||
| 1222 | } | 1246 | } |
| 1223 | jo.addDictionaryMember("destpageposfrom1", j_destpage); | 1247 | jo.addDictionaryMember("destpageposfrom1", j_destpage); |
| 1224 | JSON j_kids = jo.addDictionaryMember("kids", JSON::makeArray()); | 1248 | JSON j_kids = jo.addDictionaryMember("kids", JSON::makeArray()); |
| 1225 | - add_outlines_to_json(ol.getKids(), j_kids, page_numbers); | 1249 | + addOutlinesToJson(ol.getKids(), j_kids, page_numbers); |
| 1226 | } | 1250 | } |
| 1227 | } | 1251 | } |
| 1228 | 1252 | ||
| @@ -1240,7 +1264,7 @@ QPDFJob::doJSONOutlines(Pipeline* p, bool& first, QPDF& pdf) | @@ -1240,7 +1264,7 @@ QPDFJob::doJSONOutlines(Pipeline* p, bool& first, QPDF& pdf) | ||
| 1240 | 1264 | ||
| 1241 | JSON j_outlines = JSON::makeArray(); | 1265 | JSON j_outlines = JSON::makeArray(); |
| 1242 | QPDFOutlineDocumentHelper odh(pdf); | 1266 | QPDFOutlineDocumentHelper odh(pdf); |
| 1243 | - add_outlines_to_json(odh.getTopLevelOutlines(), j_outlines, page_numbers); | 1267 | + addOutlinesToJson(odh.getTopLevelOutlines(), j_outlines, page_numbers); |
| 1244 | JSON::writeDictionaryItem(p, first, "outlines", j_outlines, 0); | 1268 | JSON::writeDictionaryItem(p, first, "outlines", j_outlines, 0); |
| 1245 | } | 1269 | } |
| 1246 | 1270 | ||
| @@ -1265,9 +1289,11 @@ QPDFJob::doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf) | @@ -1265,9 +1289,11 @@ QPDFJob::doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf) | ||
| 1265 | QPDFFormFieldObjectHelper ffh = afdh.getFieldForAnnotation(aoh); | 1289 | QPDFFormFieldObjectHelper ffh = afdh.getFieldForAnnotation(aoh); |
| 1266 | JSON j_field = j_fields.addArrayElement(JSON::makeDictionary()); | 1290 | JSON j_field = j_fields.addArrayElement(JSON::makeDictionary()); |
| 1267 | j_field.addDictionaryMember( | 1291 | j_field.addDictionaryMember( |
| 1268 | - "object", ffh.getObjectHandle().getJSON()); | 1292 | + "object", ffh.getObjectHandle().getJSON(this->m->json_version)); |
| 1269 | j_field.addDictionaryMember( | 1293 | j_field.addDictionaryMember( |
| 1270 | - "parent", ffh.getObjectHandle().getKey("/Parent").getJSON()); | 1294 | + "parent", |
| 1295 | + ffh.getObjectHandle().getKey("/Parent").getJSON( | ||
| 1296 | + this->m->json_version)); | ||
| 1271 | j_field.addDictionaryMember( | 1297 | j_field.addDictionaryMember( |
| 1272 | "pageposfrom1", JSON::makeInt(pagepos1)); | 1298 | "pageposfrom1", JSON::makeInt(pagepos1)); |
| 1273 | j_field.addDictionaryMember( | 1299 | j_field.addDictionaryMember( |
| @@ -1282,9 +1308,11 @@ QPDFJob::doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf) | @@ -1282,9 +1308,11 @@ QPDFJob::doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf) | ||
| 1282 | "alternativename", JSON::makeString(ffh.getAlternativeName())); | 1308 | "alternativename", JSON::makeString(ffh.getAlternativeName())); |
| 1283 | j_field.addDictionaryMember( | 1309 | j_field.addDictionaryMember( |
| 1284 | "mappingname", JSON::makeString(ffh.getMappingName())); | 1310 | "mappingname", JSON::makeString(ffh.getMappingName())); |
| 1285 | - j_field.addDictionaryMember("value", ffh.getValue().getJSON()); | ||
| 1286 | j_field.addDictionaryMember( | 1311 | j_field.addDictionaryMember( |
| 1287 | - "defaultvalue", ffh.getDefaultValue().getJSON()); | 1312 | + "value", ffh.getValue().getJSON(this->m->json_version)); |
| 1313 | + j_field.addDictionaryMember( | ||
| 1314 | + "defaultvalue", | ||
| 1315 | + ffh.getDefaultValue().getJSON(this->m->json_version)); | ||
| 1288 | j_field.addDictionaryMember( | 1316 | j_field.addDictionaryMember( |
| 1289 | "quadding", JSON::makeInt(ffh.getQuadding())); | 1317 | "quadding", JSON::makeInt(ffh.getQuadding())); |
| 1290 | j_field.addDictionaryMember( | 1318 | j_field.addDictionaryMember( |
| @@ -1303,7 +1331,7 @@ QPDFJob::doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf) | @@ -1303,7 +1331,7 @@ QPDFJob::doJSONAcroform(Pipeline* p, bool& first, QPDF& pdf) | ||
| 1303 | JSON j_annot = j_field.addDictionaryMember( | 1331 | JSON j_annot = j_field.addDictionaryMember( |
| 1304 | "annotation", JSON::makeDictionary()); | 1332 | "annotation", JSON::makeDictionary()); |
| 1305 | j_annot.addDictionaryMember( | 1333 | j_annot.addDictionaryMember( |
| 1306 | - "object", aoh.getObjectHandle().getJSON()); | 1334 | + "object", aoh.getObjectHandle().getJSON(this->m->json_version)); |
| 1307 | j_annot.addDictionaryMember( | 1335 | j_annot.addDictionaryMember( |
| 1308 | "appearancestate", JSON::makeString(aoh.getAppearanceState())); | 1336 | "appearancestate", JSON::makeString(aoh.getAppearanceState())); |
| 1309 | j_annot.addDictionaryMember( | 1337 | j_annot.addDictionaryMember( |
| @@ -1621,7 +1649,8 @@ QPDFJob::doJSON(QPDF& pdf, Pipeline* p) | @@ -1621,7 +1649,8 @@ QPDFJob::doJSON(QPDF& pdf, Pipeline* p) | ||
| 1621 | // change is made to the JSON format. Clients of the JSON are to | 1649 | // change is made to the JSON format. Clients of the JSON are to |
| 1622 | // ignore unrecognized keys, so we only update the version of a | 1650 | // ignore unrecognized keys, so we only update the version of a |
| 1623 | // key disappears or if its value changes meaning. | 1651 | // key disappears or if its value changes meaning. |
| 1624 | - JSON::writeDictionaryItem(p, first, "version", JSON::makeInt(1), 0); | 1652 | + JSON::writeDictionaryItem( |
| 1653 | + p, first, "version", JSON::makeInt(this->m->json_version), 0); | ||
| 1625 | JSON j_params = JSON::makeDictionary(); | 1654 | JSON j_params = JSON::makeDictionary(); |
| 1626 | std::string decode_level_str; | 1655 | std::string decode_level_str; |
| 1627 | switch (m->decode_level) { | 1656 | switch (m->decode_level) { |
libqpdf/QPDFJob_config.cc
| @@ -235,11 +235,11 @@ QPDFJob::Config* | @@ -235,11 +235,11 @@ QPDFJob::Config* | ||
| 235 | QPDFJob::Config::json(std::string const& parameter) | 235 | QPDFJob::Config::json(std::string const& parameter) |
| 236 | { | 236 | { |
| 237 | if (parameter.empty() || (parameter == "latest")) { | 237 | if (parameter.empty() || (parameter == "latest")) { |
| 238 | - o.m->json_version = 1; | 238 | + o.m->json_version = JSON::LATEST; |
| 239 | } else { | 239 | } else { |
| 240 | o.m->json_version = QUtil::string_to_int(parameter.c_str()); | 240 | o.m->json_version = QUtil::string_to_int(parameter.c_str()); |
| 241 | } | 241 | } |
| 242 | - if (o.m->json_version != 1) { | 242 | + if ((o.m->json_version < 1) || (o.m->json_version > JSON::LATEST)) { |
| 243 | usage(std::string("unsupported json version ") + parameter); | 243 | usage(std::string("unsupported json version ") + parameter); |
| 244 | } | 244 | } |
| 245 | o.m->require_outfile = false; | 245 | o.m->require_outfile = false; |
libqpdf/QPDFObjectHandle.cc
| @@ -1775,9 +1775,16 @@ QPDFObjectHandle::unparseBinary() | @@ -1775,9 +1775,16 @@ QPDFObjectHandle::unparseBinary() | ||
| 1775 | } | 1775 | } |
| 1776 | } | 1776 | } |
| 1777 | 1777 | ||
| 1778 | +// Deprecated versionless getJSON to be removed in qpdf 12 | ||
| 1778 | JSON | 1779 | JSON |
| 1779 | QPDFObjectHandle::getJSON(bool dereference_indirect) | 1780 | QPDFObjectHandle::getJSON(bool dereference_indirect) |
| 1780 | { | 1781 | { |
| 1782 | + return getJSON(1, dereference_indirect); | ||
| 1783 | +} | ||
| 1784 | + | ||
| 1785 | +JSON | ||
| 1786 | +QPDFObjectHandle::getJSON(int json_version, bool dereference_indirect) | ||
| 1787 | +{ | ||
| 1781 | if ((!dereference_indirect) && this->isIndirect()) { | 1788 | if ((!dereference_indirect) && this->isIndirect()) { |
| 1782 | return JSON::makeString(unparse()); | 1789 | return JSON::makeString(unparse()); |
| 1783 | } else { | 1790 | } else { |
| @@ -1786,7 +1793,7 @@ QPDFObjectHandle::getJSON(bool dereference_indirect) | @@ -1786,7 +1793,7 @@ QPDFObjectHandle::getJSON(bool dereference_indirect) | ||
| 1786 | throw std::logic_error( | 1793 | throw std::logic_error( |
| 1787 | "QPDFObjectHandle: attempting to unparse a reserved object"); | 1794 | "QPDFObjectHandle: attempting to unparse a reserved object"); |
| 1788 | } | 1795 | } |
| 1789 | - return this->obj->getJSON(); | 1796 | + return this->obj->getJSON(json_version); |
| 1790 | } | 1797 | } |
| 1791 | } | 1798 | } |
| 1792 | 1799 |
libqpdf/QPDF_Array.cc
| @@ -34,12 +34,12 @@ QPDF_Array::unparse() | @@ -34,12 +34,12 @@ QPDF_Array::unparse() | ||
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | JSON | 36 | JSON |
| 37 | -QPDF_Array::getJSON() | 37 | +QPDF_Array::getJSON(int json_version) |
| 38 | { | 38 | { |
| 39 | JSON j = JSON::makeArray(); | 39 | JSON j = JSON::makeArray(); |
| 40 | size_t size = this->elements.size(); | 40 | size_t size = this->elements.size(); |
| 41 | for (size_t i = 0; i < size; ++i) { | 41 | for (size_t i = 0; i < size; ++i) { |
| 42 | - j.addArrayElement(this->elements.at(i).getJSON()); | 42 | + j.addArrayElement(this->elements.at(i).getJSON(json_version)); |
| 43 | } | 43 | } |
| 44 | return j; | 44 | return j; |
| 45 | } | 45 | } |
libqpdf/QPDF_Bool.cc
libqpdf/QPDF_Dictionary.cc
| @@ -32,13 +32,14 @@ QPDF_Dictionary::unparse() | @@ -32,13 +32,14 @@ QPDF_Dictionary::unparse() | ||
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | JSON | 34 | JSON |
| 35 | -QPDF_Dictionary::getJSON() | 35 | +QPDF_Dictionary::getJSON(int json_version) |
| 36 | { | 36 | { |
| 37 | JSON j = JSON::makeDictionary(); | 37 | JSON j = JSON::makeDictionary(); |
| 38 | for (auto& iter: this->items) { | 38 | for (auto& iter: this->items) { |
| 39 | if (!iter.second.isNull()) { | 39 | if (!iter.second.isNull()) { |
| 40 | j.addDictionaryMember( | 40 | j.addDictionaryMember( |
| 41 | - QPDF_Name::normalizeName(iter.first), iter.second.getJSON()); | 41 | + QPDF_Name::normalizeName(iter.first), |
| 42 | + iter.second.getJSON(json_version)); | ||
| 42 | } | 43 | } |
| 43 | } | 44 | } |
| 44 | return j; | 45 | return j; |
libqpdf/QPDF_InlineImage.cc
libqpdf/QPDF_Integer.cc
libqpdf/QPDF_Name.cc
| @@ -40,7 +40,7 @@ QPDF_Name::unparse() | @@ -40,7 +40,7 @@ QPDF_Name::unparse() | ||
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | JSON | 42 | JSON |
| 43 | -QPDF_Name::getJSON() | 43 | +QPDF_Name::getJSON(int json_version) |
| 44 | { | 44 | { |
| 45 | return JSON::makeString(normalizeName(this->name)); | 45 | return JSON::makeString(normalizeName(this->name)); |
| 46 | } | 46 | } |
libqpdf/QPDF_Null.cc
libqpdf/QPDF_Operator.cc
libqpdf/QPDF_Real.cc
| @@ -20,7 +20,7 @@ QPDF_Real::unparse() | @@ -20,7 +20,7 @@ QPDF_Real::unparse() | ||
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | JSON | 22 | JSON |
| 23 | -QPDF_Real::getJSON() | 23 | +QPDF_Real::getJSON(int json_version) |
| 24 | { | 24 | { |
| 25 | // While PDF allows .x or -.x, JSON does not. Rather than | 25 | // While PDF allows .x or -.x, JSON does not. Rather than |
| 26 | // converting from string to double and back, just handle this as a | 26 | // converting from string to double and back, just handle this as a |
libqpdf/QPDF_Reserved.cc
| @@ -10,7 +10,7 @@ QPDF_Reserved::unparse() | @@ -10,7 +10,7 @@ QPDF_Reserved::unparse() | ||
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | JSON | 12 | JSON |
| 13 | -QPDF_Reserved::getJSON() | 13 | +QPDF_Reserved::getJSON(int json_version) |
| 14 | { | 14 | { |
| 15 | throw std::logic_error("attempt to generate JSON from QPDF_Reserved"); | 15 | throw std::logic_error("attempt to generate JSON from QPDF_Reserved"); |
| 16 | return JSON::makeNull(); | 16 | return JSON::makeNull(); |
libqpdf/QPDF_Stream.cc
| @@ -151,9 +151,10 @@ QPDF_Stream::unparse() | @@ -151,9 +151,10 @@ QPDF_Stream::unparse() | ||
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | JSON | 153 | JSON |
| 154 | -QPDF_Stream::getJSON() | 154 | +QPDF_Stream::getJSON(int json_version) |
| 155 | { | 155 | { |
| 156 | - return this->stream_dict.getJSON(); | 156 | + // QXXXQ |
| 157 | + return this->stream_dict.getJSON(json_version); | ||
| 157 | } | 158 | } |
| 158 | 159 | ||
| 159 | QPDFObject::object_type_e | 160 | QPDFObject::object_type_e |
libqpdf/QPDF_String.cc
| @@ -43,8 +43,9 @@ QPDF_String::unparse() | @@ -43,8 +43,9 @@ QPDF_String::unparse() | ||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | JSON | 45 | JSON |
| 46 | -QPDF_String::getJSON() | 46 | +QPDF_String::getJSON(int json_version) |
| 47 | { | 47 | { |
| 48 | + // QXXXQ | ||
| 48 | return JSON::makeString(getUTF8Val()); | 49 | return JSON::makeString(getUTF8Val()); |
| 49 | } | 50 | } |
| 50 | 51 |
libqpdf/qpdf/QPDF_Array.hh
| @@ -14,7 +14,7 @@ class QPDF_Array: public QPDFObject | @@ -14,7 +14,7 @@ class QPDF_Array: public QPDFObject | ||
| 14 | QPDF_Array(SparseOHArray const& items); | 14 | QPDF_Array(SparseOHArray const& items); |
| 15 | virtual ~QPDF_Array() = default; | 15 | virtual ~QPDF_Array() = default; |
| 16 | virtual std::string unparse(); | 16 | virtual std::string unparse(); |
| 17 | - virtual JSON getJSON(); | 17 | + virtual JSON getJSON(int json_version); |
| 18 | virtual QPDFObject::object_type_e getTypeCode() const; | 18 | virtual QPDFObject::object_type_e getTypeCode() const; |
| 19 | virtual char const* getTypeName() const; | 19 | virtual char const* getTypeName() const; |
| 20 | virtual void setDescription(QPDF*, std::string const&); | 20 | virtual void setDescription(QPDF*, std::string const&); |
libqpdf/qpdf/QPDF_Bool.hh
| @@ -9,7 +9,7 @@ class QPDF_Bool: public QPDFObject | @@ -9,7 +9,7 @@ class QPDF_Bool: public QPDFObject | ||
| 9 | QPDF_Bool(bool val); | 9 | QPDF_Bool(bool val); |
| 10 | virtual ~QPDF_Bool() = default; | 10 | virtual ~QPDF_Bool() = default; |
| 11 | virtual std::string unparse(); | 11 | virtual std::string unparse(); |
| 12 | - virtual JSON getJSON(); | 12 | + virtual JSON getJSON(int json_version); |
| 13 | virtual QPDFObject::object_type_e getTypeCode() const; | 13 | virtual QPDFObject::object_type_e getTypeCode() const; |
| 14 | virtual char const* getTypeName() const; | 14 | virtual char const* getTypeName() const; |
| 15 | bool getVal() const; | 15 | bool getVal() const; |
libqpdf/qpdf/QPDF_Dictionary.hh
| @@ -14,7 +14,7 @@ class QPDF_Dictionary: public QPDFObject | @@ -14,7 +14,7 @@ class QPDF_Dictionary: public QPDFObject | ||
| 14 | QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items); | 14 | QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items); |
| 15 | virtual ~QPDF_Dictionary() = default; | 15 | virtual ~QPDF_Dictionary() = default; |
| 16 | virtual std::string unparse(); | 16 | virtual std::string unparse(); |
| 17 | - virtual JSON getJSON(); | 17 | + virtual JSON getJSON(int json_version); |
| 18 | virtual QPDFObject::object_type_e getTypeCode() const; | 18 | virtual QPDFObject::object_type_e getTypeCode() const; |
| 19 | virtual char const* getTypeName() const; | 19 | virtual char const* getTypeName() const; |
| 20 | virtual void setDescription(QPDF*, std::string const&); | 20 | virtual void setDescription(QPDF*, std::string const&); |
libqpdf/qpdf/QPDF_InlineImage.hh
| @@ -9,7 +9,7 @@ class QPDF_InlineImage: public QPDFObject | @@ -9,7 +9,7 @@ class QPDF_InlineImage: public QPDFObject | ||
| 9 | QPDF_InlineImage(std::string const& val); | 9 | QPDF_InlineImage(std::string const& val); |
| 10 | virtual ~QPDF_InlineImage() = default; | 10 | virtual ~QPDF_InlineImage() = default; |
| 11 | virtual std::string unparse(); | 11 | virtual std::string unparse(); |
| 12 | - virtual JSON getJSON(); | 12 | + virtual JSON getJSON(int json_version); |
| 13 | virtual QPDFObject::object_type_e getTypeCode() const; | 13 | virtual QPDFObject::object_type_e getTypeCode() const; |
| 14 | virtual char const* getTypeName() const; | 14 | virtual char const* getTypeName() const; |
| 15 | std::string getVal() const; | 15 | std::string getVal() const; |
libqpdf/qpdf/QPDF_Integer.hh
| @@ -9,7 +9,7 @@ class QPDF_Integer: public QPDFObject | @@ -9,7 +9,7 @@ class QPDF_Integer: public QPDFObject | ||
| 9 | QPDF_Integer(long long val); | 9 | QPDF_Integer(long long val); |
| 10 | virtual ~QPDF_Integer() = default; | 10 | virtual ~QPDF_Integer() = default; |
| 11 | virtual std::string unparse(); | 11 | virtual std::string unparse(); |
| 12 | - virtual JSON getJSON(); | 12 | + virtual JSON getJSON(int json_version); |
| 13 | virtual QPDFObject::object_type_e getTypeCode() const; | 13 | virtual QPDFObject::object_type_e getTypeCode() const; |
| 14 | virtual char const* getTypeName() const; | 14 | virtual char const* getTypeName() const; |
| 15 | long long getVal() const; | 15 | long long getVal() const; |
libqpdf/qpdf/QPDF_Name.hh
| @@ -9,7 +9,7 @@ class QPDF_Name: public QPDFObject | @@ -9,7 +9,7 @@ class QPDF_Name: public QPDFObject | ||
| 9 | QPDF_Name(std::string const& name); | 9 | QPDF_Name(std::string const& name); |
| 10 | virtual ~QPDF_Name() = default; | 10 | virtual ~QPDF_Name() = default; |
| 11 | virtual std::string unparse(); | 11 | virtual std::string unparse(); |
| 12 | - virtual JSON getJSON(); | 12 | + virtual JSON getJSON(int json_version); |
| 13 | virtual QPDFObject::object_type_e getTypeCode() const; | 13 | virtual QPDFObject::object_type_e getTypeCode() const; |
| 14 | virtual char const* getTypeName() const; | 14 | virtual char const* getTypeName() const; |
| 15 | std::string getName() const; | 15 | std::string getName() const; |
libqpdf/qpdf/QPDF_Null.hh
| @@ -8,7 +8,7 @@ class QPDF_Null: public QPDFObject | @@ -8,7 +8,7 @@ class QPDF_Null: public QPDFObject | ||
| 8 | public: | 8 | public: |
| 9 | virtual ~QPDF_Null() = default; | 9 | virtual ~QPDF_Null() = default; |
| 10 | virtual std::string unparse(); | 10 | virtual std::string unparse(); |
| 11 | - virtual JSON getJSON(); | 11 | + virtual JSON getJSON(int json_version); |
| 12 | virtual QPDFObject::object_type_e getTypeCode() const; | 12 | virtual QPDFObject::object_type_e getTypeCode() const; |
| 13 | virtual char const* getTypeName() const; | 13 | virtual char const* getTypeName() const; |
| 14 | }; | 14 | }; |
libqpdf/qpdf/QPDF_Operator.hh
| @@ -9,7 +9,7 @@ class QPDF_Operator: public QPDFObject | @@ -9,7 +9,7 @@ class QPDF_Operator: public QPDFObject | ||
| 9 | QPDF_Operator(std::string const& val); | 9 | QPDF_Operator(std::string const& val); |
| 10 | virtual ~QPDF_Operator() = default; | 10 | virtual ~QPDF_Operator() = default; |
| 11 | virtual std::string unparse(); | 11 | virtual std::string unparse(); |
| 12 | - virtual JSON getJSON(); | 12 | + virtual JSON getJSON(int json_version); |
| 13 | virtual QPDFObject::object_type_e getTypeCode() const; | 13 | virtual QPDFObject::object_type_e getTypeCode() const; |
| 14 | virtual char const* getTypeName() const; | 14 | virtual char const* getTypeName() const; |
| 15 | std::string getVal() const; | 15 | std::string getVal() const; |
libqpdf/qpdf/QPDF_Real.hh
| @@ -10,7 +10,7 @@ class QPDF_Real: public QPDFObject | @@ -10,7 +10,7 @@ class QPDF_Real: public QPDFObject | ||
| 10 | QPDF_Real(double value, int decimal_places, bool trim_trailing_zeroes); | 10 | QPDF_Real(double value, int decimal_places, bool trim_trailing_zeroes); |
| 11 | virtual ~QPDF_Real() = default; | 11 | virtual ~QPDF_Real() = default; |
| 12 | virtual std::string unparse(); | 12 | virtual std::string unparse(); |
| 13 | - virtual JSON getJSON(); | 13 | + virtual JSON getJSON(int json_version); |
| 14 | virtual QPDFObject::object_type_e getTypeCode() const; | 14 | virtual QPDFObject::object_type_e getTypeCode() const; |
| 15 | virtual char const* getTypeName() const; | 15 | virtual char const* getTypeName() const; |
| 16 | std::string getVal(); | 16 | std::string getVal(); |
libqpdf/qpdf/QPDF_Reserved.hh
| @@ -8,7 +8,7 @@ class QPDF_Reserved: public QPDFObject | @@ -8,7 +8,7 @@ class QPDF_Reserved: public QPDFObject | ||
| 8 | public: | 8 | public: |
| 9 | virtual ~QPDF_Reserved() = default; | 9 | virtual ~QPDF_Reserved() = default; |
| 10 | virtual std::string unparse(); | 10 | virtual std::string unparse(); |
| 11 | - virtual JSON getJSON(); | 11 | + virtual JSON getJSON(int json_version); |
| 12 | virtual QPDFObject::object_type_e getTypeCode() const; | 12 | virtual QPDFObject::object_type_e getTypeCode() const; |
| 13 | virtual char const* getTypeName() const; | 13 | virtual char const* getTypeName() const; |
| 14 | }; | 14 | }; |
libqpdf/qpdf/QPDF_Stream.hh
| @@ -25,7 +25,7 @@ class QPDF_Stream: public QPDFObject | @@ -25,7 +25,7 @@ class QPDF_Stream: public QPDFObject | ||
| 25 | size_t length); | 25 | size_t length); |
| 26 | virtual ~QPDF_Stream() = default; | 26 | virtual ~QPDF_Stream() = default; |
| 27 | virtual std::string unparse(); | 27 | virtual std::string unparse(); |
| 28 | - virtual JSON getJSON(); | 28 | + virtual JSON getJSON(int json_version); |
| 29 | virtual QPDFObject::object_type_e getTypeCode() const; | 29 | virtual QPDFObject::object_type_e getTypeCode() const; |
| 30 | virtual char const* getTypeName() const; | 30 | virtual char const* getTypeName() const; |
| 31 | virtual void setDescription(QPDF*, std::string const&); | 31 | virtual void setDescription(QPDF*, std::string const&); |
libqpdf/qpdf/QPDF_String.hh
| @@ -15,7 +15,7 @@ class QPDF_String: public QPDFObject | @@ -15,7 +15,7 @@ class QPDF_String: public QPDFObject | ||
| 15 | virtual QPDFObject::object_type_e getTypeCode() const; | 15 | virtual QPDFObject::object_type_e getTypeCode() const; |
| 16 | virtual char const* getTypeName() const; | 16 | virtual char const* getTypeName() const; |
| 17 | std::string unparse(bool force_binary); | 17 | std::string unparse(bool force_binary); |
| 18 | - virtual JSON getJSON(); | 18 | + virtual JSON getJSON(int json_version); |
| 19 | std::string getVal() const; | 19 | std::string getVal() const; |
| 20 | std::string getUTF8Val() const; | 20 | std::string getUTF8Val() const; |
| 21 | 21 |
libqpdf/qpdf/auto_job_init.hh
| @@ -19,7 +19,7 @@ static char const* decode_level_choices[] = {"none", "generalized", "specialized | @@ -19,7 +19,7 @@ static char const* decode_level_choices[] = {"none", "generalized", "specialized | ||
| 19 | static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0}; | 19 | static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0}; |
| 20 | static char const* remove_unref_choices[] = {"auto", "yes", "no", 0}; | 20 | static char const* remove_unref_choices[] = {"auto", "yes", "no", 0}; |
| 21 | static char const* flatten_choices[] = {"all", "print", "screen", 0}; | 21 | static char const* flatten_choices[] = {"all", "print", "screen", 0}; |
| 22 | -static char const* json_version_choices[] = {"1", "latest", 0}; | 22 | +static char const* json_version_choices[] = {"1", "2", "latest", 0}; |
| 23 | static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0}; | 23 | static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0}; |
| 24 | static char const* print128_choices[] = {"full", "low", "none", 0}; | 24 | static char const* print128_choices[] = {"full", "low", "none", 0}; |
| 25 | static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0}; | 25 | static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0}; |
libqpdf/qpdf/auto_job_json_init.hh
| @@ -12,7 +12,7 @@ static char const* decode_level_choices[] = {"none", "generalized", "specialized | @@ -12,7 +12,7 @@ static char const* decode_level_choices[] = {"none", "generalized", "specialized | ||
| 12 | static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0}; | 12 | static char const* object_streams_choices[] = {"disable", "preserve", "generate", 0}; |
| 13 | static char const* remove_unref_choices[] = {"auto", "yes", "no", 0}; | 13 | static char const* remove_unref_choices[] = {"auto", "yes", "no", 0}; |
| 14 | static char const* flatten_choices[] = {"all", "print", "screen", 0}; | 14 | static char const* flatten_choices[] = {"all", "print", "screen", 0}; |
| 15 | -static char const* json_version_choices[] = {"1", "latest", 0}; | 15 | +static char const* json_version_choices[] = {"1", "2", "latest", 0}; |
| 16 | static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0}; | 16 | static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "objectinfo", "objects", "outlines", "pagelabels", "pages", 0}; |
| 17 | static char const* print128_choices[] = {"full", "low", "none", 0}; | 17 | static char const* print128_choices[] = {"full", "low", "none", 0}; |
| 18 | static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0}; | 18 | static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0}; |
libtests/json.cc
| @@ -100,10 +100,12 @@ test_main() | @@ -100,10 +100,12 @@ test_main() | ||
| 100 | " ],\n" | 100 | " ],\n" |
| 101 | " \"yes\": false\n" | 101 | " \"yes\": false\n" |
| 102 | "}"); | 102 | "}"); |
| 103 | - check(QPDFObjectHandle::newReal("0.12").getJSON(), "0.12"); | ||
| 104 | - check(QPDFObjectHandle::newReal(".34").getJSON(), "0.34"); | ||
| 105 | - check(QPDFObjectHandle::newReal("-0.56").getJSON(), "-0.56"); | ||
| 106 | - check(QPDFObjectHandle::newReal("-.78").getJSON(), "-0.78"); | 103 | + for (int i = 1; i <= JSON::LATEST; ++i) { |
| 104 | + check(QPDFObjectHandle::newReal("0.12").getJSON(i), "0.12"); | ||
| 105 | + check(QPDFObjectHandle::newReal(".34").getJSON(i), "0.34"); | ||
| 106 | + check(QPDFObjectHandle::newReal("-0.56").getJSON(i), "-0.56"); | ||
| 107 | + check(QPDFObjectHandle::newReal("-.78").getJSON(i), "-0.78"); | ||
| 108 | + } | ||
| 107 | JSON jmap2 = JSON::parse(R"({"a": 1, "b": "two", "c": [true]})"); | 109 | JSON jmap2 = JSON::parse(R"({"a": 1, "b": "two", "c": [true]})"); |
| 108 | std::map<std::string, std::string> dvalue; | 110 | std::map<std::string, std::string> dvalue; |
| 109 | assert(jmap2.forEachDictItem( | 111 | assert(jmap2.forEachDictItem( |
qpdf/qtest/qpdf.test
| @@ -4279,7 +4279,7 @@ foreach my $d (@encrypted_files) | @@ -4279,7 +4279,7 @@ foreach my $d (@encrypted_files) | ||
| 4279 | my $enc_details = ""; | 4279 | my $enc_details = ""; |
| 4280 | my $enc_json = | 4280 | my $enc_json = |
| 4281 | "{\n" . | 4281 | "{\n" . |
| 4282 | - " \"version\": 1,\n" . | 4282 | + " \"version\": 2,\n" . |
| 4283 | " \"parameters\": {\n" . | 4283 | " \"parameters\": {\n" . |
| 4284 | " \"decodelevel\": \"generalized\"\n" . | 4284 | " \"decodelevel\": \"generalized\"\n" . |
| 4285 | " },\n" . | 4285 | " },\n" . |
qpdf/qtest/qpdf/direct-pages-json-objects.out
qpdf/qtest/qpdf/direct-pages-json-pages.out
qpdf/qtest/qpdf/optimize-images-defaults-json.out
qpdf/qtest/qpdf/optimize-images-image-streams-json.out
qpdf/qtest/qpdf/optimize-images-inline-images-all-size-json.out
qpdf/qtest/qpdf/optimize-images-inline-images-json.out
qpdf/qtest/qpdf/optimize-images-inline-images-keep-all-json.out
qpdf/qtest/qpdf/optimize-images-inline-images-keep-some-json.out
qpdf/qtest/qpdf/optimize-images-min-area-all-json.out
qpdf/qtest/qpdf/optimize-images-min-area-json.out
qpdf/qtest/qpdf/optimize-images-min-height-json.out
qpdf/qtest/qpdf/optimize-images-min-width-json.out
qpdf/qtest/qpdf/optimize-images-unsupported-json.out
qpdf/qtest/qpdf/page_api_2-json-objects.out
qpdf/qtest/qpdf/page_api_2-json-pages.out
qpdf/test_driver.cc
| @@ -1922,7 +1922,7 @@ test_50(QPDF& pdf, char const* arg2) | @@ -1922,7 +1922,7 @@ test_50(QPDF& pdf, char const* arg2) | ||
| 1922 | QPDFObjectHandle d1 = pdf.getTrailer().getKey("/Dict1"); | 1922 | QPDFObjectHandle d1 = pdf.getTrailer().getKey("/Dict1"); |
| 1923 | QPDFObjectHandle d2 = pdf.getTrailer().getKey("/Dict2"); | 1923 | QPDFObjectHandle d2 = pdf.getTrailer().getKey("/Dict2"); |
| 1924 | d1.mergeResources(d2); | 1924 | d1.mergeResources(d2); |
| 1925 | - std::cout << d1.getJSON().unparse() << std::endl; | 1925 | + std::cout << d1.getJSON(JSON::LATEST).unparse() << std::endl; |
| 1926 | // Top-level type mismatch | 1926 | // Top-level type mismatch |
| 1927 | d1.mergeResources(d2.getKey("/k1")); | 1927 | d1.mergeResources(d2.getKey("/k1")); |
| 1928 | for (auto const& name: d1.getResourceNames()) { | 1928 | for (auto const& name: d1.getResourceNames()) { |
| @@ -3114,7 +3114,7 @@ test_87(QPDF& pdf, char const* arg2) | @@ -3114,7 +3114,7 @@ test_87(QPDF& pdf, char const* arg2) | ||
| 3114 | }); | 3114 | }); |
| 3115 | assert(dict.unparse() == "<< /A 2 >>"); | 3115 | assert(dict.unparse() == "<< /A 2 >>"); |
| 3116 | assert(dict.getKeys() == std::set<std::string>({"/A"})); | 3116 | assert(dict.getKeys() == std::set<std::string>({"/A"})); |
| 3117 | - assert(dict.getJSON().unparse() == "{\n \"/A\": 2\n}"); | 3117 | + assert(dict.getJSON(JSON::LATEST).unparse() == "{\n \"/A\": 2\n}"); |
| 3118 | } | 3118 | } |
| 3119 | 3119 | ||
| 3120 | static void | 3120 | static void |