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.mapping.*;
07: import gnu.lists.*;
08:
09: /** Get the union of two node lists.
10: * Implements the XQuery 'intersect' and 'except' operators.
11: */
12:
13: public class IntersectNodes extends Procedure2 {
14: /** True if implementing 'except'; false if implementing 'intersect'. */
15: boolean isExcept;
16:
17: public static final IntersectNodes intersectNodes = new IntersectNodes(
18: false);
19: public static final IntersectNodes exceptNodes = new IntersectNodes(
20: true);
21:
22: public IntersectNodes(boolean isExcept) {
23: this .isExcept = isExcept;
24: }
25:
26: public Object apply2(Object vals1, Object vals2) {
27: SortedNodes nodes1 = new SortedNodes();
28: SortedNodes nodes2 = new SortedNodes();
29: SortedNodes result = new SortedNodes();
30: //throw new Error("unimplemented");
31: Values.writeValues(vals1, nodes1);
32: Values.writeValues(vals2, nodes2);
33: int i2 = 0;
34:
35: AbstractSequence seq2 = null;
36: int ipos2 = 0;
37:
38: // Result of AbstractSequence.compare(prev_seq1, prev_ipos1, seq2, ipos2),
39: // where (prev_seq1, prev_ipos1) is the nodes from the "previous" iteration
40: int cmp = 0;
41:
42: for (int i1 = 0;; i1++) {
43: AbstractSequence seq1 = nodes1.getSeq(i1);
44: if (seq1 == null)
45: break;
46: int ipos1 = nodes1.getPos(i1);
47:
48: // cmp == -2: Reached end of nodes2 (i2 >= nodes2.size()).
49: // cmp == -1: Previous node1 before node2, so need to re-compare.
50: // cmp == 0: Previous node1==node2, so need to read from nodes2.
51: // [Not possible: cmp == 1].
52:
53: if (cmp == -1)
54: cmp = AbstractSequence
55: .compare(seq1, ipos1, seq2, ipos2);
56: else if (cmp == 0)
57: cmp = 1;
58:
59: while (cmp > 0) {
60: seq2 = nodes2.getSeq(i2);
61: if (seq2 == null) {
62: cmp = -2;
63: break;
64: } else {
65: ipos2 = nodes2.getPos(i2++);
66: cmp = AbstractSequence.compare(seq1, ipos1, seq2,
67: ipos2);
68: }
69: }
70:
71: if ((cmp == 0) != isExcept)
72: result.writePosition(seq1, ipos1);
73: }
74:
75: return result;
76: }
77: }
|