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