Syndication Library
tools.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "tools.h"
00024 #include "personimpl.h"
00025
00026 #include <kcharsets.h>
00027 #include <kcodecs.h>
00028 #include <kdatetime.h>
00029
00030 #include <QtCore/QByteArray>
00031 #include <QtCore/QDateTime>
00032 #include <QtCore/QRegExp>
00033 #include <QtCore/QString>
00034
00035 #include <kdebug.h>
00036
00037 namespace Syndication {
00038
00039 KMD5 md5Machine;
00040
00041 unsigned int calcHash(const QString& str)
00042 {
00043 return calcHash(str.toUtf8());
00044 }
00045
00046 unsigned int calcHash(const QByteArray& array)
00047 {
00048 if (array.isEmpty())
00049 {
00050 return 0;
00051 }
00052 else
00053 {
00054 const char* s = array.data();
00055 unsigned int hash = 5381;
00056 int c;
00057 while ( ( c = *s++ ) ) hash = ((hash << 5) + hash) + c;
00058 return hash;
00059 }
00060 }
00061
00062 time_t parseISODate(const QString& str)
00063 {
00064 KDateTime kdt = KDateTime::fromString(str, KDateTime::ISODate);
00065 uint ret = kdt.isValid() ? kdt.toTime_t() : 0;
00066 return (time_t)ret;
00067 }
00068
00069 time_t parseRFCDate(const QString& str)
00070 {
00071 KDateTime kdt = KDateTime::fromString(str, KDateTime::RFCDate);
00072 uint ret = kdt.isValid() ? kdt.toTime_t() : 0;
00073 return (time_t)ret;
00074 }
00075
00076 time_t parseDate(const QString& str, DateFormat hint)
00077 {
00078 if (str.isEmpty())
00079 return 0;
00080
00081 if (hint == RFCDate)
00082 {
00083 time_t t = parseRFCDate(str);
00084 return t != 0 ? t : parseISODate(str);
00085 }
00086 else
00087 {
00088 time_t t = parseISODate(str);
00089 return t != 0 ? t : parseRFCDate(str);
00090 }
00091 }
00092
00093 QString dateTimeToString(time_t date)
00094 {
00095 if (date == 0)
00096 return QString();
00097
00098 QDateTime dt;
00099 dt.setTime_t(date);
00100 return dt.toString();
00101 }
00102
00103 QString calcMD5Sum(const QString& str)
00104 {
00105 md5Machine.reset();
00106 md5Machine.update(str.toUtf8());
00107 return QString(md5Machine.hexDigest().data());
00108 }
00109
00110 QString resolveEntities(const QString& str)
00111 {
00112 return KCharsets::resolveEntities(str);
00113 }
00114
00115 QString escapeSpecialCharacters(const QString& strp)
00116 {
00117 QString str(strp);
00118 str.replace("&", "&");
00119 str.replace("\"", """);
00120 str.replace("<", "<");
00121 str.replace(">", ">");
00122 str.replace("\'", "'");
00123 return str.trimmed();
00124 }
00125
00126 QString convertNewlines(const QString& strp)
00127 {
00128 QString str(strp);
00129 str.replace("\n", "<br/>");
00130 return str;
00131 }
00132
00133 QString plainTextToHtml(const QString& plainText)
00134 {
00135 QString str(plainText);
00136 str.replace("&", "&");
00137 str.replace("\"", """);
00138 str.replace("<", "<");
00139
00140 str.replace("\n", "<br/>");
00141 return str.trimmed();
00142 }
00143
00144 QString htmlToPlainText(const QString& html)
00145 {
00146 QString str(html);
00147
00148 str.remove(QRegExp("<[^>]*>"));
00149 str = resolveEntities(str);
00150 return str.trimmed();
00151 }
00152
00153 static QRegExp tagRegExp;
00154 static bool tagRegExpSet = false;
00155
00156 bool stringContainsMarkup(const QString& str)
00157 {
00158
00159 if (str.contains(QRegExp("&[a-zA-Z0-9#]+;")))
00160 return true;
00161
00162 int ltc = str.count('<');
00163 if (ltc == 0 || ltc != str.count('>'))
00164 return false;
00165
00166 if (!tagRegExpSet)
00167 {
00168 tagRegExp = QRegExp("<\\w+.*/?>");
00169 tagRegExpSet = true;
00170 }
00171 return str.contains(tagRegExp);
00172 }
00173
00174 bool isHtml(const QString& str)
00175 {
00176
00177 if (str.contains(QRegExp("&[a-zA-Z0-9#]+;")))
00178 return true;
00179
00180 int ltc = str.count('<');
00181 if (ltc == 0 || ltc != str.count('>'))
00182 return false;
00183
00184 if (!tagRegExpSet)
00185 {
00186 tagRegExp = QRegExp("<\\w+.*/?>");
00187 tagRegExpSet = true;
00188 }
00189 if (str.contains(tagRegExp))
00190 return true;
00191
00192 return false;
00193 }
00194
00195 QString normalize(const QString& str)
00196 {
00197 return isHtml(str) ? str.trimmed() : plainTextToHtml(str);
00198 }
00199
00200 QString normalize(const QString& strp, bool isCDATA, bool containsMarkup)
00201 {
00202 if (containsMarkup)
00203 return strp.trimmed();
00204 else
00205 {
00206 if (isCDATA)
00207 {
00208 QString str = resolveEntities(strp);
00209 str = escapeSpecialCharacters(str);
00210 str = convertNewlines(str);
00211 str = str.trimmed();
00212 return str;
00213 }
00214 else
00215 {
00216 QString str = escapeSpecialCharacters(strp);
00217 str = str.trimmed();
00218 return str;
00219 }
00220 }
00221 }
00222
00223 PersonPtr personFromString(const QString& strp)
00224 {
00225 QString str = strp.trimmed();
00226 if (str.isEmpty())
00227 return PersonPtr(new PersonImpl());
00228
00229 str = resolveEntities(str);
00230 QString name;
00231 QString uri;
00232 QString email;
00233
00234
00235
00236
00237 QRegExp remail("<?([^@\\s<]+@[^>\\s]+)>?");
00238
00239
00240 int pos = remail.indexIn(str);
00241 if (pos != -1)
00242 {
00243 QString all = remail.cap(0);
00244 email = remail.cap(1);
00245 str.remove(all);
00246 }
00247
00248
00249 email.remove("mailto:");
00250 email.remove(QRegExp("[\\(\\)]"));
00251
00252
00253
00254 name = str.simplified();
00255
00256
00257
00258
00259
00260
00261
00262 QRegExp rename("^\\(([^\\)]*)\\)");
00263
00264 if (rename.exactMatch(name))
00265 {
00266 name = rename.cap(1);
00267 }
00268
00269 name = name.isEmpty() ? QString() : name;
00270 email = email.isEmpty() ? QString() : email;
00271 uri = uri.isEmpty() ? QString() : uri;
00272
00273 if (name.isEmpty() && email.isEmpty() && uri.isEmpty())
00274 return PersonPtr(new PersonImpl());
00275
00276 return PersonPtr(new PersonImpl(name, uri, email));
00277 }
00278
00279 ElementType::ElementType(const QString& localnamep,
00280 const QString& nsp) : ns(nsp), localname(localnamep)
00281 {
00282 }
00283
00284 bool ElementType::operator==(const ElementType& other) const
00285 {
00286 return localname == other.localname && ns == other.ns;
00287 }
00288
00289 }
00290
00291