syndication/atom
content.cpp
00001 /* 00002 * This file is part of the syndication library 00003 * 00004 * Copyright (C) 2006 Frank Osterfeld <osterfeld@kde.org> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Library General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Library General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Library General Public License 00017 * along with this library; see the file COPYING.LIB. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 * 00021 */ 00022 00023 #include "content.h" 00024 00025 #include <tools.h> 00026 00027 #include <QtCore/QByteArray> 00028 #include <QtXml/QDomElement> 00029 #include <QtCore/QString> 00030 #include <QtCore/QStringList> 00031 00032 namespace Syndication { 00033 namespace Atom { 00034 00035 class Content::ContentPrivate 00036 { 00037 public: 00038 00039 ContentPrivate() : formatIdentified(false) 00040 { 00041 } 00042 mutable Format format; 00043 mutable bool formatIdentified; 00044 }; 00045 00046 Content::Content() : ElementWrapper(), d(new ContentPrivate) 00047 { 00048 } 00049 00050 Content::Content(const QDomElement& element) : ElementWrapper(element), d(new ContentPrivate) 00051 { 00052 } 00053 00054 Content::Content(const Content& other) : ElementWrapper(other), d(other.d) 00055 { 00056 } 00057 00058 Content::~Content() 00059 { 00060 } 00061 00062 Content& Content::operator=(const Content& other) 00063 { 00064 ElementWrapper::operator=(other); 00065 d = other.d; 00066 return *this; 00067 } 00068 00069 QString Content::type() const 00070 { 00071 return attribute(QLatin1String("type")); 00072 } 00073 00074 QString Content::src() const 00075 { 00076 return completeURI(attribute(QLatin1String("src"))); 00077 } 00078 00079 QByteArray Content::asByteArray() const 00080 { 00081 if (!isBinary()) 00082 return QByteArray(); 00083 return QByteArray::fromBase64(text().trimmed().toAscii()); 00084 } 00085 00086 //@cond PRIVATE 00087 static QStringList xmltypes; 00088 //@endcond 00089 00090 Content::Format Content::mapTypeToFormat(const QString& typep, const QString& src) 00091 { 00092 QString type = typep; 00093 //"If neither the type attribute nor the src attribute is provided, 00094 //Atom Processors MUST behave as though the type attribute were 00095 //present with a value of "text"" 00096 if (type.isNull() && src.isEmpty()) 00097 type = QLatin1String("text"); 00098 00099 if (type == QLatin1String("html") 00100 || type == QLatin1String("text/html")) 00101 return EscapedHTML; 00102 00103 if (type == QLatin1String("text") 00104 || (type.startsWith(QLatin1String("text/"), Qt::CaseInsensitive) 00105 && !type.startsWith(QLatin1String("text/xml"), Qt::CaseInsensitive)) 00106 ) 00107 return PlainText; 00108 00109 if (xmltypes.isEmpty()) 00110 { 00111 xmltypes.append(QLatin1String("xhtml")); 00112 xmltypes.append(QLatin1String("application/xhtml+xml")); 00113 // XML media types as defined in RFC3023: 00114 xmltypes.append(QLatin1String("text/xml")); 00115 xmltypes.append(QLatin1String("application/xml")); 00116 xmltypes.append(QLatin1String("text/xml-external-parsed-entity")); 00117 xmltypes.append(QLatin1String("application/xml-external-parsed-entity")); 00118 xmltypes.append(QLatin1String("application/xml-dtd")); 00119 xmltypes.append(QLatin1String("text/x-dtd")); // from shared-mime-info 00120 } 00121 00122 if (xmltypes.contains(type) 00123 || type.endsWith(QLatin1String("+xml"), Qt::CaseInsensitive) 00124 || type.endsWith(QLatin1String("/xml"), Qt::CaseInsensitive)) 00125 return XML; 00126 00127 return Binary; 00128 } 00129 00130 Content::Format Content::format() const 00131 { 00132 if (d->formatIdentified == false) 00133 { 00134 d->format = mapTypeToFormat(type(), src()); 00135 d->formatIdentified = true; 00136 } 00137 return d->format; 00138 } 00139 00140 bool Content::isBinary() const 00141 { 00142 return format() == Binary; 00143 } 00144 00145 bool Content::isContained() const 00146 { 00147 return src().isEmpty(); 00148 } 00149 00150 bool Content::isPlainText() const 00151 { 00152 return format() == PlainText; 00153 } 00154 00155 bool Content::isEscapedHTML() const 00156 { 00157 return format() == EscapedHTML; 00158 } 00159 00160 bool Content::isXML() const 00161 { 00162 return format() == XML; 00163 } 00164 00165 QString Content::asString() const 00166 { 00167 Format f = format(); 00168 00169 if (f == PlainText) 00170 { 00171 return plainTextToHtml(text()).trimmed(); 00172 } 00173 else if (f == EscapedHTML) 00174 { 00175 return text().trimmed(); 00176 } 00177 else if (f == XML) 00178 { 00179 return childNodesAsXML().trimmed(); 00180 } 00181 00182 return QString(); 00183 } 00184 00185 QString Content::debugInfo() const 00186 { 00187 QString info; 00188 info += QLatin1String("### Content: ###################\n"); 00189 info += QLatin1String("type: #") + type() + QLatin1String("#\n"); 00190 if (!src().isNull()) 00191 info += QLatin1String("src: #") + src() + QLatin1String("#\n"); 00192 if (!isBinary()) 00193 info += QLatin1String("content: #") + asString() + QLatin1String("#\n"); 00194 else 00195 { 00196 info += QLatin1String("binary length: #") + QString::number(asByteArray().size()) + QLatin1String("#\n"); 00197 } 00198 info += QLatin1String("### Content end ################\n"); 00199 00200 return info; 00201 } 00202 00203 } // namespace Atom 00204 } //namespace Syndication