30,7 → 30,7 |
in.close(); |
} |
|
System.err.println("Elapsed: " + (System.nanoTime() - startTime) / 1000000 + "ms"); |
System.out.println("Elapsed: " + (System.nanoTime() - startTime) / 1000000 + "ms"); |
} |
} |
|
80,15 → 80,20 |
class XmlBuffer |
{ |
private InputStream in; |
private byte[] buf = new byte[2048]; // (buf.length % 2 == 0) |
private int size = buf.length; |
private int half = size/2; |
private long len = -1; |
private long pos = 0; |
private long marked = -1; |
private boolean second = true; // which half of buffer is used |
private boolean end = false; |
|
private byte[] buf = new byte[2*2048]; // (buf.length % 2 == 0) |
private int size = buf.length; |
private int half = size/2; |
private long len = -1; |
private long pos = 0; |
private boolean second = true; // which half of buffer is used |
private boolean end = false; |
private long line = 1; |
private long linePos = 1; |
private long lastPosUsed = pos; |
private long marked = -1; |
private long markedLine = -1; |
private long markedLinePos = -1; |
|
public XmlBuffer(InputStream in) |
throws IOException |
{ |
103,29 → 108,52 |
public byte cur() |
throws IOException |
{ |
/* if(pos >= len) { |
if(!ensure(pos)) return 0; |
} |
|
int p = (int)(pos % size); |
|
if(!second && p >= half || second && p < half) { |
if(!ensure(p)) return 0; |
} |
|
return buf[p]; |
return buf[p];*/ |
return at(0); |
} |
|
public byte at(int n) |
throws IOException |
{ |
if(pos + n >= len) { |
if(!ensure(pos + n)) return 0; |
} |
|
int p = (int)((pos + n) % size); |
|
if(!second && p >= half || second && p < half) { |
if(!ensure(p)) return 0; |
byte c = buf[p]; |
if(lastPosUsed != pos) { |
if(c == '\r') { |
} |
else if(c == '\n') { |
++line; |
linePos = 0; // a small issue: the \n is counted at zero position of next line |
} |
else { |
++linePos; |
} |
lastPosUsed = pos; |
} |
|
//System.out.println("at " + pos + "+" + n + "=" + line + ":" + linePos + " (" + p + ") [" + (char)c + "]"); |
return c; |
|
return buf[p]; |
// return buf[p]; |
} |
|
public void toNext() |
throws IOException |
{ |
if(lastPosUsed != pos) { |
cur(); |
} |
|
++pos; |
} |
|
135,8 → 163,10 |
} |
|
public void skip(int n) |
throws IOException |
{ |
pos += n; |
//pos += n; |
for(int i = 0; i < n; ++i) toNext(); |
} |
|
public long getPosition() |
144,9 → 174,21 |
return pos; |
} |
|
public long getLine() |
{ |
return line; |
} |
|
public long getLinePosition() |
{ |
return linePos; |
} |
|
public void mark() |
{ |
marked = pos; |
marked = pos; |
markedLine = line; |
markedLinePos = linePos; |
} |
|
public void reset() |
155,17 → 197,23 |
throw new RuntimeException("no position saved"); |
} |
else { |
pos = marked; |
marked = -1; |
pos = marked; |
line = markedLine; |
linePos = markedLinePos; |
lastPosUsed = pos; |
marked = -1; |
markedLine = -1; |
markedLinePos = -1; |
} |
} |
|
private boolean ensure(int p) |
private boolean ensure(long p) |
throws IOException |
{ |
if(end) return false; |
|
if(len >= 0 && (!second && p < half || second && p >= half)) { |
if(end) { |
return false; |
} |
else if(len >= 0 && p < len) { |
return true; |
} |
|
185,7 → 233,7 |
} |
|
len += read; |
System.out.println("ensure " + len + " " + second); |
//System.out.println("ensure " + p + " " + len + " " + second); |
|
return true; |
} |
193,25 → 241,32 |
public String toString(long begin, int length) |
throws IOException |
{ |
if(begin < (len/half-1)*half) return ""; |
if(length > half) return ""; |
//System.out.println("toString " + begin + " " + length + " : " + len + " " + half + " " + ((len-1)/half-1)*half); |
if(begin < ((len-1)/half-1)*half) return ""; |
if(begin+length >= len) return ""; |
|
int p1 = (int)(begin % size); |
int p2 = (int)((begin+length) % size); |
//System.out.println(" toString p1 " + p1 + " " + p2); |
|
if(p1 > p2) { |
//System.out.println(" toString p2"); |
if(second) return ""; |
//System.out.println(" toString p3"); |
|
return new String(buf, p1, size, "UTF-8") |
return new String(buf, p1, size-p1, "UTF-8") |
+ new String(buf, 0, p2, "UTF-8"); |
} |
else if(p1 < half && p2 >= half) { |
//System.out.println(" toString p4"); |
if(!second) return ""; |
//System.out.println(" toString p5"); |
|
return new String(buf, p1, half-p1, "UTF-8") |
+ new String(buf, half, p2-half, "UTF-8"); |
} |
else { |
//System.out.println(" toString p6"); |
return new String(buf, p1, p2-p1, "UTF-8"); |
} |
} |
221,15 → 276,11 |
class XmlDocument |
{ |
private XmlBuffer buf; |
private long line; |
private long linePos; |
|
public void parse(InputStream in) |
throws XmlException, IOException |
{ |
this.buf = new XmlBuffer(in); |
this.line = 1; |
this.linePos = 0; |
this.buf = new XmlBuffer(in); |
|
if(parseProlog()) { |
parseElement(); |
244,7 → 295,7 |
private void throwException(String message) |
throws XmlException, IOException |
{ |
throw new XmlException(message, line, /*linePos*/ buf.getPosition()); |
throw new XmlException(message, buf.getLine(), buf.getLinePosition()); |
} |
|
private void log(String message) |
381,10 → 432,13 |
private boolean testChar(char c) |
throws XmlException, IOException |
{ |
//log("testChar begin " + buf.getPosition() + " [" + c + "]"); |
if(buf.cur() != c) { |
//log("testChar false " + buf.getPosition()); |
return false; |
} |
else { |
//log("testChar true " + buf.getPosition()); |
buf.toNext(); |
return true; |
} |
541,6 → 595,10 |
throws XmlException, IOException |
{ |
//log("parseStartTag begin " + buf.getPosition()); |
long pos = buf.getPosition(); |
long line = buf.getLine(); |
long linePos = buf.getLinePosition(); |
|
// begin |
if(!testChar('<')) { |
//log("parseStartTag no signature " + buf.getPosition()); |
554,7 → 612,7 |
buf.reset(); |
return false; |
} |
System.out.print("[" + toString(sel) + "]"); |
//System.out.print("[" + toString(sel) + "]@" + line + ":" + linePos + " (" + pos + ")"); |
|
// attributes |
XmlSelection selName = new XmlSelection(); |
562,9 → 620,9 |
for(;;) { |
if(!skipSpaces()) break; |
if(!parseAttribute(selName, selValue)) break; |
System.out.print(" [" + toString(selName) + "]=[" + toString(selValue) + "]"); |
//System.out.print(" [" + toString(selName) + "]=[" + toString(selValue) + "]"); |
} |
System.out.println(); |
//System.out.println(); |
|
// end |
element.isEmpty = testChar('/'); |