From 1c3169cf69a08e5920e5f1c3e3e153b4da5a2de3 Mon Sep 17 00:00:00 2001 From: adam Date: Mon, 27 Sep 2004 07:52:27 +0000 Subject: [PATCH] Adam seriously mangles XML.java in the process of adding a pull-based API darcs-hash:20040927075227-5007d-6322087fa922c2a0eb51b1034e406cafed282276.gz --- src/org/ibex/util/XML.java | 79 +++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/src/org/ibex/util/XML.java b/src/org/ibex/util/XML.java index d0775c7..5837b04 100644 --- a/src/org/ibex/util/XML.java +++ b/src/org/ibex/util/XML.java @@ -8,6 +8,7 @@ package org.ibex.util; import java.io.Reader; +import java.io.Writer; import java.io.IOException; import java.io.EOFException; @@ -47,8 +48,8 @@ import java.io.EOFException; * @see XML Specification * @see XML Namespaces */ -public abstract class XML -{ +public abstract class XML { + ///////////////////////////////////////////////////////////////////////////////////////////// // XML Parser ///////////////////////////////////////////////////////////////////////////////////////////// @@ -64,16 +65,16 @@ public abstract class XML private static final char[] single_lt = new char[] { '<' }; private static final char[] single_quot = new char[] { '"' }; - private int line; - private int col; + int line; + int col; - private Reader in; - private char[] buf; - private int off; - private int base; // base+off == distance into the stream - private int len; + Reader in; + char[] buf; + int off; + int base; // base+off == distance into the stream + int len; - private Element current; + Element current = null; // used in readEntity() to process a single character without creating a new array private char[] singlechar = new char[1]; @@ -83,9 +84,8 @@ public abstract class XML public XML(int bSize) { buf = new char[bSize]; - - current = (Element)elements.remove(false); - if (current == null) current = new Element(); + //current = (Element)elements.remove(false); + if (current == null) current = newElement(); } /** Returns the line number at the beginning of the last process call. */ @@ -97,6 +97,8 @@ public abstract class XML /** Returns the global file offset at the beginning of the last process call. */ public int getGlobalOffset() { return base + off; } + Element newElement() { return new Element(); } + /** * Parse given input and call the abstract event functions. * @@ -123,8 +125,39 @@ public abstract class XML } finally { clear(); } // clean up elements } + // Stuff below here is Adam's hack ////////////////////////////////////////////////////////////////////////////// + + boolean done = false; + public static class Pull extends XML { + public Pull(Reader in) { this.in = in; off = len = 0; line = col = 1; clear(); } + StringBuffer sb = new StringBuffer(); + Element pending = null; + boolean emptytag = true; + public int level = 0; + public final void startElement(Element e) throws Exn { emptytag = false; level++; pending = e; } + public final void endElement(Element e) throws Exn, IOException { emptytag=pending!=null; level--; } + public final void whitespace(char[] ch, int start, int length) throws Exn, IOException { } + public final void characters(char[] ch, int start, int length) throws Exn, IOException { + emptytag=false; sb.append(ch,start,length);} + public Object read() throws Exn, IOException { + while(!done) { + if (pending != null) { Element ret = pending; pending = null; ret.level = level-(emptytag?0:1); return ret; } + if (sb.length() > 0) { String ret = sb.toString(); sb.setLength(0); return ret; } + if (!buffer(1)) { + if (done) return null; + throw new Exn("reached eof without closing <"+current.qName+"> element", Exn.WFC, getLine(), getCol()); + } + if (buf[off] == '<') readTag(); else readChars(!done); + } + return null; + } + } + + + // Stuff above here is Adam's hack ////////////////////////////////////////////////////////////////////////////// + /** remove any leftover elements from the linked list and queue them */ - private final void clear() { + final void clear() { for (Element last = current; current.parent != null; ) { current = current.parent; last.clear(); @@ -134,7 +167,7 @@ public abstract class XML } /** reads in a tag. expects buf[off] == '<' */ - private final void readTag() throws IOException, Exn { + final void readTag() throws IOException, Exn { // Start Tag '<' Name (S Attribute)* S? '>' boolean starttag = true; @@ -296,8 +329,7 @@ public abstract class XML // create the in-memory element representation of this beast // if current.qName == null then this is the root element we're dealing with if (current.qName != null) { - Element next = (Element)elements.remove(false); - if (next == null) next = new Element(); + Element next = newElement(); //next.clear(); // TODO: remove as elements now checked as they're added to the queue next.parent = current; current = next; @@ -358,17 +390,18 @@ public abstract class XML // we just closed an element, so remove it from the element 'stack' if (current.getParent() == null) { // we just finished the root element - current.clear(); + done = true; } else { Element last = current; current = current.parent; - last.clear(); + //last.clear(); FIXME elements.append(last); } } } } + /** reads in an attribute of an element. expects Name(buf[off]) */ private final void readAttribute() throws IOException, Exn { int ref = 0; @@ -538,7 +571,7 @@ public abstract class XML } /** reads until the passed string is encountered. */ - private final void readChars(boolean p, String match, boolean entities) throws IOException, Exn { + final void readChars(boolean p, String match, boolean entities) throws IOException, Exn { int ref; char[] end = match.toCharArray(); @@ -593,7 +626,7 @@ public abstract class XML * reads until a < symbol is encountered * @param p If true call the characters(char[],int,int) funciton for the processed characters */ - private final void readChars(boolean p) throws IOException, Exn { + final void readChars(boolean p) throws IOException, Exn { int ref; for (boolean more = true; more;) { @@ -686,7 +719,7 @@ public abstract class XML * @param min Minimum number of characters to read (even if we have to block to do it). * @return return false if min can't be reached. */ - private final boolean buffer(int min) throws IOException { + final boolean buffer(int min) throws IOException { if (len > min) return true; if (buf.length - (off+len) >= min) { @@ -746,7 +779,6 @@ public abstract class XML /** Represents the end of an Element. */ public abstract void endElement(Element e) throws Exn, IOException; - ///////////////////////////////////////////////////////////////////////////////////////////// // Inner Classes for Parser Support ///////////////////////////////////////////////////////////////////////////////////////////// @@ -769,6 +801,7 @@ public abstract class XML protected String localName = null; protected String qName = null; protected String prefix = null; + public int level = 0; protected Hash urimap = new Hash(3,3); -- 1.7.10.4