aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorm-holger <m-holger@kubitscheck.org>2023-03-21 19:54:36 +0100
committerm-holger <m-holger@kubitscheck.org>2023-04-02 10:45:19 +0200
commit41f79bedbc1ebc2666471ec97b87999410242973 (patch)
tree3b1f1269122f88b316338a5c99046ae0e4077ae6
parentc78f44798a0b07e7a585c85c7b8bcc1907542cd4 (diff)
downloadqpdf-41f79bedbc1ebc2666471ec97b87999410242973.tar.zst
Add new functions qpdfjob_create_qpdf and qpdfjob_write_qpdf
-rw-r--r--include/qpdf/qpdfjob-c.h23
-rw-r--r--libqpdf/qpdfjob-c.cc25
-rw-r--r--qpdf/qpdfjob-ctest.c27
-rw-r--r--qpdf/qtest/qpdf/qpdfjob-ctest.out5
-rw-r--r--qpdf/qtest/qpdf/qpdfjob-ctest4.pdfbin0 -> 799 bytes
-rw-r--r--qpdf/qtest/qpdfjob.test4
6 files changed, 82 insertions, 2 deletions
diff --git a/include/qpdf/qpdfjob-c.h b/include/qpdf/qpdfjob-c.h
index 8408f0d6..a251bd93 100644
--- a/include/qpdf/qpdfjob-c.h
+++ b/include/qpdf/qpdfjob-c.h
@@ -32,6 +32,7 @@
*/
#include <qpdf/DLL.h>
+#include <qpdf/qpdf-c.h>
#include <qpdf/qpdflogger-c.h>
#include <string.h>
#ifndef QPDF_NO_WCHAR_T
@@ -138,6 +139,28 @@ extern "C" {
QPDF_DLL
int qpdfjob_run(qpdfjob_handle j);
+ /* The following two functions allow a job to be run in two stages -
+ * creation of a qpdf_data object and writing of the qpdf_data object. This
+ * allows the qpdf_data object to be modified prior to writing it out. See
+ * examples/qpdfjob-remove-annotations for a C++ illustration of its use.
+ *
+ * This function wraps QPDFJob::createQPDF. It runs the first stage of the
+ * job. A nullptr is returned if the job did not produce any pdf file to be
+ * written.
+ */
+ QPDF_DLL
+ qpdf_data qpdfjob_create_qpdf(qpdfjob_handle j);
+
+ /* This function wraps QPDFJob::writeQPDF. It returns the error code that
+ * qpdf would return with the equivalent command-line invocation. Exit code
+ * values are defined in Constants.h in the qpdf_exit_code_e type. NOTE it
+ * is the callers responsibility to clean up the resources associated
+ * qpdf_data object by calling qpdf_cleanup after the call to
+ * qpdfjob_write_qpdf.
+ */
+ QPDF_DLL
+ int qpdfjob_write_qpdf(qpdfjob_handle j, qpdf_data qpdf);
+
/* 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).
diff --git a/libqpdf/qpdfjob-c.cc b/libqpdf/qpdfjob-c.cc
index 889afec6..ddb33349 100644
--- a/libqpdf/qpdfjob-c.cc
+++ b/libqpdf/qpdfjob-c.cc
@@ -4,6 +4,7 @@
#include <qpdf/QPDFLogger.hh>
#include <qpdf/QPDFUsage.hh>
#include <qpdf/QUtil.hh>
+#include <qpdf/qpdf-c_impl.hh>
#include <qpdf/qpdflogger-c_impl.hh>
#include <cstdio>
@@ -98,6 +99,30 @@ qpdfjob_run(qpdfjob_handle j)
});
}
+qpdf_data
+qpdfjob_create_qpdf(qpdfjob_handle j)
+{
+ QUtil::setLineBuf(stdout);
+ try {
+ auto qpdf = j->j.createQPDF();
+ return qpdf ? new _qpdf_data(std::move(qpdf)) : nullptr;
+ } catch (std::exception& e) {
+ *j->j.getLogger()->getError()
+ << j->j.getMessagePrefix() << ": " << e.what() << "\n";
+ }
+ return nullptr;
+}
+
+int
+qpdfjob_write_qpdf(qpdfjob_handle j, qpdf_data qpdf)
+{
+ QUtil::setLineBuf(stdout);
+ return wrap_qpdfjob(j, [qpdf](qpdfjob_handle jh) {
+ jh->j.writeQPDF(*(qpdf->qpdf));
+ return jh->j.getExitCode();
+ });
+}
+
static int
run_with_handle(std::function<int(qpdfjob_handle)> fn)
{
diff --git a/qpdf/qpdfjob-ctest.c b/qpdf/qpdfjob-ctest.c
index 708d5fa6..31f22d28 100644
--- a/qpdf/qpdfjob-ctest.c
+++ b/qpdf/qpdfjob-ctest.c
@@ -97,6 +97,33 @@ run_tests()
assert(qpdfjob_run(j) == 2);
qpdfjob_cleanup(&j);
printf("json error test passed\n");
+
+ /* qpdfjob_create_qpdf and qpdfjob_write_qpdf test */
+ argv[0] = "qpdfjob";
+ argv[1] = "minimal.pdf";
+ argv[2] = "d.pdf";
+ argv[3] = "--deterministic-id";
+ argv[4] = "--progress";
+ argv[5] = NULL;
+ j = qpdfjob_init();
+ assert(qpdfjob_initialize_from_argv(j, argv) == 0);
+ qpdf_data qpdf = qpdfjob_create_qpdf(j);
+ assert(qpdfjob_write_qpdf(j, qpdf) == 0);
+ qpdf_cleanup(&qpdf);
+ qpdfjob_cleanup(&j);
+
+ /* Try to open a missing file to test case of QPDFJob::createQPDF returning
+ * nullptr.
+ */
+ argv[0] = "qpdfjob";
+ argv[1] = "m.pdf";
+ argv[2] = "--check";
+ argv[3] = NULL;
+ j = qpdfjob_init();
+ assert(qpdfjob_initialize_from_argv(j, argv) == 0);
+ assert(qpdfjob_create_qpdf(j) == NULL);
+ qpdfjob_cleanup(&j);
+ printf("qpdfjob_create_qpdf and qpdfjob_write_qpdf test passed\n");
}
int
diff --git a/qpdf/qtest/qpdf/qpdfjob-ctest.out b/qpdf/qtest/qpdf/qpdfjob-ctest.out
index 1778e70a..125e6257 100644
--- a/qpdf/qtest/qpdf/qpdfjob-ctest.out
+++ b/qpdf/qtest/qpdf/qpdfjob-ctest.out
@@ -9,3 +9,8 @@ json warn test passed
|custom|qpdfjob json|custom|: |custom|an output file name is required; use - for standard output|custom|
|custom|qpdfjob json|custom|: |custom|an output file name is required; use - for standard output|custom|
json error test passed
+qpdfjob: d.pdf: write progress: 0%
+....other write progress....
+qpdfjob: d.pdf: write progress: 100%
+qpdfjob: open m.pdf: No such file or directory
+qpdfjob_create_qpdf and qpdfjob_write_qpdf test passed
diff --git a/qpdf/qtest/qpdf/qpdfjob-ctest4.pdf b/qpdf/qtest/qpdf/qpdfjob-ctest4.pdf
new file mode 100644
index 00000000..b2c4c2c0
--- /dev/null
+++ b/qpdf/qtest/qpdf/qpdfjob-ctest4.pdf
Binary files differ
diff --git a/qpdf/qtest/qpdfjob.test b/qpdf/qtest/qpdfjob.test
index 0724ba9f..2aea654b 100644
--- a/qpdf/qtest/qpdfjob.test
+++ b/qpdf/qtest/qpdfjob.test
@@ -43,7 +43,7 @@ my @good_json = (
"underlay-overlay-password",
"misc-options",
);
-my $n_tests = 10 + scalar(@bad_json) + (2 * scalar(@good_json));
+my $n_tests = 11 + scalar(@bad_json) + (2 * scalar(@good_json));
foreach my $i (@bad_json)
@@ -104,7 +104,7 @@ $td->runtest("C job API",
$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])
+foreach my $i (['a.pdf', 1], ['b.pdf', 2], ['c.pdf', 3], ['d.pdf', 4])
{
$td->runtest("check output",
{$td->FILE => $i->[0]},