From f1f711963b8e5f0b2b5a9d80a522cbd616a153a9 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 4 Jun 2022 21:15:40 -0400 Subject: Add and test QPDFLogger class --- libqpdf/QPDFLogger.cc | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 libqpdf/QPDFLogger.cc (limited to 'libqpdf/QPDFLogger.cc') diff --git a/libqpdf/QPDFLogger.cc b/libqpdf/QPDFLogger.cc new file mode 100644 index 00000000..859d6dcd --- /dev/null +++ b/libqpdf/QPDFLogger.cc @@ -0,0 +1,244 @@ +#include + +#include +#include +#include +#include + +namespace +{ + class Pl_Track: public Pipeline + { + public: + Pl_Track(char const* identifier, Pipeline* next) : + Pipeline(identifier, next), + used(false) + { + } + + virtual void + write(unsigned char const* data, size_t len) override + { + this->used = true; + getNext()->write(data, len); + } + + virtual void + finish() override + { + getNext()->finish(); + } + + bool + getUsed() const + { + return used; + } + + private: + bool used; + }; +}; // namespace + +QPDFLogger::Members::Members() : + p_discard(new Pl_Discard()), + p_real_stdout(new Pl_OStream("standard output", std::cout)), + p_stdout(new Pl_Track("track stdout", p_real_stdout.get())), + p_stderr(new Pl_OStream("standard error", std::cerr)), + p_info(p_stdout), + p_warn(nullptr), + p_error(p_stderr), + p_save(nullptr) +{ +} + +QPDFLogger::Members::~Members() +{ + p_stdout->finish(); + p_stderr->finish(); +} + +QPDFLogger::QPDFLogger() : + m(new Members()) +{ +} + +std::shared_ptr +QPDFLogger::defaultLogger() +{ + static auto l = std::make_shared(); + return l; +} + +void +QPDFLogger::info(char const* s) +{ + getInfo(false)->writeCStr(s); +} + +void +QPDFLogger::info(std::string const& s) +{ + getInfo(false)->writeString(s); +} + +std::shared_ptr +QPDFLogger::getInfo(bool null_okay) +{ + return throwIfNull(this->m->p_info, null_okay); +} + +void +QPDFLogger::warn(char const* s) +{ + getWarn(false)->writeCStr(s); +} + +void +QPDFLogger::warn(std::string const& s) +{ + getWarn(false)->writeString(s); +} + +std::shared_ptr +QPDFLogger::getWarn(bool null_okay) +{ + if (this->m->p_warn) { + return this->m->p_warn; + } + return getError(null_okay); +} + +void +QPDFLogger::error(char const* s) +{ + getError(false)->writeCStr(s); +} + +void +QPDFLogger::error(std::string const& s) +{ + getError(false)->writeString(s); +} + +std::shared_ptr +QPDFLogger::getError(bool null_okay) +{ + return throwIfNull(this->m->p_error, null_okay); +} + +std::shared_ptr +QPDFLogger::getSave(bool null_okay) +{ + return throwIfNull(this->m->p_save, null_okay); +} + +std::shared_ptr +QPDFLogger::standardOutput() +{ + return this->m->p_stdout; +} + +std::shared_ptr +QPDFLogger::standardError() +{ + return this->m->p_stderr; +} + +std::shared_ptr +QPDFLogger::discard() +{ + return this->m->p_discard; +} + +void +QPDFLogger::setInfo(std::shared_ptr p) +{ + if (p == nullptr) { + if (this->m->p_save == this->m->p_stdout) { + p = this->m->p_stderr; + } else { + p = this->m->p_stdout; + } + } + this->m->p_info = p; +} + +void +QPDFLogger::setWarn(std::shared_ptr p) +{ + this->m->p_warn = p; +} + +void +QPDFLogger::setError(std::shared_ptr p) +{ + if (p == nullptr) { + p = this->m->p_stderr; + } + this->m->p_error = p; +} + +void +QPDFLogger::setSave(std::shared_ptr p) +{ + if (p == this->m->p_stdout) { + auto pt = dynamic_cast(p.get()); + if (pt->getUsed()) { + throw std::logic_error( + "QPDFLogger: called setSave on standard output after standard" + " output has already been used"); + } + if (this->m->p_info == this->m->p_stdout) { + this->m->p_info = this->m->p_stderr; + } + } + this->m->p_save = p; +} + +void +QPDFLogger::saveToStandardOutput() +{ + setSave(standardOutput()); +} + +void +QPDFLogger::setOutputStreams(std::ostream* out_stream, std::ostream* err_stream) +{ + if (out_stream == &std::cout) { + out_stream = nullptr; + } + if (err_stream == &std::cerr) { + err_stream = nullptr; + } + std::shared_ptr new_out; + std::shared_ptr new_err; + + if (out_stream == nullptr) { + if (this->m->p_save == this->m->p_stdout) { + new_out = this->m->p_stderr; + } else { + new_out = this->m->p_stdout; + } + } else { + new_out = std::make_shared("output", *out_stream); + } + if (err_stream == nullptr) { + new_err = this->m->p_stderr; + } else { + new_err = std::make_shared("error output", *err_stream); + } + this->m->p_info = new_out; + this->m->p_warn = nullptr; + this->m->p_error = new_err; +} + +std::shared_ptr +QPDFLogger::throwIfNull(std::shared_ptr p, bool null_okay) +{ + if (!(null_okay || p)) { + throw std::logic_error( + "QPDFLogger: requested a null pipeline without null_okay == true"); + } + return p; +} -- cgit v1.2.3-54-g00ecf