package org.ibex.util;
import java.io.Reader;
-import java.io.Writer;
import java.io.IOException;
import java.io.EOFException;
* @see <a href="http://w3.org/TR/REC-xml">XML Specification</a>
* @see <a href="http://w3.org/TR/REC-xml-names">XML Namespaces</a>
*/
-public abstract class XML {
-
+public abstract class XML
+{
/////////////////////////////////////////////////////////////////////////////////////////////
// XML Parser
/////////////////////////////////////////////////////////////////////////////////////////////
private static final char[] single_lt = new char[] { '<' };
private static final char[] single_quot = new char[] { '"' };
- int line;
- int col;
+ private int line;
+ private int col;
- Reader in;
- char[] buf;
- int off;
- int base; // base+off == distance into the stream
- int len;
+ private Reader in;
+ private char[] buf;
+ private int off;
+ private int base; // base+off == distance into the stream
+ private int len;
- Element current = null;
+ private Element current;
// used in readEntity() to process a single character without creating a new array
private char[] singlechar = new char[1];
public XML(int bSize) {
buf = new char[bSize];
- //current = (Element)elements.remove(false);
- if (current == null) current = newElement();
+
+ current = (Element)elements.remove(false);
+ if (current == null) current = new Element();
}
/** Returns the line number at the beginning of the last process call. */
/** 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.
*
} 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 */
- final void clear() {
+ private final void clear() {
for (Element last = current; current.parent != null; ) {
current = current.parent;
last.clear();
}
/** reads in a tag. expects <tt>buf[off] == '<'</tt> */
- final void readTag() throws IOException, Exn {
+ private final void readTag() throws IOException, Exn {
// Start Tag '<' Name (S Attribute)* S? '>'
boolean starttag = true;
// 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 = newElement();
+ Element next = (Element)elements.remove(false);
+ if (next == null) next = new Element();
//next.clear(); // TODO: remove as elements now checked as they're added to the queue
next.parent = current;
current = next;
// we just closed an element, so remove it from the element 'stack'
if (current.getParent() == null) {
// we just finished the root element
- done = true;
+ current.clear();
} else {
Element last = current;
current = current.parent;
- //last.clear(); FIXME
+ last.clear();
elements.append(last);
}
}
}
}
-
/** reads in an attribute of an element. expects Name(buf[off]) */
private final void readAttribute() throws IOException, Exn {
int ref = 0;
}
/** reads until the passed string is encountered. */
- final void readChars(boolean p, String match, boolean entities) throws IOException, Exn {
+ private final void readChars(boolean p, String match, boolean entities) throws IOException, Exn {
int ref;
char[] end = match.toCharArray();
* reads until a <tt><</tt> symbol is encountered
* @param p If true call the characters(char[],int,int) funciton for the processed characters
*/
- final void readChars(boolean p) throws IOException, Exn {
+ private final void readChars(boolean p) throws IOException, Exn {
int ref;
for (boolean more = true; more;) {
* @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.
*/
- final boolean buffer(int min) throws IOException {
+ private final boolean buffer(int min) throws IOException {
if (len > min) return true;
if (buf.length - (off+len) >= min) {
/** Represents the end of an Element. */
public abstract void endElement(Element e) throws Exn, IOException;
+
/////////////////////////////////////////////////////////////////////////////////////////////
// Inner Classes for Parser Support
/////////////////////////////////////////////////////////////////////////////////////////////
protected String localName = null;
protected String qName = null;
protected String prefix = null;
- public int level = 0;
protected Hash urimap = new Hash(3,3);