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