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 android.widget.cts.util; 18 19 import org.xmlpull.v1.XmlPullParser; 20 import org.xmlpull.v1.XmlPullParserException; 21 import org.xmlpull.v1.XmlSerializer; 22 23 import android.graphics.Bitmap; 24 import android.graphics.Bitmap.CompressFormat; 25 import android.graphics.BitmapFactory; 26 import android.net.Uri; 27 import android.util.ArrayMap; 28 import android.util.Base64; 29 import android.util.Xml; 30 31 import java.io.ByteArrayOutputStream; 32 import java.io.IOException; 33 import java.io.InputStream; 34 import java.io.OutputStream; 35 import java.net.ProtocolException; 36 import java.nio.charset.StandardCharsets; 37 import java.util.ArrayList; 38 import java.util.HashMap; 39 import java.util.HashSet; 40 import java.util.Iterator; 41 import java.util.List; 42 import java.util.Map; 43 import java.util.Set; 44 45 /** {@hide} */ 46 public class XmlUtils { 47 48 public static void skipCurrentTag(XmlPullParser parser) 49 throws XmlPullParserException, IOException { 50 int outerDepth = parser.getDepth(); 51 int type; 52 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 53 && (type != XmlPullParser.END_TAG 54 || parser.getDepth() > outerDepth)) { 55 } 56 } 57 58 public static final int 59 convertValueToList(CharSequence value, String[] options, int defaultValue) 60 { 61 if (null != value) { 62 for (int i = 0; i < options.length; i++) { 63 if (value.equals(options[i])) 64 return i; 65 } 66 } 67 68 return defaultValue; 69 } 70 71 public static final boolean 72 convertValueToBoolean(CharSequence value, boolean defaultValue) 73 { 74 boolean result = false; 75 76 if (null == value) 77 return defaultValue; 78 79 if (value.equals("1") 80 || value.equals("true") 81 || value.equals("TRUE")) 82 result = true; 83 84 return result; 85 } 86 87 public static final int 88 convertValueToInt(CharSequence charSeq, int defaultValue) 89 { 90 if (null == charSeq) 91 return defaultValue; 92 93 String nm = charSeq.toString(); 94 95 // XXX This code is copied from Integer.decode() so we don't 96 // have to instantiate an Integer! 97 98 int value; 99 int sign = 1; 100 int index = 0; 101 int len = nm.length(); 102 int base = 10; 103 104 if ('-' == nm.charAt(0)) { 105 sign = -1; 106 index++; 107 } 108 109 if ('0' == nm.charAt(index)) { 110 // Quick check for a zero by itself 111 if (index == (len - 1)) 112 return 0; 113 114 char c = nm.charAt(index + 1); 115 116 if ('x' == c || 'X' == c) { 117 index += 2; 118 base = 16; 119 } else { 120 index++; 121 base = 8; 122 } 123 } 124 else if ('#' == nm.charAt(index)) 125 { 126 index++; 127 base = 16; 128 } 129 130 return Integer.parseInt(nm.substring(index), base) * sign; 131 } 132 133 public static int convertValueToUnsignedInt(String value, int defaultValue) { 134 if (null == value) { 135 return defaultValue; 136 } 137 138 return parseUnsignedIntAttribute(value); 139 } 140 141 public static int parseUnsignedIntAttribute(CharSequence charSeq) { 142 String value = charSeq.toString(); 143 144 long bits; 145 int index = 0; 146 int len = value.length(); 147 int base = 10; 148 149 if ('0' == value.charAt(index)) { 150 // Quick check for zero by itself 151 if (index == (len - 1)) 152 return 0; 153 154 char c = value.charAt(index + 1); 155 156 if ('x' == c || 'X' == c) { // check for hex 157 index += 2; 158 base = 16; 159 } else { // check for octal 160 index++; 161 base = 8; 162 } 163 } else if ('#' == value.charAt(index)) { 164 index++; 165 base = 16; 166 } 167 168 return (int) Long.parseLong(value.substring(index), base); 169 } 170 171 /** 172 * Flatten a List into an output stream as XML. The list can later be 173 * read back with readListXml(). 174 * 175 * @param val The list to be flattened. 176 * @param out Where to write the XML data. 177 * 178 * @see #writeListXml(List, String, XmlSerializer) 179 * @see #writeMapXml 180 * @see #writeValueXml 181 * @see #readListXml 182 */ 183 public static final void writeListXml(List val, OutputStream out) 184 throws XmlPullParserException, IOException 185 { 186 XmlSerializer serializer = Xml.newSerializer(); 187 serializer.setOutput(out, StandardCharsets.UTF_8.name()); 188 serializer.startDocument(null, true); 189 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 190 writeListXml(val, null, serializer); 191 serializer.endDocument(); 192 } 193 194 /** 195 * Flatten a Map into an XmlSerializer. The map can later be read back 196 * with readThisMapXml(). 197 * 198 * @param val The map to be flattened. 199 * @param name Name attribute to include with this list's tag, or null for 200 * none. 201 * @param out XmlSerializer to write the map into. 202 * 203 * @see #writeListXml 204 * @see #writeValueXml 205 * @see #readMapXml 206 */ 207 public static final void writeMapXml(Map val, String name, XmlSerializer out) 208 throws XmlPullParserException, IOException { 209 writeMapXml(val, name, out, null); 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 * @param callback Method to call when an Object type is not recognized. 221 * 222 * @see #writeListXml 223 * @see #writeValueXml 224 * @see #readMapXml 225 * 226 * @hide 227 */ 228 public static final void writeMapXml(Map val, String name, XmlSerializer out, 229 WriteMapCallback callback) throws XmlPullParserException, IOException { 230 231 if (val == null) { 232 out.startTag(null, "null"); 233 out.endTag(null, "null"); 234 return; 235 } 236 237 out.startTag(null, "map"); 238 if (name != null) { 239 out.attribute(null, "name", name); 240 } 241 242 writeMapXml(val, out, callback); 243 244 out.endTag(null, "map"); 245 } 246 247 /** 248 * Flatten a Map into an XmlSerializer. The map can later be read back 249 * with readThisMapXml(). This method presumes that the start tag and 250 * name attribute have already been written and does not write an end tag. 251 * 252 * @param val The map to be flattened. 253 * @param out XmlSerializer to write the map into. 254 * 255 * @see #writeListXml 256 * @see #writeValueXml 257 * @see #readMapXml 258 * 259 * @hide 260 */ 261 public static final void writeMapXml(Map val, XmlSerializer out, 262 WriteMapCallback callback) throws XmlPullParserException, IOException { 263 if (val == null) { 264 return; 265 } 266 267 Set s = val.entrySet(); 268 Iterator i = s.iterator(); 269 270 while (i.hasNext()) { 271 Map.Entry e = (Map.Entry)i.next(); 272 writeValueXml(e.getValue(), (String)e.getKey(), out, callback); 273 } 274 } 275 276 /** 277 * Flatten a List into an XmlSerializer. The list can later be read back 278 * with readThisListXml(). 279 * 280 * @param val The list to be flattened. 281 * @param name Name attribute to include with this list's tag, or null for 282 * none. 283 * @param out XmlSerializer to write the list into. 284 * 285 * @see #writeListXml(List, OutputStream) 286 * @see #writeMapXml 287 * @see #writeValueXml 288 * @see #readListXml 289 */ 290 public static final void writeListXml(List val, String name, XmlSerializer out) 291 throws XmlPullParserException, IOException 292 { 293 if (val == null) { 294 out.startTag(null, "null"); 295 out.endTag(null, "null"); 296 return; 297 } 298 299 out.startTag(null, "list"); 300 if (name != null) { 301 out.attribute(null, "name", name); 302 } 303 304 int N = val.size(); 305 int i=0; 306 while (i < N) { 307 writeValueXml(val.get(i), null, out); 308 i++; 309 } 310 311 out.endTag(null, "list"); 312 } 313 314 public static final void writeSetXml(Set val, String name, XmlSerializer out) 315 throws XmlPullParserException, IOException { 316 if (val == null) { 317 out.startTag(null, "null"); 318 out.endTag(null, "null"); 319 return; 320 } 321 322 out.startTag(null, "set"); 323 if (name != null) { 324 out.attribute(null, "name", name); 325 } 326 327 for (Object v : val) { 328 writeValueXml(v, null, out); 329 } 330 331 out.endTag(null, "set"); 332 } 333 334 /** 335 * Flatten a byte[] into an XmlSerializer. The list can later be read back 336 * with readThisByteArrayXml(). 337 * 338 * @param val The byte array to be flattened. 339 * @param name Name attribute to include with this array's tag, or null for 340 * none. 341 * @param out XmlSerializer to write the array into. 342 * 343 * @see #writeMapXml 344 * @see #writeValueXml 345 */ 346 public static final void writeByteArrayXml(byte[] val, String name, 347 XmlSerializer out) 348 throws XmlPullParserException, IOException { 349 350 if (val == null) { 351 out.startTag(null, "null"); 352 out.endTag(null, "null"); 353 return; 354 } 355 356 out.startTag(null, "byte-array"); 357 if (name != null) { 358 out.attribute(null, "name", name); 359 } 360 361 final int N = val.length; 362 out.attribute(null, "num", Integer.toString(N)); 363 364 StringBuilder sb = new StringBuilder(val.length*2); 365 for (int i=0; i<N; i++) { 366 int b = val[i]; 367 int h = b>>4; 368 sb.append(h >= 10 ? ('a'+h-10) : ('0'+h)); 369 h = b&0xff; 370 sb.append(h >= 10 ? ('a'+h-10) : ('0'+h)); 371 } 372 373 out.text(sb.toString()); 374 375 out.endTag(null, "byte-array"); 376 } 377 378 /** 379 * Flatten an int[] into an XmlSerializer. The list can later be read back 380 * with readThisIntArrayXml(). 381 * 382 * @param val The int array to be flattened. 383 * @param name Name attribute to include with this array's tag, or null for 384 * none. 385 * @param out XmlSerializer to write the array into. 386 * 387 * @see #writeMapXml 388 * @see #writeValueXml 389 * @see #readThisIntArrayXml 390 */ 391 public static final void writeIntArrayXml(int[] val, String name, 392 XmlSerializer out) 393 throws XmlPullParserException, IOException { 394 395 if (val == null) { 396 out.startTag(null, "null"); 397 out.endTag(null, "null"); 398 return; 399 } 400 401 out.startTag(null, "int-array"); 402 if (name != null) { 403 out.attribute(null, "name", name); 404 } 405 406 final int N = val.length; 407 out.attribute(null, "num", Integer.toString(N)); 408 409 for (int i=0; i<N; i++) { 410 out.startTag(null, "item"); 411 out.attribute(null, "value", Integer.toString(val[i])); 412 out.endTag(null, "item"); 413 } 414 415 out.endTag(null, "int-array"); 416 } 417 418 /** 419 * Flatten a long[] into an XmlSerializer. The list can later be read back 420 * with readThisLongArrayXml(). 421 * 422 * @param val The long array to be flattened. 423 * @param name Name attribute to include with this array's tag, or null for 424 * none. 425 * @param out XmlSerializer to write the array into. 426 * 427 * @see #writeMapXml 428 * @see #writeValueXml 429 * @see #readThisIntArrayXml 430 */ 431 public static final void writeLongArrayXml(long[] val, String name, XmlSerializer out) 432 throws XmlPullParserException, IOException { 433 434 if (val == null) { 435 out.startTag(null, "null"); 436 out.endTag(null, "null"); 437 return; 438 } 439 440 out.startTag(null, "long-array"); 441 if (name != null) { 442 out.attribute(null, "name", name); 443 } 444 445 final int N = val.length; 446 out.attribute(null, "num", Integer.toString(N)); 447 448 for (int i=0; i<N; i++) { 449 out.startTag(null, "item"); 450 out.attribute(null, "value", Long.toString(val[i])); 451 out.endTag(null, "item"); 452 } 453 454 out.endTag(null, "long-array"); 455 } 456 457 /** 458 * Flatten a double[] into an XmlSerializer. The list can later be read back 459 * with readThisDoubleArrayXml(). 460 * 461 * @param val The double array to be flattened. 462 * @param name Name attribute to include with this array's tag, or null for 463 * none. 464 * @param out XmlSerializer to write the array into. 465 * 466 * @see #writeMapXml 467 * @see #writeValueXml 468 * @see #readThisIntArrayXml 469 */ 470 public static final void writeDoubleArrayXml(double[] val, String name, XmlSerializer out) 471 throws XmlPullParserException, IOException { 472 473 if (val == null) { 474 out.startTag(null, "null"); 475 out.endTag(null, "null"); 476 return; 477 } 478 479 out.startTag(null, "double-array"); 480 if (name != null) { 481 out.attribute(null, "name", name); 482 } 483 484 final int N = val.length; 485 out.attribute(null, "num", Integer.toString(N)); 486 487 for (int i=0; i<N; i++) { 488 out.startTag(null, "item"); 489 out.attribute(null, "value", Double.toString(val[i])); 490 out.endTag(null, "item"); 491 } 492 493 out.endTag(null, "double-array"); 494 } 495 496 /** 497 * Flatten a String[] into an XmlSerializer. The list can later be read back 498 * with readThisStringArrayXml(). 499 * 500 * @param val The String array to be flattened. 501 * @param name Name attribute to include with this array's tag, or null for 502 * none. 503 * @param out XmlSerializer to write the array into. 504 * 505 * @see #writeMapXml 506 * @see #writeValueXml 507 * @see #readThisIntArrayXml 508 */ 509 public static final void writeStringArrayXml(String[] val, String name, XmlSerializer out) 510 throws XmlPullParserException, IOException { 511 512 if (val == null) { 513 out.startTag(null, "null"); 514 out.endTag(null, "null"); 515 return; 516 } 517 518 out.startTag(null, "string-array"); 519 if (name != null) { 520 out.attribute(null, "name", name); 521 } 522 523 final int N = val.length; 524 out.attribute(null, "num", Integer.toString(N)); 525 526 for (int i=0; i<N; i++) { 527 out.startTag(null, "item"); 528 out.attribute(null, "value", val[i]); 529 out.endTag(null, "item"); 530 } 531 532 out.endTag(null, "string-array"); 533 } 534 535 /** 536 * Flatten a boolean[] into an XmlSerializer. The list can later be read back 537 * with readThisBooleanArrayXml(). 538 * 539 * @param val The boolean array to be flattened. 540 * @param name Name attribute to include with this array's tag, or null for 541 * none. 542 * @param out XmlSerializer to write the array into. 543 * 544 * @see #writeMapXml 545 * @see #writeValueXml 546 * @see #readThisIntArrayXml 547 */ 548 public static final void writeBooleanArrayXml(boolean[] val, String name, XmlSerializer out) 549 throws XmlPullParserException, IOException { 550 551 if (val == null) { 552 out.startTag(null, "null"); 553 out.endTag(null, "null"); 554 return; 555 } 556 557 out.startTag(null, "boolean-array"); 558 if (name != null) { 559 out.attribute(null, "name", name); 560 } 561 562 final int N = val.length; 563 out.attribute(null, "num", Integer.toString(N)); 564 565 for (int i=0; i<N; i++) { 566 out.startTag(null, "item"); 567 out.attribute(null, "value", Boolean.toString(val[i])); 568 out.endTag(null, "item"); 569 } 570 571 out.endTag(null, "boolean-array"); 572 } 573 574 /** 575 * Flatten an object's value into an XmlSerializer. The value can later 576 * be read back with readThisValueXml(). 577 * 578 * Currently supported value types are: null, String, Integer, Long, 579 * Float, Double Boolean, Map, List. 580 * 581 * @param v The object to be flattened. 582 * @param name Name attribute to include with this value's tag, or null 583 * for none. 584 * @param out XmlSerializer to write the object into. 585 * 586 * @see #writeMapXml 587 * @see #writeListXml 588 * @see #readValueXml 589 */ 590 public static final void writeValueXml(Object v, String name, XmlSerializer out) 591 throws XmlPullParserException, IOException { 592 writeValueXml(v, name, out, null); 593 } 594 595 /** 596 * Flatten an object's value into an XmlSerializer. The value can later 597 * be read back with readThisValueXml(). 598 * 599 * Currently supported value types are: null, String, Integer, Long, 600 * Float, Double Boolean, Map, List. 601 * 602 * @param v The object to be flattened. 603 * @param name Name attribute to include with this value's tag, or null 604 * for none. 605 * @param out XmlSerializer to write the object into. 606 * @param callback Handler for Object types not recognized. 607 * 608 * @see #writeMapXml 609 * @see #writeListXml 610 * @see #readValueXml 611 */ 612 private static final void writeValueXml(Object v, String name, XmlSerializer out, 613 WriteMapCallback callback) throws XmlPullParserException, IOException { 614 String typeStr; 615 if (v == null) { 616 out.startTag(null, "null"); 617 if (name != null) { 618 out.attribute(null, "name", name); 619 } 620 out.endTag(null, "null"); 621 return; 622 } else if (v instanceof String) { 623 out.startTag(null, "string"); 624 if (name != null) { 625 out.attribute(null, "name", name); 626 } 627 out.text(v.toString()); 628 out.endTag(null, "string"); 629 return; 630 } else if (v instanceof Integer) { 631 typeStr = "int"; 632 } else if (v instanceof Long) { 633 typeStr = "long"; 634 } else if (v instanceof Float) { 635 typeStr = "float"; 636 } else if (v instanceof Double) { 637 typeStr = "double"; 638 } else if (v instanceof Boolean) { 639 typeStr = "boolean"; 640 } else if (v instanceof byte[]) { 641 writeByteArrayXml((byte[])v, name, out); 642 return; 643 } else if (v instanceof int[]) { 644 writeIntArrayXml((int[])v, name, out); 645 return; 646 } else if (v instanceof long[]) { 647 writeLongArrayXml((long[])v, name, out); 648 return; 649 } else if (v instanceof double[]) { 650 writeDoubleArrayXml((double[])v, name, out); 651 return; 652 } else if (v instanceof String[]) { 653 writeStringArrayXml((String[])v, name, out); 654 return; 655 } else if (v instanceof boolean[]) { 656 writeBooleanArrayXml((boolean[])v, name, out); 657 return; 658 } else if (v instanceof Map) { 659 writeMapXml((Map)v, name, out); 660 return; 661 } else if (v instanceof List) { 662 writeListXml((List) v, name, out); 663 return; 664 } else if (v instanceof Set) { 665 writeSetXml((Set) v, name, out); 666 return; 667 } else if (v instanceof CharSequence) { 668 // XXX This is to allow us to at least write something if 669 // we encounter styled text... but it means we will drop all 670 // of the styling information. :( 671 out.startTag(null, "string"); 672 if (name != null) { 673 out.attribute(null, "name", name); 674 } 675 out.text(v.toString()); 676 out.endTag(null, "string"); 677 return; 678 } else if (callback != null) { 679 callback.writeUnknownObject(v, name, out); 680 return; 681 } else { 682 throw new RuntimeException("writeValueXml: unable to write value " + v); 683 } 684 685 out.startTag(null, typeStr); 686 if (name != null) { 687 out.attribute(null, "name", name); 688 } 689 out.attribute(null, "value", v.toString()); 690 out.endTag(null, typeStr); 691 } 692 693 /** 694 * Read a HashMap from an InputStream containing XML. The stream can 695 * previously have been written by writeMapXml(). 696 * 697 * @param in The InputStream from which to read. 698 * 699 * @return HashMap The resulting map. 700 * 701 * @see #readListXml 702 * @see #readValueXml 703 * @see #readThisMapXml 704 * #see #writeMapXml 705 */ 706 @SuppressWarnings("unchecked") 707 public static final HashMap<String, ?> readMapXml(InputStream in) 708 throws XmlPullParserException, IOException 709 { 710 XmlPullParser parser = Xml.newPullParser(); 711 parser.setInput(in, StandardCharsets.UTF_8.name()); 712 return (HashMap<String, ?>) readValueXml(parser, new String[1]); 713 } 714 715 /** 716 * Read an ArrayList from an InputStream containing XML. The stream can 717 * previously have been written by writeListXml(). 718 * 719 * @param in The InputStream from which to read. 720 * 721 * @return ArrayList The resulting list. 722 * 723 * @see #readMapXml 724 * @see #readValueXml 725 * @see #readThisListXml 726 * @see #writeListXml 727 */ 728 public static final ArrayList readListXml(InputStream in) 729 throws XmlPullParserException, IOException 730 { 731 XmlPullParser parser = Xml.newPullParser(); 732 parser.setInput(in, StandardCharsets.UTF_8.name()); 733 return (ArrayList)readValueXml(parser, new String[1]); 734 } 735 736 737 /** 738 * Read a HashSet from an InputStream containing XML. The stream can 739 * previously have been written by writeSetXml(). 740 * 741 * @param in The InputStream from which to read. 742 * 743 * @return HashSet The resulting set. 744 * 745 * @throws XmlPullParserException 746 * @throws IOException 747 * 748 * @see #readValueXml 749 * @see #readThisSetXml 750 * @see #writeSetXml 751 */ 752 public static final HashSet readSetXml(InputStream in) 753 throws XmlPullParserException, IOException { 754 XmlPullParser parser = Xml.newPullParser(); 755 parser.setInput(in, null); 756 return (HashSet) readValueXml(parser, new String[1]); 757 } 758 759 /** 760 * Read a HashMap object from an XmlPullParser. The XML data could 761 * previously have been generated by writeMapXml(). The XmlPullParser 762 * must be positioned <em>after</em> the tag that begins the map. 763 * 764 * @param parser The XmlPullParser from which to read the map data. 765 * @param endTag Name of the tag that will end the map, usually "map". 766 * @param name An array of one string, used to return the name attribute 767 * of the map's tag. 768 * 769 * @return HashMap The newly generated map. 770 * 771 * @see #readMapXml 772 */ 773 public static final HashMap<String, ?> readThisMapXml(XmlPullParser parser, String endTag, 774 String[] name) throws XmlPullParserException, IOException { 775 return readThisMapXml(parser, endTag, name, null); 776 } 777 778 /** 779 * Read a HashMap object from an XmlPullParser. The XML data could 780 * previously have been generated by writeMapXml(). The XmlPullParser 781 * must be positioned <em>after</em> the tag that begins the map. 782 * 783 * @param parser The XmlPullParser from which to read the map data. 784 * @param endTag Name of the tag that will end the map, usually "map". 785 * @param name An array of one string, used to return the name attribute 786 * of the map's tag. 787 * 788 * @return HashMap The newly generated map. 789 * 790 * @see #readMapXml 791 * @hide 792 */ 793 public static final HashMap<String, ?> readThisMapXml(XmlPullParser parser, String endTag, 794 String[] name, ReadMapCallback callback) 795 throws XmlPullParserException, IOException 796 { 797 HashMap<String, Object> map = new HashMap<String, Object>(); 798 799 int eventType = parser.getEventType(); 800 do { 801 if (eventType == parser.START_TAG) { 802 Object val = readThisValueXml(parser, name, callback, false); 803 map.put(name[0], val); 804 } else if (eventType == parser.END_TAG) { 805 if (parser.getName().equals(endTag)) { 806 return map; 807 } 808 throw new XmlPullParserException( 809 "Expected " + endTag + " end tag at: " + parser.getName()); 810 } 811 eventType = parser.next(); 812 } while (eventType != parser.END_DOCUMENT); 813 814 throw new XmlPullParserException( 815 "Document ended before " + endTag + " end tag"); 816 } 817 818 /** 819 * Like {@link #readThisMapXml}, but returns an ArrayMap instead of HashMap. 820 * @hide 821 */ 822 public static final ArrayMap<String, ?> readThisArrayMapXml(XmlPullParser parser, String endTag, 823 String[] name, ReadMapCallback callback) 824 throws XmlPullParserException, IOException 825 { 826 ArrayMap<String, Object> map = new ArrayMap<>(); 827 828 int eventType = parser.getEventType(); 829 do { 830 if (eventType == parser.START_TAG) { 831 Object val = readThisValueXml(parser, name, callback, true); 832 map.put(name[0], val); 833 } else if (eventType == parser.END_TAG) { 834 if (parser.getName().equals(endTag)) { 835 return map; 836 } 837 throw new XmlPullParserException( 838 "Expected " + endTag + " end tag at: " + parser.getName()); 839 } 840 eventType = parser.next(); 841 } while (eventType != parser.END_DOCUMENT); 842 843 throw new XmlPullParserException( 844 "Document ended before " + endTag + " end tag"); 845 } 846 847 /** 848 * Read an ArrayList object from an XmlPullParser. The XML data could 849 * previously have been generated by writeListXml(). The XmlPullParser 850 * must be positioned <em>after</em> the tag that begins the list. 851 * 852 * @param parser The XmlPullParser from which to read the list data. 853 * @param endTag Name of the tag that will end the list, usually "list". 854 * @param name An array of one string, used to return the name attribute 855 * of the list's tag. 856 * 857 * @return HashMap The newly generated list. 858 * 859 * @see #readListXml 860 */ 861 public static final ArrayList readThisListXml(XmlPullParser parser, String endTag, 862 String[] name) throws XmlPullParserException, IOException { 863 return readThisListXml(parser, endTag, name, null, false); 864 } 865 866 /** 867 * Read an ArrayList object from an XmlPullParser. The XML data could 868 * previously have been generated by writeListXml(). The XmlPullParser 869 * must be positioned <em>after</em> the tag that begins the list. 870 * 871 * @param parser The XmlPullParser from which to read the list data. 872 * @param endTag Name of the tag that will end the list, usually "list". 873 * @param name An array of one string, used to return the name attribute 874 * of the list's tag. 875 * 876 * @return HashMap The newly generated list. 877 * 878 * @see #readListXml 879 */ 880 private static final ArrayList readThisListXml(XmlPullParser parser, String endTag, 881 String[] name, ReadMapCallback callback, boolean arrayMap) 882 throws XmlPullParserException, IOException { 883 ArrayList list = new ArrayList(); 884 885 int eventType = parser.getEventType(); 886 do { 887 if (eventType == parser.START_TAG) { 888 Object val = readThisValueXml(parser, name, callback, arrayMap); 889 list.add(val); 890 //System.out.println("Adding to list: " + val); 891 } else if (eventType == parser.END_TAG) { 892 if (parser.getName().equals(endTag)) { 893 return list; 894 } 895 throw new XmlPullParserException( 896 "Expected " + endTag + " end tag at: " + parser.getName()); 897 } 898 eventType = parser.next(); 899 } while (eventType != parser.END_DOCUMENT); 900 901 throw new XmlPullParserException( 902 "Document ended before " + endTag + " end tag"); 903 } 904 905 /** 906 * Read a HashSet object from an XmlPullParser. The XML data could previously 907 * have been generated by writeSetXml(). The XmlPullParser must be positioned 908 * <em>after</em> the tag that begins the set. 909 * 910 * @param parser The XmlPullParser from which to read the set data. 911 * @param endTag Name of the tag that will end the set, usually "set". 912 * @param name An array of one string, used to return the name attribute 913 * of the set's tag. 914 * 915 * @return HashSet The newly generated set. 916 * 917 * @throws XmlPullParserException 918 * @throws IOException 919 * 920 * @see #readSetXml 921 */ 922 public static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name) 923 throws XmlPullParserException, IOException { 924 return readThisSetXml(parser, endTag, name, null, false); 925 } 926 927 /** 928 * Read a HashSet object from an XmlPullParser. The XML data could previously 929 * have been generated by writeSetXml(). The XmlPullParser must be positioned 930 * <em>after</em> the tag that begins the set. 931 * 932 * @param parser The XmlPullParser from which to read the set data. 933 * @param endTag Name of the tag that will end the set, usually "set". 934 * @param name An array of one string, used to return the name attribute 935 * of the set's tag. 936 * 937 * @return HashSet The newly generated set. 938 * 939 * @throws XmlPullParserException 940 * @throws IOException 941 * 942 * @see #readSetXml 943 * @hide 944 */ 945 private static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name, 946 ReadMapCallback callback, boolean arrayMap) 947 throws XmlPullParserException, IOException { 948 HashSet set = new HashSet(); 949 950 int eventType = parser.getEventType(); 951 do { 952 if (eventType == parser.START_TAG) { 953 Object val = readThisValueXml(parser, name, callback, arrayMap); 954 set.add(val); 955 //System.out.println("Adding to set: " + val); 956 } else if (eventType == parser.END_TAG) { 957 if (parser.getName().equals(endTag)) { 958 return set; 959 } 960 throw new XmlPullParserException( 961 "Expected " + endTag + " end tag at: " + parser.getName()); 962 } 963 eventType = parser.next(); 964 } while (eventType != parser.END_DOCUMENT); 965 966 throw new XmlPullParserException( 967 "Document ended before " + endTag + " end tag"); 968 } 969 970 /** 971 * Read an int[] object from an XmlPullParser. The XML data could 972 * previously have been generated by writeIntArrayXml(). The XmlPullParser 973 * must be positioned <em>after</em> the tag that begins the list. 974 * 975 * @param parser The XmlPullParser from which to read the list data. 976 * @param endTag Name of the tag that will end the list, usually "list". 977 * @param name An array of one string, used to return the name attribute 978 * of the list's tag. 979 * 980 * @return Returns a newly generated int[]. 981 * 982 * @see #readListXml 983 */ 984 public static final int[] readThisIntArrayXml(XmlPullParser parser, 985 String endTag, String[] name) 986 throws XmlPullParserException, IOException { 987 988 int num; 989 try { 990 num = Integer.parseInt(parser.getAttributeValue(null, "num")); 991 } catch (NullPointerException e) { 992 throw new XmlPullParserException( 993 "Need num attribute in byte-array"); 994 } catch (NumberFormatException e) { 995 throw new XmlPullParserException( 996 "Not a number in num attribute in byte-array"); 997 } 998 parser.next(); 999 1000 int[] array = new int[num]; 1001 int i = 0; 1002 1003 int eventType = parser.getEventType(); 1004 do { 1005 if (eventType == parser.START_TAG) { 1006 if (parser.getName().equals("item")) { 1007 try { 1008 array[i] = Integer.parseInt( 1009 parser.getAttributeValue(null, "value")); 1010 } catch (NullPointerException e) { 1011 throw new XmlPullParserException( 1012 "Need value attribute in item"); 1013 } catch (NumberFormatException e) { 1014 throw new XmlPullParserException( 1015 "Not a number in value attribute in item"); 1016 } 1017 } else { 1018 throw new XmlPullParserException( 1019 "Expected item tag at: " + parser.getName()); 1020 } 1021 } else if (eventType == parser.END_TAG) { 1022 if (parser.getName().equals(endTag)) { 1023 return array; 1024 } else if (parser.getName().equals("item")) { 1025 i++; 1026 } else { 1027 throw new XmlPullParserException( 1028 "Expected " + endTag + " end tag at: " 1029 + parser.getName()); 1030 } 1031 } 1032 eventType = parser.next(); 1033 } while (eventType != parser.END_DOCUMENT); 1034 1035 throw new XmlPullParserException( 1036 "Document ended before " + endTag + " end tag"); 1037 } 1038 1039 /** 1040 * Read a long[] object from an XmlPullParser. The XML data could 1041 * previously have been generated by writeLongArrayXml(). The XmlPullParser 1042 * must be positioned <em>after</em> the tag that begins the list. 1043 * 1044 * @param parser The XmlPullParser from which to read the list data. 1045 * @param endTag Name of the tag that will end the list, usually "list". 1046 * @param name An array of one string, used to return the name attribute 1047 * of the list's tag. 1048 * 1049 * @return Returns a newly generated long[]. 1050 * 1051 * @see #readListXml 1052 */ 1053 public static final long[] readThisLongArrayXml(XmlPullParser parser, 1054 String endTag, String[] name) 1055 throws XmlPullParserException, IOException { 1056 1057 int num; 1058 try { 1059 num = Integer.parseInt(parser.getAttributeValue(null, "num")); 1060 } catch (NullPointerException e) { 1061 throw new XmlPullParserException("Need num attribute in long-array"); 1062 } catch (NumberFormatException e) { 1063 throw new XmlPullParserException("Not a number in num attribute in long-array"); 1064 } 1065 parser.next(); 1066 1067 long[] array = new long[num]; 1068 int i = 0; 1069 1070 int eventType = parser.getEventType(); 1071 do { 1072 if (eventType == parser.START_TAG) { 1073 if (parser.getName().equals("item")) { 1074 try { 1075 array[i] = Long.parseLong(parser.getAttributeValue(null, "value")); 1076 } catch (NullPointerException e) { 1077 throw new XmlPullParserException("Need value attribute in item"); 1078 } catch (NumberFormatException e) { 1079 throw new XmlPullParserException("Not a number in value attribute in item"); 1080 } 1081 } else { 1082 throw new XmlPullParserException("Expected item tag at: " + parser.getName()); 1083 } 1084 } else if (eventType == parser.END_TAG) { 1085 if (parser.getName().equals(endTag)) { 1086 return array; 1087 } else if (parser.getName().equals("item")) { 1088 i++; 1089 } else { 1090 throw new XmlPullParserException("Expected " + endTag + " end tag at: " + 1091 parser.getName()); 1092 } 1093 } 1094 eventType = parser.next(); 1095 } while (eventType != parser.END_DOCUMENT); 1096 1097 throw new XmlPullParserException("Document ended before " + endTag + " end tag"); 1098 } 1099 1100 /** 1101 * Read a double[] object from an XmlPullParser. The XML data could 1102 * previously have been generated by writeDoubleArrayXml(). The XmlPullParser 1103 * must be positioned <em>after</em> the tag that begins the list. 1104 * 1105 * @param parser The XmlPullParser from which to read the list data. 1106 * @param endTag Name of the tag that will end the list, usually "double-array". 1107 * @param name An array of one string, used to return the name attribute 1108 * of the list's tag. 1109 * 1110 * @return Returns a newly generated double[]. 1111 * 1112 * @see #readListXml 1113 */ 1114 public static final double[] readThisDoubleArrayXml(XmlPullParser parser, String endTag, 1115 String[] name) throws XmlPullParserException, IOException { 1116 1117 int num; 1118 try { 1119 num = Integer.parseInt(parser.getAttributeValue(null, "num")); 1120 } catch (NullPointerException e) { 1121 throw new XmlPullParserException("Need num attribute in double-array"); 1122 } catch (NumberFormatException e) { 1123 throw new XmlPullParserException("Not a number in num attribute in double-array"); 1124 } 1125 parser.next(); 1126 1127 double[] array = new double[num]; 1128 int i = 0; 1129 1130 int eventType = parser.getEventType(); 1131 do { 1132 if (eventType == parser.START_TAG) { 1133 if (parser.getName().equals("item")) { 1134 try { 1135 array[i] = Double.parseDouble(parser.getAttributeValue(null, "value")); 1136 } catch (NullPointerException e) { 1137 throw new XmlPullParserException("Need value attribute in item"); 1138 } catch (NumberFormatException e) { 1139 throw new XmlPullParserException("Not a number in value attribute in item"); 1140 } 1141 } else { 1142 throw new XmlPullParserException("Expected item tag at: " + parser.getName()); 1143 } 1144 } else if (eventType == parser.END_TAG) { 1145 if (parser.getName().equals(endTag)) { 1146 return array; 1147 } else if (parser.getName().equals("item")) { 1148 i++; 1149 } else { 1150 throw new XmlPullParserException("Expected " + endTag + " end tag at: " + 1151 parser.getName()); 1152 } 1153 } 1154 eventType = parser.next(); 1155 } while (eventType != parser.END_DOCUMENT); 1156 1157 throw new XmlPullParserException("Document ended before " + endTag + " end tag"); 1158 } 1159 1160 /** 1161 * Read a String[] object from an XmlPullParser. The XML data could 1162 * previously have been generated by writeStringArrayXml(). The XmlPullParser 1163 * must be positioned <em>after</em> the tag that begins the list. 1164 * 1165 * @param parser The XmlPullParser from which to read the list data. 1166 * @param endTag Name of the tag that will end the list, usually "string-array". 1167 * @param name An array of one string, used to return the name attribute 1168 * of the list's tag. 1169 * 1170 * @return Returns a newly generated String[]. 1171 * 1172 * @see #readListXml 1173 */ 1174 public static final String[] readThisStringArrayXml(XmlPullParser parser, String endTag, 1175 String[] name) throws XmlPullParserException, IOException { 1176 1177 int num; 1178 try { 1179 num = Integer.parseInt(parser.getAttributeValue(null, "num")); 1180 } catch (NullPointerException e) { 1181 throw new XmlPullParserException("Need num attribute in string-array"); 1182 } catch (NumberFormatException e) { 1183 throw new XmlPullParserException("Not a number in num attribute in string-array"); 1184 } 1185 parser.next(); 1186 1187 String[] array = new String[num]; 1188 int i = 0; 1189 1190 int eventType = parser.getEventType(); 1191 do { 1192 if (eventType == parser.START_TAG) { 1193 if (parser.getName().equals("item")) { 1194 try { 1195 array[i] = parser.getAttributeValue(null, "value"); 1196 } catch (NullPointerException e) { 1197 throw new XmlPullParserException("Need value attribute in item"); 1198 } catch (NumberFormatException e) { 1199 throw new XmlPullParserException("Not a number in value attribute in item"); 1200 } 1201 } else { 1202 throw new XmlPullParserException("Expected item tag at: " + parser.getName()); 1203 } 1204 } else if (eventType == parser.END_TAG) { 1205 if (parser.getName().equals(endTag)) { 1206 return array; 1207 } else if (parser.getName().equals("item")) { 1208 i++; 1209 } else { 1210 throw new XmlPullParserException("Expected " + endTag + " end tag at: " + 1211 parser.getName()); 1212 } 1213 } 1214 eventType = parser.next(); 1215 } while (eventType != parser.END_DOCUMENT); 1216 1217 throw new XmlPullParserException("Document ended before " + endTag + " end tag"); 1218 } 1219 1220 /** 1221 * Read a boolean[] object from an XmlPullParser. The XML data could 1222 * previously have been generated by writeBooleanArrayXml(). The XmlPullParser 1223 * must be positioned <em>after</em> the tag that begins the list. 1224 * 1225 * @param parser The XmlPullParser from which to read the list data. 1226 * @param endTag Name of the tag that will end the list, usually "string-array". 1227 * @param name An array of one string, used to return the name attribute 1228 * of the list's tag. 1229 * 1230 * @return Returns a newly generated boolean[]. 1231 * 1232 * @see #readListXml 1233 */ 1234 public static final boolean[] readThisBooleanArrayXml(XmlPullParser parser, String endTag, 1235 String[] name) throws XmlPullParserException, IOException { 1236 1237 int num; 1238 try { 1239 num = Integer.parseInt(parser.getAttributeValue(null, "num")); 1240 } catch (NullPointerException e) { 1241 throw new XmlPullParserException("Need num attribute in string-array"); 1242 } catch (NumberFormatException e) { 1243 throw new XmlPullParserException("Not a number in num attribute in string-array"); 1244 } 1245 parser.next(); 1246 1247 boolean[] array = new boolean[num]; 1248 int i = 0; 1249 1250 int eventType = parser.getEventType(); 1251 do { 1252 if (eventType == parser.START_TAG) { 1253 if (parser.getName().equals("item")) { 1254 try { 1255 array[i] = Boolean.valueOf(parser.getAttributeValue(null, "value")); 1256 } catch (NullPointerException e) { 1257 throw new XmlPullParserException("Need value attribute in item"); 1258 } catch (NumberFormatException e) { 1259 throw new XmlPullParserException("Not a number in value attribute in item"); 1260 } 1261 } else { 1262 throw new XmlPullParserException("Expected item tag at: " + parser.getName()); 1263 } 1264 } else if (eventType == parser.END_TAG) { 1265 if (parser.getName().equals(endTag)) { 1266 return array; 1267 } else if (parser.getName().equals("item")) { 1268 i++; 1269 } else { 1270 throw new XmlPullParserException("Expected " + endTag + " end tag at: " + 1271 parser.getName()); 1272 } 1273 } 1274 eventType = parser.next(); 1275 } while (eventType != parser.END_DOCUMENT); 1276 1277 throw new XmlPullParserException("Document ended before " + endTag + " end tag"); 1278 } 1279 1280 /** 1281 * Read a flattened object from an XmlPullParser. The XML data could 1282 * previously have been written with writeMapXml(), writeListXml(), or 1283 * writeValueXml(). The XmlPullParser must be positioned <em>at</em> the 1284 * tag that defines the value. 1285 * 1286 * @param parser The XmlPullParser from which to read the object. 1287 * @param name An array of one string, used to return the name attribute 1288 * of the value's tag. 1289 * 1290 * @return Object The newly generated value object. 1291 * 1292 * @see #readMapXml 1293 * @see #readListXml 1294 * @see #writeValueXml 1295 */ 1296 public static final Object readValueXml(XmlPullParser parser, String[] name) 1297 throws XmlPullParserException, IOException 1298 { 1299 int eventType = parser.getEventType(); 1300 do { 1301 if (eventType == parser.START_TAG) { 1302 return readThisValueXml(parser, name, null, false); 1303 } else if (eventType == parser.END_TAG) { 1304 throw new XmlPullParserException( 1305 "Unexpected end tag at: " + parser.getName()); 1306 } else if (eventType == parser.TEXT) { 1307 throw new XmlPullParserException( 1308 "Unexpected text: " + parser.getText()); 1309 } 1310 eventType = parser.next(); 1311 } while (eventType != parser.END_DOCUMENT); 1312 1313 throw new XmlPullParserException( 1314 "Unexpected end of document"); 1315 } 1316 1317 private static final Object readThisValueXml(XmlPullParser parser, String[] name, 1318 ReadMapCallback callback, boolean arrayMap) 1319 throws XmlPullParserException, IOException { 1320 final String valueName = parser.getAttributeValue(null, "name"); 1321 final String tagName = parser.getName(); 1322 1323 //System.out.println("Reading this value tag: " + tagName + ", name=" + valueName); 1324 1325 Object res; 1326 1327 if (tagName.equals("null")) { 1328 res = null; 1329 } else if (tagName.equals("string")) { 1330 String value = ""; 1331 int eventType; 1332 while ((eventType = parser.next()) != parser.END_DOCUMENT) { 1333 if (eventType == parser.END_TAG) { 1334 if (parser.getName().equals("string")) { 1335 name[0] = valueName; 1336 //System.out.println("Returning value for " + valueName + ": " + value); 1337 return value; 1338 } 1339 throw new XmlPullParserException( 1340 "Unexpected end tag in <string>: " + parser.getName()); 1341 } else if (eventType == parser.TEXT) { 1342 value += parser.getText(); 1343 } else if (eventType == parser.START_TAG) { 1344 throw new XmlPullParserException( 1345 "Unexpected start tag in <string>: " + parser.getName()); 1346 } 1347 } 1348 throw new XmlPullParserException( 1349 "Unexpected end of document in <string>"); 1350 } else if ((res = readThisPrimitiveValueXml(parser, tagName)) != null) { 1351 // all work already done by readThisPrimitiveValueXml 1352 } else if (tagName.equals("int-array")) { 1353 res = readThisIntArrayXml(parser, "int-array", name); 1354 name[0] = valueName; 1355 //System.out.println("Returning value for " + valueName + ": " + res); 1356 return res; 1357 } else if (tagName.equals("long-array")) { 1358 res = readThisLongArrayXml(parser, "long-array", name); 1359 name[0] = valueName; 1360 //System.out.println("Returning value for " + valueName + ": " + res); 1361 return res; 1362 } else if (tagName.equals("double-array")) { 1363 res = readThisDoubleArrayXml(parser, "double-array", name); 1364 name[0] = valueName; 1365 //System.out.println("Returning value for " + valueName + ": " + res); 1366 return res; 1367 } else if (tagName.equals("string-array")) { 1368 res = readThisStringArrayXml(parser, "string-array", name); 1369 name[0] = valueName; 1370 //System.out.println("Returning value for " + valueName + ": " + res); 1371 return res; 1372 } else if (tagName.equals("boolean-array")) { 1373 res = readThisBooleanArrayXml(parser, "boolean-array", name); 1374 name[0] = valueName; 1375 //System.out.println("Returning value for " + valueName + ": " + res); 1376 return res; 1377 } else if (tagName.equals("map")) { 1378 parser.next(); 1379 res = arrayMap 1380 ? readThisArrayMapXml(parser, "map", name, callback) 1381 : readThisMapXml(parser, "map", name, callback); 1382 name[0] = valueName; 1383 //System.out.println("Returning value for " + valueName + ": " + res); 1384 return res; 1385 } else if (tagName.equals("list")) { 1386 parser.next(); 1387 res = readThisListXml(parser, "list", name, callback, arrayMap); 1388 name[0] = valueName; 1389 //System.out.println("Returning value for " + valueName + ": " + res); 1390 return res; 1391 } else if (tagName.equals("set")) { 1392 parser.next(); 1393 res = readThisSetXml(parser, "set", name, callback, arrayMap); 1394 name[0] = valueName; 1395 //System.out.println("Returning value for " + valueName + ": " + res); 1396 return res; 1397 } else if (callback != null) { 1398 res = callback.readThisUnknownObjectXml(parser, tagName); 1399 name[0] = valueName; 1400 return res; 1401 } else { 1402 throw new XmlPullParserException("Unknown tag: " + tagName); 1403 } 1404 1405 // Skip through to end tag. 1406 int eventType; 1407 while ((eventType = parser.next()) != parser.END_DOCUMENT) { 1408 if (eventType == parser.END_TAG) { 1409 if (parser.getName().equals(tagName)) { 1410 name[0] = valueName; 1411 //System.out.println("Returning value for " + valueName + ": " + res); 1412 return res; 1413 } 1414 throw new XmlPullParserException( 1415 "Unexpected end tag in <" + tagName + ">: " + parser.getName()); 1416 } else if (eventType == parser.TEXT) { 1417 throw new XmlPullParserException( 1418 "Unexpected text in <" + tagName + ">: " + parser.getName()); 1419 } else if (eventType == parser.START_TAG) { 1420 throw new XmlPullParserException( 1421 "Unexpected start tag in <" + tagName + ">: " + parser.getName()); 1422 } 1423 } 1424 throw new XmlPullParserException( 1425 "Unexpected end of document in <" + tagName + ">"); 1426 } 1427 1428 private static final Object readThisPrimitiveValueXml(XmlPullParser parser, String tagName) 1429 throws XmlPullParserException, IOException 1430 { 1431 try { 1432 if (tagName.equals("int")) { 1433 return Integer.parseInt(parser.getAttributeValue(null, "value")); 1434 } else if (tagName.equals("long")) { 1435 return Long.valueOf(parser.getAttributeValue(null, "value")); 1436 } else if (tagName.equals("float")) { 1437 return new Float(parser.getAttributeValue(null, "value")); 1438 } else if (tagName.equals("double")) { 1439 return new Double(parser.getAttributeValue(null, "value")); 1440 } else if (tagName.equals("boolean")) { 1441 return Boolean.valueOf(parser.getAttributeValue(null, "value")); 1442 } else { 1443 return null; 1444 } 1445 } catch (NullPointerException e) { 1446 throw new XmlPullParserException("Need value attribute in <" + tagName + ">"); 1447 } catch (NumberFormatException e) { 1448 throw new XmlPullParserException( 1449 "Not a number in value attribute in <" + tagName + ">"); 1450 } 1451 } 1452 1453 public static final void beginDocument(XmlPullParser parser, String firstElementName) throws XmlPullParserException, IOException 1454 { 1455 int type; 1456 while ((type=parser.next()) != parser.START_TAG 1457 && type != parser.END_DOCUMENT) { 1458 ; 1459 } 1460 1461 if (type != parser.START_TAG) { 1462 throw new XmlPullParserException("No start tag found"); 1463 } 1464 1465 if (!parser.getName().equals(firstElementName)) { 1466 throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() + 1467 ", expected " + firstElementName); 1468 } 1469 } 1470 1471 public static final void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException 1472 { 1473 int type; 1474 while ((type=parser.next()) != parser.START_TAG 1475 && type != parser.END_DOCUMENT) { 1476 ; 1477 } 1478 } 1479 1480 public static boolean nextElementWithin(XmlPullParser parser, int outerDepth) 1481 throws IOException, XmlPullParserException { 1482 for (;;) { 1483 int type = parser.next(); 1484 if (type == XmlPullParser.END_DOCUMENT 1485 || (type == XmlPullParser.END_TAG && parser.getDepth() == outerDepth)) { 1486 return false; 1487 } 1488 if (type == XmlPullParser.START_TAG 1489 && parser.getDepth() == outerDepth + 1) { 1490 return true; 1491 } 1492 } 1493 } 1494 1495 public static int readIntAttribute(XmlPullParser in, String name, int defaultValue) { 1496 final String value = in.getAttributeValue(null, name); 1497 try { 1498 return Integer.parseInt(value); 1499 } catch (NumberFormatException e) { 1500 return defaultValue; 1501 } 1502 } 1503 1504 public static int readIntAttribute(XmlPullParser in, String name) throws IOException { 1505 final String value = in.getAttributeValue(null, name); 1506 try { 1507 return Integer.parseInt(value); 1508 } catch (NumberFormatException e) { 1509 throw new ProtocolException("problem parsing " + name + "=" + value + " as int"); 1510 } 1511 } 1512 1513 public static void writeIntAttribute(XmlSerializer out, String name, int value) 1514 throws IOException { 1515 out.attribute(null, name, Integer.toString(value)); 1516 } 1517 1518 public static long readLongAttribute(XmlPullParser in, String name, long defaultValue) { 1519 final String value = in.getAttributeValue(null, name); 1520 try { 1521 return Long.parseLong(value); 1522 } catch (NumberFormatException e) { 1523 return defaultValue; 1524 } 1525 } 1526 1527 public static long readLongAttribute(XmlPullParser in, String name) throws IOException { 1528 final String value = in.getAttributeValue(null, name); 1529 try { 1530 return Long.parseLong(value); 1531 } catch (NumberFormatException e) { 1532 throw new ProtocolException("problem parsing " + name + "=" + value + " as long"); 1533 } 1534 } 1535 1536 public static void writeLongAttribute(XmlSerializer out, String name, long value) 1537 throws IOException { 1538 out.attribute(null, name, Long.toString(value)); 1539 } 1540 1541 public static float readFloatAttribute(XmlPullParser in, String name) throws IOException { 1542 final String value = in.getAttributeValue(null, name); 1543 try { 1544 return Float.parseFloat(value); 1545 } catch (NumberFormatException e) { 1546 throw new ProtocolException("problem parsing " + name + "=" + value + " as long"); 1547 } 1548 } 1549 1550 public static void writeFloatAttribute(XmlSerializer out, String name, float value) 1551 throws IOException { 1552 out.attribute(null, name, Float.toString(value)); 1553 } 1554 1555 public static boolean readBooleanAttribute(XmlPullParser in, String name) { 1556 final String value = in.getAttributeValue(null, name); 1557 return Boolean.parseBoolean(value); 1558 } 1559 1560 public static boolean readBooleanAttribute(XmlPullParser in, String name, 1561 boolean defaultValue) { 1562 final String value = in.getAttributeValue(null, name); 1563 if (value == null) { 1564 return defaultValue; 1565 } else { 1566 return Boolean.parseBoolean(value); 1567 } 1568 } 1569 1570 public static void writeBooleanAttribute(XmlSerializer out, String name, boolean value) 1571 throws IOException { 1572 out.attribute(null, name, Boolean.toString(value)); 1573 } 1574 1575 public static Uri readUriAttribute(XmlPullParser in, String name) { 1576 final String value = in.getAttributeValue(null, name); 1577 return (value != null) ? Uri.parse(value) : null; 1578 } 1579 1580 public static void writeUriAttribute(XmlSerializer out, String name, Uri value) 1581 throws IOException { 1582 if (value != null) { 1583 out.attribute(null, name, value.toString()); 1584 } 1585 } 1586 1587 public static String readStringAttribute(XmlPullParser in, String name) { 1588 return in.getAttributeValue(null, name); 1589 } 1590 1591 public static void writeStringAttribute(XmlSerializer out, String name, String value) 1592 throws IOException { 1593 if (value != null) { 1594 out.attribute(null, name, value); 1595 } 1596 } 1597 1598 public static byte[] readByteArrayAttribute(XmlPullParser in, String name) { 1599 final String value = in.getAttributeValue(null, name); 1600 if (value != null) { 1601 return Base64.decode(value, Base64.DEFAULT); 1602 } else { 1603 return null; 1604 } 1605 } 1606 1607 public static void writeByteArrayAttribute(XmlSerializer out, String name, byte[] value) 1608 throws IOException { 1609 if (value != null) { 1610 out.attribute(null, name, Base64.encodeToString(value, Base64.DEFAULT)); 1611 } 1612 } 1613 1614 public static Bitmap readBitmapAttribute(XmlPullParser in, String name) { 1615 final byte[] value = readByteArrayAttribute(in, name); 1616 if (value != null) { 1617 return BitmapFactory.decodeByteArray(value, 0, value.length); 1618 } else { 1619 return null; 1620 } 1621 } 1622 1623 @Deprecated 1624 public static void writeBitmapAttribute(XmlSerializer out, String name, Bitmap value) 1625 throws IOException { 1626 if (value != null) { 1627 final ByteArrayOutputStream os = new ByteArrayOutputStream(); 1628 value.compress(CompressFormat.PNG, 90, os); 1629 writeByteArrayAttribute(out, name, os.toByteArray()); 1630 } 1631 } 1632 1633 /** @hide */ 1634 public interface WriteMapCallback { 1635 /** 1636 * Called from writeMapXml when an Object type is not recognized. The implementer 1637 * must write out the entire element including start and end tags. 1638 * 1639 * @param v The object to be written out 1640 * @param name The mapping key for v. Must be written into the "name" attribute of the 1641 * start tag. 1642 * @param out The XML output stream. 1643 * @throws XmlPullParserException on unrecognized Object type. 1644 * @throws IOException on XmlSerializer serialization errors. 1645 * @hide 1646 */ 1647 public void writeUnknownObject(Object v, String name, XmlSerializer out) 1648 throws XmlPullParserException, IOException; 1649 } 1650 1651 /** @hide */ 1652 public interface ReadMapCallback { 1653 /** 1654 * Called from readThisMapXml when a START_TAG is not recognized. The input stream 1655 * is positioned within the start tag so that attributes can be read using in.getAttribute. 1656 * 1657 * @param in the XML input stream 1658 * @param tag the START_TAG that was not recognized. 1659 * @return the Object parsed from the stream which will be put into the map. 1660 * @throws XmlPullParserException if the START_TAG is not recognized. 1661 * @throws IOException on XmlPullParser serialization errors. 1662 * @hide 1663 */ 1664 public Object readThisUnknownObjectXml(XmlPullParser in, String tag) 1665 throws XmlPullParserException, IOException; 1666 } 1667 } 1668