doc: Remove cruft from a doc entry.
[gpgme.git] / lang / qt / src / threadedjobmixin.cpp
1 /*
2     threadedjobmixin.cpp
3
4     This file is part of qgpgme, the Qt API binding for gpgme
5     Copyright (c) 2008 Klarälvdalens Datakonsult AB
6     Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik
7     Software engineering by Intevation GmbH
8
9     QGpgME is free software; you can redistribute it and/or
10     modify it under the terms of the GNU General Public License as
11     published by the Free Software Foundation; either version 2 of the
12     License, or (at your option) any later version.
13
14     QGpgME is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17     General Public License for more details.
18
19     You should have received a copy of the GNU General Public License
20     along with this program; if not, write to the Free Software
21     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
23     In addition, as a special exception, the copyright holders give
24     permission to link the code of this program with any edition of
25     the Qt library by Trolltech AS, Norway (or with modified versions
26     of Qt that use the same license as Qt), and distribute linked
27     combinations including the two.  You must obey the GNU General
28     Public License in all respects for all of the code used other than
29     Qt.  If you modify this file, you may extend this exception to
30     your version of the file, but you are not obligated to do so.  If
31     you do not wish to do so, delete this exception statement from
32     your version.
33 */
34
35 #ifdef HAVE_CONFIG_H
36  #include "config.h"
37 #endif
38
39 #include "threadedjobmixin.h"
40
41 #include "dataprovider.h"
42
43 #include "data.h"
44
45 #include <QString>
46 #include <QStringList>
47 #include <QByteArray>
48
49
50 #include <algorithm>
51 #include <iterator>
52
53 using namespace QGpgME;
54 using namespace GpgME;
55
56 #ifdef Q_OS_WIN
57 #include <windows.h>
58
59 static QString fromEncoding (unsigned int src_encoding, const char *data)
60 {
61     int n = MultiByteToWideChar(src_encoding, 0, data, -1, NULL, 0);
62     if (n < 0) {
63         return QString();
64     }
65
66     wchar_t *result = (wchar_t *) malloc ((n+1) * sizeof *result);
67
68     n = MultiByteToWideChar(src_encoding, 0, data, -1, result, n);
69     if (n < 0) {
70         free(result);
71         return QString();
72     }
73     const auto ret = QString::fromWCharArray(result, n);
74     free(result);
75     return ret;
76 }
77 #endif
78
79 static QString stringFromGpgOutput(const QByteArray &ba)
80 {
81 #ifdef Q_OS_WIN
82     /* Qt on Windows uses GetACP while GnuPG prefers
83      * GetConsoleOutputCP.
84      *
85      * As we are not a console application GetConsoleOutputCP
86      * usually returns 0.
87      * From experience the closest thing that let's us guess
88      * what GetConsoleOutputCP returns for a console application
89      * it appears to be the OEMCP.
90      */
91     unsigned int cpno = GetConsoleOutputCP ();
92     if (!cpno) {
93         cpno = GetOEMCP();
94     }
95     if (!cpno) {
96         cpno = GetACP();
97     }
98     if (!cpno) {
99         return QString();
100     }
101
102     return fromEncoding(cpno, ba.constData());
103 #else
104     return QString::fromLocal8Bit(ba);
105 #endif
106 }
107
108 static QString markupDiagnostics(const QString &data)
109 {
110     // First ensure that we don't have html in the diag.
111     QString ret = QStringLiteral("<pre>%1</pre>").arg(data.toHtmlEscaped());
112
113     return ret;
114 }
115
116 static const unsigned int CMSAuditLogFlags = Context::AuditLogWithHelp | Context::HtmlAuditLog;
117 static const unsigned int OpenPGPAuditLogFlags = Context::DiagnosticAuditLog;
118
119 QString _detail::audit_log_as_html(Context *ctx, GpgME::Error &err)
120 {
121     assert(ctx);
122     QGpgME::QByteArrayDataProvider dp;
123     Data data(&dp);
124     assert(!data.isNull());
125
126     if (ctx->protocol() == OpenPGP) {
127         if ((err = ctx->getAuditLog(data, OpenPGPAuditLogFlags))) {
128             return QString::fromLocal8Bit(err.asString());
129         }
130         const QByteArray ba = dp.data();
131         return markupDiagnostics(stringFromGpgOutput(ba));
132     }
133
134     if (ctx->protocol() == CMS) {
135         if ((err = ctx->lastError())) {
136             if ((err = ctx->getAuditLog(data, Context::DiagnosticAuditLog))) {
137                 return QString::fromLocal8Bit(err.asString());
138             }
139             const QByteArray ba = dp.data();
140             return markupDiagnostics(stringFromGpgOutput(ba));
141         } else if ((err = ctx->getAuditLog(data, CMSAuditLogFlags))) {
142             return QString::fromLocal8Bit(err.asString());
143         }
144         const QByteArray ba = dp.data();
145         return QString::fromUtf8(ba.data(), ba.size());
146     }
147
148     return QStringLiteral("Unsupported protocol for Audit Log");
149 }
150
151 static QList<QByteArray> from_sl(const QStringList &sl)
152 {
153     QList<QByteArray> result;
154     Q_FOREACH (const QString &str, sl) {
155         result.append(str.toUtf8());
156     }
157
158 #if 0
159     std::transform(sl.begin(), sl.end(), std::back_inserter(result),
160                    mem_fn(static_cast<QByteArray()const>(&QString::toUtf8)));
161 #endif
162     return result;
163 }
164
165 static QList<QByteArray> single(const QByteArray &ba)
166 {
167     QList<QByteArray> result;
168     result.push_back(ba);
169     return result;
170 }
171
172 _detail::PatternConverter::PatternConverter(const QByteArray &ba)
173     : m_list(single(ba)), m_patterns(nullptr) {}
174 _detail::PatternConverter::PatternConverter(const QString &s)
175     : m_list(single(s.toUtf8())), m_patterns(nullptr) {}
176 _detail::PatternConverter::PatternConverter(const QList<QByteArray> &lba)
177     : m_list(lba), m_patterns(nullptr) {}
178 _detail::PatternConverter::PatternConverter(const QStringList &sl)
179     :  m_list(from_sl(sl)), m_patterns(nullptr) {}
180
181 const char **_detail::PatternConverter::patterns() const
182 {
183     if (!m_patterns) {
184         m_patterns = new const char *[ m_list.size() + 1 ];
185         const char **end = std::transform(m_list.begin(), m_list.end(), m_patterns,
186                                           std::mem_fn(&QByteArray::constData));
187         *end = nullptr;
188     }
189     return m_patterns;
190 }
191
192 _detail::PatternConverter::~PatternConverter()
193 {
194     delete [] m_patterns;
195 }