aboutsummaryrefslogtreecommitdiffstats
path: root/include/qpdf/QPDFLogger.hh
blob: 0b5b61864add0907e275ea573a2df38160c77292 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// 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 with QPDF and QPDFJob objects, but there are few reasons to do
    // so. One reason may be that 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