-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathXPathScanner.cpp
103 lines (93 loc) · 2.96 KB
/
XPathScanner.cpp
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
95
96
97
98
99
100
101
102
103
/*
* xPath.cpp
*
* Created on: Nov 17, 2014
* Author: matthijs
*/
#include "XPathScanner.h"
// XPathScanner constructor. Here the BinaryTree blueprint is created from an
// xpath. Identical NodeScanners are combined for efficiency.
XPathScanner::XPathScanner(const Xpath& x) :
xpath(x), blueprint(new BinaryTree(0, xpath)) {
blueprint->optimize();
//blueprint->printStructure();
addTree(new BinaryTree(*blueprint, 0));
}
// XPathScanner deconstructor
XPathScanner::~XPathScanner() {
for (auto it = cases.begin(); it != cases.end();) {
BinaryTree * tree = *it;
it = cases.erase(it);
delete tree;
}
auto locators = blueprint->getDataSources();
delete blueprint;
emptyTrash();
for (auto it = locators.begin(); it != locators.end();) {
NodeScanner * node = *it;
it = locators.erase(it);
delete node;
}
}
// Called when new data is allocated to a branch. Here the BinaryTree is
// evaluated and results are sent to the containing Factory object.
void XPathScanner::onAllocatedToBranch(Directory * source, Node* ) {
BinaryTree * tree = static_cast<BinaryTree *>(source->getTopParent());
if (activated == 0) activated = tree;
if (tree->iscomplete()) return;
Node * data = tree->test();
if(data) notifyNewMatch(data);
emptyTrash(activated);
}
// Called when new data is sent to a branch that already has allocated data.
// Here the BinaryTree is copied and the new data is allocated to the
// redirecting branch position in the new BinaryTree.
void XPathScanner::onRedirectedFromBranch(Directory * source, Node* node) {
activated = static_cast<BinaryTree *>(source->getTopParent());
if(activated == cases.back()) {
BinaryTree *newTree = new BinaryTree(*activated, 0,
static_cast<BinaryTree *>(source)->getDataSource()->getID(), node);
removeUnusedCases();
addTree(newTree);
onAllocatedToBranch(newTree, node);
}
activated = 0;
}
// Add a BinaryTree to the collection and start listening for branch updates.
void XPathScanner::addTree(BinaryTree *tree) {
notifyNewTree(tree);
tree->addListener(this);
cases.push_back(tree);
}
// Check if any BinaryTrees have drawn an true or false conclusion. add those
// structures to the trashbin
void XPathScanner::removeUnusedCases() {
for(auto it = cases.begin(); it != cases.end(); ) {
BinaryTree * tree = *it;
if(tree->iscomplete()) {
it = cases.erase(it);
addToTrash(tree);
}
else {
++it;
}
}
}
// Delete a BinaryTree from the trashbin. Activated by the emptyTrash function.
void XPathScanner::removeFromTrash(BinaryTree *tree) {
SecureTrashBin::removeFromTrash(tree);
cases.remove(tree);
notifyRemoveTree(tree);
delete tree;
}
// Link the NodeScanner to a data source
void XPathScanner::setAdapter(SaxParserAdapter *p) {
parser = p;
for (NodeScanner * loc : blueprint->getDataSources())
if (!parser->hasListener(loc))
parser->addListener(loc);
}
// Get the number of BinaryTrees under evaluations
size_t XPathScanner::getSize() const {
return cases.size();
}