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