]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/save/xml/GpxSlicer.java
Version 11, August 2010
[GpsPrune.git] / tim / prune / save / xml / GpxSlicer.java
1 package tim.prune.save.xml;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5
6 /**
7  * Class to slice up a gpx stream and report the found tags
8  * back to a listener.
9  * Used by Gpx caching to re-read and store the gpx source
10  */
11 public class GpxSlicer
12 {
13         /** listener to receive tags */
14         private TagReceiver _receiver = null;
15         /** string builder for copying source xml */
16         private StringBuilder _builder = null;
17
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();
29
30
31         /**
32          * Constructor
33          * @param inReceiver listener for tags
34          */
35         public GpxSlicer(TagReceiver inReceiver)
36         {
37                 _receiver = inReceiver;
38         }
39
40         /**
41          * Begin the slicing and pass the found tags back to the listener
42          * @param inStream input stream for reading gpx source
43          */
44         public void slice(InputStream inStream)
45         {
46                 _builder = new StringBuilder(100);
47                 boolean insideTag = false;
48                 boolean insideCdata = false;
49                 char[] endTag = null;
50                 boolean foundHeader = false;
51                 int b = 0;
52                 try
53                 {
54                         while ((b = inStream.read()) >= 0)
55                         {
56                                 if (!insideTag && !insideCdata) {
57                                         if (b == '<') _builder.setLength(0);
58                                 }
59                                 // copy character
60                                 _builder.append((char)b);
61
62                                 if (insideCdata) {
63                                         // Just look for end of cdata block
64                                         if (foundSequence(CDATA_END)) {insideCdata = false;}
65                                 }
66                                 else
67                                 {
68                                         if (!insideTag)
69                                         {
70                                                 // Look for start of one of the tags
71                                                 if (!foundHeader && foundSequence(GPX_START)) {
72                                                         insideTag = true;
73                                                         foundHeader = true;
74                                                         endTag = GPX_END;
75                                                 }
76                                                 else if (b == 't')
77                                                 {
78                                                         if (foundSequence(TRKPT_START)) {
79                                                                 insideTag = true;
80                                                                 endTag = TRKPT_END;
81                                                         }
82                                                         else if (foundSequence(WPT_START)) {
83                                                                 insideTag = true;
84                                                                 endTag = WPT_END;
85                                                         }
86                                                         else if (foundSequence(RTEPT_START)) {
87                                                                 insideTag = true;
88                                                                 endTag = RTEPT_END;
89                                                         }
90                                                 }
91                                         }
92                                         else
93                                         {
94                                                 // Look for end of found tag
95                                                 if (foundSequence(endTag)) {
96                                                         _receiver.reportTag(_builder.toString());
97                                                         _builder.setLength(0);
98                                                         insideTag = false;
99                                                 }
100                                         }
101                                         // Look for start of cdata block
102                                         if (foundSequence(CDATA_START)) {insideCdata = true;}
103                                 }
104                         }
105                 }
106                 catch (IOException e) {} // ignore
107         }
108
109         /**
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
113          */
114         private boolean foundSequence(char[] inChars)
115         {
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++)
120                 {
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;}
125                 }
126                 return true;
127         }
128 }