From bb0ea2f8e7d8fffa575b291004e4426138c7bb1a Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 18 Jun 2022 21:04:44 -0400 Subject: [PATCH] Add qpdfjob_register_progress_reporter --- ChangeLog | 5 +++++ TODO | 4 +--- include/qpdf/qpdfjob-c.h | 10 ++++++++++ libqpdf/qpdfjob-c.cc | 9 +++++++++ manual/release-notes.rst | 10 ++++++++-- qpdf/qpdfjob-ctest.c | 18 +++++++++++++++--- qpdf/qtest/qpdf/qpdfjob-ctest.out | 3 +++ qpdf/qtest/qpdfjob.test | 3 ++- 8 files changed, 53 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index abf10459..0a51a970 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2022-06-18 Jay Berkenbilt + * Add QPDFJob::registerProgressReporter, making it possible to + override the progress reporter that is used when --progress (or + the equivalent) is configured with QPDFJob. This is + qpdfjob_register_progress_reporter in the C API. + * Add examples that show how to capture QPDFJob's output by configuring the default logger (qpdfjob-save-attachment.cc, qpdfjob-c-save-attachment.c). Fixes #691. diff --git a/TODO b/TODO index 8a0ad3a0..d5dd796b 100644 --- a/TODO +++ b/TODO @@ -14,9 +14,7 @@ Next: Pending changes: -* 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 +* 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 diff --git a/include/qpdf/qpdfjob-c.h b/include/qpdf/qpdfjob-c.h index e15c8fa5..e404d580 100644 --- a/include/qpdf/qpdfjob-c.h +++ b/include/qpdf/qpdfjob-c.h @@ -125,6 +125,16 @@ extern "C" { QPDF_DLL int qpdfjob_run(qpdfjob_handle j); + /* Allow specification of a custom progress reporter. The progress + * reporter is only used if progress is otherwise requested (with + * the --progress option or "progress": "" in the JSON). + */ + QPDF_DLL + void qpdfjob_register_progress_reporter( + qpdfjob_handle j, + void (*report_progress)(int percent, void* data), + void* data); + #ifdef __cplusplus } #endif diff --git a/libqpdf/qpdfjob-c.cc b/libqpdf/qpdfjob-c.cc index 81433661..4f7bd92c 100644 --- a/libqpdf/qpdfjob-c.cc +++ b/libqpdf/qpdfjob-c.cc @@ -120,3 +120,12 @@ int qpdfjob_run_from_json(char const* json) }); } +void +qpdfjob_register_progress_reporter( + qpdfjob_handle j, + void (*report_progress)(int percent, void* data), + void* data) +{ + j->j.registerProgressReporter( + std::bind(report_progress, std::placeholders::_1, data)); +} diff --git a/manual/release-notes.rst b/manual/release-notes.rst index 9a911eea..f50e8e3d 100644 --- a/manual/release-notes.rst +++ b/manual/release-notes.rst @@ -186,8 +186,8 @@ For a detailed list of changes, please see the file - Add new ``Pipeline`` type ``Pl_String`` to append to a ``std::string``. - - Add methods to QUtil for converting PDF timestamps and QPDFTime - objects to ISO-8601 timestamps. + - Add methods to ``QUtil`` for converting PDF timestamps and + ``QPDFTime`` objects to ISO-8601 timestamps. - Enhance JSON class to better support incrementally reading and writing large amounts of data without having to keep everything @@ -200,6 +200,12 @@ For a detailed list of changes, please see the file interface offers more flexibility than the old interface, which remains available. + - Add ``QPDFJob::registerProgressReporter`` and + ``qpdfjob_register_progress_reporter`` to allow a custom + progress reporter to be used with ``QPDFJob``. The ``QPDFJob`` + object must be configured to report progress (via command-line + argument or otherwise) for this to be used. + - Other changes - In JSON v1 mode, the ``"objects"`` key now reflects the repaired diff --git a/qpdf/qpdfjob-ctest.c b/qpdf/qpdfjob-ctest.c index 8d5e374e..f3272aef 100644 --- a/qpdf/qpdfjob-ctest.c +++ b/qpdf/qpdfjob-ctest.c @@ -20,18 +20,30 @@ wide_test() } #endif // QPDF_NO_WCHAR_T +static void +custom_progress(int progress, void* data) +{ + printf("%s: write progress: %d%%\n", (char const*)data, progress); +} + static void run_tests() { /* Be sure to use a different output file for each test. */ + qpdfjob_handle j = NULL; - char const* argv[5]; + char const* argv[6]; argv[0] = "qpdfjob"; argv[1] = "minimal.pdf"; argv[2] = "a.pdf"; argv[3] = "--deterministic-id"; - argv[4] = NULL; - assert(qpdfjob_run_from_argv(argv) == 0); + argv[4] = "--progress"; + argv[5] = NULL; + j = qpdfjob_init(); + qpdfjob_register_progress_reporter(j, custom_progress, (void*)"potato"); + assert(qpdfjob_initialize_from_argv(j, argv) == 0); + assert(qpdfjob_run(j) == 0); + qpdfjob_cleanup(&j); printf("argv test passed\n"); assert(qpdfjob_run_from_json("{\n\ diff --git a/qpdf/qtest/qpdf/qpdfjob-ctest.out b/qpdf/qtest/qpdf/qpdfjob-ctest.out index ac2959f2..22d431de 100644 --- a/qpdf/qtest/qpdf/qpdfjob-ctest.out +++ b/qpdf/qtest/qpdf/qpdfjob-ctest.out @@ -1,3 +1,6 @@ +potato: write progress: 0% +....other write progress.... +potato: write progress: 100% argv test passed json test passed WARNING: xref-with-short-size.pdf (xref stream, offset 16227): Cross-reference stream data has the wrong size; expected = 52; actual = 56 diff --git a/qpdf/qtest/qpdfjob.test b/qpdf/qtest/qpdfjob.test index 1c14a884..0724ba9f 100644 --- a/qpdf/qtest/qpdfjob.test +++ b/qpdf/qtest/qpdfjob.test @@ -100,7 +100,8 @@ $td->runtest("json output from job", $td->NORMALIZE_NEWLINES); $td->runtest("C job API", - {$td->COMMAND => "qpdfjob-ctest"}, + {$td->COMMAND => "qpdfjob-ctest", + $td->FILTER => "perl filter-progress.pl"}, {$td->FILE => "qpdfjob-ctest.out", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); foreach my $i (['a.pdf', 1], ['b.pdf', 2], ['c.pdf', 3])