00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #if !defined(NODE_ITERATOR_H)
00034 #define NODE_ITERATOR_H
00035
00036 #include "Node.h"
00037 #include "Edge.h"
00038
00039 namespace Dyninst {
00040
00041
00042 class NodeIteratorImpl {
00043 friend class NodeIterator;
00044
00045 public:
00046 virtual void inc() = 0;
00047 virtual void dec() = 0;
00048 virtual Node::Ptr get() = 0;
00049 virtual bool equals(NodeIteratorImpl *) = 0;
00050 virtual NodeIteratorImpl *copy() = 0;
00051
00052 virtual ~NodeIteratorImpl() {};
00053 };
00054
00055
00056 class NodeIteratorSet : public NodeIteratorImpl {
00057 public:
00058 virtual void inc() { ++internal_; }
00059 virtual void dec() { --internal_; }
00060 virtual Node::Ptr get() { return *internal_; }
00061 virtual bool equals(NodeIteratorImpl *rhs) {
00062 NodeIteratorSet *tmp = dynamic_cast<NodeIteratorSet *>(rhs);
00063 if (tmp == NULL) return false;
00064 return internal_ == tmp->internal_;
00065 }
00066
00067 virtual NodeIteratorImpl *copy() {
00068 return new NodeIteratorSet(internal_);
00069 }
00070
00071 virtual ~NodeIteratorSet() {
00072
00073 }
00074
00075 NodeIteratorSet(const std::set<Node::Ptr>::iterator iter) : internal_(iter) {};
00076
00077 private:
00078 std::set<Node::Ptr>::iterator internal_;
00079 };
00080
00081 class NodeFromEdgeSet : public NodeIteratorImpl {
00082 public:
00083 typedef enum {
00084 target,
00085 source,
00086 unset } iterType;
00087
00088 virtual void inc() { ++internal_; }
00089 virtual void dec() { --internal_; }
00090 virtual Node::Ptr get() {
00091 switch(type_) {
00092 case target:
00093 return (*internal_)->target();
00094 case source:
00095 return (*internal_)->source();
00096 default:
00097 return Node::Ptr();
00098 }
00099 }
00100 virtual bool equals(NodeIteratorImpl *rhs) {
00101 NodeFromEdgeSet *tmp = dynamic_cast<NodeFromEdgeSet *>(rhs);
00102 if (tmp == NULL) return false;
00103
00104 return ((internal_ == tmp->internal_) &&
00105 (type_ == tmp->type_));
00106 }
00107 virtual NodeIteratorImpl *copy () {
00108 NodeIteratorImpl *tmp = new NodeFromEdgeSet(internal_, type_);
00109 return tmp;
00110 }
00111
00112 virtual ~NodeFromEdgeSet() {};
00113
00114 NodeFromEdgeSet(const std::set<Edge::Ptr>::iterator iter,
00115 iterType type) : internal_(iter), type_(type) {};
00116
00117 private:
00118 std::set<Edge::Ptr>::iterator internal_;
00119 iterType type_;
00120 };
00121
00122 class NodeSearchIterator : public NodeIteratorImpl{
00123 friend class NodeIterator;
00124 public:
00125
00126 typedef enum {
00127 depth,
00128 breadth} Type;
00129 typedef enum {
00130 in,
00131 out} Direction;
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 virtual void inc() {
00151
00152 if (!current) return;
00153
00154 Node::Ptr next;
00155
00156
00157 while (next == NULL && (!worklist.empty())) {
00158 next = popWorklist();
00159 }
00160
00161
00162 if (worklist.empty()) {
00163 setToEnd();
00164 return;
00165 }
00166 assert(next != NULL);
00167
00168 current = next;
00169
00170 updateVisited(current);
00171 NodeIterator begin, end;
00172 getNext(begin, end);
00173 updateWorklist(begin, end);
00174 }
00175 virtual void dec() {
00176
00177 assert(0); return;
00178 }
00179 virtual Node::Ptr get() { return current; }
00180
00181
00182
00183 virtual bool equals(NodeIteratorImpl *rhs) {
00184 NodeSearchIterator *tmp = dynamic_cast<NodeSearchIterator *>(rhs);
00185 if (!tmp) return false;
00186
00187 if (end() && tmp->end()) return true;
00188 return ((current == tmp->current) &&
00189 (type == tmp->type) &&
00190 (direction == tmp->direction) &&
00191 (worklist == tmp->worklist) &&
00192 (visited == tmp->visited));
00193 }
00194
00195 virtual NodeIteratorImpl *copy() {
00196 return new NodeSearchIterator(current, direction, type, worklist, visited);
00197 }
00198
00199 NodeSearchIterator() : direction(in), type(depth) {};
00200 NodeSearchIterator(Node::Ptr cur, Direction d, Type t) : current(cur), direction(d), type(t) {
00201 updateVisited(current);
00202 NodeIterator begin, end;
00203 getNext(begin,end);
00204 updateWorklist(begin,end);
00205 };
00206 NodeSearchIterator(Node::Ptr cur, Direction d, Type t, std::deque<Node::Ptr> wl, std::set<Node::Ptr> v) :
00207 current(cur), direction(d), type(t), worklist(wl), visited(v) {};
00208
00209 NodeSearchIterator(NodeIterator &rangeBegin, NodeIterator &rangeEnd, Direction d, Type t) :
00210 direction(d), type(t) {
00211 updateWorklist(rangeBegin, rangeEnd);
00212
00213 if (worklist.empty()) return;
00214 current = popWorklist();
00215 updateVisited(current);
00216 NodeIterator begin, end;
00217 getNext(begin, end);
00218 updateWorklist(begin, end);
00219 }
00220
00221 virtual ~NodeSearchIterator() {};
00222
00223 private:
00224
00225 bool end() {
00226 if (current == NULL) return true;
00227 return false;
00228 }
00229
00230 void updateVisited(Node::Ptr ¤t) {
00231 assert(current);
00232 visited.insert(current);
00233 }
00234
00235
00236
00237
00238 void getNext(NodeIterator &begin, NodeIterator &end) {
00239 assert(current);
00240 switch (direction) {
00241 case in:
00242 current->ins(begin, end);
00243 break;
00244 case out:
00245 current->outs(begin, end);
00246 break;
00247 default:
00248 assert(0);
00249 }
00250 }
00251 void updateWorklist(NodeIterator &begin, NodeIterator &end) {
00252 for (; begin != end; begin++) {
00253 if (visited.find(*begin) == visited.end()) {
00254 switch (type) {
00255 case depth:
00256 worklist.push_front(*begin);
00257 break;
00258 case breadth:
00259 worklist.push_back(*begin);
00260 break;
00261 default:
00262 assert(0);
00263 }
00264 }
00265 }
00266 }
00267
00268 Node::Ptr popWorklist() {
00269 if (worklist.empty()) return Node::Ptr();
00270 Node::Ptr tmp = worklist.front();
00271 worklist.pop_front();
00272 return tmp;
00273 }
00274
00275 void setToEnd() {
00276 current = Node::Ptr();
00277 worklist.clear();
00278 visited.clear();
00279 }
00280
00281 Node::Ptr current;
00282 Direction direction;
00283 Type type;
00284 std::deque<Node::Ptr> worklist;
00285 std::set<Node::Ptr> visited;
00286 };
00287
00288
00289 class NodeIteratorPredicateObj : public NodeIteratorImpl {
00290 public:
00291 virtual void inc() {
00292 if (cur == end) return;
00293 cur = next;
00294 setNext();
00295 }
00296 virtual void dec() { return; }
00297 virtual Node::Ptr get() { return *cur; }
00298 virtual bool equals(NodeIteratorImpl *rhs) {
00299 NodeIteratorPredicateObj *tmp = dynamic_cast<NodeIteratorPredicateObj *>(rhs);
00300 if (tmp == NULL) return false;
00301 return ((pred == tmp->pred) &&
00302 (cur == tmp->cur) &&
00303 (next == tmp->next) &&
00304 (end == tmp->end));
00305 }
00306
00307 virtual NodeIteratorImpl *copy() {
00308 return new NodeIteratorPredicateObj(pred, cur, next, end);
00309 }
00310
00311 virtual ~NodeIteratorPredicateObj() {
00312
00313 }
00314
00315 NodeIteratorPredicateObj(Graph::NodePredicate::Ptr p,
00316 NodeIterator &c,
00317 NodeIterator &n,
00318 NodeIterator &e) :
00319 pred(p),
00320 cur(c), next(n), end(e) {};
00321 NodeIteratorPredicateObj(Graph::NodePredicate::Ptr p,
00322 NodeIterator &b,
00323 NodeIterator &e) :
00324 pred(p), cur(b), next(b), end(e) {
00325 setNext();
00326
00327
00328 if ((cur != end) && !pred->predicate(*cur)) {
00329 inc();
00330 }
00331 }
00332 void setNext() {
00333
00334 if (next == end) return;
00335 do {
00336 ++next;
00337 } while (next != end && !(pred->predicate(*next)));
00338 }
00339
00340 private:
00341 Graph::NodePredicate::Ptr pred;
00342
00343
00344 NodeIterator cur, next, end;
00345 };
00346
00347
00348 class NodeIteratorPredicateFunc : public NodeIteratorImpl {
00349 public:
00350 virtual void inc() {
00351 if (cur == end) return;
00352 cur = next;
00353 setNext();
00354 }
00355 virtual void dec() { return; }
00356 virtual Node::Ptr get() { return *cur; }
00357 virtual bool equals(NodeIteratorImpl *rhs) {
00358 NodeIteratorPredicateFunc *tmp = dynamic_cast<NodeIteratorPredicateFunc *>(rhs);
00359 if (tmp == NULL) return false;
00360 return ((pred == tmp->pred) &&
00361 (user_arg == tmp->user_arg) &&
00362 (cur == tmp->cur) &&
00363 (next == tmp->next) &&
00364 (end == tmp->end));
00365 }
00366
00367 virtual NodeIteratorImpl *copy() {
00368 return new NodeIteratorPredicateFunc(pred, user_arg, cur, next, end);
00369 }
00370
00371 virtual ~NodeIteratorPredicateFunc() {
00372
00373 }
00374
00375 NodeIteratorPredicateFunc(Graph::NodePredicateFunc p,
00376 void *u,
00377 NodeIterator &c,
00378 NodeIterator &n,
00379 NodeIterator &e) :
00380 pred(p),
00381 user_arg(u),
00382 cur(c), next(n), end(e) {};
00383 NodeIteratorPredicateFunc(Graph::NodePredicateFunc p,
00384 void *u,
00385 NodeIterator &b,
00386 NodeIterator &e) :
00387 pred(p), user_arg(u), cur(b), next(b), end(e) {
00388 setNext();
00389
00390
00391 if ((cur != end) && !pred(*cur, user_arg)) {
00392 inc();
00393 }
00394 }
00395 void setNext() {
00396
00397 if (next == end) return;
00398 ++next;
00399 do {
00400 ++next;
00401 } while (next != end && !(pred(*next, user_arg)));
00402 }
00403
00404 private:
00405 Graph::NodePredicateFunc pred;
00406 void *user_arg;
00407
00408
00409 NodeIterator begin, cur, next, end;
00410 };
00411
00412 }
00413
00414 #endif