Commit 41f79bedbc1ebc2666471ec97b87999410242973
1 parent
c78f4479
Add new functions qpdfjob_create_qpdf and qpdfjob_write_qpdf
Showing
6 changed files
with
82 additions
and
2 deletions
include/qpdf/qpdfjob-c.h
| @@ -32,6 +32,7 @@ | @@ -32,6 +32,7 @@ | ||
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | #include <qpdf/DLL.h> | 34 | #include <qpdf/DLL.h> |
| 35 | +#include <qpdf/qpdf-c.h> | ||
| 35 | #include <qpdf/qpdflogger-c.h> | 36 | #include <qpdf/qpdflogger-c.h> |
| 36 | #include <string.h> | 37 | #include <string.h> |
| 37 | #ifndef QPDF_NO_WCHAR_T | 38 | #ifndef QPDF_NO_WCHAR_T |
| @@ -138,6 +139,28 @@ extern "C" { | @@ -138,6 +139,28 @@ extern "C" { | ||
| 138 | QPDF_DLL | 139 | QPDF_DLL |
| 139 | int qpdfjob_run(qpdfjob_handle j); | 140 | int qpdfjob_run(qpdfjob_handle j); |
| 140 | 141 | ||
| 142 | + /* The following two functions allow a job to be run in two stages - | ||
| 143 | + * creation of a qpdf_data object and writing of the qpdf_data object. This | ||
| 144 | + * allows the qpdf_data object to be modified prior to writing it out. See | ||
| 145 | + * examples/qpdfjob-remove-annotations for a C++ illustration of its use. | ||
| 146 | + * | ||
| 147 | + * This function wraps QPDFJob::createQPDF. It runs the first stage of the | ||
| 148 | + * job. A nullptr is returned if the job did not produce any pdf file to be | ||
| 149 | + * written. | ||
| 150 | + */ | ||
| 151 | + QPDF_DLL | ||
| 152 | + qpdf_data qpdfjob_create_qpdf(qpdfjob_handle j); | ||
| 153 | + | ||
| 154 | + /* This function wraps QPDFJob::writeQPDF. It returns the error code that | ||
| 155 | + * qpdf would return with the equivalent command-line invocation. Exit code | ||
| 156 | + * values are defined in Constants.h in the qpdf_exit_code_e type. NOTE it | ||
| 157 | + * is the callers responsibility to clean up the resources associated | ||
| 158 | + * qpdf_data object by calling qpdf_cleanup after the call to | ||
| 159 | + * qpdfjob_write_qpdf. | ||
| 160 | + */ | ||
| 161 | + QPDF_DLL | ||
| 162 | + int qpdfjob_write_qpdf(qpdfjob_handle j, qpdf_data qpdf); | ||
| 163 | + | ||
| 141 | /* Allow specification of a custom progress reporter. The progress | 164 | /* Allow specification of a custom progress reporter. The progress |
| 142 | * reporter is only used if progress is otherwise requested (with | 165 | * reporter is only used if progress is otherwise requested (with |
| 143 | * the --progress option or "progress": "" in the JSON). | 166 | * the --progress option or "progress": "" in the JSON). |
libqpdf/qpdfjob-c.cc
| @@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
| 4 | #include <qpdf/QPDFLogger.hh> | 4 | #include <qpdf/QPDFLogger.hh> |
| 5 | #include <qpdf/QPDFUsage.hh> | 5 | #include <qpdf/QPDFUsage.hh> |
| 6 | #include <qpdf/QUtil.hh> | 6 | #include <qpdf/QUtil.hh> |
| 7 | +#include <qpdf/qpdf-c_impl.hh> | ||
| 7 | #include <qpdf/qpdflogger-c_impl.hh> | 8 | #include <qpdf/qpdflogger-c_impl.hh> |
| 8 | 9 | ||
| 9 | #include <cstdio> | 10 | #include <cstdio> |
| @@ -98,6 +99,30 @@ qpdfjob_run(qpdfjob_handle j) | @@ -98,6 +99,30 @@ qpdfjob_run(qpdfjob_handle j) | ||
| 98 | }); | 99 | }); |
| 99 | } | 100 | } |
| 100 | 101 | ||
| 102 | +qpdf_data | ||
| 103 | +qpdfjob_create_qpdf(qpdfjob_handle j) | ||
| 104 | +{ | ||
| 105 | + QUtil::setLineBuf(stdout); | ||
| 106 | + try { | ||
| 107 | + auto qpdf = j->j.createQPDF(); | ||
| 108 | + return qpdf ? new _qpdf_data(std::move(qpdf)) : nullptr; | ||
| 109 | + } catch (std::exception& e) { | ||
| 110 | + *j->j.getLogger()->getError() | ||
| 111 | + << j->j.getMessagePrefix() << ": " << e.what() << "\n"; | ||
| 112 | + } | ||
| 113 | + return nullptr; | ||
| 114 | +} | ||
| 115 | + | ||
| 116 | +int | ||
| 117 | +qpdfjob_write_qpdf(qpdfjob_handle j, qpdf_data qpdf) | ||
| 118 | +{ | ||
| 119 | + QUtil::setLineBuf(stdout); | ||
| 120 | + return wrap_qpdfjob(j, [qpdf](qpdfjob_handle jh) { | ||
| 121 | + jh->j.writeQPDF(*(qpdf->qpdf)); | ||
| 122 | + return jh->j.getExitCode(); | ||
| 123 | + }); | ||
| 124 | +} | ||
| 125 | + | ||
| 101 | static int | 126 | static int |
| 102 | run_with_handle(std::function<int(qpdfjob_handle)> fn) | 127 | run_with_handle(std::function<int(qpdfjob_handle)> fn) |
| 103 | { | 128 | { |
qpdf/qpdfjob-ctest.c
| @@ -97,6 +97,33 @@ run_tests() | @@ -97,6 +97,33 @@ run_tests() | ||
| 97 | assert(qpdfjob_run(j) == 2); | 97 | assert(qpdfjob_run(j) == 2); |
| 98 | qpdfjob_cleanup(&j); | 98 | qpdfjob_cleanup(&j); |
| 99 | printf("json error test passed\n"); | 99 | printf("json error test passed\n"); |
| 100 | + | ||
| 101 | + /* qpdfjob_create_qpdf and qpdfjob_write_qpdf test */ | ||
| 102 | + argv[0] = "qpdfjob"; | ||
| 103 | + argv[1] = "minimal.pdf"; | ||
| 104 | + argv[2] = "d.pdf"; | ||
| 105 | + argv[3] = "--deterministic-id"; | ||
| 106 | + argv[4] = "--progress"; | ||
| 107 | + argv[5] = NULL; | ||
| 108 | + j = qpdfjob_init(); | ||
| 109 | + assert(qpdfjob_initialize_from_argv(j, argv) == 0); | ||
| 110 | + qpdf_data qpdf = qpdfjob_create_qpdf(j); | ||
| 111 | + assert(qpdfjob_write_qpdf(j, qpdf) == 0); | ||
| 112 | + qpdf_cleanup(&qpdf); | ||
| 113 | + qpdfjob_cleanup(&j); | ||
| 114 | + | ||
| 115 | + /* Try to open a missing file to test case of QPDFJob::createQPDF returning | ||
| 116 | + * nullptr. | ||
| 117 | + */ | ||
| 118 | + argv[0] = "qpdfjob"; | ||
| 119 | + argv[1] = "m.pdf"; | ||
| 120 | + argv[2] = "--check"; | ||
| 121 | + argv[3] = NULL; | ||
| 122 | + j = qpdfjob_init(); | ||
| 123 | + assert(qpdfjob_initialize_from_argv(j, argv) == 0); | ||
| 124 | + assert(qpdfjob_create_qpdf(j) == NULL); | ||
| 125 | + qpdfjob_cleanup(&j); | ||
| 126 | + printf("qpdfjob_create_qpdf and qpdfjob_write_qpdf test passed\n"); | ||
| 100 | } | 127 | } |
| 101 | 128 | ||
| 102 | int | 129 | int |
qpdf/qtest/qpdf/qpdfjob-ctest.out
| @@ -9,3 +9,8 @@ json warn test passed | @@ -9,3 +9,8 @@ json warn test passed | ||
| 9 | |custom|qpdfjob json|custom|: |custom|an output file name is required; use - for standard output|custom| | 9 | |custom|qpdfjob json|custom|: |custom|an output file name is required; use - for standard output|custom| |
| 10 | |custom|qpdfjob json|custom|: |custom|an output file name is required; use - for standard output|custom| | 10 | |custom|qpdfjob json|custom|: |custom|an output file name is required; use - for standard output|custom| |
| 11 | json error test passed | 11 | json error test passed |
| 12 | +qpdfjob: d.pdf: write progress: 0% | ||
| 13 | +....other write progress.... | ||
| 14 | +qpdfjob: d.pdf: write progress: 100% | ||
| 15 | +qpdfjob: open m.pdf: No such file or directory | ||
| 16 | +qpdfjob_create_qpdf and qpdfjob_write_qpdf test passed |
qpdf/qtest/qpdf/qpdfjob-ctest4.pdf
0 → 100644
No preview for this file type
qpdf/qtest/qpdfjob.test
| @@ -43,7 +43,7 @@ my @good_json = ( | @@ -43,7 +43,7 @@ my @good_json = ( | ||
| 43 | "underlay-overlay-password", | 43 | "underlay-overlay-password", |
| 44 | "misc-options", | 44 | "misc-options", |
| 45 | ); | 45 | ); |
| 46 | -my $n_tests = 10 + scalar(@bad_json) + (2 * scalar(@good_json)); | 46 | +my $n_tests = 11 + scalar(@bad_json) + (2 * scalar(@good_json)); |
| 47 | 47 | ||
| 48 | 48 | ||
| 49 | foreach my $i (@bad_json) | 49 | foreach my $i (@bad_json) |
| @@ -104,7 +104,7 @@ $td->runtest("C job API", | @@ -104,7 +104,7 @@ $td->runtest("C job API", | ||
| 104 | $td->FILTER => "perl filter-progress.pl"}, | 104 | $td->FILTER => "perl filter-progress.pl"}, |
| 105 | {$td->FILE => "qpdfjob-ctest.out", $td->EXIT_STATUS => 0}, | 105 | {$td->FILE => "qpdfjob-ctest.out", $td->EXIT_STATUS => 0}, |
| 106 | $td->NORMALIZE_NEWLINES); | 106 | $td->NORMALIZE_NEWLINES); |
| 107 | -foreach my $i (['a.pdf', 1], ['b.pdf', 2], ['c.pdf', 3]) | 107 | +foreach my $i (['a.pdf', 1], ['b.pdf', 2], ['c.pdf', 3], ['d.pdf', 4]) |
| 108 | { | 108 | { |
| 109 | $td->runtest("check output", | 109 | $td->runtest("check output", |
| 110 | {$td->FILE => $i->[0]}, | 110 | {$td->FILE => $i->[0]}, |