aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO5
-rw-r--r--include/qpdf/QPDFJob.hh9
-rw-r--r--libqpdf/QPDFJob.cc33
-rw-r--r--qpdf/qtest/qpdf/filter-progress.pl7
-rw-r--r--qpdf/qtest/qpdf/job-api.out7
-rw-r--r--qpdf/qtest/qpdfjob.test3
-rw-r--r--qpdf/test_driver.cc21
7 files changed, 72 insertions, 13 deletions
diff --git a/TODO b/TODO
index f71528e1..8a0ad3a0 100644
--- a/TODO
+++ b/TODO
@@ -14,7 +14,10 @@ Next:
Pending changes:
-* Allow users to supply a custom progress reporter for QPDFJob
+* Allow users to supply a custom progress reporter for QPDFJob. If one
+ is provided, use it instead of creating one. Then expose to the C
+ API. Consider also exposing a way to set a new logger and to get the
+ logger from QPDF and QPDFJob in the C API.
* Check about runpath in the linux-bin distribution. I think the
appimage build specifically is setting the runpath, which is
actually desirable in this case. Make sure to understand and
diff --git a/include/qpdf/QPDFJob.hh b/include/qpdf/QPDFJob.hh
index 16b1ab74..96b05768 100644
--- a/include/qpdf/QPDFJob.hh
+++ b/include/qpdf/QPDFJob.hh
@@ -134,6 +134,14 @@ class QPDFJob
"configure logger from getLogger() or call setLogger()")]] QPDF_DLL void
setOutputStreams(std::ostream* out_stream, std::ostream* err_stream);
+ // You can register a custom progress reporter to be called by
+ // QPDFWriter (see QPDFWriter::registerProgressReporter). This is
+ // only called if you also request progress reporting through
+ // normal configuration methods (e.g., pass --progress, call
+ // config()->progress, etc.)
+ QPDF_DLL
+ void registerProgressReporter(std::function<void(int)>);
+
// Check to make sure no contradictory options have been
// specified. This is called automatically after initializing from
// argv or json and is also called by run, but you can call it
@@ -579,6 +587,7 @@ class QPDFJob
bool decrypt;
int split_pages;
bool progress;
+ std::function<void(int)> progress_handler;
bool suppress_warnings;
bool warnings_exit_zero;
bool copy_encryption;
diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc
index 606a612a..5631df49 100644
--- a/libqpdf/QPDFJob.cc
+++ b/libqpdf/QPDFJob.cc
@@ -323,6 +323,7 @@ QPDFJob::Members::Members() :
decrypt(false),
split_pages(0),
progress(false),
+ progress_handler(nullptr),
suppress_warnings(false),
warnings_exit_zero(false),
copy_encryption(false),
@@ -464,6 +465,11 @@ QPDFJob::setOutputStreams(std::ostream* out, std::ostream* err)
}
void
+QPDFJob::registerProgressReporter(std::function<void(int)> handler) {
+ this->m->progress_handler = handler;
+}
+
+void
QPDFJob::doIfVerbose(
std::function<void(Pipeline&, std::string const& prefix)> fn)
{
@@ -3146,16 +3152,23 @@ QPDFJob::setWriterOptions(QPDF& pdf, QPDFWriter& w)
w.forcePDFVersion(version, extension_level);
}
if (m->progress) {
- char const* outfilename = this->m->outfilename
- ? this->m->outfilename.get()
- : "standard output";
- w.registerProgressReporter(
- std::shared_ptr<QPDFWriter::ProgressReporter>(
- // line-break
- new ProgressReporter(
- *this->m->log->getInfo(),
- this->m->message_prefix,
- outfilename)));
+ if (this->m->progress_handler) {
+ w.registerProgressReporter(
+ std::shared_ptr<QPDFWriter::ProgressReporter>(
+ new QPDFWriter::FunctionProgressReporter(
+ this->m->progress_handler)));
+ } else {
+ char const* outfilename = this->m->outfilename
+ ? this->m->outfilename.get()
+ : "standard output";
+ w.registerProgressReporter(
+ std::shared_ptr<QPDFWriter::ProgressReporter>(
+ // line-break
+ new ProgressReporter(
+ *this->m->log->getInfo(),
+ this->m->message_prefix,
+ outfilename)));
+ }
}
}
diff --git a/qpdf/qtest/qpdf/filter-progress.pl b/qpdf/qtest/qpdf/filter-progress.pl
index 97453fcb..943929af 100644
--- a/qpdf/qtest/qpdf/filter-progress.pl
+++ b/qpdf/qtest/qpdf/filter-progress.pl
@@ -4,10 +4,15 @@ use warnings;
my $seen = 0;
while (<>)
{
- if (m/write progress: (?:10)?0\%/)
+ if (m/write progress: 0\%/)
{
print;
}
+ elsif (m/write progress: 100\%/)
+ {
+ print;
+ $seen = 0;
+ }
elsif (m/write progress: /)
{
if (! $seen)
diff --git a/qpdf/qtest/qpdf/job-api.out b/qpdf/qtest/qpdf/job-api.out
index d69b2ac9..7ef99171 100644
--- a/qpdf/qtest/qpdf/job-api.out
+++ b/qpdf/qtest/qpdf/job-api.out
@@ -1,4 +1,11 @@
normal
+qpdf: a.pdf: write progress: 0%
+....other write progress....
+qpdf: a.pdf: write progress: 100%
+custom progress reporter
+custom write progress: 0%
+....other write progress....
+custom write progress: 100%
error caught by check
finished config
usage: an input file name is required
diff --git a/qpdf/qtest/qpdfjob.test b/qpdf/qtest/qpdfjob.test
index f6f40755..1c14a884 100644
--- a/qpdf/qtest/qpdfjob.test
+++ b/qpdf/qtest/qpdfjob.test
@@ -87,7 +87,8 @@ $td->runtest("QPDFJob json partial",
{$td->FILE => "job-partial-json.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("QPDFJob API",
- {$td->COMMAND => "test_driver 84 -"},
+ {$td->COMMAND => "test_driver 84 -",
+ $td->FILTER => "perl filter-progress.pl"},
{$td->FILE => "job-api.out", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("check output",
diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc
index 106f5f99..2384ddef 100644
--- a/qpdf/test_driver.cc
+++ b/qpdf/test_driver.cc
@@ -2937,6 +2937,27 @@ test_84(QPDF& pdf, char const* arg2)
->qdf()
->deterministicId()
->objectStreams("preserve")
+ ->progress()
+ ->checkConfiguration();
+ j.run();
+ assert(j.getExitCode() == 0);
+ assert(!j.hasWarnings());
+ assert(j.getEncryptionStatus() == 0);
+ }
+
+ std::cout << "custom progress reporter" << std::endl;
+ {
+ QPDFJob j;
+ j.registerProgressReporter([](int p) {
+ std::cout << "custom write progress: " << p << "%" << std::endl;
+ });
+ j.config()
+ ->inputFile("minimal.pdf")
+ ->outputFile("a.pdf")
+ ->qdf()
+ ->deterministicId()
+ ->objectStreams("preserve")
+ ->progress()
->checkConfiguration();
j.run();
assert(j.getExitCode() == 0);