File indexing completed on 2023-10-03 03:26:47
0001 /* 0002 This file is part of the syndication library 0003 SPDX-FileCopyrightText: 2006 Frank Osterfeld <osterfeld@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "content.h" 0009 0010 #include <tools.h> 0011 0012 #include <QByteArray> 0013 #include <QDomElement> 0014 #include <QStringList> 0015 0016 namespace Syndication 0017 { 0018 namespace Atom 0019 { 0020 class SYNDICATION_NO_EXPORT Content::ContentPrivate 0021 { 0022 public: 0023 ContentPrivate() 0024 : formatIdentified(false) 0025 { 0026 } 0027 mutable Format format; 0028 mutable bool formatIdentified; 0029 }; 0030 0031 Content::Content() 0032 : ElementWrapper() 0033 , d(new ContentPrivate) 0034 { 0035 } 0036 0037 Content::Content(const QDomElement &element) 0038 : ElementWrapper(element) 0039 , d(new ContentPrivate) 0040 { 0041 } 0042 0043 Content::Content(const Content &other) 0044 : ElementWrapper(other) 0045 , d(other.d) 0046 { 0047 } 0048 0049 Content::~Content() 0050 { 0051 } 0052 0053 Content &Content::operator=(const Content &other) 0054 { 0055 ElementWrapper::operator=(other); 0056 d = other.d; 0057 return *this; 0058 } 0059 0060 QString Content::type() const 0061 { 0062 return attribute(QStringLiteral("type")); 0063 } 0064 0065 QString Content::src() const 0066 { 0067 return completeURI(attribute(QStringLiteral("src"))); 0068 } 0069 0070 QByteArray Content::asByteArray() const 0071 { 0072 if (!isBinary()) { 0073 return QByteArray(); 0074 } 0075 return QByteArray::fromBase64(text().trimmed().toLatin1()); 0076 } 0077 0078 Content::Format Content::mapTypeToFormat(const QString &typep, const QString &src) 0079 { 0080 QString type = typep; 0081 //"If neither the type attribute nor the src attribute is provided, 0082 // Atom Processors MUST behave as though the type attribute were 0083 // present with a value of "text"" 0084 if (type.isNull() && src.isEmpty()) { 0085 type = QStringLiteral("text"); 0086 } 0087 0088 if (type == QLatin1String("html") || type == QLatin1String("text/html")) { 0089 return EscapedHTML; 0090 } 0091 0092 /* clang-format off */ 0093 if (type == QLatin1String("text") 0094 || (type.startsWith(QLatin1String("text/"), Qt::CaseInsensitive) 0095 && !type.startsWith(QLatin1String("text/xml"), Qt::CaseInsensitive))) { /* clang-format on */ 0096 return PlainText; 0097 } 0098 0099 static QStringList xmltypes; 0100 if (xmltypes.isEmpty()) { 0101 xmltypes.reserve(8); 0102 xmltypes.append(QStringLiteral("xhtml")); 0103 xmltypes.append(QStringLiteral("application/xhtml+xml")); 0104 // XML media types as defined in RFC3023: 0105 xmltypes.append(QStringLiteral("text/xml")); 0106 xmltypes.append(QStringLiteral("application/xml")); 0107 xmltypes.append(QStringLiteral("text/xml-external-parsed-entity")); 0108 xmltypes.append(QStringLiteral("application/xml-external-parsed-entity")); 0109 xmltypes.append(QStringLiteral("application/xml-dtd")); 0110 xmltypes.append(QStringLiteral("text/x-dtd")); // from shared-mime-info 0111 } 0112 0113 /* clang-format off */ 0114 if (xmltypes.contains(type) 0115 || type.endsWith(QLatin1String("+xml"), Qt::CaseInsensitive) 0116 || type.endsWith(QLatin1String("/xml"), Qt::CaseInsensitive)) { /* clang-format on */ 0117 return XML; 0118 } 0119 0120 return Binary; 0121 } 0122 0123 Content::Format Content::format() const 0124 { 0125 if (d->formatIdentified == false) { 0126 d->format = mapTypeToFormat(type(), src()); 0127 d->formatIdentified = true; 0128 } 0129 return d->format; 0130 } 0131 0132 bool Content::isBinary() const 0133 { 0134 return format() == Binary; 0135 } 0136 0137 bool Content::isContained() const 0138 { 0139 return src().isEmpty(); 0140 } 0141 0142 bool Content::isPlainText() const 0143 { 0144 return format() == PlainText; 0145 } 0146 0147 bool Content::isEscapedHTML() const 0148 { 0149 return format() == EscapedHTML; 0150 } 0151 0152 bool Content::isXML() const 0153 { 0154 return format() == XML; 0155 } 0156 0157 QString Content::asString() const 0158 { 0159 Format f = format(); 0160 0161 if (f == PlainText) { 0162 return plainTextToHtml(text()).trimmed(); 0163 } else if (f == EscapedHTML) { 0164 return text().trimmed(); 0165 } else if (f == XML) { 0166 return childNodesAsXML().trimmed(); 0167 } 0168 0169 return QString(); 0170 } 0171 0172 QString Content::debugInfo() const 0173 { 0174 QString info = QLatin1String("### Content: ###################\n"); 0175 info += QLatin1String("type: #") + type() + QLatin1String("#\n"); 0176 if (!src().isNull()) { 0177 info += QLatin1String("src: #") + src() + QLatin1String("#\n"); 0178 } 0179 if (!isBinary()) { 0180 info += QLatin1String("content: #") + asString() + QLatin1String("#\n"); 0181 } else { 0182 info += QLatin1String("binary length: #") + QString::number(asByteArray().size()) + QLatin1String("#\n"); 0183 } 0184 info += QLatin1String("### Content end ################\n"); 0185 0186 return info; 0187 } 0188 0189 } // namespace Atom 0190 } // namespace Syndication