1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qplatformdefs.h"
5#include "qurl.h"
6#include "private/qdataurl_p.h"
7
8QT_BEGIN_NAMESPACE
9
10using namespace Qt::Literals;
11
12/*!
13 \internal
14
15 Decode a data: URL into its mimetype and payload. Returns a null string if
16 the URL could not be decoded.
17*/
18Q_CORE_EXPORT bool qDecodeDataUrl(const QUrl &uri, QString &mimeType, QByteArray &payload)
19{
20 if (uri.scheme() != "data"_L1 || !uri.host().isEmpty())
21 return false;
22
23 mimeType = QStringLiteral("text/plain;charset=US-ASCII");
24
25 // the following would have been the correct thing, but
26 // reality often differs from the specification. People have
27 // data: URIs with ? and #
28 //QByteArray data = QByteArray::fromPercentEncoding(uri.path(QUrl::FullyEncoded).toLatin1());
29 const QByteArray dataArray =
30 QByteArray::fromPercentEncoding(pctEncoded: uri.url(options: QUrl::FullyEncoded | QUrl::RemoveScheme).toLatin1());
31 QByteArrayView data = dataArray;
32
33 // parse it:
34 const qsizetype pos = data.indexOf(ch: ',');
35 if (pos != -1) {
36 payload = data.mid(pos: pos + 1).toByteArray();
37 data.truncate(n: pos);
38 data = data.trimmed();
39
40 // find out if the payload is encoded in Base64
41 constexpr auto base64 = ";base64"_L1;
42 if (QLatin1StringView{data}.endsWith(s: base64, cs: Qt::CaseInsensitive)) {
43 payload = QByteArray::fromBase64(base64: payload);
44 data.chop(n: base64.size());
45 }
46
47 QLatin1StringView textPlain;
48 constexpr auto charset = "charset"_L1;
49 if (QLatin1StringView{data}.startsWith(s: charset, cs: Qt::CaseInsensitive)) {
50 qsizetype i = charset.size();
51 while (data.at(n: i) == ' ')
52 ++i;
53 if (data.at(n: i) == '=')
54 textPlain = "text/plain;"_L1;
55 }
56
57 if (!data.isEmpty())
58 mimeType = textPlain + QLatin1StringView(data.trimmed());
59 }
60
61 return true;
62}
63
64QT_END_NAMESPACE
65

source code of qtbase/src/corelib/io/qdataurl.cpp