1 package tim.prune.save.xml;
3 import java.io.IOException;
4 import java.io.InputStream;
7 * Class to slice up a gpx stream and report the found tags
9 * Used by Gpx caching to re-read and store the gpx source
11 public class GpxSlicer
13 /** listener to receive tags */
14 private TagReceiver _receiver = null;
15 /** string builder for copying source xml */
16 private StringBuilder _builder = null;
18 // character sequences for start and end of tags
19 private static final char[] GPX_START = "<gpx".toCharArray();
20 private static final char[] GPX_END = ">".toCharArray();
21 private static final char[] TRKPT_START = "<trkpt".toCharArray();
22 private static final char[] TRKPT_END = "/trkpt>".toCharArray();
23 private static final char[] WPT_START = "<wpt".toCharArray();
24 private static final char[] WPT_END = "/wpt>".toCharArray();
25 private static final char[] RTEPT_START = "<rtept".toCharArray();
26 private static final char[] RTEPT_END = "/rtept>".toCharArray();
27 private static final char[] CDATA_START = "<![CDATA[".toCharArray();
28 private static final char[] CDATA_END = "]]>".toCharArray();
33 * @param inReceiver listener for tags
35 public GpxSlicer(TagReceiver inReceiver)
37 _receiver = inReceiver;
41 * Begin the slicing and pass the found tags back to the listener
42 * @param inStream input stream for reading gpx source
44 public void slice(InputStream inStream)
46 _builder = new StringBuilder(100);
47 boolean insideTag = false;
48 boolean insideCdata = false;
50 boolean foundHeader = false;
54 while ((b = inStream.read()) >= 0)
56 if (!insideTag && !insideCdata) {
57 if (b == '<') _builder.setLength(0);
60 _builder.append((char)b);
63 // Just look for end of cdata block
64 if (foundSequence(CDATA_END)) {insideCdata = false;}
70 // Look for start of one of the tags
71 if (!foundHeader && foundSequence(GPX_START)) {
78 if (foundSequence(TRKPT_START)) {
82 else if (foundSequence(WPT_START)) {
86 else if (foundSequence(RTEPT_START)) {
94 // Look for end of found tag
95 if (foundSequence(endTag)) {
96 _receiver.reportTag(_builder.toString());
97 _builder.setLength(0);
101 // Look for start of cdata block
102 if (foundSequence(CDATA_START)) {insideCdata = true;}
106 catch (IOException e) {} // ignore
110 * Look for the given character sequence in the last characters read
111 * @param inChars sequence to look for
112 * @return true if sequence found
114 private boolean foundSequence(char[] inChars)
116 final int numChars = inChars.length;
117 final int bufflen = _builder.length();
118 if (bufflen < numChars) {return false;}
119 for (int i=0; i<numChars; i++)
121 char searchChar = inChars[numChars - 1 - i];
122 char sourceChar = _builder.charAt(bufflen - 1 - i);
123 if (searchChar != sourceChar) {return false;}
124 //if (Character.toLowerCase(searchChar) != Character.toLowerCase(sourceChar)) {return false;}