3 import org.ibex.util.*;
11 public String name = null;
12 public String cdata = null;
13 public int numattrs = 0;
14 public String[] attrs = null;
15 public String uri = null;
16 private int delta = 0;
19 public Node(Node n) { copyFrom(n); }
20 public final void clear() { name = null; cdata = null; numattrs = 0; delta = 0; uri = null; }
21 public final void copyFrom(Node n) {
22 name=n.name; cdata=n.cdata; numattrs=n.numattrs; delta=n.delta; uri=n.uri;
23 if (n.attrs == null) { attrs = null; return; }
24 attrs = new String[n.attrs.length]; System.arraycopy(n.attrs, 0, attrs, 0, attrs.length); }
25 public final String attr(String key) {
26 for(int i=0; i<numattrs; i++) if (key.equals(attrs[i*2])) return attrs[i*2+1]; return null; }
28 public static abstract class Stream {
29 public static final Stream NULL = new Stream() { public boolean _read(Node n) { return false; } };
30 public static interface Functor { public Node.Stream wrap(Node.Stream in); }
31 public static class ConstantFunctor implements Functor {
32 private final Node.Stream stream;
33 public ConstantFunctor(Node.Stream stream) { this.stream = stream; }
34 public Node.Stream wrap(Node.Stream in) { return stream; }
36 public static abstract class Filter extends Stream {
39 public Filter(Stream upstream) { this.upstream = upstream; }
40 public boolean upstreamRead(Node n) { upstream = upstream.simplify(); return upstream.read(n); }
41 public void wrapUpstream(Functor f) { upstream = f.wrap(upstream); }
42 public Filter graft(Functor f, Node n) {
43 upstream = new Graft((upstream instanceof Peekable) ? (Peekable)upstream : new Peekable(upstream), n, f);
48 public Stream simplify() { return this; }
49 protected abstract boolean _read(Node n);
50 public final boolean read(Node n) { n.clear(); if (!_read(n)) { n.clear(); return false; } return true; }
52 public static class Peekable extends Filter {
53 public Peekable(Stream s) { super(s); }
54 private Node pending = null;
55 public boolean peek(Node n) {
56 if (pending == null) {
58 if (!upstreamRead(n2)) return false;
64 public boolean _read(Node n) {
65 if (pending != null) { n.copyFrom(pending); pending = null; return true; }
66 return upstreamRead(n);
70 private static class Graft extends Filter {
71 private Stream inner2;
75 boolean simple = false;
76 private Node pending = new Node();
77 public Graft(final Peekable a, final Node n, final Functor f) {
79 upstream = inner2 = new Stream() {
80 public boolean _read(Node n) {
81 if (!Graft.this.a.peek(n)) return false;
82 if (net + n.delta <= 0) return false;
88 if (__read(pending)) pending.delta = n.delta;
91 public boolean _read(Node n) {
92 if (pending != null) { n.copyFrom(pending); pending = null; return true; }
93 boolean ret = __read(n);
94 if (ret) total += n.delta;
97 public boolean __read(Node n) {
98 if (simple) return a.read(n);
99 if (upstreamRead(n)) return true;
100 while(inner2.read(n));
101 if (!a.read(n)) return false;
102 n.delta += net - total;
108 public static class FromXML extends Node.Stream {
109 private final XML.Pull xml;
110 private XML.Element parent = null;
111 private XML.Element e;
112 private int currentdelta = 0;
113 public FromXML(Reader r) { this.xml = new XML.Pull(r); }
114 protected boolean _read(Node n) { try {
115 Object ret = xml.read();
116 if (ret == null) return false;
117 if (ret instanceof String) {
118 n.cdata = (String)ret;
119 n.delta = xml.level - currentdelta;
120 currentdelta = xml.level;
123 XML.Element e = (XML.Element)ret;
124 n.name = e.getLocalName();
126 n.numattrs = e.getAttrLen();
127 n.delta = e.level - currentdelta;
128 currentdelta = e.level;
129 if (n.attrs == null || n.attrs.length < n.numattrs*2) n.attrs = new String[n.numattrs*4];
130 for(int i=0; i<n.numattrs; i++) { n.attrs[i*2] = e.getAttrKey(i); n.attrs[i*2+1] = e.getAttrVal(i); }
132 } catch (Exception e) { throw new RuntimeException(e); } }
135 public void toXML(Writer writer) throws IOException { Node n = new Node(); if (read(n)) toXML(writer, n); }
136 private Node toXML(Writer w, Node n) throws IOException {
137 final String name = n.name;
138 if (n.cdata != null) {
140 if (!read(n)) n = null;
144 for(int i=0; i < n.numattrs * 2; i+=2) {
148 w.write(n.attrs[i+1]);
151 if (!read(n)) n = null;
152 if (n == null || n.delta <= 0) {
156 while(n != null && n.delta > 0) n = toXML(w, n);
162 if (n != null) n.delta++;