Commit ae9455bf449a22329507efd01455d5e9322cf134
1 parent
ce714ac9
Implement --json-objects
Showing
1 changed file
with
60 additions
and
19 deletions
qpdf/qpdf.cc
| ... | ... | @@ -195,6 +195,7 @@ struct Options |
| 195 | 195 | bool show_page_images; |
| 196 | 196 | bool json; |
| 197 | 197 | std::set<std::string> json_keys; |
| 198 | + std::set<std::string> json_objects; | |
| 198 | 199 | bool check; |
| 199 | 200 | std::vector<PageSpec> page_specs; |
| 200 | 201 | std::map<std::string, RotationSpec> rotations; |
| ... | ... | @@ -344,6 +345,26 @@ static JSON json_schema(std::set<std::string>* keys = 0) |
| 344 | 345 | return schema; |
| 345 | 346 | } |
| 346 | 347 | |
| 348 | +static void parse_object_id(std::string const& objspec, | |
| 349 | + bool& trailer, int& obj, int& gen) | |
| 350 | +{ | |
| 351 | + if (objspec == "trailer") | |
| 352 | + { | |
| 353 | + trailer = true; | |
| 354 | + } | |
| 355 | + else | |
| 356 | + { | |
| 357 | + trailer = false; | |
| 358 | + obj = QUtil::string_to_int(objspec.c_str()); | |
| 359 | + size_t comma = objspec.find(','); | |
| 360 | + if ((comma != std::string::npos) && (comma + 1 < objspec.length())) | |
| 361 | + { | |
| 362 | + gen = QUtil::string_to_int( | |
| 363 | + objspec.substr(1 + comma, std::string::npos).c_str()); | |
| 364 | + } | |
| 365 | + } | |
| 366 | +} | |
| 367 | + | |
| 347 | 368 | // This is not a general-purpose argument parser. It is tightly |
| 348 | 369 | // crafted to work with qpdf. qpdf's command-line syntax is very |
| 349 | 370 | // complex because of its long history, and it doesn't really follow |
| ... | ... | @@ -437,6 +458,7 @@ class ArgParser |
| 437 | 458 | void argWithImages(); |
| 438 | 459 | void argJson(); |
| 439 | 460 | void argJsonKey(char* parameter); |
| 461 | + void argJsonObject(char* parameter); | |
| 440 | 462 | void argCheck(); |
| 441 | 463 | void arg40Print(char* parameter); |
| 442 | 464 | void arg40Modify(char* parameter); |
| ... | ... | @@ -638,6 +660,8 @@ ArgParser::initOptionTable() |
| 638 | 660 | char const* jsonKeyChoices[] = {"objects", "pages", "pagelabels", 0}; |
| 639 | 661 | (*t)["json-key"] = oe_requiredChoices( |
| 640 | 662 | &ArgParser::argJsonKey, jsonKeyChoices); |
| 663 | + (*t)["json-object"] = oe_requiredParameter( | |
| 664 | + &ArgParser::argJsonObject, "trailer|obj[,gen]"); | |
| 641 | 665 | (*t)["check"] = oe_bare(&ArgParser::argCheck); |
| 642 | 666 | |
| 643 | 667 | t = &this->encrypt40_option_table; |
| ... | ... | @@ -1143,21 +1167,7 @@ ArgParser::argShowXref() |
| 1143 | 1167 | void |
| 1144 | 1168 | ArgParser::argShowObject(char* parameter) |
| 1145 | 1169 | { |
| 1146 | - if (strcmp(parameter, "trailer") == 0) | |
| 1147 | - { | |
| 1148 | - o.show_trailer = true; | |
| 1149 | - } | |
| 1150 | - else | |
| 1151 | - { | |
| 1152 | - char* obj = parameter; | |
| 1153 | - char* gen = obj; | |
| 1154 | - if ((gen = strchr(obj, ',')) != 0) | |
| 1155 | - { | |
| 1156 | - *gen++ = 0; | |
| 1157 | - o.show_gen = QUtil::string_to_int(gen); | |
| 1158 | - } | |
| 1159 | - o.show_obj = QUtil::string_to_int(obj); | |
| 1160 | - } | |
| 1170 | + parse_object_id(parameter, o.show_trailer, o.show_obj, o.show_gen); | |
| 1161 | 1171 | o.require_outfile = false; |
| 1162 | 1172 | } |
| 1163 | 1173 | |
| ... | ... | @@ -1207,6 +1217,12 @@ ArgParser::argJsonKey(char* parameter) |
| 1207 | 1217 | } |
| 1208 | 1218 | |
| 1209 | 1219 | void |
| 1220 | +ArgParser::argJsonObject(char* parameter) | |
| 1221 | +{ | |
| 1222 | + o.json_objects.insert(parameter); | |
| 1223 | +} | |
| 1224 | + | |
| 1225 | +void | |
| 1210 | 1226 | ArgParser::argCheck() |
| 1211 | 1227 | { |
| 1212 | 1228 | o.check = true; |
| ... | ... | @@ -1691,7 +1707,11 @@ automated test suites for software that uses the qpdf library.\n\ |
| 1691 | 1707 | --json generate a json representation of the file\n\ |
| 1692 | 1708 | --json-help describe the format of the json representation\n\ |
| 1693 | 1709 | --json-key=key repeatable; prune json structure to include only\n\ |
| 1694 | - specified keys\n\ | |
| 1710 | + specified keys. If absent, all keys are shown\n\ | |
| 1711 | +--json-object=trailer|[obj,gen]\n\ | |
| 1712 | + repeatable; include only specified objects in the\n\ | |
| 1713 | + \"objects\" section of the json. If absent, all\n\ | |
| 1714 | + objects are shown\n\ | |
| 1695 | 1715 | \n\ |
| 1696 | 1716 | The json representation generated by qpdf is designed to facilitate\n\ |
| 1697 | 1717 | processing of qpdf from other programming languages that have a hard\n\ |
| ... | ... | @@ -2586,14 +2606,35 @@ static void do_json_objects(QPDF& pdf, Options& o, JSON& j) |
| 2586 | 2606 | // Add all objects. Do this first before other code below modifies |
| 2587 | 2607 | // things by doing stuff like calling |
| 2588 | 2608 | // pushInheritedAttributesToPage. |
| 2609 | + bool all_objects = o.json_objects.empty(); | |
| 2610 | + std::set<QPDFObjGen> wanted_og; | |
| 2611 | + for (std::set<std::string>::iterator iter = o.json_objects.begin(); | |
| 2612 | + iter != o.json_objects.end(); ++iter) | |
| 2613 | + { | |
| 2614 | + bool trailer; | |
| 2615 | + int obj = 0; | |
| 2616 | + int gen = 0; | |
| 2617 | + parse_object_id(*iter, trailer, obj, gen); | |
| 2618 | + if (obj) | |
| 2619 | + { | |
| 2620 | + wanted_og.insert(QPDFObjGen(obj, gen)); | |
| 2621 | + } | |
| 2622 | + } | |
| 2589 | 2623 | JSON j_objects = j.addDictionaryMember("objects", JSON::makeDictionary()); |
| 2590 | - j_objects.addDictionaryMember("trailer", pdf.getTrailer().getJSON(true)); | |
| 2624 | + if (all_objects || o.json_objects.count("trailer")) | |
| 2625 | + { | |
| 2626 | + j_objects.addDictionaryMember( | |
| 2627 | + "trailer", pdf.getTrailer().getJSON(true)); | |
| 2628 | + } | |
| 2591 | 2629 | std::vector<QPDFObjectHandle> objects = pdf.getAllObjects(); |
| 2592 | 2630 | for (std::vector<QPDFObjectHandle>::iterator iter = objects.begin(); |
| 2593 | 2631 | iter != objects.end(); ++iter) |
| 2594 | 2632 | { |
| 2595 | - j_objects.addDictionaryMember( | |
| 2596 | - (*iter).unparse(), (*iter).getJSON(true)); | |
| 2633 | + if (all_objects || wanted_og.count((*iter).getObjGen())) | |
| 2634 | + { | |
| 2635 | + j_objects.addDictionaryMember( | |
| 2636 | + (*iter).unparse(), (*iter).getJSON(true)); | |
| 2637 | + } | |
| 2597 | 2638 | } |
| 2598 | 2639 | } |
| 2599 | 2640 | ... | ... |