aboutsummaryrefslogtreecommitdiffstats
path: root/include/qpdf/QPDFLogger.hh
blob: 6875721f04a40f79b35975b33e2021a9934b6cb0 (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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// 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