mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Add C API functions for using custom loggers
Expose functions to the C API to create new loggers and to setLogger and getLogger for QPDF and QPDFJob.
This commit is contained in:
parent
0ad4e190ff
commit
3dbab589e3
@ -1,3 +1,8 @@
|
||||
2022-09-09 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Expose ability to create custom loggers and to get and set the
|
||||
logger for QPDF and QPDFJob through the C API.
|
||||
|
||||
2022-09-08 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Added new functions to the C API to support qpdf JSON:
|
||||
|
7
TODO
7
TODO
@ -8,12 +8,7 @@ Always
|
||||
Next
|
||||
====
|
||||
|
||||
Pending changes:
|
||||
|
||||
* Consider also exposing a way to set a new logger and to get the
|
||||
logger from QPDF and QPDFJob in the C API.
|
||||
|
||||
Soon: Break ground on "Document-level work"
|
||||
* Break ground on "Document-level work"
|
||||
|
||||
Possible future JSON enhancements
|
||||
=================================
|
||||
|
@ -140,6 +140,7 @@
|
||||
#include <qpdf/Constants.h>
|
||||
#include <qpdf/DLL.h>
|
||||
#include <qpdf/Types.h>
|
||||
#include <qpdf/qpdflogger-c.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -249,6 +250,20 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
void qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL value);
|
||||
|
||||
/* LOG FUNCTIONS */
|
||||
|
||||
/* Set or get the current logger. You need to call
|
||||
* qpdflogger_cleanup on the logger handles when you are done with
|
||||
* the handles. The underlying logger is cleaned up automatically
|
||||
* and persists if needed after the logger handle is destroyed.
|
||||
* See comments in qpdflogger-c.h for details.
|
||||
*/
|
||||
|
||||
QPDF_DLL
|
||||
void qpdf_set_logger(qpdf_data qpdf, qpdflogger_handle logger);
|
||||
QPDF_DLL
|
||||
qpdflogger_handle qpdf_get_logger(qpdf_data qpdf);
|
||||
|
||||
/* CHECK FUNCTIONS */
|
||||
|
||||
/* Attempt to read the entire PDF file to see if there are any
|
||||
|
@ -32,6 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <qpdf/DLL.h>
|
||||
#include <qpdf/qpdflogger-c.h>
|
||||
#include <string.h>
|
||||
#ifndef QPDF_NO_WCHAR_T
|
||||
# include <wchar.h>
|
||||
@ -92,6 +93,18 @@ extern "C" {
|
||||
QPDF_DLL
|
||||
void qpdfjob_cleanup(qpdfjob_handle* j);
|
||||
|
||||
/* Set or get the current logger. You need to call
|
||||
* qpdflogger_cleanup on the logger handles when you are done with
|
||||
* the handles. The underlying logger is cleaned up automatically
|
||||
* and persists if needed after the logger handle is destroyed.
|
||||
* See comments in qpdflogger-c.h for details.
|
||||
*/
|
||||
|
||||
QPDF_DLL
|
||||
void qpdfjob_set_logger(qpdfjob_handle j, qpdflogger_handle logger);
|
||||
QPDF_DLL
|
||||
qpdflogger_handle qpdfjob_get_logger(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.
|
||||
|
@ -38,16 +38,28 @@ extern "C" {
|
||||
|
||||
/* To operate on a logger, you need a handle to it. call
|
||||
* qpdflogger_default_logger to get a handle for the default
|
||||
* logger. The qpdf and qpdfjob functions may offer ways to get
|
||||
* other logger handles. When you're done with the logger handler,
|
||||
* call qpdflogger_cleanup. This does not destroy the underlying
|
||||
* log object. It just cleans up the handle to it.
|
||||
* logger. There are functions in qpdf-c.h and qpdfjob-c.h that
|
||||
* also take or return logger handles. When you're done with the
|
||||
* logger handler, call qpdflogger_cleanup. This cleans up the
|
||||
* handle but leaves the underlying log object intact. (It uses a
|
||||
* shared pointer and will be cleaned up automatically when it is
|
||||
* no longer in use.) That means you can create a logger with
|
||||
* qpdflogger_create(), pass the logger handle to a function in
|
||||
* qpdf-c.h or qpdfjob-c.h, and then clean it up, subject to
|
||||
* constraints imposed by the other function.
|
||||
*/
|
||||
|
||||
typedef struct _qpdflogger_handle* qpdflogger_handle;
|
||||
QPDF_DLL
|
||||
qpdflogger_handle qpdflogger_default_logger();
|
||||
|
||||
/* Calling cleanup on the handle returned by qpdflogger_create
|
||||
* destroys the handle but not the underlying logger. See comments
|
||||
* above.
|
||||
*/
|
||||
QPDF_DLL
|
||||
qpdflogger_handle qpdflogger_create();
|
||||
|
||||
QPDF_DLL
|
||||
void qpdflogger_cleanup(qpdflogger_handle* l);
|
||||
|
||||
@ -95,6 +107,10 @@ extern "C" {
|
||||
void qpdflogger_save_to_standard_output(
|
||||
qpdflogger_handle l, int only_if_not_set);
|
||||
|
||||
/* For testing */
|
||||
QPDF_DLL
|
||||
int qpdflogger_equal(qpdflogger_handle l1, qpdflogger_handle l2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <qpdf/QPDFWriter.hh>
|
||||
#include <qpdf/QTC.hh>
|
||||
#include <qpdf/QUtil.hh>
|
||||
#include <qpdf/qpdflogger-c_impl.hh>
|
||||
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
@ -279,6 +280,18 @@ qpdf_check_pdf(qpdf_data qpdf)
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
qpdf_set_logger(qpdf_data qpdf, qpdflogger_handle logger)
|
||||
{
|
||||
qpdf->qpdf->setLogger(logger->l);
|
||||
}
|
||||
|
||||
qpdflogger_handle
|
||||
qpdf_get_logger(qpdf_data qpdf)
|
||||
{
|
||||
return new _qpdflogger_handle(qpdf->qpdf->getLogger());
|
||||
}
|
||||
|
||||
void
|
||||
qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL value)
|
||||
{
|
||||
|
11
libqpdf/qpdf/qpdflogger-c_impl.hh
Normal file
11
libqpdf/qpdf/qpdflogger-c_impl.hh
Normal file
@ -0,0 +1,11 @@
|
||||
#include <qpdf/qpdflogger-c.h>
|
||||
|
||||
#include <qpdf/QPDFLogger.hh>
|
||||
|
||||
struct _qpdflogger_handle
|
||||
{
|
||||
_qpdflogger_handle(std::shared_ptr<QPDFLogger> l);
|
||||
~_qpdflogger_handle() = default;
|
||||
|
||||
std::shared_ptr<QPDFLogger> l;
|
||||
};
|
@ -4,6 +4,7 @@
|
||||
#include <qpdf/QPDFLogger.hh>
|
||||
#include <qpdf/QPDFUsage.hh>
|
||||
#include <qpdf/QUtil.hh>
|
||||
#include <qpdf/qpdflogger-c_impl.hh>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
@ -41,6 +42,18 @@ wrap_qpdfjob(qpdfjob_handle j, std::function<int(qpdfjob_handle j)> fn)
|
||||
return QPDFJob::EXIT_ERROR;
|
||||
}
|
||||
|
||||
void
|
||||
qpdfjob_set_logger(qpdfjob_handle j, qpdflogger_handle logger)
|
||||
{
|
||||
j->j.setLogger(logger->l);
|
||||
}
|
||||
|
||||
qpdflogger_handle
|
||||
qpdfjob_get_logger(qpdfjob_handle j)
|
||||
{
|
||||
return new _qpdflogger_handle(j->j.getLogger());
|
||||
}
|
||||
|
||||
int
|
||||
qpdfjob_initialize_from_argv(qpdfjob_handle j, char const* const argv[])
|
||||
{
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <qpdf/qpdflogger-c.h>
|
||||
|
||||
#include <qpdf/qpdflogger-c_impl.hh>
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
#include <qpdf/Pl_Function.hh>
|
||||
#include <qpdf/QIntC.hh>
|
||||
@ -7,14 +9,6 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
struct _qpdflogger_handle
|
||||
{
|
||||
_qpdflogger_handle(std::shared_ptr<QPDFLogger> l);
|
||||
~_qpdflogger_handle() = default;
|
||||
|
||||
std::shared_ptr<QPDFLogger> l;
|
||||
};
|
||||
|
||||
_qpdflogger_handle::_qpdflogger_handle(std::shared_ptr<QPDFLogger> l) :
|
||||
l(l)
|
||||
{
|
||||
@ -26,6 +20,12 @@ qpdflogger_default_logger()
|
||||
return new _qpdflogger_handle(QPDFLogger::defaultLogger());
|
||||
}
|
||||
|
||||
qpdflogger_handle
|
||||
qpdflogger_create()
|
||||
{
|
||||
return new _qpdflogger_handle(QPDFLogger::create());
|
||||
}
|
||||
|
||||
void
|
||||
qpdflogger_cleanup(qpdflogger_handle* l)
|
||||
{
|
||||
@ -125,3 +125,9 @@ qpdflogger_save_to_standard_output(qpdflogger_handle l, int only_if_not_set)
|
||||
qpdflogger_set_save(
|
||||
l, qpdf_log_dest_stdout, nullptr, nullptr, only_if_not_set);
|
||||
}
|
||||
|
||||
int
|
||||
qpdflogger_equal(qpdflogger_handle l1, qpdflogger_handle l2)
|
||||
{
|
||||
return l1->l.get() == l2->l.get();
|
||||
}
|
||||
|
@ -140,6 +140,15 @@ write_to_file(char const* data, size_t size, void* udata)
|
||||
return fwrite(data, 1, size, f) != size;
|
||||
}
|
||||
|
||||
static int
|
||||
custom_log(char const* data, size_t size, void* udata)
|
||||
{
|
||||
fprintf(stderr, "|custom|");
|
||||
fwrite(data, 1, size, stderr);
|
||||
fflush(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
test01(
|
||||
char const* infile,
|
||||
@ -583,6 +592,20 @@ test23(
|
||||
char const* outfile,
|
||||
char const* xarg)
|
||||
{
|
||||
/* Test check and also exercise custom logger */
|
||||
qpdflogger_handle l1 = qpdf_get_logger(qpdf);
|
||||
qpdflogger_handle l2 = qpdflogger_default_logger();
|
||||
assert(qpdflogger_equal(l1, l2));
|
||||
qpdflogger_cleanup(&l1);
|
||||
qpdflogger_cleanup(&l2);
|
||||
qpdflogger_handle l = qpdflogger_create();
|
||||
qpdflogger_set_warn(l, qpdf_log_dest_custom, custom_log, NULL);
|
||||
qpdf_set_logger(qpdf, l);
|
||||
qpdflogger_handle l3 = qpdf_get_logger(qpdf);
|
||||
assert(qpdflogger_equal(l, l3));
|
||||
qpdflogger_cleanup(&l);
|
||||
qpdflogger_cleanup(&l3);
|
||||
|
||||
QPDF_ERROR_CODE status = 0;
|
||||
qpdf_read(qpdf, infile, password);
|
||||
status = qpdf_check_pdf(qpdf);
|
||||
|
@ -26,6 +26,15 @@ custom_progress(int progress, void* data)
|
||||
printf("%s: write progress: %d%%\n", (char const*)data, progress);
|
||||
}
|
||||
|
||||
static int
|
||||
custom_log(char const* data, size_t size, void* udata)
|
||||
{
|
||||
fprintf(stderr, "|custom|");
|
||||
fwrite(data, 1, size, stderr);
|
||||
fflush(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
run_tests()
|
||||
{
|
||||
@ -55,6 +64,7 @@ run_tests()
|
||||
\"objectStreams\": \"generate\"\n\
|
||||
}") == 0);
|
||||
printf("json test passed\n");
|
||||
fflush(stdout);
|
||||
|
||||
assert(qpdfjob_run_from_json("{\n\
|
||||
\"inputFile\": \"xref-with-short-size.pdf\",\n\
|
||||
@ -64,10 +74,28 @@ run_tests()
|
||||
\"objectStreams\": \"generate\"\n\
|
||||
}") == 3);
|
||||
printf("json warn test passed\n");
|
||||
fflush(stdout);
|
||||
|
||||
assert(qpdfjob_run_from_json("{\n\
|
||||
/* Also exercise custom logger */
|
||||
j = qpdfjob_init();
|
||||
qpdflogger_handle l1 = qpdfjob_get_logger(j);
|
||||
qpdflogger_handle l2 = qpdflogger_default_logger();
|
||||
assert(qpdflogger_equal(l1, l2));
|
||||
qpdflogger_cleanup(&l1);
|
||||
qpdflogger_cleanup(&l2);
|
||||
qpdflogger_handle l = qpdflogger_create();
|
||||
qpdflogger_set_error(l, qpdf_log_dest_custom, custom_log, NULL);
|
||||
qpdfjob_set_logger(j, l);
|
||||
qpdflogger_handle l3 = qpdfjob_get_logger(j);
|
||||
assert(qpdflogger_equal(l, l3));
|
||||
qpdflogger_cleanup(&l);
|
||||
qpdflogger_cleanup(&l3);
|
||||
|
||||
qpdfjob_initialize_from_json(j, "{\n\
|
||||
\"inputFile\": \"nothing-there.pdf\"\n\
|
||||
}") == 2);
|
||||
}");
|
||||
assert(qpdfjob_run(j) == 2);
|
||||
qpdfjob_cleanup(&j);
|
||||
printf("json error test passed\n");
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
WARNING: c-check-warn-in.pdf: file is damaged
|
||||
WARNING: c-check-warn-in.pdf (offset 1556): xref not found
|
||||
WARNING: c-check-warn-in.pdf: Attempting to reconstruct cross-reference table
|
||||
|custom|WARNING: |custom|c-check-warn-in.pdf: file is damaged|custom|
|
||||
|custom|WARNING: |custom|c-check-warn-in.pdf (offset 1556): xref not found|custom|
|
||||
|custom|WARNING: |custom|c-check-warn-in.pdf: Attempting to reconstruct cross-reference table|custom|
|
||||
status: 1
|
||||
warning: c-check-warn-in.pdf: file is damaged
|
||||
code: 5
|
||||
|
@ -6,5 +6,6 @@ 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
|
||||
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
|
||||
|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
|
||||
|
Loading…
Reference in New Issue
Block a user