diff --git a/src/micropolisj/XML_Helper.java b/src/micropolisj/XML_Helper.java new file mode 100644 index 0000000..3980d1c --- /dev/null +++ b/src/micropolisj/XML_Helper.java @@ -0,0 +1,137 @@ +package micropolisj; + +import java.io.*; +import javax.xml.stream.*; + +public class XML_Helper +{ + private XML_Helper() {} + + public static void skipToEndElement(XMLStreamReader in) + throws XMLStreamException + { + if (!in.isStartElement()) { + return; + } + + int tagDepth = 1; + while (tagDepth > 0 && in.hasNext()) { + in.next(); + if (in.isStartElement()) { + tagDepth++; + } + else if (in.isEndElement()) { + tagDepth--; + } + } + } + + public static Reader readElementText(XMLStreamReader in) + { + return new ElementTextReader(in); + } + + static class ElementTextReader extends Reader + { + XMLStreamReader xsr; + int tagDepth; + char [] buf; + int buf_start; + int buf_end; + + ElementTextReader(XMLStreamReader xsr) + { + this.xsr = xsr; + this.tagDepth = 1; + } + + private void readMore() + throws XMLStreamException + { + while (tagDepth > 0 && buf_start == buf_end) { + + int nodeType = xsr.next(); + if (nodeType == XMLStreamConstants.START_ELEMENT) { + tagDepth++; + } + else if (nodeType == XMLStreamConstants.END_ELEMENT) { + tagDepth--; + } + else if (nodeType == XMLStreamConstants.CDATA || + nodeType == XMLStreamConstants.CHARACTERS || + nodeType == XMLStreamConstants.ENTITY_REFERENCE || + nodeType == XMLStreamConstants.SPACE) + { + buf = xsr.getTextCharacters(); + buf_start = xsr.getTextStart(); + buf_end = buf_start + xsr.getTextLength(); + } + } + + } + + @Override + public int read(char[] cbuf, int off, int len) + throws IOException + { + if (buf_start == buf_end) { + + try { + readMore(); + } + catch (XMLStreamException e) { + throw new IOException("XML stream error: "+ e, e); + } + + if (tagDepth == 0) { + // reached closing tag + return -1; + } + } + + if (buf_start + len <= buf_end) { + // already have the text loaded + System.arraycopy(buf, buf_start, cbuf, off, len); + buf_start += len; + return len; + } + else { + // not enough text available for entire request, + // so just return what we have until the next + // request + + len = buf_end - buf_start; + assert len > 0; + + System.arraycopy(buf, buf_start, cbuf, off, len); + buf_start += len; + assert buf_start == buf_end; + return len; + } + } + + @Override + public void close() + throws IOException + { + buf_start = 0; + buf_end = 0; + + try { + + while (tagDepth > 0 && xsr.hasNext()) { + xsr.next(); + if (xsr.isStartElement()) { + tagDepth++; + } + else if (xsr.isEndElement()) { + tagDepth--; + } + } + } + catch (XMLStreamException e) { + throw new IOException("XML stream error: "+e, e); + } + } + } +} diff --git a/src/micropolisj/build_tool/MakeTiles.java b/src/micropolisj/build_tool/MakeTiles.java index bcc4c3b..33ae818 100644 --- a/src/micropolisj/build_tool/MakeTiles.java +++ b/src/micropolisj/build_tool/MakeTiles.java @@ -111,8 +111,10 @@ public class MakeTiles for (int i = 0; i < tileNames.length; i++) { out.writeStartElement("tile"); out.writeAttribute("name", tileNames[i]); + out.writeStartElement("image"); out.writeAttribute("offsetY", Integer.toString(i)); out.writeEndElement(); + out.writeEndElement(); } out.writeEndElement(); out.writeEndDocument(); diff --git a/src/micropolisj/gui/TileImages.java b/src/micropolisj/gui/TileImages.java index bc1a028..05a5140 100644 --- a/src/micropolisj/gui/TileImages.java +++ b/src/micropolisj/gui/TileImages.java @@ -18,6 +18,7 @@ import javax.xml.stream.*; import micropolisj.engine.*; import static micropolisj.engine.TileConstants.*; +import static micropolisj.XML_Helper.*; public class TileImages { @@ -60,19 +61,26 @@ public class TileImages throw new IOException("Unrecognized file format"); } - while (in.next() != XMLStreamConstants.END_ELEMENT) { - if (!in.isStartElement()) { - continue; - } + while (in.nextTag() != XMLStreamConstants.END_ELEMENT) { + assert in.isStartElement(); String tagName = in.getLocalName(); if (!tagName.equals("tile")) { - in.next(); + skipToEndElement(in); continue; } String tileName = in.getAttributeValue(null, "name"); - int imageNumber = Integer.parseInt(in.getAttributeValue(null, "offsetY")); + int imageNumber = -1; + + while (in.nextTag() != XMLStreamConstants.END_ELEMENT) { + assert in.isStartElement(); + if (in.getLocalName().equals("image")) { + String tmp = in.getAttributeValue(null, "offsetY"); + imageNumber = tmp != null ? Integer.parseInt(tmp) : 0; + } + skipToEndElement(in); + } assert tileName != null; assert imageNumber >= 0 && imageNumber < images.length; @@ -80,7 +88,7 @@ public class TileImages TileSpec ts = Tiles.load(tileName); tileImageMap[ts.tileNumber] = imageNumber; - in.next(); + assert in.isEndElement() && in.getLocalName().equals("tile"); } in.close();