]> gitweb.fperrin.net Git - GpsPrune.git/blob - src/tim/prune/save/xml/GpxSlicer.java
Version 19.2, December 2018
[GpsPrune.git] / src / 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
16         // character sequences for start and end of tags
17         private static final char[] GPX_START = "<gpx".toCharArray();
18         private static final char[] GPX_END = ">".toCharArray();
19         private static final char[] TRKPT_START = "<trkpt".toCharArray();
20         private static final char[] TRKPT_END = "/trkpt>".toCharArray();
21         private static final char[] WPT_START = "<wpt".toCharArray();
22         private static final char[] WPT_END = "/wpt>".toCharArray();
23         private static final char[] RTEPT_START = "<rtept".toCharArray();
24         private static final char[] RTEPT_END = "/rtept>".toCharArray();
25         private static final char[] CDATA_START = "<![CDATA[".toCharArray();
26         private static final char[] CDATA_END = "]]>".toCharArray();
27
28         /**
29          * Constructor
30          * @param inReceiver listener for tags
31          */
32         public GpxSlicer(TagReceiver inReceiver)
33         {
34                 _receiver = inReceiver;
35         }
36
37         /**
38          * Begin the slicing and pass the found tags back to the listener
39          * @param inStream input stream for reading gpx source
40          */
41         public void slice(InputStream inStream)
42         {
43                 StringBuffer beginBuffer = new StringBuffer(200);
44                 ByteBuffer byteBuffer = new ByteBuffer();
45                 boolean insideTag = false;
46                 boolean insideCdata = false;
47                 char[] endTag = null;
48                 boolean foundHeader = false;
49                 int b = 0;
50                 try
51                 {
52                         while ((b = inStream.read()) >= 0)
53                         {
54                                 // copy character
55                                 byteBuffer.appendByte((byte) b);
56                                 // clear buffer if necessary
57                                 if (!insideTag && !insideCdata && (b == '>' || b == '\n'))
58                                 {
59                                         byteBuffer.clear();
60                                         continue;
61                                 }
62                                 // if we're still at the beginning, copy to the begin buffer as well
63                                 if (beginBuffer != null) {beginBuffer.append((char) b);}
64
65                                 if (insideCdata) {
66                                         // Just look for end of cdata block
67                                         if (byteBuffer.foundSequence(CDATA_END)) {insideCdata = false;}
68                                 }
69                                 else
70                                 {
71                                         if (!insideTag)
72                                         {
73                                                 // Look for start of one of the tags
74                                                 if (!foundHeader && byteBuffer.foundSequence(GPX_START))
75                                                 {
76                                                         insideTag = true;
77                                                         foundHeader = true;
78                                                         endTag = GPX_END;
79                                                         // Check begin buffer for utf8 encoding
80                                                         if (beginBuffer != null && beginBuffer.toString().toLowerCase().indexOf("encoding=\"utf-8\"") > 0)
81                                                         {
82                                                                 byteBuffer.setEncodingUtf8();
83                                                         }
84                                                         beginBuffer = null; // don't need it any more
85                                                 }
86                                                 else if (b == 't')
87                                                 {
88                                                         if (byteBuffer.foundSequence(TRKPT_START)) {
89                                                                 insideTag = true;
90                                                                 endTag = TRKPT_END;
91                                                         }
92                                                         else if (byteBuffer.foundSequence(WPT_START)) {
93                                                                 insideTag = true;
94                                                                 endTag = WPT_END;
95                                                         }
96                                                         else if (byteBuffer.foundSequence(RTEPT_START)) {
97                                                                 insideTag = true;
98                                                                 endTag = RTEPT_END;
99                                                         }
100                                                 }
101                                         }
102                                         else
103                                         {
104                                                 // Look for end of found tag
105                                                 if (byteBuffer.foundSequence(endTag))
106                                                 {
107                                                         String tag = byteBuffer.toString();
108                                                         _receiver.reportTag(tag);
109                                                         byteBuffer.clear();
110                                                         insideTag = false;
111                                                 }
112                                         }
113                                         // Look for start of cdata block
114                                         if (byteBuffer.foundSequence(CDATA_START)) {
115                                                 insideCdata = true;
116                                         }
117                                 }
118                         }
119                 }
120                 catch (IOException e) {} // ignore
121         }
122 }