mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 19:08:59 +00:00
Add more flexible funtions to qpdfjob C API
This commit is contained in:
parent
28cc3692e3
commit
daef4e8fb8
@ -1,5 +1,7 @@
|
|||||||
2022-06-18 Jay Berkenbilt <ejb@ql.org>
|
2022-06-18 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
|
* Add additional qpdfjob C API functions take a handle.
|
||||||
|
|
||||||
* Add qpdf_exit_code_e to Constants.h so that exit codes from
|
* Add qpdf_exit_code_e to Constants.h so that exit codes from
|
||||||
QPDFJob are accessible to the C API.
|
QPDFJob are accessible to the C API.
|
||||||
|
|
||||||
|
@ -108,6 +108,8 @@ class QPDFJob
|
|||||||
// and error streams on the caller's behalf. Defaults to "qpdf".
|
// and error streams on the caller's behalf. Defaults to "qpdf".
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
void setMessagePrefix(std::string const&);
|
void setMessagePrefix(std::string const&);
|
||||||
|
QPDF_DLL
|
||||||
|
std::string getMessagePrefix() const;
|
||||||
|
|
||||||
// To capture or redirect output, configure the logger returned by
|
// To capture or redirect output, configure the logger returned by
|
||||||
// getLogger(). By default, all QPDF and QPDFJob objects share the
|
// getLogger(). By default, all QPDF and QPDFJob objects share the
|
||||||
|
@ -45,6 +45,11 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
/* SHORT INTERFACE -- These functions are single calls that take
|
||||||
|
* care of the whole life cycle of QPDFJob. They can be used for
|
||||||
|
* one-shot ooperations where no additional configuration is
|
||||||
|
* needed. See FULL INTERFACE below. */
|
||||||
|
|
||||||
/* This function does the equivalent of running the qpdf
|
/* This function does the equivalent of running the qpdf
|
||||||
* command-line with the given arguments and returns the exit code
|
* command-line with the given arguments and returns the exit code
|
||||||
* that qpdf would use. argv must be a null-terminated array of
|
* that qpdf would use. argv must be a null-terminated array of
|
||||||
@ -74,6 +79,52 @@ extern "C" {
|
|||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
int qpdfjob_run_from_json(char const* json);
|
int qpdfjob_run_from_json(char const* json);
|
||||||
|
|
||||||
|
/* FULL INTERFACE -- new in qpdf11. Similar to the qpdf-c.h API,
|
||||||
|
* you must call qpdfjob_init to get a qpdfjob_handle and, when
|
||||||
|
* done, call qpdfjob_cleanup to free resources. Remaining methods
|
||||||
|
* take qpdfjob_handle as an argument. This interface requires
|
||||||
|
* more calls but also offers greater flexibility.
|
||||||
|
*/
|
||||||
|
typedef struct _qpdfjob_handle* qpdfjob_handle;
|
||||||
|
QPDF_DLL
|
||||||
|
qpdfjob_handle qpdfjob_init();
|
||||||
|
|
||||||
|
QPDF_DLL
|
||||||
|
void qpdfjob_cleanup(qpdfjob_handle* j);
|
||||||
|
|
||||||
|
/* This function wraps QPDFJob::initializeFromArgv. The return
|
||||||
|
* value is the same as qpdfjob_run. If this returns an error, it
|
||||||
|
* is invalid to call any other functions this job handle.
|
||||||
|
*/
|
||||||
|
QPDF_DLL
|
||||||
|
int
|
||||||
|
qpdfjob_initialize_from_argv(qpdfjob_handle j, char const* const argv[]);
|
||||||
|
|
||||||
|
#ifndef QPDF_NO_WCHAR_T
|
||||||
|
/* This function is the same as qpdfjob_initialize_from_argv
|
||||||
|
* except argv is encoded with wide characters. This would be
|
||||||
|
* suitable for calling from a Windows wmain function.
|
||||||
|
*/
|
||||||
|
QPDF_DLL
|
||||||
|
int qpdfjob_initialize_from_wide_argv(
|
||||||
|
qpdfjob_handle j, wchar_t const* const argv[]);
|
||||||
|
#endif /* QPDF_NO_WCHAR_T */
|
||||||
|
|
||||||
|
/* This function wraps QPDFJob::initializeFromJson. The return
|
||||||
|
* value is the same as qpdfjob_run. If this returns an error, it
|
||||||
|
* is invalid to call any other functions this job handle.
|
||||||
|
*/
|
||||||
|
QPDF_DLL
|
||||||
|
int qpdfjob_initialize_from_json(qpdfjob_handle j, char const* json);
|
||||||
|
|
||||||
|
/* This function wraps QPDFJob::run. 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.
|
||||||
|
*/
|
||||||
|
QPDF_DLL
|
||||||
|
int qpdfjob_run(qpdfjob_handle j);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -438,6 +438,12 @@ QPDFJob::setMessagePrefix(std::string const& message_prefix)
|
|||||||
this->m->message_prefix = message_prefix;
|
this->m->message_prefix = message_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
QPDFJob::getMessagePrefix() const
|
||||||
|
{
|
||||||
|
return this->m->message_prefix;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<QPDFLogger>
|
std::shared_ptr<QPDFLogger>
|
||||||
QPDFJob::getLogger()
|
QPDFJob::getLogger()
|
||||||
{
|
{
|
||||||
|
@ -8,51 +8,115 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
int
|
struct _qpdfjob_handle
|
||||||
qpdfjob_run_from_argv(char const* const argv[])
|
|
||||||
{
|
{
|
||||||
auto whoami_p = QUtil::make_unique_cstr(argv[0]);
|
_qpdfjob_handle() = default;
|
||||||
auto whoami = QUtil::getWhoami(whoami_p.get());
|
~_qpdfjob_handle() = default;
|
||||||
QUtil::setLineBuf(stdout);
|
|
||||||
|
|
||||||
QPDFJob j;
|
QPDFJob j;
|
||||||
|
};
|
||||||
|
|
||||||
|
qpdfjob_handle
|
||||||
|
qpdfjob_init()
|
||||||
|
{
|
||||||
|
return new _qpdfjob_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qpdfjob_cleanup(qpdfjob_handle* j)
|
||||||
|
{
|
||||||
|
delete *j;
|
||||||
|
*j = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
wrap_qpdfjob(qpdfjob_handle j, std::function<int(qpdfjob_handle j)> fn)
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
j.initializeFromArgv(argv);
|
return fn(j);
|
||||||
j.run();
|
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
*QPDFLogger::defaultLogger()->getError()
|
*j->j.getLogger()->getError()
|
||||||
<< whoami << ": " << e.what() << "\n";
|
<< j->j.getMessagePrefix() << ": " << e.what() << "\n";
|
||||||
return QPDFJob::EXIT_ERROR;
|
|
||||||
}
|
}
|
||||||
return j.getExitCode();
|
return QPDFJob::EXIT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qpdfjob_initialize_from_argv(qpdfjob_handle j, char const* const argv[])
|
||||||
|
{
|
||||||
|
return wrap_qpdfjob(j, [argv](qpdfjob_handle jh) {
|
||||||
|
jh->j.initializeFromArgv(argv);
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QPDF_NO_WCHAR_T
|
#ifndef QPDF_NO_WCHAR_T
|
||||||
int
|
int
|
||||||
qpdfjob_run_from_wide_argv(wchar_t const* const argv[])
|
qpdfjob_initialize_from_wide_argv(qpdfjob_handle j, wchar_t const* const argv[])
|
||||||
{
|
{
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
for (auto k = argv; *k; ++k) {
|
for (auto k = argv; *k; ++k) {
|
||||||
++argc;
|
++argc;
|
||||||
}
|
}
|
||||||
return QUtil::call_main_from_wmain(
|
return QUtil::call_main_from_wmain(
|
||||||
argc, argv, [](int, char const* const new_argv[]) {
|
argc, argv, [j](int, char const* const new_argv[]) {
|
||||||
return qpdfjob_run_from_argv(new_argv);
|
return qpdfjob_initialize_from_argv(j, new_argv);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endif // QPDF_NO_WCHAR_T
|
#endif // QPDF_NO_WCHAR_T
|
||||||
|
|
||||||
int
|
int
|
||||||
qpdfjob_run_from_json(char const* json)
|
qpdfjob_initialize_from_json(qpdfjob_handle j, char const* json)
|
||||||
{
|
{
|
||||||
QPDFJob j;
|
return wrap_qpdfjob(j, [json](qpdfjob_handle jh) {
|
||||||
try {
|
jh->j.setMessagePrefix("qpdfjob json");
|
||||||
j.initializeFromJson(json);
|
jh->j.initializeFromJson(json);
|
||||||
j.run();
|
return 0;
|
||||||
} catch (std::exception& e) {
|
});
|
||||||
*QPDFLogger::defaultLogger()->getError()
|
|
||||||
<< "qpdfjob json: " << e.what() << "\n";
|
|
||||||
return QPDFJob::EXIT_ERROR;
|
|
||||||
}
|
|
||||||
return j.getExitCode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qpdfjob_run(qpdfjob_handle j)
|
||||||
|
{
|
||||||
|
QUtil::setLineBuf(stdout);
|
||||||
|
return wrap_qpdfjob(j, [](qpdfjob_handle jh) {
|
||||||
|
jh->j.run();
|
||||||
|
return jh->j.getExitCode();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static int run_with_handle(std::function<int(qpdfjob_handle)> fn)
|
||||||
|
{
|
||||||
|
auto j = qpdfjob_init();
|
||||||
|
int status = fn(j);
|
||||||
|
if (status == 0) {
|
||||||
|
status = qpdfjob_run(j);
|
||||||
|
}
|
||||||
|
qpdfjob_cleanup(&j);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qpdfjob_run_from_argv(char const* const argv[])
|
||||||
|
{
|
||||||
|
return run_with_handle([argv](qpdfjob_handle j) {
|
||||||
|
return qpdfjob_initialize_from_argv(j, argv);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QPDF_NO_WCHAR_T
|
||||||
|
int
|
||||||
|
qpdfjob_run_from_wide_argv(wchar_t const* const argv[])
|
||||||
|
{
|
||||||
|
return run_with_handle([argv](qpdfjob_handle j) {
|
||||||
|
return qpdfjob_initialize_from_wide_argv(j, argv);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#endif /* QPDF_NO_WCHAR_T */
|
||||||
|
|
||||||
|
int qpdfjob_run_from_json(char const* json)
|
||||||
|
{
|
||||||
|
return run_with_handle([json](qpdfjob_handle j) {
|
||||||
|
return qpdfjob_initialize_from_json(j, json);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -188,6 +188,13 @@ For a detailed list of changes, please see the file
|
|||||||
writing large amounts of data without having to keep everything
|
writing large amounts of data without having to keep everything
|
||||||
in memory.
|
in memory.
|
||||||
|
|
||||||
|
- Add new functions to the C API for qpdfjob that use a
|
||||||
|
``qpdfjob_handle``. Like with the regular C API for qpdf, you
|
||||||
|
have to call ``qpdfjob_init`` first, pass the handle to the
|
||||||
|
functions, and call ``qpdfjob_cleanup`` at the end. This
|
||||||
|
interface offers more flexibility than the old interface, which
|
||||||
|
remains available.
|
||||||
|
|
||||||
- Other changes
|
- Other changes
|
||||||
|
|
||||||
- In JSON v1 mode, the ``"objects"`` key now reflects the repaired
|
- In JSON v1 mode, the ``"objects"`` key now reflects the repaired
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
argv test passed
|
argv test passed
|
||||||
json 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
|
WARNING: xref-with-short-size.pdf (xref stream, offset 16227): Cross-reference stream data has the wrong size; expected = 52; actual = 56
|
||||||
qpdf: operation succeeded with warnings; resulting file may have some problems
|
qpdfjob json: operation succeeded with warnings; resulting file may have some problems
|
||||||
json warn test passed
|
json warn test passed
|
||||||
qpdfjob json: an output file name is required; use - for standard output
|
qpdfjob json: an output file name is required; use - for standard output
|
||||||
json error test passed
|
json error test passed
|
||||||
|
Loading…
Reference in New Issue
Block a user