mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 02:49:00 +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>
|
||||
|
||||
* Add additional qpdfjob C API functions take a handle.
|
||||
|
||||
* Add qpdf_exit_code_e to Constants.h so that exit codes from
|
||||
QPDFJob are accessible to the C API.
|
||||
|
||||
|
@ -108,6 +108,8 @@ class QPDFJob
|
||||
// and error streams on the caller's behalf. Defaults to "qpdf".
|
||||
QPDF_DLL
|
||||
void setMessagePrefix(std::string const&);
|
||||
QPDF_DLL
|
||||
std::string getMessagePrefix() const;
|
||||
|
||||
// To capture or redirect output, configure the logger returned by
|
||||
// getLogger(). By default, all QPDF and QPDFJob objects share the
|
||||
|
@ -45,6 +45,11 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#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
|
||||
* command-line with the given arguments and returns the exit code
|
||||
* that qpdf would use. argv must be a null-terminated array of
|
||||
@ -74,6 +79,52 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
@ -438,6 +438,12 @@ QPDFJob::setMessagePrefix(std::string const& message_prefix)
|
||||
this->m->message_prefix = message_prefix;
|
||||
}
|
||||
|
||||
std::string
|
||||
QPDFJob::getMessagePrefix() const
|
||||
{
|
||||
return this->m->message_prefix;
|
||||
}
|
||||
|
||||
std::shared_ptr<QPDFLogger>
|
||||
QPDFJob::getLogger()
|
||||
{
|
||||
|
@ -8,51 +8,115 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
int
|
||||
qpdfjob_run_from_argv(char const* const argv[])
|
||||
struct _qpdfjob_handle
|
||||
{
|
||||
auto whoami_p = QUtil::make_unique_cstr(argv[0]);
|
||||
auto whoami = QUtil::getWhoami(whoami_p.get());
|
||||
QUtil::setLineBuf(stdout);
|
||||
_qpdfjob_handle() = default;
|
||||
~_qpdfjob_handle() = default;
|
||||
|
||||
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 {
|
||||
j.initializeFromArgv(argv);
|
||||
j.run();
|
||||
return fn(j);
|
||||
} catch (std::exception& e) {
|
||||
*QPDFLogger::defaultLogger()->getError()
|
||||
<< whoami << ": " << e.what() << "\n";
|
||||
return QPDFJob::EXIT_ERROR;
|
||||
*j->j.getLogger()->getError()
|
||||
<< j->j.getMessagePrefix() << ": " << e.what() << "\n";
|
||||
}
|
||||
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
|
||||
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;
|
||||
for (auto k = argv; *k; ++k) {
|
||||
++argc;
|
||||
}
|
||||
return QUtil::call_main_from_wmain(
|
||||
argc, argv, [](int, char const* const new_argv[]) {
|
||||
return qpdfjob_run_from_argv(new_argv);
|
||||
argc, argv, [j](int, char const* const new_argv[]) {
|
||||
return qpdfjob_initialize_from_argv(j, new_argv);
|
||||
});
|
||||
}
|
||||
#endif // QPDF_NO_WCHAR_T
|
||||
|
||||
int
|
||||
qpdfjob_run_from_json(char const* json)
|
||||
qpdfjob_initialize_from_json(qpdfjob_handle j, char const* json)
|
||||
{
|
||||
QPDFJob j;
|
||||
try {
|
||||
j.initializeFromJson(json);
|
||||
j.run();
|
||||
} catch (std::exception& e) {
|
||||
*QPDFLogger::defaultLogger()->getError()
|
||||
<< "qpdfjob json: " << e.what() << "\n";
|
||||
return QPDFJob::EXIT_ERROR;
|
||||
}
|
||||
return j.getExitCode();
|
||||
return wrap_qpdfjob(j, [json](qpdfjob_handle jh) {
|
||||
jh->j.setMessagePrefix("qpdfjob json");
|
||||
jh->j.initializeFromJson(json);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
- In JSON v1 mode, the ``"objects"`` key now reflects the repaired
|
||||
|
@ -1,7 +1,7 @@
|
||||
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
|
||||
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
|
||||
qpdfjob json: an output file name is required; use - for standard output
|
||||
json error test passed
|
||||
|
Loading…
Reference in New Issue
Block a user