01: // Copyright (c) 2001 Per M.A. Bothner and Brainfood Inc.
02: // This is free software; for terms and warranty disclaimer see ./COPYING.
03:
04: package gnu.kawa.xml;
05:
06: import gnu.mapping.*;
07: import gnu.lists.*;
08:
09: public class Children extends MethodProc {
10: public static final Children children = new Children();
11:
12: public int numArgs() {
13: return 0x1001;
14: }
15:
16: public static void children(TreeList tlist, int index,
17: Consumer consumer) {
18: int child = tlist.gotoChildrenStart(index);
19: if (child < 0)
20: return;
21: int limit = tlist.nextDataIndex(index);
22: for (;;) {
23: int ipos = child << 1;
24: // If the current child is a char or primitive, skip to next real node.
25: int next = tlist.nextNodeIndex(child, limit);
26: // The child node wasn't primtive, so call nextDataIndex instead.
27: int next0 = next;
28: if (next == child)
29: next = tlist.nextDataIndex(child);
30: if (next < 0)
31: break;
32: if (consumer instanceof PositionConsumer)
33: ((PositionConsumer) consumer)
34: .writePosition(tlist, ipos);
35: else
36: tlist.consumeIRange(child, next, consumer);
37: child = next;
38: }
39: }
40:
41: public static void children(Object node, Consumer consumer) {
42: if (node instanceof TreeList) {
43: children((TreeList) node, 0, consumer);
44: } else if (node instanceof SeqPosition
45: && !(node instanceof TreePosition)) {
46: SeqPosition pos = (SeqPosition) node;
47: if (pos.sequence instanceof TreeList)
48: children((TreeList) pos.sequence, pos.ipos >> 1,
49: consumer);
50: }
51: }
52:
53: public void apply(CallContext ctx) {
54: Consumer consumer = ctx.consumer;
55: Object node = ctx.getNextArg();
56: ctx.lastArg();
57: if (node instanceof Values) {
58: TreeList tlist = (TreeList) node;
59: int index = 0;
60: for (;;) {
61: int kind = tlist.getNextKind(index << 1);
62: if (kind == Sequence.EOF_VALUE)
63: break;
64: if (kind == Sequence.OBJECT_VALUE)
65: children(tlist.getPosNext(index << 1), consumer);
66: else
67: children(tlist, index, consumer);
68: index = tlist.nextDataIndex(index);
69: }
70: } else
71: children(node, consumer);
72: }
73: }
|