blob: 2cdd6d00d61e3f1f564be09b58040a90113e788e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
/*
* This file is part of smolbote. It's copyrighted by the contributors recorded
* in the version control history of the file, available from its original
* location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
*
* SPDX-License-Identifier: GPL-3.0
*/
#include "filtertree.h"
#include "filterleaf.h"
#include "formats/hostlistrule.h"
#include <QTextStream>
bool loadHostlist(QIODevice &from, FilterTree *tree)
{
Q_ASSERT(from.isReadable());
QTextStream stream(&from);
while(!stream.atEnd()) {
const QString line = stream.readLine().trimmed();
if(line.isEmpty() || line.startsWith(QLatin1Literal("#")))
continue;
const QStringList &parts = line.split(QLatin1Literal(" "));
if(parts.length() < 2) {
#ifdef QT_DEBUG
qDebug("Cannot parse: %s", qUtf8Printable(line));
#endif
return false;
}
for(int i = 1; i < parts.length(); ++i) {
// HostlistRule(domain, redirect)
auto *rule = new HostlistRule(parts.at(i), parts.constFirst());
// addRule(rule, enable_on_domain)
const bool added = tree->addRule(rule, QString());
if(!added)
return false;
}
}
return true;
}
FilterTree::~FilterTree()
{
for(auto &branch : m_branches) {
qDeleteAll(branch.leaves);
branch.leaves.clear();
}
}
const QStringList FilterTree::branches() const
{
QStringList branches;
for(auto &branch : m_branches) {
branches.append(branch.domain.host());
}
return branches;
}
QVector<const FilterLeaf *> FilterTree::match(const QUrl &domain, const QUrl &requestUrl) const
{
QVector<const FilterLeaf *> leaves;
for(const auto &branch : m_branches) {
if(branch.domain.matches(domain)) {
for(const auto leaf : branch.leaves) {
if(leaf->match(requestUrl)) {
leaves.append(leaf);
}
}
}
}
return leaves;
}
bool FilterTree::addRule(FilterLeaf *rule, const QString &domain)
{
branchLock.lock();
this->branch(domain).leaves.emplace_back(rule);
branchLock.unlock();
return true;
}
FilterTree::Branch & FilterTree::branch(const QString& domain)
{
for(auto &branch : m_branches) {
if(branch.domain.matches(QUrl(domain)))
return branch;
}
// no branch was found
Branch branch(domain);
return m_branches.emplace_back(std::move(branch));
}
|