qpdf/include/qpdf/QPDFLogger.hh

183 lines
6.5 KiB
C++

// Copyright (c) 2005-2023 Jay Berkenbilt
//
// This file is part of qpdf.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Versions of qpdf prior to version 7 were released under the terms
// of version 2.0 of the Artistic License. At your option, you may
// continue to consider qpdf to be licensed under those terms. Please
// see the manual for additional information.
#ifndef QPDFLOGGER_HH
#define QPDFLOGGER_HH
#include <qpdf/DLL.h>
#include <qpdf/Pipeline.hh>
#include <iostream>
#include <memory>
class QPDFLogger
{
public:
QPDF_DLL
static std::shared_ptr<QPDFLogger> create();
// Return the default logger. In general, you should use the
// default logger. You can also create your own loggers and use
// them QPDF and QPDFJob objects, but there are few reasons to do
// so. One reason may if you are using multiple QPDF or QPDFJob
// objects in different threads and want to capture output and
// errors to different streams. (Note that a single QPDF or
// QPDFJob can't be safely used from multiple threads, but it is
// safe to use separate QPDF and QPDFJob objects on separate
// threads.) Another possible reason would be if you are writing
// an application that uses the qpdf library directly and qpdf is
// also used by a downstream library or if you are using qpdf from
// a library and don't want to interfere with potential uses of
// qpdf by other libraries or applications.
QPDF_DLL
static std::shared_ptr<QPDFLogger> defaultLogger();
// Defaults:
//
// info -- if save is standard output, standard error, else standard output
// warn -- whatever error points to
// error -- standard error
// save -- undefined unless set
//
// "info" is used for diagnostic messages, verbose messages, and
// progress messages. "warn" is used for warnings. "error" is used
// for errors. "save" is used for saving output -- see below.
//
// On deletion, finish() is called for the standard output and
// standard error pipelines, which flushes output. If you supply
// any custom pipelines, you must call finish() on them yourself.
// Note that calling finish is not needed for string, stdio, or
// ostream pipelines.
//
// NOTES ABOUT THE SAVE PIPELINE
//
// The save pipeline is used by QPDFJob when some kind of binary
// output is being saved. This includes saving attachments and
// stream data and also includes when the output file is standard
// output. If you want to grab that output, you can call setSave.
// See examples/qpdfjob-save-attachment.cc and
// examples/qpdfjob-c-save-attachment.c.
//
// You should never set the save pipeline to the same destination
// as something else. Doing so will corrupt your save output. If
// you want to save to standard output, use the method
// saveToStandardOutput(). In addition to setting the save
// pipeline, that does the following extra things:
//
// * If standard output has been used, a logic error is thrown
// * If info is set to standard output at the time of the set save
// call, it is switched to standard error.
//
// This is not a guarantee. You can still mess this up in ways
// that are not checked. Here are a few examples:
//
// * Don't set any pipeline to standard output *after* passing it
// to setSave()
// * Don't use a separate mechanism to write stdout/stderr other
// than QPDFLogger::standardOutput()
// * Don't set anything to the same custom pipeline that save is
// set to.
//
// Just be sure that if you change pipelines around, you should
// avoid having the save pipeline also be used for any other
// purpose. The special case for saving to standard output allows
// you to call saveToStandardOutput() early without having to
// worry about the info pipeline.
QPDF_DLL
void info(char const*);
QPDF_DLL
void info(std::string const&);
QPDF_DLL
std::shared_ptr<Pipeline> getInfo(bool null_okay = false);
QPDF_DLL
void warn(char const*);
QPDF_DLL
void warn(std::string const&);
QPDF_DLL
std::shared_ptr<Pipeline> getWarn(bool null_okay = false);
QPDF_DLL
void error(char const*);
QPDF_DLL
void error(std::string const&);
QPDF_DLL
std::shared_ptr<Pipeline> getError(bool null_okay = false);
QPDF_DLL
std::shared_ptr<Pipeline> getSave(bool null_okay = false);
QPDF_DLL
std::shared_ptr<Pipeline> standardOutput();
QPDF_DLL
std::shared_ptr<Pipeline> standardError();
QPDF_DLL
std::shared_ptr<Pipeline> discard();
// Passing a null pointer resets to default
QPDF_DLL
void setInfo(std::shared_ptr<Pipeline>);
QPDF_DLL
void setWarn(std::shared_ptr<Pipeline>);
QPDF_DLL
void setError(std::shared_ptr<Pipeline>);
// See notes above about the save pipeline
QPDF_DLL
void setSave(std::shared_ptr<Pipeline>, bool only_if_not_set);
QPDF_DLL
void saveToStandardOutput(bool only_if_not_set);
// Shortcut for logic to reset output to new output/error streams.
// out_stream is used for info, err_stream is used for error, and
// warning is cleared so that it follows error.
QPDF_DLL
void setOutputStreams(std::ostream* out_stream, std::ostream* err_stream);
private:
QPDFLogger();
std::shared_ptr<Pipeline> throwIfNull(std::shared_ptr<Pipeline>, bool null_okay);
class Members
{
friend class QPDFLogger;
public:
QPDF_DLL
~Members();
private:
Members();
Members(Members const&) = delete;
std::shared_ptr<Pipeline> p_discard;
std::shared_ptr<Pipeline> p_real_stdout;
std::shared_ptr<Pipeline> p_stdout;
std::shared_ptr<Pipeline> p_stderr;
std::shared_ptr<Pipeline> p_info;
std::shared_ptr<Pipeline> p_warn;
std::shared_ptr<Pipeline> p_error;
std::shared_ptr<Pipeline> p_save;
};
std::shared_ptr<Members> m;
};
#endif // QPDFLOGGER_HH