13,15 → 13,15 |
System.err.println("Need file name as parameter"); |
return; |
} |
|
|
long startTime = System.nanoTime(); |
|
|
FileInputStream in = new FileInputStream(args[0]); |
|
|
try { |
XmlListenerImpl listener = new XmlListenerImpl(); |
XmlDocument doc = new XmlDocument(listener); |
|
|
doc.parse(in); |
System.out.println(listener.count + " elements found"); |
} |
41,31 → 41,31 |
implements XmlListener |
{ |
public long count = 0; |
|
|
private XmlDocument document; |
|
|
public void init(XmlDocument document) |
throws XmlException, IOException |
{ |
this.document = document; |
} |
|
|
public void processElementBegin(XmlElement element) |
throws XmlException, IOException |
{ |
++count; |
} |
|
|
public void processElementEnd(XmlElement element) |
throws XmlException, IOException |
{ |
} |
|
|
public void processCharData(XmlSelection sel) |
throws XmlException, IOException |
{ |
} |
|
|
public void processCData(XmlSelection sel) |
throws XmlException, IOException |
{ |
80,19 → 80,19 |
|
private long line; |
private long linePos; |
|
|
public XmlException(String message, long line, long linePos) |
{ |
super(message); |
|
|
this.line = line; |
this.linePos = linePos; |
} |
|
|
public long getLine() { return line; } |
|
|
public long getLinePos() { return linePos; } |
|
|
public String toString() |
{ |
return "Error: " + getMessage() + " at " + line + ":" + linePos; |
104,7 → 104,7 |
{ |
public long begin; |
public long end; |
|
|
public long getLength() { return end - begin; } |
} |
|
113,18 → 113,18 |
{ |
public void init(XmlDocument document) |
throws XmlException, IOException; |
|
|
public void processElementBegin(XmlElement element) |
throws XmlException, IOException; |
|
|
public void processElementEnd(XmlElement element) |
throws XmlException, IOException; |
|
|
public void processCharData(XmlSelection sel) |
throws XmlException, IOException; |
|
throws XmlException, IOException; |
|
public void processCData(XmlSelection sel) |
throws XmlException, IOException; |
throws XmlException, IOException; |
} |
|
// -------------------------------------------------------------------------------------------------------------------- |
150,7 → 150,7 |
if(buf.length % 16 != 0) { |
throw new RuntimeException("wrong buffer size: " + buf.length); |
} |
|
|
this.in = in; |
this.len = 0; |
this.pos = 0; |
239,7 → 239,7 |
} |
offset += buf.length / 16 * 15; |
} |
|
|
return (pos + count < len); |
} |
else { |
246,7 → 246,7 |
return true; |
} |
} |
|
|
public String toString(long begin, int length) |
throws IOException |
{ |
265,7 → 265,7 |
{ |
this.listener = listener; |
} |
|
|
public void parse(InputStream in) |
throws XmlException, IOException |
{ |
273,12 → 273,12 |
this.level = 0; |
|
if(listener != null) listener.init(this); |
|
|
if(parseProlog()) { |
parseElement(); |
|
|
while(parseMisc()); |
|
|
if(!buf.isEnd()) throwException("EoF expected"); |
} |
} |
299,17 → 299,17 |
{ |
return buf.toString(sel.begin, (int)sel.getLength()); |
} |
|
|
private void saveSelBegin(XmlSelection sel) |
{ |
sel.begin = buf.getPosition(); |
} |
|
|
private void saveSelEnd(XmlSelection sel) |
{ |
sel.end = buf.getPosition(); |
} |
|
|
private boolean parseProlog() |
throws XmlException, IOException |
{ |
326,7 → 326,7 |
throws XmlException, IOException |
{ |
boolean found = false; |
|
|
for(;;) { |
byte c = buf.cur(); |
if(c == 0) { |
340,7 → 340,7 |
break; |
} |
} |
|
|
return found; |
} |
|
353,7 → 353,7 |
{ |
return false; |
} |
|
|
// attributes |
XmlSelection selName = new XmlSelection(); |
XmlSelection selValue = new XmlSelection(); |
366,7 → 366,7 |
if(!testChar('?') || !testChar('>')) { |
throwException("end of XML declaration expected"); |
} |
|
|
return true; |
} |
|
374,10 → 374,10 |
throws XmlException, IOException |
{ |
// FIXME not implemented |
|
|
return true; |
} |
|
|
private boolean parseName(XmlSelection sel) |
throws XmlException, IOException |
{ |
390,12 → 390,12 |
else { |
return false; |
} |
|
|
for(;;) { |
if(buf.isEnd()) { |
throwException("unexpected EoF"); |
} |
|
|
c = buf.cur(); |
if(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') |
|| c == '.' || c == '-' || c == '_' || c == ':') |
407,7 → 407,7 |
} |
} |
saveSelEnd(sel); |
|
|
return true; |
} |
|
432,7 → 432,7 |
buf.reset(); |
return false; |
} |
|
|
// eq |
skipSpaces(); |
if(!testChar('=')) { |
439,20 → 439,20 |
throwException("equal sign expected"); |
} |
skipSpaces(); |
|
|
// FIXME allow 'Reference' here |
|
|
// value |
if(!testChar('"')) { |
throwException("quoted string expected"); |
} |
|
|
saveSelBegin(selValue); |
for(;; buf.toNext()) { |
if(buf.isEnd()) { |
throwException("unexpected EoF"); |
} |
|
|
byte c = buf.cur(); |
if(c == '<' || c == '&' || c == '"') { |
break; |
459,13 → 459,13 |
} |
} |
saveSelEnd(selValue); |
|
|
if(!testChar('"')) { |
throwException("end of quoted string expected"); |
} |
|
|
// FIXME check '[WFC: No External Entity References]' |
|
|
return true; |
} |
|
492,13 → 492,13 |
if(buf.at(0) != '<' || buf.at(1) != '!' || buf.at(2) != '-' || buf.at(3) != '-') { |
return false; |
} |
|
|
buf.skip(4); |
for(;; buf.toNext()) { |
if(buf.isEnd()) { |
throwException("unexpected EoF"); |
} |
|
|
if(buf.at(0) == '-' && buf.at(1) == '-') { |
if(buf.at(2) == '>') { |
buf.skip(3); |
518,7 → 518,7 |
if(buf.at(0) != '<' || buf.at(1) != '?') { |
return false; |
} |
|
|
buf.skip(2); |
for(;; buf.toNext()) { |
if(buf.isEnd()) { |
527,7 → 527,7 |
|
if(buf.at(0) == '?' && buf.at(1) == '>') { |
buf.skip(2); |
|
|
return true; |
} |
} |
539,31 → 539,31 |
XmlElement element = new XmlElement(); |
element.elementSel = new XmlSelection(); |
saveSelBegin(element.elementSel); |
|
|
if(!parseStartTag(element)) { |
return null; |
} |
|
++level; |
|
|
if(listener != null) listener.processElementBegin(element); |
|
|
if(!element.isEmpty) { |
if(!parseTagContent(element)) { |
throwException("cannot parse tag content"); |
} |
|
|
XmlSelection selEndName = new XmlSelection(); |
parseEndTag(selEndName); |
|
|
//if(!selectionToString(element.nameSel).equals(selectionToString(selEndName))) { |
// throwException("tag names do not match"); |
//} |
} |
|
|
saveSelEnd(element.elementSel); |
if(listener != null) listener.processElementEnd(element); |
|
|
--level; |
|
return element; |
576,16 → 576,16 |
if(!testChar('<')) { |
return false; |
} |
|
|
// name |
buf.mark(); |
element.nameSel = new XmlSelection(); |
if(!parseName(element.nameSel)) { |
buf.reset(); |
|
|
return false; |
} |
|
|
// attributes |
XmlSelection selName = new XmlSelection(); |
XmlSelection selValue = new XmlSelection(); |
593,13 → 593,13 |
if(!skipSpaces()) break; |
if(!parseAttribute(selName, selValue)) break; |
} |
|
|
// end |
element.isEmpty = testChar('/'); |
if(!testChar('>')) { |
throwException("end of tag expected"); |
} |
|
|
return true; |
} |
|
610,15 → 610,15 |
if(!testChar('<') || !testChar('/')) { |
throwException("cannot find tag end"); |
} |
|
|
// name |
if(!parseName(sel)) { |
throwException("tag name expected"); |
} |
|
|
// spaces |
skipSpaces(); |
|
|
// end |
if(!testChar('>')) { |
throwException("end of tag expected"); |
634,7 → 634,7 |
throwException("unexpected EoF"); |
} |
if(buf.at(0) == '<' && buf.at(1) == '/') break; |
|
|
if(parseElement() != null) { |
} |
else if(parseComment()) { |
648,10 → 648,10 |
else { |
throwException("unexpected tag content"); |
} |
|
|
// FIXME allow 'Reference' here |
} |
|
|
return true; |
} |
|
662,23 → 662,23 |
|
boolean found = false; |
saveSelBegin(sel); |
|
|
for(;; buf.toNext()) { |
byte c = buf.cur(); |
if(buf.isEnd()) { |
throwException("unexpected EoF"); |
} |
|
|
if(c == '<' || c == '&') { |
break; |
} |
|
|
found = true; |
} |
|
|
saveSelEnd(sel); |
if(listener != null) listener.processCharData(sel); |
|
|
return found; |
} |
|
685,7 → 685,7 |
private boolean parseCData(XmlSelection sel) |
throws XmlException, IOException |
{ |
if(buf.at(0) != '<' || buf.at(1) != '!' |
if(buf.at(0) != '<' || buf.at(1) != '!' |
|| buf.at(2) != '[' || buf.at(3) != 'C' |
|| buf.at(4) != 'D' || buf.at(5) != 'A' |
|| buf.at(6) != 'T' || buf.at(7) != 'A' |
693,10 → 693,10 |
{ |
return false; |
} |
|
|
buf.skip(9); |
saveSelBegin(sel); |
|
|
for(;; buf.toNext()) { |
if(buf.isEnd()) { |
throwException("unexpected EoF"); |