01: // Copyright (c) 2003 Per M.A. Bothner.
02: // This is free software; for terms and warranty disclaimer see ./COPYING.
03:
04: package gnu.kawa.xml;
05:
06: import gnu.lists.*;
07:
08: /** Used to implement a descendant-or-self:: step in a path expression. */
09:
10: public class DescendantOrSelfAxis extends TreeScanner {
11: public static final DescendantOrSelfAxis anyNode = new DescendantOrSelfAxis(
12: NodeType.anyNodeTest);
13:
14: private DescendantOrSelfAxis(NodePredicate type) {
15: this .type = type;
16: }
17:
18: public static DescendantOrSelfAxis make(NodePredicate type) {
19: if (type == NodeType.anyNodeTest)
20: return anyNode;
21: return new DescendantOrSelfAxis(type);
22: }
23:
24: public void scan(AbstractSequence seq, int ipos,
25: PositionConsumer out) {
26: if (type.isInstancePos(seq, ipos))
27: out.writePosition(seq, ipos);
28: if (!(seq instanceof TreeList)) { // AbstractSequence's nextMatching does not support descend. FIXME.
29: ipos = seq.firstChildPos(ipos);
30: while (ipos != 0) {
31: scan(seq, ipos, out);
32: ipos = seq.nextPos(ipos);
33: }
34: return;
35: }
36: int limit = seq.nextPos(ipos);
37: int child = ipos;
38: for (;;) {
39: child = seq.nextMatching(child, type, limit, true);
40: if (child == 0)
41: break;
42: out.writePosition(seq, child);
43: }
44: }
45: }
|