Commit 87412eb05be3148e812310128f361f79922baad8
1 parent
3a7ee7e9
Add QPDFJob::registerProgressReporter
Showing
7 changed files
with
72 additions
and
13 deletions
TODO
| ... | ... | @@ -14,7 +14,10 @@ Next: |
| 14 | 14 | |
| 15 | 15 | Pending changes: |
| 16 | 16 | |
| 17 | -* Allow users to supply a custom progress reporter for QPDFJob | |
| 17 | +* Allow users to supply a custom progress reporter for QPDFJob. If one | |
| 18 | + is provided, use it instead of creating one. Then expose to the C | |
| 19 | + API. Consider also exposing a way to set a new logger and to get the | |
| 20 | + logger from QPDF and QPDFJob in the C API. | |
| 18 | 21 | * Check about runpath in the linux-bin distribution. I think the |
| 19 | 22 | appimage build specifically is setting the runpath, which is |
| 20 | 23 | actually desirable in this case. Make sure to understand and | ... | ... |
include/qpdf/QPDFJob.hh
| ... | ... | @@ -134,6 +134,14 @@ class QPDFJob |
| 134 | 134 | "configure logger from getLogger() or call setLogger()")]] QPDF_DLL void |
| 135 | 135 | setOutputStreams(std::ostream* out_stream, std::ostream* err_stream); |
| 136 | 136 | |
| 137 | + // You can register a custom progress reporter to be called by | |
| 138 | + // QPDFWriter (see QPDFWriter::registerProgressReporter). This is | |
| 139 | + // only called if you also request progress reporting through | |
| 140 | + // normal configuration methods (e.g., pass --progress, call | |
| 141 | + // config()->progress, etc.) | |
| 142 | + QPDF_DLL | |
| 143 | + void registerProgressReporter(std::function<void(int)>); | |
| 144 | + | |
| 137 | 145 | // Check to make sure no contradictory options have been |
| 138 | 146 | // specified. This is called automatically after initializing from |
| 139 | 147 | // argv or json and is also called by run, but you can call it |
| ... | ... | @@ -579,6 +587,7 @@ class QPDFJob |
| 579 | 587 | bool decrypt; |
| 580 | 588 | int split_pages; |
| 581 | 589 | bool progress; |
| 590 | + std::function<void(int)> progress_handler; | |
| 582 | 591 | bool suppress_warnings; |
| 583 | 592 | bool warnings_exit_zero; |
| 584 | 593 | bool copy_encryption; | ... | ... |
libqpdf/QPDFJob.cc
| ... | ... | @@ -323,6 +323,7 @@ QPDFJob::Members::Members() : |
| 323 | 323 | decrypt(false), |
| 324 | 324 | split_pages(0), |
| 325 | 325 | progress(false), |
| 326 | + progress_handler(nullptr), | |
| 326 | 327 | suppress_warnings(false), |
| 327 | 328 | warnings_exit_zero(false), |
| 328 | 329 | copy_encryption(false), |
| ... | ... | @@ -464,6 +465,11 @@ QPDFJob::setOutputStreams(std::ostream* out, std::ostream* err) |
| 464 | 465 | } |
| 465 | 466 | |
| 466 | 467 | void |
| 468 | +QPDFJob::registerProgressReporter(std::function<void(int)> handler) { | |
| 469 | + this->m->progress_handler = handler; | |
| 470 | +} | |
| 471 | + | |
| 472 | +void | |
| 467 | 473 | QPDFJob::doIfVerbose( |
| 468 | 474 | std::function<void(Pipeline&, std::string const& prefix)> fn) |
| 469 | 475 | { |
| ... | ... | @@ -3146,16 +3152,23 @@ QPDFJob::setWriterOptions(QPDF& pdf, QPDFWriter& w) |
| 3146 | 3152 | w.forcePDFVersion(version, extension_level); |
| 3147 | 3153 | } |
| 3148 | 3154 | if (m->progress) { |
| 3149 | - char const* outfilename = this->m->outfilename | |
| 3150 | - ? this->m->outfilename.get() | |
| 3151 | - : "standard output"; | |
| 3152 | - w.registerProgressReporter( | |
| 3153 | - std::shared_ptr<QPDFWriter::ProgressReporter>( | |
| 3154 | - // line-break | |
| 3155 | - new ProgressReporter( | |
| 3156 | - *this->m->log->getInfo(), | |
| 3157 | - this->m->message_prefix, | |
| 3158 | - outfilename))); | |
| 3155 | + if (this->m->progress_handler) { | |
| 3156 | + w.registerProgressReporter( | |
| 3157 | + std::shared_ptr<QPDFWriter::ProgressReporter>( | |
| 3158 | + new QPDFWriter::FunctionProgressReporter( | |
| 3159 | + this->m->progress_handler))); | |
| 3160 | + } else { | |
| 3161 | + char const* outfilename = this->m->outfilename | |
| 3162 | + ? this->m->outfilename.get() | |
| 3163 | + : "standard output"; | |
| 3164 | + w.registerProgressReporter( | |
| 3165 | + std::shared_ptr<QPDFWriter::ProgressReporter>( | |
| 3166 | + // line-break | |
| 3167 | + new ProgressReporter( | |
| 3168 | + *this->m->log->getInfo(), | |
| 3169 | + this->m->message_prefix, | |
| 3170 | + outfilename))); | |
| 3171 | + } | |
| 3159 | 3172 | } |
| 3160 | 3173 | } |
| 3161 | 3174 | ... | ... |
qpdf/qtest/qpdf/filter-progress.pl
| ... | ... | @@ -4,10 +4,15 @@ use warnings; |
| 4 | 4 | my $seen = 0; |
| 5 | 5 | while (<>) |
| 6 | 6 | { |
| 7 | - if (m/write progress: (?:10)?0\%/) | |
| 7 | + if (m/write progress: 0\%/) | |
| 8 | 8 | { |
| 9 | 9 | print; |
| 10 | 10 | } |
| 11 | + elsif (m/write progress: 100\%/) | |
| 12 | + { | |
| 13 | + print; | |
| 14 | + $seen = 0; | |
| 15 | + } | |
| 11 | 16 | elsif (m/write progress: /) |
| 12 | 17 | { |
| 13 | 18 | if (! $seen) | ... | ... |
qpdf/qtest/qpdf/job-api.out
| 1 | 1 | normal |
| 2 | +qpdf: a.pdf: write progress: 0% | |
| 3 | +....other write progress.... | |
| 4 | +qpdf: a.pdf: write progress: 100% | |
| 5 | +custom progress reporter | |
| 6 | +custom write progress: 0% | |
| 7 | +....other write progress.... | |
| 8 | +custom write progress: 100% | |
| 2 | 9 | error caught by check |
| 3 | 10 | finished config |
| 4 | 11 | usage: an input file name is required | ... | ... |
qpdf/qtest/qpdfjob.test
| ... | ... | @@ -87,7 +87,8 @@ $td->runtest("QPDFJob json partial", |
| 87 | 87 | {$td->FILE => "job-partial-json.out", $td->EXIT_STATUS => 0}, |
| 88 | 88 | $td->NORMALIZE_NEWLINES); |
| 89 | 89 | $td->runtest("QPDFJob API", |
| 90 | - {$td->COMMAND => "test_driver 84 -"}, | |
| 90 | + {$td->COMMAND => "test_driver 84 -", | |
| 91 | + $td->FILTER => "perl filter-progress.pl"}, | |
| 91 | 92 | {$td->FILE => "job-api.out", $td->EXIT_STATUS => 0}, |
| 92 | 93 | $td->NORMALIZE_NEWLINES); |
| 93 | 94 | $td->runtest("check output", | ... | ... |
qpdf/test_driver.cc
| ... | ... | @@ -2937,6 +2937,27 @@ test_84(QPDF& pdf, char const* arg2) |
| 2937 | 2937 | ->qdf() |
| 2938 | 2938 | ->deterministicId() |
| 2939 | 2939 | ->objectStreams("preserve") |
| 2940 | + ->progress() | |
| 2941 | + ->checkConfiguration(); | |
| 2942 | + j.run(); | |
| 2943 | + assert(j.getExitCode() == 0); | |
| 2944 | + assert(!j.hasWarnings()); | |
| 2945 | + assert(j.getEncryptionStatus() == 0); | |
| 2946 | + } | |
| 2947 | + | |
| 2948 | + std::cout << "custom progress reporter" << std::endl; | |
| 2949 | + { | |
| 2950 | + QPDFJob j; | |
| 2951 | + j.registerProgressReporter([](int p) { | |
| 2952 | + std::cout << "custom write progress: " << p << "%" << std::endl; | |
| 2953 | + }); | |
| 2954 | + j.config() | |
| 2955 | + ->inputFile("minimal.pdf") | |
| 2956 | + ->outputFile("a.pdf") | |
| 2957 | + ->qdf() | |
| 2958 | + ->deterministicId() | |
| 2959 | + ->objectStreams("preserve") | |
| 2960 | + ->progress() | |
| 2940 | 2961 | ->checkConfiguration(); |
| 2941 | 2962 | j.run(); |
| 2942 | 2963 | assert(j.getExitCode() == 0); | ... | ... |