Coverage Report

Created: 2024-09-08 06:05

/src/qpdf/libqpdf/QPDFLogger.cc
Line
Count
Source (jump to first uncovered line)
1
#include <qpdf/QPDFLogger.hh>
2
3
#include <qpdf/Pl_Discard.hh>
4
#include <qpdf/Pl_OStream.hh>
5
#include <qpdf/QUtil.hh>
6
#include <iostream>
7
#include <stdexcept>
8
9
namespace
10
{
11
    class Pl_Track: public Pipeline
12
    {
13
      public:
14
        Pl_Track(char const* identifier, Pipeline* next) :
15
            Pipeline(identifier, next)
16
1
        {
17
1
        }
18
19
        void
20
        write(unsigned char const* data, size_t len) override
21
0
        {
22
0
            this->used = true;
23
0
            getNext()->write(data, len);
24
0
        }
25
26
        void
27
        finish() override
28
1
        {
29
1
            getNext()->finish();
30
1
        }
31
32
        bool
33
        getUsed() const
34
0
        {
35
0
            return used;
36
0
        }
37
38
      private:
39
        bool used{false};
40
    };
41
}; // namespace
42
43
QPDFLogger::Members::Members() :
44
    p_discard(new Pl_Discard()),
45
    p_real_stdout(new Pl_OStream("standard output", std::cout)),
46
    p_stdout(new Pl_Track("track stdout", p_real_stdout.get())),
47
    p_stderr(new Pl_OStream("standard error", std::cerr)),
48
    p_info(p_stdout),
49
    p_warn(nullptr),
50
    p_error(p_stderr),
51
    p_save(nullptr)
52
1
{
53
1
}
54
55
QPDFLogger::Members::~Members()
56
1
{
57
1
    p_stdout->finish();
58
1
    p_stderr->finish();
59
1
}
60
61
QPDFLogger::QPDFLogger() :
62
    m(new Members())
63
1
{
64
1
}
65
66
std::shared_ptr<QPDFLogger>
67
QPDFLogger::create()
68
1
{
69
1
    return std::shared_ptr<QPDFLogger>(new QPDFLogger);
70
1
}
71
72
std::shared_ptr<QPDFLogger>
73
QPDFLogger::defaultLogger()
74
6.73k
{
75
6.73k
    static auto l = create();
76
6.73k
    return l;
77
6.73k
}
78
79
void
80
QPDFLogger::info(char const* s)
81
0
{
82
0
    getInfo(false)->writeCStr(s);
83
0
}
84
85
void
86
QPDFLogger::info(std::string const& s)
87
0
{
88
0
    getInfo(false)->writeString(s);
89
0
}
90
91
std::shared_ptr<Pipeline>
92
QPDFLogger::getInfo(bool null_okay)
93
0
{
94
0
    return throwIfNull(m->p_info, null_okay);
95
0
}
96
97
void
98
QPDFLogger::warn(char const* s)
99
0
{
100
0
    getWarn(false)->writeCStr(s);
101
0
}
102
103
void
104
QPDFLogger::warn(std::string const& s)
105
0
{
106
0
    getWarn(false)->writeString(s);
107
0
}
108
109
std::shared_ptr<Pipeline>
110
QPDFLogger::getWarn(bool null_okay)
111
50.9k
{
112
50.9k
    if (m->p_warn) {
113
0
        return m->p_warn;
114
0
    }
115
50.9k
    return getError(null_okay);
116
50.9k
}
117
118
void
119
QPDFLogger::error(char const* s)
120
0
{
121
0
    getError(false)->writeCStr(s);
122
0
}
123
124
void
125
QPDFLogger::error(std::string const& s)
126
0
{
127
0
    getError(false)->writeString(s);
128
0
}
129
130
std::shared_ptr<Pipeline>
131
QPDFLogger::getError(bool null_okay)
132
50.9k
{
133
50.9k
    return throwIfNull(m->p_error, null_okay);
134
50.9k
}
135
136
std::shared_ptr<Pipeline>
137
QPDFLogger::getSave(bool null_okay)
138
0
{
139
0
    return throwIfNull(m->p_save, null_okay);
140
0
}
141
142
std::shared_ptr<Pipeline>
143
QPDFLogger::standardOutput()
144
0
{
145
0
    return m->p_stdout;
146
0
}
147
148
std::shared_ptr<Pipeline>
149
QPDFLogger::standardError()
150
0
{
151
0
    return m->p_stderr;
152
0
}
153
154
std::shared_ptr<Pipeline>
155
QPDFLogger::discard()
156
0
{
157
0
    return m->p_discard;
158
0
}
159
160
void
161
QPDFLogger::setInfo(std::shared_ptr<Pipeline> p)
162
0
{
163
0
    if (p == nullptr) {
164
0
        if (m->p_save == m->p_stdout) {
165
0
            p = m->p_stderr;
166
0
        } else {
167
0
            p = m->p_stdout;
168
0
        }
169
0
    }
170
0
    m->p_info = p;
171
0
}
172
173
void
174
QPDFLogger::setWarn(std::shared_ptr<Pipeline> p)
175
0
{
176
0
    m->p_warn = p;
177
0
}
178
179
void
180
QPDFLogger::setError(std::shared_ptr<Pipeline> p)
181
0
{
182
0
    if (p == nullptr) {
183
0
        p = m->p_stderr;
184
0
    }
185
0
    m->p_error = p;
186
0
}
187
188
void
189
QPDFLogger::setSave(std::shared_ptr<Pipeline> p, bool only_if_not_set)
190
0
{
191
0
    if (only_if_not_set && (m->p_save != nullptr)) {
192
0
        return;
193
0
    }
194
0
    if (m->p_save == p) {
195
0
        return;
196
0
    }
197
0
    if (p == m->p_stdout) {
198
0
        auto pt = dynamic_cast<Pl_Track*>(p.get());
199
0
        if (pt->getUsed()) {
200
0
            throw std::logic_error("QPDFLogger: called setSave on standard output after standard"
201
0
                                   " output has already been used");
202
0
        }
203
0
        if (m->p_info == m->p_stdout) {
204
0
            m->p_info = m->p_stderr;
205
0
        }
206
0
        QUtil::binary_stdout();
207
0
    }
208
0
    m->p_save = p;
209
0
}
210
211
void
212
QPDFLogger::saveToStandardOutput(bool only_if_not_set)
213
0
{
214
0
    setSave(standardOutput(), only_if_not_set);
215
0
}
216
217
void
218
QPDFLogger::setOutputStreams(std::ostream* out_stream, std::ostream* err_stream)
219
0
{
220
0
    if (out_stream == &std::cout) {
221
0
        out_stream = nullptr;
222
0
    }
223
0
    if (err_stream == &std::cerr) {
224
0
        err_stream = nullptr;
225
0
    }
226
0
    std::shared_ptr<Pipeline> new_out;
227
0
    std::shared_ptr<Pipeline> new_err;
228
229
0
    if (out_stream == nullptr) {
230
0
        if (m->p_save == m->p_stdout) {
231
0
            new_out = m->p_stderr;
232
0
        } else {
233
0
            new_out = m->p_stdout;
234
0
        }
235
0
    } else {
236
0
        new_out = std::make_shared<Pl_OStream>("output", *out_stream);
237
0
    }
238
0
    if (err_stream == nullptr) {
239
0
        new_err = m->p_stderr;
240
0
    } else {
241
0
        new_err = std::make_shared<Pl_OStream>("error output", *err_stream);
242
0
    }
243
0
    m->p_info = new_out;
244
0
    m->p_warn = nullptr;
245
0
    m->p_error = new_err;
246
0
}
247
248
std::shared_ptr<Pipeline>
249
QPDFLogger::throwIfNull(std::shared_ptr<Pipeline> p, bool null_okay)
250
50.9k
{
251
50.9k
    if (!(null_okay || p)) {
252
0
        throw std::logic_error("QPDFLogger: requested a null pipeline without null_okay == true");
253
0
    }
254
50.9k
    return p;
255
50.9k
}