aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-06-18 19:38:36 +0200
committerJay Berkenbilt <ejb@ql.org>2022-06-19 14:46:58 +0200
commit8130d50e3b5aa0235a133c3c5a3018ac01afb5e1 (patch)
tree461c961df0299707b628f4fa6a41539fafa2d193 /libqpdf
parentdaef4e8fb856e84e2a9151cd7715a941a0ae9c6c (diff)
downloadqpdf-8130d50e3b5aa0235a133c3c5a3018ac01afb5e1.tar.zst
Add C API to QPDFLogger
Diffstat (limited to 'libqpdf')
-rw-r--r--libqpdf/CMakeLists.txt3
-rw-r--r--libqpdf/QPDFJob.cc8
-rw-r--r--libqpdf/QPDFLogger.cc9
-rw-r--r--libqpdf/qpdflogger-c.cc163
4 files changed, 175 insertions, 8 deletions
diff --git a/libqpdf/CMakeLists.txt b/libqpdf/CMakeLists.txt
index a6b036a7..3c14115b 100644
--- a/libqpdf/CMakeLists.txt
+++ b/libqpdf/CMakeLists.txt
@@ -110,7 +110,8 @@ set(libqpdf_SOURCES
SF_FlateLzwDecode.cc
SparseOHArray.cc
qpdf-c.cc
- qpdfjob-c.cc)
+ qpdfjob-c.cc
+ qpdflogger-c.cc)
include(FindPkgConfig)
include(CheckTypeSize)
diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc
index b25257a1..606a612a 100644
--- a/libqpdf/QPDFJob.cc
+++ b/libqpdf/QPDFJob.cc
@@ -710,7 +710,7 @@ QPDFJob::checkConfiguration()
save_to_stdout = true;
}
if (save_to_stdout) {
- this->m->log->saveToStandardOutput();
+ this->m->log->saveToStandardOutput(true);
}
if ((!m->split_pages) &&
QUtil::same_file(m->infilename.get(), m->outfilename.get())) {
@@ -925,7 +925,7 @@ QPDFJob::doShowObj(QPDF& pdf)
} else {
// If anything has been written to standard output,
// this will fail.
- this->m->log->saveToStandardOutput();
+ this->m->log->saveToStandardOutput(true);
obj.pipeStreamData(
this->m->log->getSave().get(),
(filter && m->normalize) ? qpdf_ef_normalize : 0,
@@ -1031,7 +1031,7 @@ QPDFJob::doShowAttachment(QPDF& pdf)
auto efs = fs->getEmbeddedFileStream();
// saveToStandardOutput has already been called, but it's harmless
// to call it again, so do as defensive coding.
- this->m->log->saveToStandardOutput();
+ this->m->log->saveToStandardOutput(true);
efs.pipeStreamData(this->m->log->getSave().get(), 0, qpdf_dl_all);
}
@@ -3289,7 +3289,7 @@ QPDFJob::writeOutfile(QPDF& pdf)
} else {
// saveToStandardOutput has already been called, but
// calling it again is defensive and harmless.
- this->m->log->saveToStandardOutput();
+ this->m->log->saveToStandardOutput(true);
w.setOutputPipeline(this->m->log->getSave().get());
}
setWriterOptions(pdf, w);
diff --git a/libqpdf/QPDFLogger.cc b/libqpdf/QPDFLogger.cc
index 3b25c050..78cb2a32 100644
--- a/libqpdf/QPDFLogger.cc
+++ b/libqpdf/QPDFLogger.cc
@@ -181,8 +181,11 @@ QPDFLogger::setError(std::shared_ptr<Pipeline> p)
}
void
-QPDFLogger::setSave(std::shared_ptr<Pipeline> p)
+QPDFLogger::setSave(std::shared_ptr<Pipeline> p, bool only_if_not_set)
{
+ if (only_if_not_set && (this->m->p_save != nullptr)) {
+ return;
+ }
if (this->m->p_save == p) {
return;
}
@@ -202,9 +205,9 @@ QPDFLogger::setSave(std::shared_ptr<Pipeline> p)
}
void
-QPDFLogger::saveToStandardOutput()
+QPDFLogger::saveToStandardOutput(bool only_if_not_set)
{
- setSave(standardOutput());
+ setSave(standardOutput(), only_if_not_set);
}
void
diff --git a/libqpdf/qpdflogger-c.cc b/libqpdf/qpdflogger-c.cc
new file mode 100644
index 00000000..46fd9fba
--- /dev/null
+++ b/libqpdf/qpdflogger-c.cc
@@ -0,0 +1,163 @@
+#include <qpdf/qpdflogger-c.h>
+
+#include <qpdf/Pipeline.hh>
+#include <qpdf/QIntC.hh>
+#include <qpdf/QPDFLogger.hh>
+#include <functional>
+#include <memory>
+
+struct _qpdflogger_handle
+{
+ _qpdflogger_handle(std::shared_ptr<QPDFLogger> l);
+ ~_qpdflogger_handle() = default;
+
+ std::shared_ptr<QPDFLogger> l;
+};
+
+namespace
+{
+ class FunctionPipeline: public Pipeline
+ {
+ public:
+ FunctionPipeline(char const* identifier, qpdf_log_fn_t fn, void* udata);
+ virtual ~FunctionPipeline() = default;
+
+ virtual void write(unsigned char const* buf, size_t len) override;
+ virtual void finish() override;
+
+ private:
+ qpdf_log_fn_t fn;
+ void* udata;
+ };
+}; // namespace
+
+FunctionPipeline::FunctionPipeline(
+ char const* identifier, qpdf_log_fn_t fn, void* udata) :
+ Pipeline(identifier, nullptr),
+ fn(fn),
+ udata(udata)
+{
+}
+
+void
+FunctionPipeline::write(unsigned char const* buf, size_t len)
+{
+ fn(reinterpret_cast<char const*>(buf), QIntC::to_ulong(len), udata);
+}
+
+void
+FunctionPipeline::finish()
+{
+ // Nothing needed
+}
+
+_qpdflogger_handle::_qpdflogger_handle(std::shared_ptr<QPDFLogger> l) :
+ l(l)
+{
+}
+
+qpdflogger_handle
+qpdflogger_default_logger()
+{
+ return new _qpdflogger_handle(QPDFLogger::defaultLogger());
+}
+
+void
+qpdflogger_cleanup(qpdflogger_handle* l)
+{
+ delete *l;
+ *l = nullptr;
+}
+
+static void
+set_log_dest(
+ QPDFLogger* l,
+ std::function<void(std::shared_ptr<Pipeline>)> method,
+ qpdf_log_dest_e dest,
+ char const* identifier,
+ qpdf_log_fn_t fn,
+ void* udata)
+{
+ switch (dest) {
+ case qpdf_log_dest_default:
+ method(nullptr);
+ break;
+ case qpdf_log_dest_stdout:
+ method(l->standardOutput());
+ break;
+ case qpdf_log_dest_stderr:
+ method(l->standardError());
+ break;
+ case qpdf_log_dest_discard:
+ method(l->discard());
+ break;
+ case qpdf_log_dest_custom:
+ method(std::make_shared<FunctionPipeline>(identifier, fn, udata));
+ break;
+ }
+}
+
+static void
+set_log_dest(
+ QPDFLogger* l,
+ void (QPDFLogger::*method)(std::shared_ptr<Pipeline>),
+ qpdf_log_dest_e dest,
+ char const* identifier,
+ qpdf_log_fn_t fn,
+ void* udata)
+{
+ set_log_dest(
+ l,
+ std::bind(std::mem_fn(method), l, std::placeholders::_1),
+ dest,
+ identifier,
+ fn,
+ udata);
+}
+
+void
+qpdflogger_set_info(
+ qpdflogger_handle l, qpdf_log_dest_e dest, qpdf_log_fn_t fn, void* udata)
+{
+ set_log_dest(
+ l->l.get(), &QPDFLogger::setInfo, dest, "info logger", fn, udata);
+}
+
+void
+qpdflogger_set_warn(
+ qpdflogger_handle l, qpdf_log_dest_e dest, qpdf_log_fn_t fn, void* udata)
+{
+ set_log_dest(
+ l->l.get(), &QPDFLogger::setWarn, dest, "warn logger", fn, udata);
+}
+
+void
+qpdflogger_set_error(
+ qpdflogger_handle l, qpdf_log_dest_e dest, qpdf_log_fn_t fn, void* udata)
+{
+ set_log_dest(
+ l->l.get(), &QPDFLogger::setError, dest, "error logger", fn, udata);
+}
+
+void
+qpdflogger_set_save(
+ qpdflogger_handle l,
+ qpdf_log_dest_e dest,
+ qpdf_log_fn_t fn,
+ void* udata,
+ int only_if_not_set)
+{
+ auto method = std::bind(
+ std::mem_fn(&QPDFLogger::setSave),
+ l->l.get(),
+ std::placeholders::_1,
+ only_if_not_set);
+ set_log_dest(l->l.get(), method, dest, "save logger", fn, udata);
+}
+
+void
+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);
+}