KHTML
khtml_filter.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "khtml_filter_p.h"
00024 #include <QDebug>
00025
00026
00027 #define HASH_P (2003)
00028 #define HASH_Q (8191)
00029
00030 #define HASH_MOD (6843)
00031
00032 namespace khtml {
00033
00034 void FilterSet::addFilter(const QString& filterStr)
00035 {
00036 QString filter = filterStr;
00037
00038 if (filter.startsWith(QLatin1Char('!')))
00039 return;
00040
00041
00042 int first = 0;
00043 int last = filter.length() - 1;
00044 if (filter.startsWith(QLatin1String("@@")))
00045 first = 2;
00046
00047
00048 int dollar = filter.lastIndexOf(QLatin1Char('$'));
00049 if (dollar != -1)
00050 last = dollar - 1;
00051
00052
00053 if (first > last)
00054 return;
00055
00056 filter = filter.mid(first, last - first + 1);
00057
00058
00059 if (filter.length()>2 && filter.startsWith(QLatin1Char('/')) && filter.endsWith(QLatin1Char('/')))
00060 {
00061 QString inside = filter.mid(1, filter.length()-2);
00062 QRegExp rx(inside);
00063 reFilters.append(rx);
00064
00065 }
00066 else
00067 {
00068
00069
00070
00071
00072 first = 0;
00073 last = filter.length() - 1;
00074
00075 while (first < filter.length() && filter[first] == QLatin1Char('*'))
00076 ++first;
00077
00078 while (last >= 0 && filter[last] == QLatin1Char('*'))
00079 --last;
00080
00081 if (first > last)
00082 filter = QLatin1String("*");
00083 else
00084 filter = filter.mid(first, last - first + 1);
00085
00086
00087 if (filter.contains("*") || filter.contains("?"))
00088 {
00089
00090 QRegExp rx;
00091
00092 rx.setPatternSyntax(QRegExp::Wildcard);
00093 rx.setPattern(filter);
00094 reFilters.append(rx);
00095 }
00096 else
00097 {
00098
00099 stringFiltersMatcher.addString(filter);
00100 }
00101 }
00102 }
00103
00104 bool FilterSet::isUrlMatched(const QString& url)
00105 {
00106 if (stringFiltersMatcher.isMatched(url))
00107 return true;
00108
00109 for (int c = 0; c < reFilters.size(); ++c)
00110 {
00111 if (url.contains(reFilters[c]))
00112 return true;
00113 }
00114
00115 return false;
00116 }
00117
00118 void FilterSet::clear()
00119 {
00120 reFilters.clear();
00121 stringFiltersMatcher.clear();
00122 }
00123
00124
00125 void StringsMatcher::addString(const QString& pattern)
00126 {
00127 if (pattern.length() < 8) {
00128
00129 shortStringFilters.append(pattern);
00130 } else {
00131
00132
00133 stringFilters.append(pattern);
00134 int ind = stringFilters.size() - 1;
00135 int current = 0;
00136
00137
00138
00139
00140
00141 for (int k = 0; k < 8; ++k)
00142 current = (current * HASH_P + pattern[k].unicode()) & HASH_Q;
00143
00144
00145 WTF::HashMap<int, QVector<int> >::iterator it = stringFiltersHash.find(current + 1);
00146 if (it == stringFiltersHash.end()) {
00147 QVector<int> list;
00148 list.append(ind);
00149 stringFiltersHash.add(current + 1, list);
00150 } else {
00151 it->second.append(ind);
00152 }
00153 }
00154 }
00155
00156 bool StringsMatcher::isMatched(const QString& str) const
00157 {
00158
00159 for (int i = 0; i < shortStringFilters.size(); ++i) {
00160 if (str.contains(shortStringFilters[i]))
00161 return true;
00162 }
00163
00164 int len = str.length();
00165 int k;
00166
00167 int current = 0;
00168
00169 for (k = 0; k < 8 && k < len; ++k)
00170 current = (current * HASH_P + str[k].unicode()) & HASH_Q;
00171
00172 WTF::HashMap<int, QVector<int> >::const_iterator hashEnd = stringFiltersHash.end();
00173
00174 for (k = 7; k < len; ++k) {
00175
00176 WTF::HashMap<int, QVector<int> >::const_iterator it = stringFiltersHash.find(current + 1);
00177
00178
00179 if (it != hashEnd) {
00180 for (int j = 0; j < it->second.size(); ++j) {
00181 int index = it->second[j];
00182 int flen = stringFilters[index].length();
00183 if (k - 8 + flen < len && stringFilters[index] == str.midRef(k - 7, flen))
00184 return true;
00185 }
00186 }
00187
00188
00189 if (k + 1 < len)
00190 current = (HASH_P * ((current + HASH_Q + 1 - ((HASH_MOD * str[k - 7].unicode()) & HASH_Q)) & HASH_Q) + str[k + 1].unicode()) & HASH_Q;
00191 }
00192
00193 return false;
00194 }
00195
00196 }
00197
00198