blob: 32ac1c5c6a69f13552bb0993774740a8c321494d [file] [log] [blame]
Meki Cherkaoui97e7a592012-04-14 02:50:06 -07001
2
3var TextXMLDecoder = function TextXMLDecoder(){
4
5 this.reader = null;
6
7};
8
9
10exports.TextXMLDecoder = TextXMLDecoder;
11
12
13exports.prototype.initializeDecoding = function(){
14 try {
15 XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
16 factory.setNamespaceAware(true);
17 _reader = factory.newPullParser();
18 _reader.setInput(_istream, null);
19 } catch (XmlPullParserException e) {
20 throw new ContentDecodingException(e.getMessage(), e);
21 }
22};
23
24exports.prototype.readStartDocument = function(){
25 try {
26 int event = _reader.getEventType();
27 _reader.next();
28 if (event != XmlPullParser.START_DOCUMENT) {
29 throw new ContentDecodingException("Expected start document, got: " + XmlPullParser.TYPES[event]);
30 }
31 } catch (XmlPullParserException e) {
32 throw new ContentDecodingException(e.getMessage(), e);
33 } catch (IOException e) {
34 throw new ContentDecodingException(e.getMessage(), e);
35 }
36};
37
38public void readEndDocument() throws ContentDecodingException {
39 int event;
40 try {
41 event = _reader.getEventType();
42 } catch (XmlPullParserException e) {
43 throw new ContentDecodingException(e.getMessage(), e);
44 }
45 if (event != XmlPullParser.END_DOCUMENT) {
46 throw new ContentDecodingException("Expected end document, got: " + XmlPullParser.TYPES[event]);
47 }
48};
49
50exports.prototype.readStartElement = function(/*String*/ startTag,
51 TreeMap<String, String> attributes) throws ContentDecodingException {
52
53 int event = readToNextTag(XmlPullParser.START_TAG);
54 if (event != XmlPullParser.START_TAG) {
55 throw new ContentDecodingException("Expected start element, got: " + XmlPullParser.TYPES[event]);
56 }
57 // Use getLocalPart to strip namespaces.
58 // Assumes we are working with a global default namespace of CCN.
59 if (!startTag.equals(_reader.getName())) {
60 // Coming back with namespace decoration doesn't match
61 throw new ContentDecodingException("Expected start element: " + startTag + " got: " + _reader.getName());
62 }
63 if (null != attributes) {
64 // we might be expecting attributes
65 for (int i=0; i < _reader.getAttributeCount(); ++i) {
66 // may need fancier namespace handling.
67 attributes.put(_reader.getAttributeName(i), _reader.getAttributeValue(i));
68 }
69 }
70 try {
71 _reader.next();
72 } catch (XmlPullParserException e) {
73 throw new ContentDecodingException(e.getMessage());
74 } catch (IOException e) {
75 throw new ContentDecodingException(e.getMessage());
76 }
77}
78
79 public void readStartElement(long startTagLong,
80 TreeMap<String, String> attributes) throws ContentDecodingException {
81
82 String startTag = tagToString(startTagLong);
83
84 int event = readToNextTag(XmlPullParser.START_TAG);
85 if (event != XmlPullParser.START_TAG) {
86 throw new ContentDecodingException("Expected start element, got: " + XmlPullParser.TYPES[event]);
87 }
88 // Use getLocalPart to strip namespaces.
89 // Assumes we are working with a global default namespace of CCN.
90 if (!startTag.equals(_reader.getName())) {
91 // Coming back with namespace decoration doesn't match
92 throw new ContentDecodingException("Expected start element: " + startTag + " got: " + _reader.getName());
93 }
94 if (null != attributes) {
95 // we might be expecting attributes
96 for (int i=0; i < _reader.getAttributeCount(); ++i) {
97 // may need fancier namespace handling.
98 attributes.put(_reader.getAttributeName(i), _reader.getAttributeValue(i));
99 }
100 }
101 try {
102 _reader.next();
103 } catch (XmlPullParserException e) {
104 throw new ContentDecodingException(e.getMessage());
105 } catch (IOException e) {
106 throw new ContentDecodingException(e.getMessage());
107 }
108 }
109 public String peekStartElementAsString() throws ContentDecodingException {
110 int event = readToNextTag(XmlPullParser.START_TAG);
111 if (event != XmlPullParser.START_TAG) {
112 return null;
113 }
114 return _reader.getName();
115 }
116
117 public Long peekStartElementAsLong() throws ContentDecodingException {
118 String strTag = peekStartElementAsString();
119 if (null == strTag) {
120 return null; // e.g. hit an end tag...
121 }
122 return stringToTag(strTag);
123 }
124
125 /**
126 * Helper method to decode text (UTF-8) and binary elements. Consumes the end element,
127 * behavior which other decoders are forced to match.
128 * @return the read data, as a String
129 * @throws ContentDecodingException if there is a problem decoding the data
130 */
131 public String readUString() throws ContentDecodingException {
132 StringBuffer buf = new StringBuffer();
133 try {
134 int event = _reader.getEventType();;
135 // Handles empty text element.
136 while (event == XmlPullParser.TEXT) {
137 buf.append(_reader.getText());
138 event = _reader.next();
139 }
140 if (event == XmlPullParser.START_TAG) {
141 throw new ContentDecodingException("readElementText expects start element to have been previously consumed, got: " + XmlPullParser.TYPES[event]);
142 } else if (event != XmlPullParser.END_TAG) {
143 throw new ContentDecodingException("Expected end of text element, got: " + XmlPullParser.TYPES[event]);
144 }
145 readEndElement();
146 return buf.toString();
147 } catch (XmlPullParserException e) {
148 throw new ContentDecodingException(e.getMessage(), e);
149 } catch (IOException e) {
150 throw new ContentDecodingException(e.getMessage(), e);
151 }
152 }
153
154 public void readEndElement() throws ContentDecodingException {
155 int event = readToNextTag(XmlPullParser.END_TAG);
156 if (event != XmlPullParser.END_TAG) {
157 throw new ContentDecodingException("Expected end element, got: " + XmlPullParser.TYPES[event]);
158 }
159 try {
160 _reader.next();
161 } catch (XmlPullParserException e) {
162 throw new ContentDecodingException(e.getMessage());
163 } catch (IOException e) {
164 throw new ContentDecodingException(e.getMessage());
165 }
166 }
167
168 /**
169 * Read a BLOB. Consumes the end element, so force other versions
170 * to match.
171 */
172 public byte [] readBlob() throws ContentDecodingException {
173 try {
174 String strElementText = readUString();
175 // readEndElement(); // readElementText consumes end element
176 return TextXMLCodec.decodeBinaryElement(strElementText);
177 } catch (IOException e) {
178 throw new ContentDecodingException(e.getMessage(),e);
179 }
180 }
181
182 public CCNTime readDateTime(String startTag) throws ContentDecodingException {
183 String strTimestamp = readUTF8Element(startTag);
184 CCNTime timestamp;
185 try {
186 timestamp = TextXMLCodec.parseDateTime(strTimestamp);
187 } catch (ParseException e) {
188 timestamp = null;
189 }
190 if (null == timestamp) {
191 throw new ContentDecodingException("Cannot parse timestamp: " + strTimestamp);
192 }
193 return timestamp;
194 }
195
196 public CCNTime readDateTime(long startTag) throws ContentDecodingException {
197 String strTimestamp = readUTF8Element(startTag);
198 CCNTime timestamp;
199 try {
200 timestamp = TextXMLCodec.parseDateTime(strTimestamp);
201 } catch (ParseException e) {
202 timestamp = null;
203 }
204 if (null == timestamp) {
205 throw new ContentDecodingException("Cannot parse timestamp: " + strTimestamp);
206 }
207 return timestamp;
208 }
209
210 private int readToNextTag(int type) throws ContentDecodingException {
211 int event;
212 try {
213 event = _reader.getEventType();
214 if (event == type)
215 return event;
216 if (event == XmlPullParser.TEXT || event == XmlPullParser.COMMENT)
217 event = _reader.next();
218 } catch (IOException e) {
219 throw new ContentDecodingException(e.getMessage(), e);
220 } catch (XmlPullParserException e) {
221 throw new ContentDecodingException(e.getMessage(), e);
222 }
223 return event;
224 }
225};