1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache Public Source License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
7 import org.ibex.util.*;
15 public String name = null;
16 public String cdata = null;
17 public int numattrs = 0;
18 public String[] attrs = null;
19 public String uri = null;
20 private int delta = 0;
23 public Node(Node n) { copyFrom(n); }
24 public final void clear() { name = null; cdata = null; numattrs = 0; delta = 0; uri = null; }
25 public final void copyFrom(Node n) {
26 name=n.name; cdata=n.cdata; numattrs=n.numattrs; delta=n.delta; uri=n.uri;
27 if (n.attrs == null) { attrs = null; return; }
28 attrs = new String[n.attrs.length]; System.arraycopy(n.attrs, 0, attrs, 0, attrs.length); }
29 public final String attr(String key) {
30 for(int i=0; i<numattrs; i++) if (key.equals(attrs[i*2])) return attrs[i*2+1]; return null; }
32 public static abstract class Stream {
33 public static final Stream NULL = new Stream() { public boolean _read(Node n) { return false; } };
34 public static interface Functor { public Node.Stream wrap(Node.Stream in); }
35 public static class ConstantFunctor implements Functor {
36 private final Node.Stream stream;
37 public ConstantFunctor(Node.Stream stream) { this.stream = stream; }
38 public Node.Stream wrap(Node.Stream in) { return stream; }
40 public static abstract class Filter extends Stream {
43 public Filter(Stream upstream) { this.upstream = upstream; }
44 public boolean upstreamRead(Node n) { upstream = upstream.simplify(); return upstream.read(n); }
45 public void wrapUpstream(Functor f) { upstream = f.wrap(upstream); }
46 public Filter graft(Functor f, Node n) {
47 upstream = new Graft((upstream instanceof Peekable) ? (Peekable)upstream : new Peekable(upstream), n, f);
52 public Stream simplify() { return this; }
53 protected abstract boolean _read(Node n);
54 public final boolean read(Node n) { n.clear(); if (!_read(n)) { n.clear(); return false; } return true; }
56 public static class Peekable extends Filter {
57 public Peekable(Stream s) { super(s); }
58 private Node pending = null;
59 public boolean peek(Node n) {
60 if (pending == null) {
62 if (!upstreamRead(n2)) return false;
68 public boolean _read(Node n) {
69 if (pending != null) { n.copyFrom(pending); pending = null; return true; }
70 return upstreamRead(n);
74 private static class Graft extends Filter {
75 private Stream inner2;
79 boolean simple = false;
80 private Node pending = new Node();
81 public Graft(final Peekable a, final Node n, final Functor f) {
83 upstream = inner2 = new Stream() {
84 public boolean _read(Node n) {
85 if (!Graft.this.a.peek(n)) return false;
86 if (net + n.delta <= 0) return false;
92 if (__read(pending)) pending.delta = n.delta;
95 public boolean _read(Node n) {
96 if (pending != null) { n.copyFrom(pending); pending = null; return true; }
97 boolean ret = __read(n);
98 if (ret) total += n.delta;
101 public boolean __read(Node n) {
102 if (simple) return a.read(n);
103 if (upstreamRead(n)) return true;
104 while(inner2.read(n));
105 if (!a.read(n)) return false;
106 n.delta += net - total;
112 public static class FromXML extends Node.Stream {
113 private final XML.Stream xml;
114 private XML.Elem parent = null;
116 private int currentdelta = 0;
117 public FromXML(Reader r) { this.xml = new XML.Stream(r); }
118 protected boolean _read(Node n) { try {
119 Object ret = xml.next();
120 if (ret == null) return false;
121 if (ret instanceof XML.Text) {
122 n.cdata = ((XML.Text)ret).t;
123 n.delta = xml.getDepth() - currentdelta;
124 currentdelta = xml.getDepth();
127 XML.Elem e = (XML.Elem)ret;
128 n.name = e.getLocalName();
130 n.numattrs = e.getAttributes().attrSize();
131 n.delta = xml.getDepth() - currentdelta;
132 currentdelta = xml.getDepth();
133 if (n.attrs == null || n.attrs.length < n.numattrs*2) n.attrs = new String[n.numattrs*4];
134 for(int i=0; i<n.numattrs; i++) {
135 n.attrs[i*2] = e.getAttributes().getKey(i);
136 n.attrs[i*2+1] = e.getAttributes().getVal(i);
139 } catch (Exception e) { throw new RuntimeException(e); } }
142 public void toXML(Writer writer) throws IOException {
144 do { if (!read(n)) n = null; } while (n!=null && n.cdata != null);
147 private Node toXML(Writer w, Node n) throws IOException {
148 final String name = n.name;
149 if (n.cdata != null) {
151 if (!read(n)) n = null;
155 for(int i=0; i < n.numattrs * 2; i+=2) {
159 w.write(n.attrs[i+1]);
162 if (!read(n)) n = null;
163 if (n == null || n.delta <= 0) {
167 while(n != null && n.delta > 0) { n = toXML(w, n); }
173 if (n != null) n.delta++;