Commit 12d065c75120d68cb7dd8445be4620e003598d7d

Authored by Jay Berkenbilt
1 parent 13cf35ce

Provide a simpler QPDF::writeJSON

@@ -69,8 +69,6 @@ Soon: Break ground on "Document-level work" @@ -69,8 +69,6 @@ Soon: Break ground on "Document-level work"
69 JSON v2 fixes 69 JSON v2 fixes
70 ============= 70 =============
71 71
72 -* Rethink QPDF::writeJSON. Maybe provide a simpler overload?  
73 -  
74 * Support json v2 in the C API. At a minimum, write_json, 72 * Support json v2 in the C API. At a minimum, write_json,
75 create_from_json, and update_from_json need to be there and should 73 create_from_json, and update_from_json need to be there and should
76 take the same kinds of functions as the C API for logger. 74 take the same kinds of functions as the C API for logger.
include/qpdf/QPDF.hh
@@ -134,16 +134,8 @@ class QPDF @@ -134,16 +134,8 @@ class QPDF
134 void updateFromJSON(std::shared_ptr<InputSource>); 134 void updateFromJSON(std::shared_ptr<InputSource>);
135 135
136 // Write qpdf JSON format to the pipeline "p". The only supported 136 // Write qpdf JSON format to the pipeline "p". The only supported
137 - // version is 2.  
138 - //  
139 - // If the value of "complete" is true, a complete JSON object  
140 - // containing only the "qpdf" key is written to the pipeline, and  
141 - // finish() is called on the pipeline at the end. If the value of  
142 - // "complete" is false, the "qpdf" key and its value are written  
143 - // to the pipeline assuming that a dictionary is already open, and  
144 - // finish() is not called. The parameter first_key indicates  
145 - // whether this is the first key in an in-progress dictionary. It  
146 - // will be set to false by writeJSON. 137 + // version is 2. The finish() method is not called on the
  138 + // pipeline.
147 // 139 //
148 // The decode_level parameter controls which streams are 140 // The decode_level parameter controls which streams are
149 // uncompressed in the JSON. Use qpdf_dl_none to preserve all 141 // uncompressed in the JSON. Use qpdf_dl_none to preserve all
@@ -168,6 +160,26 @@ class QPDF @@ -168,6 +160,26 @@ class QPDF
168 void writeJSON( 160 void writeJSON(
169 int version, 161 int version,
170 Pipeline* p, 162 Pipeline* p,
  163 + qpdf_stream_decode_level_e decode_level,
  164 + qpdf_json_stream_data_e json_stream_data,
  165 + std::string const& file_prefix,
  166 + std::set<std::string> wanted_objects);
  167 +
  168 + // This version of writeJSON enables writing only the "qpdf" key
  169 + // of an in-progress dictionary. If the value of "complete" is
  170 + // true, a complete JSON object containing only the "qpdf" key is
  171 + // written to the pipeline. If the value of "complete" is false,
  172 + // the "qpdf" key and its value are written to the pipeline
  173 + // assuming that a dictionary is already open. The parameter
  174 + // first_key indicates whether this is the first key in an
  175 + // in-progress dictionary. It will be set to false by writeJSON.
  176 + // The "qpdf" key and value are written as if at depth 1 in a
  177 + // prettified JSON output. Remaining arguments are the same as the
  178 + // above version.
  179 + QPDF_DLL
  180 + void writeJSON(
  181 + int version,
  182 + Pipeline* p,
171 bool complete, 183 bool complete,
172 bool& first_key, 184 bool& first_key,
173 qpdf_stream_decode_level_e decode_level, 185 qpdf_stream_decode_level_e decode_level,
libqpdf/QPDF_json.cc
@@ -493,9 +493,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const&amp; key, JSON const&amp; value) @@ -493,9 +493,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const&amp; key, JSON const&amp; value)
493 } 493 }
494 } else { 494 } else {
495 QTC::TC("qpdf", "QPDF_json bad calledgetallpages"); 495 QTC::TC("qpdf", "QPDF_json bad calledgetallpages");
496 - error(  
497 - value.getStart(),  
498 - "calledgetallpages must be a boolean"); 496 + error(value.getStart(), "calledgetallpages must be a boolean");
499 } 497 }
500 } else { 498 } else {
501 // ignore unknown keys for forward compatibility and to 499 // ignore unknown keys for forward compatibility and to
@@ -825,6 +823,27 @@ void @@ -825,6 +823,27 @@ void
825 QPDF::writeJSON( 823 QPDF::writeJSON(
826 int version, 824 int version,
827 Pipeline* p, 825 Pipeline* p,
  826 + qpdf_stream_decode_level_e decode_level,
  827 + qpdf_json_stream_data_e json_stream_data,
  828 + std::string const& file_prefix,
  829 + std::set<std::string> wanted_objects)
  830 +{
  831 + bool first = true;
  832 + writeJSON(
  833 + version,
  834 + p,
  835 + true,
  836 + first,
  837 + decode_level,
  838 + json_stream_data,
  839 + file_prefix,
  840 + wanted_objects);
  841 +}
  842 +
  843 +void
  844 +QPDF::writeJSON(
  845 + int version,
  846 + Pipeline* p,
828 bool complete, 847 bool complete,
829 bool& first_key, 848 bool& first_key,
830 qpdf_stream_decode_level_e decode_level, 849 qpdf_stream_decode_level_e decode_level,
qpdf/qtest/qpdf-json.test
@@ -282,5 +282,11 @@ $td-&gt;runtest(&quot;check PDF (2)&quot;, @@ -282,5 +282,11 @@ $td-&gt;runtest(&quot;check PDF (2)&quot;,
282 {$td->FILE => "a.pdf"}, 282 {$td->FILE => "a.pdf"},
283 {$td->FILE => "duplicate-page-inherited-2-fixed.pdf"}); 283 {$td->FILE => "duplicate-page-inherited-2-fixed.pdf"});
284 284
  285 +$n_tests += 1;
  286 +$td->runtest("simple version of writeJSON",
  287 + {$td->COMMAND => "test_driver 91 minimal.pdf"},
  288 + {$td->FILE => "minimal-write-json.json", $td->EXIT_STATUS => 0},
  289 + $td->NORMALIZE_NEWLINES);
  290 +
285 cleanup(); 291 cleanup();
286 $td->report($n_tests); 292 $td->report($n_tests);
qpdf/qtest/qpdf/minimal-write-json.json 0 โ†’ 100644
  1 +{
  2 + "qpdf": [
  3 + {
  4 + "jsonversion": 2,
  5 + "pdfversion": "1.3",
  6 + "pushedinheritedpageresources": false,
  7 + "calledgetallpages": false,
  8 + "maxobjectid": 6
  9 + },
  10 + {
  11 + "obj:1 0 R": {
  12 + "value": {
  13 + "/Pages": "2 0 R",
  14 + "/Type": "/Catalog"
  15 + }
  16 + },
  17 + "obj:2 0 R": {
  18 + "value": {
  19 + "/Count": 1,
  20 + "/Kids": [
  21 + "3 0 R"
  22 + ],
  23 + "/Type": "/Pages"
  24 + }
  25 + },
  26 + "obj:3 0 R": {
  27 + "value": {
  28 + "/Contents": "4 0 R",
  29 + "/MediaBox": [
  30 + 0,
  31 + 0,
  32 + 612,
  33 + 792
  34 + ],
  35 + "/Parent": "2 0 R",
  36 + "/Resources": {
  37 + "/Font": {
  38 + "/F1": "6 0 R"
  39 + },
  40 + "/ProcSet": "5 0 R"
  41 + },
  42 + "/Type": "/Page"
  43 + }
  44 + },
  45 + "obj:4 0 R": {
  46 + "stream": {
  47 + "data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=",
  48 + "dict": {}
  49 + }
  50 + },
  51 + "obj:5 0 R": {
  52 + "value": [
  53 + "/PDF",
  54 + "/Text"
  55 + ]
  56 + },
  57 + "obj:6 0 R": {
  58 + "value": {
  59 + "/BaseFont": "/Helvetica",
  60 + "/Encoding": "/WinAnsiEncoding",
  61 + "/Name": "/F1",
  62 + "/Subtype": "/Type1",
  63 + "/Type": "/Font"
  64 + }
  65 + },
  66 + "trailer": {
  67 + "value": {
  68 + "/Root": "1 0 R",
  69 + "/Size": 7
  70 + }
  71 + }
  72 + }
  73 + ]
  74 +}
  75 +test 91 done
qpdf/test_driver.cc
@@ -3249,6 +3249,15 @@ test_90(QPDF&amp; pdf, char const* arg2) @@ -3249,6 +3249,15 @@ test_90(QPDF&amp; pdf, char const* arg2)
3249 pdf.getRoot().appendItem(QPDFObjectHandle::newNull()); 3249 pdf.getRoot().appendItem(QPDFObjectHandle::newNull());
3250 } 3250 }
3251 3251
  3252 +static void
  3253 +test_91(QPDF& pdf, char const* arg2)
  3254 +{
  3255 + // Exercise the simpler version of writeJSON.
  3256 + Pl_StdioFile p("stdout", stdout);
  3257 + pdf.writeJSON(
  3258 + 2, &p, qpdf_dl_none, qpdf_sj_inline, "", std::set<std::string>());
  3259 +}
  3260 +
3252 void 3261 void
3253 runtest(int n, char const* filename1, char const* arg2) 3262 runtest(int n, char const* filename1, char const* arg2)
3254 { 3263 {
@@ -3353,7 +3362,7 @@ runtest(int n, char const* filename1, char const* arg2) @@ -3353,7 +3362,7 @@ runtest(int n, char const* filename1, char const* arg2)
3353 {76, test_76}, {77, test_77}, {78, test_78}, {79, test_79}, 3362 {76, test_76}, {77, test_77}, {78, test_78}, {79, test_79},
3354 {80, test_80}, {81, test_81}, {82, test_82}, {83, test_83}, 3363 {80, test_80}, {81, test_81}, {82, test_82}, {83, test_83},
3355 {84, test_84}, {85, test_85}, {86, test_86}, {87, test_87}, 3364 {84, test_84}, {85, test_85}, {86, test_86}, {87, test_87},
3356 - {88, test_88}, {89, test_89}, {90, test_90}}; 3365 + {88, test_88}, {89, test_89}, {90, test_90}, {91, test_91}};
3357 3366
3358 auto fn = test_functions.find(n); 3367 auto fn = test_functions.find(n);
3359 if (fn == test_functions.end()) { 3368 if (fn == test_functions.end()) {