• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.util;
18 
19 
20 import org.xmlpull.v1.XmlPullParser;
21 import org.xmlpull.v1.XmlPullParserException;
22 import org.xmlpull.v1.XmlSerializer;
23 
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33 
34 import android.util.Xml;
35 
36 /** {@hide} */
37 public class XmlUtils
38 {
39 
skipCurrentTag(XmlPullParser parser)40     public static void skipCurrentTag(XmlPullParser parser)
41             throws XmlPullParserException, IOException {
42         int outerDepth = parser.getDepth();
43         int type;
44         while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
45                && (type != XmlPullParser.END_TAG
46                        || parser.getDepth() > outerDepth)) {
47         }
48     }
49 
50     public static final int
convertValueToList(CharSequence value, String[] options, int defaultValue)51     convertValueToList(CharSequence value, String[] options, int defaultValue)
52     {
53         if (null != value) {
54             for (int i = 0; i < options.length; i++) {
55                 if (value.equals(options[i]))
56                     return i;
57             }
58         }
59 
60         return defaultValue;
61     }
62 
63     public static final boolean
convertValueToBoolean(CharSequence value, boolean defaultValue)64     convertValueToBoolean(CharSequence value, boolean defaultValue)
65     {
66         boolean result = false;
67 
68         if (null == value)
69             return defaultValue;
70 
71         if (value.equals("1")
72         ||  value.equals("true")
73         ||  value.equals("TRUE"))
74             result = true;
75 
76         return result;
77     }
78 
79     public static final int
convertValueToInt(CharSequence charSeq, int defaultValue)80     convertValueToInt(CharSequence charSeq, int defaultValue)
81     {
82         if (null == charSeq)
83             return defaultValue;
84 
85         String nm = charSeq.toString();
86 
87         // XXX This code is copied from Integer.decode() so we don't
88         // have to instantiate an Integer!
89 
90         int value;
91         int sign = 1;
92         int index = 0;
93         int len = nm.length();
94         int base = 10;
95 
96         if ('-' == nm.charAt(0)) {
97             sign = -1;
98             index++;
99         }
100 
101         if ('0' == nm.charAt(index)) {
102             //  Quick check for a zero by itself
103             if (index == (len - 1))
104                 return 0;
105 
106             char    c = nm.charAt(index + 1);
107 
108             if ('x' == c || 'X' == c) {
109                 index += 2;
110                 base = 16;
111             } else {
112                 index++;
113                 base = 8;
114             }
115         }
116         else if ('#' == nm.charAt(index))
117         {
118             index++;
119             base = 16;
120         }
121 
122         return Integer.parseInt(nm.substring(index), base) * sign;
123     }
124 
125     public static final int
convertValueToUnsignedInt(String value, int defaultValue)126     convertValueToUnsignedInt(String value, int defaultValue)
127     {
128         if (null == value)
129             return defaultValue;
130 
131         return parseUnsignedIntAttribute(value);
132     }
133 
134     public static final int
parseUnsignedIntAttribute(CharSequence charSeq)135     parseUnsignedIntAttribute(CharSequence charSeq)
136     {
137         String  value = charSeq.toString();
138 
139         long    bits;
140         int     index = 0;
141         int     len = value.length();
142         int     base = 10;
143 
144         if ('0' == value.charAt(index)) {
145             //  Quick check for zero by itself
146             if (index == (len - 1))
147                 return 0;
148 
149             char    c = value.charAt(index + 1);
150 
151             if ('x' == c || 'X' == c) {     //  check for hex
152                 index += 2;
153                 base = 16;
154             } else {                        //  check for octal
155                 index++;
156                 base = 8;
157             }
158         } else if ('#' == value.charAt(index)) {
159             index++;
160             base = 16;
161         }
162 
163         return (int) Long.parseLong(value.substring(index), base);
164     }
165 
166     /**
167      * Flatten a Map into an output stream as XML.  The map can later be
168      * read back with readMapXml().
169      *
170      * @param val The map to be flattened.
171      * @param out Where to write the XML data.
172      *
173      * @see #writeMapXml(Map, String, XmlSerializer)
174      * @see #writeListXml
175      * @see #writeValueXml
176      * @see #readMapXml
177      */
writeMapXml(Map val, OutputStream out)178     public static final void writeMapXml(Map val, OutputStream out)
179             throws XmlPullParserException, java.io.IOException {
180         XmlSerializer serializer = new FastXmlSerializer();
181         serializer.setOutput(out, "utf-8");
182         serializer.startDocument(null, true);
183         serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
184         writeMapXml(val, null, serializer);
185         serializer.endDocument();
186     }
187 
188     /**
189      * Flatten a List into an output stream as XML.  The list can later be
190      * read back with readListXml().
191      *
192      * @param val The list to be flattened.
193      * @param out Where to write the XML data.
194      *
195      * @see #writeListXml(List, String, XmlSerializer)
196      * @see #writeMapXml
197      * @see #writeValueXml
198      * @see #readListXml
199      */
writeListXml(List val, OutputStream out)200     public static final void writeListXml(List val, OutputStream out)
201     throws XmlPullParserException, java.io.IOException
202     {
203         XmlSerializer serializer = Xml.newSerializer();
204         serializer.setOutput(out, "utf-8");
205         serializer.startDocument(null, true);
206         serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
207         writeListXml(val, null, serializer);
208         serializer.endDocument();
209     }
210 
211     /**
212      * Flatten a Map into an XmlSerializer.  The map can later be read back
213      * with readThisMapXml().
214      *
215      * @param val The map to be flattened.
216      * @param name Name attribute to include with this list's tag, or null for
217      *             none.
218      * @param out XmlSerializer to write the map into.
219      *
220      * @see #writeMapXml(Map, OutputStream)
221      * @see #writeListXml
222      * @see #writeValueXml
223      * @see #readMapXml
224      */
writeMapXml(Map val, String name, XmlSerializer out)225     public static final void writeMapXml(Map val, String name, XmlSerializer out)
226     throws XmlPullParserException, java.io.IOException
227     {
228         if (val == null) {
229             out.startTag(null, "null");
230             out.endTag(null, "null");
231             return;
232         }
233 
234         Set s = val.entrySet();
235         Iterator i = s.iterator();
236 
237         out.startTag(null, "map");
238         if (name != null) {
239             out.attribute(null, "name", name);
240         }
241 
242         while (i.hasNext()) {
243             Map.Entry e = (Map.Entry)i.next();
244             writeValueXml(e.getValue(), (String)e.getKey(), out);
245         }
246 
247         out.endTag(null, "map");
248     }
249 
250     /**
251      * Flatten a List into an XmlSerializer.  The list can later be read back
252      * with readThisListXml().
253      *
254      * @param val The list to be flattened.
255      * @param name Name attribute to include with this list's tag, or null for
256      *             none.
257      * @param out XmlSerializer to write the list into.
258      *
259      * @see #writeListXml(List, OutputStream)
260      * @see #writeMapXml
261      * @see #writeValueXml
262      * @see #readListXml
263      */
writeListXml(List val, String name, XmlSerializer out)264     public static final void writeListXml(List val, String name, XmlSerializer out)
265     throws XmlPullParserException, java.io.IOException
266     {
267         if (val == null) {
268             out.startTag(null, "null");
269             out.endTag(null, "null");
270             return;
271         }
272 
273         out.startTag(null, "list");
274         if (name != null) {
275             out.attribute(null, "name", name);
276         }
277 
278         int N = val.size();
279         int i=0;
280         while (i < N) {
281             writeValueXml(val.get(i), null, out);
282             i++;
283         }
284 
285         out.endTag(null, "list");
286     }
287 
288     /**
289      * Flatten a byte[] into an XmlSerializer.  The list can later be read back
290      * with readThisByteArrayXml().
291      *
292      * @param val The byte array to be flattened.
293      * @param name Name attribute to include with this array's tag, or null for
294      *             none.
295      * @param out XmlSerializer to write the array into.
296      *
297      * @see #writeMapXml
298      * @see #writeValueXml
299      */
writeByteArrayXml(byte[] val, String name, XmlSerializer out)300     public static final void writeByteArrayXml(byte[] val, String name,
301             XmlSerializer out)
302             throws XmlPullParserException, java.io.IOException {
303 
304         if (val == null) {
305             out.startTag(null, "null");
306             out.endTag(null, "null");
307             return;
308         }
309 
310         out.startTag(null, "byte-array");
311         if (name != null) {
312             out.attribute(null, "name", name);
313         }
314 
315         final int N = val.length;
316         out.attribute(null, "num", Integer.toString(N));
317 
318         StringBuilder sb = new StringBuilder(val.length*2);
319         for (int i=0; i<N; i++) {
320             int b = val[i];
321             int h = b>>4;
322             sb.append(h >= 10 ? ('a'+h-10) : ('0'+h));
323             h = b&0xff;
324             sb.append(h >= 10 ? ('a'+h-10) : ('0'+h));
325         }
326 
327         out.text(sb.toString());
328 
329         out.endTag(null, "byte-array");
330     }
331 
332     /**
333      * Flatten an int[] into an XmlSerializer.  The list can later be read back
334      * with readThisIntArrayXml().
335      *
336      * @param val The int array to be flattened.
337      * @param name Name attribute to include with this array's tag, or null for
338      *             none.
339      * @param out XmlSerializer to write the array into.
340      *
341      * @see #writeMapXml
342      * @see #writeValueXml
343      * @see #readThisIntArrayXml
344      */
writeIntArrayXml(int[] val, String name, XmlSerializer out)345     public static final void writeIntArrayXml(int[] val, String name,
346             XmlSerializer out)
347             throws XmlPullParserException, java.io.IOException {
348 
349         if (val == null) {
350             out.startTag(null, "null");
351             out.endTag(null, "null");
352             return;
353         }
354 
355         out.startTag(null, "int-array");
356         if (name != null) {
357             out.attribute(null, "name", name);
358         }
359 
360         final int N = val.length;
361         out.attribute(null, "num", Integer.toString(N));
362 
363         for (int i=0; i<N; i++) {
364             out.startTag(null, "item");
365             out.attribute(null, "value", Integer.toString(val[i]));
366             out.endTag(null, "item");
367         }
368 
369         out.endTag(null, "int-array");
370     }
371 
372     /**
373      * Flatten an object's value into an XmlSerializer.  The value can later
374      * be read back with readThisValueXml().
375      *
376      * Currently supported value types are: null, String, Integer, Long,
377      * Float, Double Boolean, Map, List.
378      *
379      * @param v The object to be flattened.
380      * @param name Name attribute to include with this value's tag, or null
381      *             for none.
382      * @param out XmlSerializer to write the object into.
383      *
384      * @see #writeMapXml
385      * @see #writeListXml
386      * @see #readValueXml
387      */
writeValueXml(Object v, String name, XmlSerializer out)388     public static final void writeValueXml(Object v, String name, XmlSerializer out)
389     throws XmlPullParserException, java.io.IOException
390     {
391         String typeStr;
392         if (v == null) {
393             out.startTag(null, "null");
394             if (name != null) {
395                 out.attribute(null, "name", name);
396             }
397             out.endTag(null, "null");
398             return;
399         } else if (v instanceof String) {
400             out.startTag(null, "string");
401             if (name != null) {
402                 out.attribute(null, "name", name);
403             }
404             out.text(v.toString());
405             out.endTag(null, "string");
406             return;
407         } else if (v instanceof Integer) {
408             typeStr = "int";
409         } else if (v instanceof Long) {
410             typeStr = "long";
411         } else if (v instanceof Float) {
412             typeStr = "float";
413         } else if (v instanceof Double) {
414             typeStr = "double";
415         } else if (v instanceof Boolean) {
416             typeStr = "boolean";
417         } else if (v instanceof byte[]) {
418             writeByteArrayXml((byte[])v, name, out);
419             return;
420         } else if (v instanceof int[]) {
421             writeIntArrayXml((int[])v, name, out);
422             return;
423         } else if (v instanceof Map) {
424             writeMapXml((Map)v, name, out);
425             return;
426         } else if (v instanceof List) {
427             writeListXml((List)v, name, out);
428             return;
429         } else if (v instanceof CharSequence) {
430             // XXX This is to allow us to at least write something if
431             // we encounter styled text...  but it means we will drop all
432             // of the styling information. :(
433             out.startTag(null, "string");
434             if (name != null) {
435                 out.attribute(null, "name", name);
436             }
437             out.text(v.toString());
438             out.endTag(null, "string");
439             return;
440         } else {
441             throw new RuntimeException("writeValueXml: unable to write value " + v);
442         }
443 
444         out.startTag(null, typeStr);
445         if (name != null) {
446             out.attribute(null, "name", name);
447         }
448         out.attribute(null, "value", v.toString());
449         out.endTag(null, typeStr);
450     }
451 
452     /**
453      * Read a HashMap from an InputStream containing XML.  The stream can
454      * previously have been written by writeMapXml().
455      *
456      * @param in The InputStream from which to read.
457      *
458      * @return HashMap The resulting map.
459      *
460      * @see #readListXml
461      * @see #readValueXml
462      * @see #readThisMapXml
463      * #see #writeMapXml
464      */
readMapXml(InputStream in)465     public static final HashMap readMapXml(InputStream in)
466     throws XmlPullParserException, java.io.IOException
467     {
468         XmlPullParser   parser = Xml.newPullParser();
469         parser.setInput(in, null);
470         return (HashMap)readValueXml(parser, new String[1]);
471     }
472 
473     /**
474      * Read an ArrayList from an InputStream containing XML.  The stream can
475      * previously have been written by writeListXml().
476      *
477      * @param in The InputStream from which to read.
478      *
479      * @return HashMap The resulting list.
480      *
481      * @see #readMapXml
482      * @see #readValueXml
483      * @see #readThisListXml
484      * @see #writeListXml
485      */
readListXml(InputStream in)486     public static final ArrayList readListXml(InputStream in)
487     throws XmlPullParserException, java.io.IOException
488     {
489         XmlPullParser   parser = Xml.newPullParser();
490         parser.setInput(in, null);
491         return (ArrayList)readValueXml(parser, new String[1]);
492     }
493 
494     /**
495      * Read a HashMap object from an XmlPullParser.  The XML data could
496      * previously have been generated by writeMapXml().  The XmlPullParser
497      * must be positioned <em>after</em> the tag that begins the map.
498      *
499      * @param parser The XmlPullParser from which to read the map data.
500      * @param endTag Name of the tag that will end the map, usually "map".
501      * @param name An array of one string, used to return the name attribute
502      *             of the map's tag.
503      *
504      * @return HashMap The newly generated map.
505      *
506      * @see #readMapXml
507      */
readThisMapXml(XmlPullParser parser, String endTag, String[] name)508     public static final HashMap readThisMapXml(XmlPullParser parser, String endTag, String[] name)
509     throws XmlPullParserException, java.io.IOException
510     {
511         HashMap map = new HashMap();
512 
513         int eventType = parser.getEventType();
514         do {
515             if (eventType == parser.START_TAG) {
516                 Object val = readThisValueXml(parser, name);
517                 if (name[0] != null) {
518                     //System.out.println("Adding to map: " + name + " -> " + val);
519                     map.put(name[0], val);
520                 } else {
521                     throw new XmlPullParserException(
522                         "Map value without name attribute: " + parser.getName());
523                 }
524             } else if (eventType == parser.END_TAG) {
525                 if (parser.getName().equals(endTag)) {
526                     return map;
527                 }
528                 throw new XmlPullParserException(
529                     "Expected " + endTag + " end tag at: " + parser.getName());
530             }
531             eventType = parser.next();
532         } while (eventType != parser.END_DOCUMENT);
533 
534         throw new XmlPullParserException(
535             "Document ended before " + endTag + " end tag");
536     }
537 
538     /**
539      * Read an ArrayList object from an XmlPullParser.  The XML data could
540      * previously have been generated by writeListXml().  The XmlPullParser
541      * must be positioned <em>after</em> the tag that begins the list.
542      *
543      * @param parser The XmlPullParser from which to read the list data.
544      * @param endTag Name of the tag that will end the list, usually "list".
545      * @param name An array of one string, used to return the name attribute
546      *             of the list's tag.
547      *
548      * @return HashMap The newly generated list.
549      *
550      * @see #readListXml
551      */
readThisListXml(XmlPullParser parser, String endTag, String[] name)552     public static final ArrayList readThisListXml(XmlPullParser parser, String endTag, String[] name)
553     throws XmlPullParserException, java.io.IOException
554     {
555         ArrayList list = new ArrayList();
556 
557         int eventType = parser.getEventType();
558         do {
559             if (eventType == parser.START_TAG) {
560                 Object val = readThisValueXml(parser, name);
561                 list.add(val);
562                 //System.out.println("Adding to list: " + val);
563             } else if (eventType == parser.END_TAG) {
564                 if (parser.getName().equals(endTag)) {
565                     return list;
566                 }
567                 throw new XmlPullParserException(
568                     "Expected " + endTag + " end tag at: " + parser.getName());
569             }
570             eventType = parser.next();
571         } while (eventType != parser.END_DOCUMENT);
572 
573         throw new XmlPullParserException(
574             "Document ended before " + endTag + " end tag");
575     }
576 
577     /**
578      * Read an int[] object from an XmlPullParser.  The XML data could
579      * previously have been generated by writeIntArrayXml().  The XmlPullParser
580      * must be positioned <em>after</em> the tag that begins the list.
581      *
582      * @param parser The XmlPullParser from which to read the list data.
583      * @param endTag Name of the tag that will end the list, usually "list".
584      * @param name An array of one string, used to return the name attribute
585      *             of the list's tag.
586      *
587      * @return Returns a newly generated int[].
588      *
589      * @see #readListXml
590      */
readThisIntArrayXml(XmlPullParser parser, String endTag, String[] name)591     public static final int[] readThisIntArrayXml(XmlPullParser parser,
592             String endTag, String[] name)
593             throws XmlPullParserException, java.io.IOException {
594 
595         int num;
596         try {
597             num = Integer.parseInt(parser.getAttributeValue(null, "num"));
598         } catch (NullPointerException e) {
599             throw new XmlPullParserException(
600                     "Need num attribute in byte-array");
601         } catch (NumberFormatException e) {
602             throw new XmlPullParserException(
603                     "Not a number in num attribute in byte-array");
604         }
605 
606         int[] array = new int[num];
607         int i = 0;
608 
609         int eventType = parser.getEventType();
610         do {
611             if (eventType == parser.START_TAG) {
612                 if (parser.getName().equals("item")) {
613                     try {
614                         array[i] = Integer.parseInt(
615                                 parser.getAttributeValue(null, "value"));
616                     } catch (NullPointerException e) {
617                         throw new XmlPullParserException(
618                                 "Need value attribute in item");
619                     } catch (NumberFormatException e) {
620                         throw new XmlPullParserException(
621                                 "Not a number in value attribute in item");
622                     }
623                 } else {
624                     throw new XmlPullParserException(
625                             "Expected item tag at: " + parser.getName());
626                 }
627             } else if (eventType == parser.END_TAG) {
628                 if (parser.getName().equals(endTag)) {
629                     return array;
630                 } else if (parser.getName().equals("item")) {
631                     i++;
632                 } else {
633                     throw new XmlPullParserException(
634                         "Expected " + endTag + " end tag at: "
635                         + parser.getName());
636                 }
637             }
638             eventType = parser.next();
639         } while (eventType != parser.END_DOCUMENT);
640 
641         throw new XmlPullParserException(
642             "Document ended before " + endTag + " end tag");
643     }
644 
645     /**
646      * Read a flattened object from an XmlPullParser.  The XML data could
647      * previously have been written with writeMapXml(), writeListXml(), or
648      * writeValueXml().  The XmlPullParser must be positioned <em>at</em> the
649      * tag that defines the value.
650      *
651      * @param parser The XmlPullParser from which to read the object.
652      * @param name An array of one string, used to return the name attribute
653      *             of the value's tag.
654      *
655      * @return Object The newly generated value object.
656      *
657      * @see #readMapXml
658      * @see #readListXml
659      * @see #writeValueXml
660      */
readValueXml(XmlPullParser parser, String[] name)661     public static final Object readValueXml(XmlPullParser parser, String[] name)
662     throws XmlPullParserException, java.io.IOException
663     {
664         int eventType = parser.getEventType();
665         do {
666             if (eventType == parser.START_TAG) {
667                 return readThisValueXml(parser, name);
668             } else if (eventType == parser.END_TAG) {
669                 throw new XmlPullParserException(
670                     "Unexpected end tag at: " + parser.getName());
671             } else if (eventType == parser.TEXT) {
672                 throw new XmlPullParserException(
673                     "Unexpected text: " + parser.getText());
674             }
675             eventType = parser.next();
676         } while (eventType != parser.END_DOCUMENT);
677 
678         throw new XmlPullParserException(
679             "Unexpected end of document");
680     }
681 
readThisValueXml(XmlPullParser parser, String[] name)682     private static final Object readThisValueXml(XmlPullParser parser, String[] name)
683     throws XmlPullParserException, java.io.IOException
684     {
685         final String valueName = parser.getAttributeValue(null, "name");
686         final String tagName = parser.getName();
687 
688         //System.out.println("Reading this value tag: " + tagName + ", name=" + valueName);
689 
690         Object res;
691 
692         if (tagName.equals("null")) {
693             res = null;
694         } else if (tagName.equals("string")) {
695             String value = "";
696             int eventType;
697             while ((eventType = parser.next()) != parser.END_DOCUMENT) {
698                 if (eventType == parser.END_TAG) {
699                     if (parser.getName().equals("string")) {
700                         name[0] = valueName;
701                         //System.out.println("Returning value for " + valueName + ": " + value);
702                         return value;
703                     }
704                     throw new XmlPullParserException(
705                         "Unexpected end tag in <string>: " + parser.getName());
706                 } else if (eventType == parser.TEXT) {
707                     value += parser.getText();
708                 } else if (eventType == parser.START_TAG) {
709                     throw new XmlPullParserException(
710                         "Unexpected start tag in <string>: " + parser.getName());
711                 }
712             }
713             throw new XmlPullParserException(
714                 "Unexpected end of document in <string>");
715         } else if (tagName.equals("int")) {
716             res = Integer.parseInt(parser.getAttributeValue(null, "value"));
717         } else if (tagName.equals("long")) {
718             res = Long.valueOf(parser.getAttributeValue(null, "value"));
719         } else if (tagName.equals("float")) {
720             res = new Float(parser.getAttributeValue(null, "value"));
721         } else if (tagName.equals("double")) {
722             res = new Double(parser.getAttributeValue(null, "value"));
723         } else if (tagName.equals("boolean")) {
724             res = Boolean.valueOf(parser.getAttributeValue(null, "value"));
725         } else if (tagName.equals("int-array")) {
726             parser.next();
727             res = readThisIntArrayXml(parser, "int-array", name);
728             name[0] = valueName;
729             //System.out.println("Returning value for " + valueName + ": " + res);
730             return res;
731         } else if (tagName.equals("map")) {
732             parser.next();
733             res = readThisMapXml(parser, "map", name);
734             name[0] = valueName;
735             //System.out.println("Returning value for " + valueName + ": " + res);
736             return res;
737         } else if (tagName.equals("list")) {
738             parser.next();
739             res = readThisListXml(parser, "list", name);
740             name[0] = valueName;
741             //System.out.println("Returning value for " + valueName + ": " + res);
742             return res;
743         } else {
744             throw new XmlPullParserException(
745                 "Unknown tag: " + tagName);
746         }
747 
748         // Skip through to end tag.
749         int eventType;
750         while ((eventType = parser.next()) != parser.END_DOCUMENT) {
751             if (eventType == parser.END_TAG) {
752                 if (parser.getName().equals(tagName)) {
753                     name[0] = valueName;
754                     //System.out.println("Returning value for " + valueName + ": " + res);
755                     return res;
756                 }
757                 throw new XmlPullParserException(
758                     "Unexpected end tag in <" + tagName + ">: " + parser.getName());
759             } else if (eventType == parser.TEXT) {
760                 throw new XmlPullParserException(
761                 "Unexpected text in <" + tagName + ">: " + parser.getName());
762             } else if (eventType == parser.START_TAG) {
763                 throw new XmlPullParserException(
764                     "Unexpected start tag in <" + tagName + ">: " + parser.getName());
765             }
766         }
767         throw new XmlPullParserException(
768             "Unexpected end of document in <" + tagName + ">");
769     }
770 
beginDocument(XmlPullParser parser, String firstElementName)771     public static final void beginDocument(XmlPullParser parser, String firstElementName) throws XmlPullParserException, IOException
772     {
773         int type;
774         while ((type=parser.next()) != parser.START_TAG
775                    && type != parser.END_DOCUMENT) {
776             ;
777         }
778 
779         if (type != parser.START_TAG) {
780             throw new XmlPullParserException("No start tag found");
781         }
782 
783         if (!parser.getName().equals(firstElementName)) {
784             throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
785                     ", expected " + firstElementName);
786         }
787     }
788 
nextElement(XmlPullParser parser)789     public static final void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException
790     {
791         int type;
792         while ((type=parser.next()) != parser.START_TAG
793                    && type != parser.END_DOCUMENT) {
794             ;
795         }
796     }
797 }
798