Commit 87412eb05be3148e812310128f361f79922baad8

Authored by Jay Berkenbilt
1 parent 3a7ee7e9

Add QPDFJob::registerProgressReporter

... ... @@ -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&amp; pdf, QPDFWriter&amp; 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-&gt;runtest(&quot;QPDFJob json partial&quot;,
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&amp; 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);
... ...