Parcel.java revision 6aff905048ba3b03724f17e2aba9089872e14cd2
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 android.os; 18 19import android.text.TextUtils; 20import android.util.Log; 21import android.util.SparseArray; 22import android.util.SparseBooleanArray; 23 24import java.io.ByteArrayInputStream; 25import java.io.ByteArrayOutputStream; 26import java.io.FileDescriptor; 27import java.io.FileNotFoundException; 28import java.io.IOException; 29import java.io.ObjectInputStream; 30import java.io.ObjectOutputStream; 31import java.io.Serializable; 32import java.lang.reflect.Field; 33import java.util.ArrayList; 34import java.util.HashMap; 35import java.util.List; 36import java.util.Map; 37import java.util.Set; 38 39/** 40 * Container for a message (data and object references) that can 41 * be sent through an IBinder. A Parcel can contain both flattened data 42 * that will be unflattened on the other side of the IPC (using the various 43 * methods here for writing specific types, or the general 44 * {@link Parcelable} interface), and references to live {@link IBinder} 45 * objects that will result in the other side receiving a proxy IBinder 46 * connected with the original IBinder in the Parcel. 47 * 48 * <p class="note">Parcel is <strong>not</strong> a general-purpose 49 * serialization mechanism. This class (and the corresponding 50 * {@link Parcelable} API for placing arbitrary objects into a Parcel) is 51 * designed as a high-performance IPC transport. As such, it is not 52 * appropriate to place any Parcel data in to persistent storage: changes 53 * in the underlying implementation of any of the data in the Parcel can 54 * render older data unreadable.</p> 55 * 56 * <p>The bulk of the Parcel API revolves around reading and writing data 57 * of various types. There are six major classes of such functions available.</p> 58 * 59 * <h3>Primitives</h3> 60 * 61 * <p>The most basic data functions are for writing and reading primitive 62 * data types: {@link #writeByte}, {@link #readByte}, {@link #writeDouble}, 63 * {@link #readDouble}, {@link #writeFloat}, {@link #readFloat}, {@link #writeInt}, 64 * {@link #readInt}, {@link #writeLong}, {@link #readLong}, 65 * {@link #writeString}, {@link #readString}. Most other 66 * data operations are built on top of these. The given data is written and 67 * read using the endianess of the host CPU.</p> 68 * 69 * <h3>Primitive Arrays</h3> 70 * 71 * <p>There are a variety of methods for reading and writing raw arrays 72 * of primitive objects, which generally result in writing a 4-byte length 73 * followed by the primitive data items. The methods for reading can either 74 * read the data into an existing array, or create and return a new array. 75 * These available types are:</p> 76 * 77 * <ul> 78 * <li> {@link #writeBooleanArray(boolean[])}, 79 * {@link #readBooleanArray(boolean[])}, {@link #createBooleanArray()} 80 * <li> {@link #writeByteArray(byte[])}, 81 * {@link #writeByteArray(byte[], int, int)}, {@link #readByteArray(byte[])}, 82 * {@link #createByteArray()} 83 * <li> {@link #writeCharArray(char[])}, {@link #readCharArray(char[])}, 84 * {@link #createCharArray()} 85 * <li> {@link #writeDoubleArray(double[])}, {@link #readDoubleArray(double[])}, 86 * {@link #createDoubleArray()} 87 * <li> {@link #writeFloatArray(float[])}, {@link #readFloatArray(float[])}, 88 * {@link #createFloatArray()} 89 * <li> {@link #writeIntArray(int[])}, {@link #readIntArray(int[])}, 90 * {@link #createIntArray()} 91 * <li> {@link #writeLongArray(long[])}, {@link #readLongArray(long[])}, 92 * {@link #createLongArray()} 93 * <li> {@link #writeStringArray(String[])}, {@link #readStringArray(String[])}, 94 * {@link #createStringArray()}. 95 * <li> {@link #writeSparseBooleanArray(SparseBooleanArray)}, 96 * {@link #readSparseBooleanArray()}. 97 * </ul> 98 * 99 * <h3>Parcelables</h3> 100 * 101 * <p>The {@link Parcelable} protocol provides an extremely efficient (but 102 * low-level) protocol for objects to write and read themselves from Parcels. 103 * You can use the direct methods {@link #writeParcelable(Parcelable, int)} 104 * and {@link #readParcelable(ClassLoader)} or 105 * {@link #writeParcelableArray} and 106 * {@link #readParcelableArray(ClassLoader)} to write or read. These 107 * methods write both the class type and its data to the Parcel, allowing 108 * that class to be reconstructed from the appropriate class loader when 109 * later reading.</p> 110 * 111 * <p>There are also some methods that provide a more efficient way to work 112 * with Parcelables: {@link #writeTypedArray}, 113 * {@link #writeTypedList(List)}, 114 * {@link #readTypedArray} and {@link #readTypedList}. These methods 115 * do not write the class information of the original object: instead, the 116 * caller of the read function must know what type to expect and pass in the 117 * appropriate {@link Parcelable.Creator Parcelable.Creator} instead to 118 * properly construct the new object and read its data. (To more efficient 119 * write and read a single Parceable object, you can directly call 120 * {@link Parcelable#writeToParcel Parcelable.writeToParcel} and 121 * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel} 122 * yourself.)</p> 123 * 124 * <h3>Bundles</h3> 125 * 126 * <p>A special type-safe container, called {@link Bundle}, is available 127 * for key/value maps of heterogeneous values. This has many optimizations 128 * for improved performance when reading and writing data, and its type-safe 129 * API avoids difficult to debug type errors when finally marshalling the 130 * data contents into a Parcel. The methods to use are 131 * {@link #writeBundle(Bundle)}, {@link #readBundle()}, and 132 * {@link #readBundle(ClassLoader)}. 133 * 134 * <h3>Active Objects</h3> 135 * 136 * <p>An unusual feature of Parcel is the ability to read and write active 137 * objects. For these objects the actual contents of the object is not 138 * written, rather a special token referencing the object is written. When 139 * reading the object back from the Parcel, you do not get a new instance of 140 * the object, but rather a handle that operates on the exact same object that 141 * was originally written. There are two forms of active objects available.</p> 142 * 143 * <p>{@link Binder} objects are a core facility of Android's general cross-process 144 * communication system. The {@link IBinder} interface describes an abstract 145 * protocol with a Binder object. Any such interface can be written in to 146 * a Parcel, and upon reading you will receive either the original object 147 * implementing that interface or a special proxy implementation 148 * that communicates calls back to the original object. The methods to use are 149 * {@link #writeStrongBinder(IBinder)}, 150 * {@link #writeStrongInterface(IInterface)}, {@link #readStrongBinder()}, 151 * {@link #writeBinderArray(IBinder[])}, {@link #readBinderArray(IBinder[])}, 152 * {@link #createBinderArray()}, 153 * {@link #writeBinderList(List)}, {@link #readBinderList(List)}, 154 * {@link #createBinderArrayList()}.</p> 155 * 156 * <p>FileDescriptor objects, representing raw Linux file descriptor identifiers, 157 * can be written and {@link ParcelFileDescriptor} objects returned to operate 158 * on the original file descriptor. The returned file descriptor is a dup 159 * of the original file descriptor: the object and fd is different, but 160 * operating on the same underlying file stream, with the same position, etc. 161 * The methods to use are {@link #writeFileDescriptor(FileDescriptor)}, 162 * {@link #readFileDescriptor()}. 163 * 164 * <h3>Untyped Containers</h3> 165 * 166 * <p>A final class of methods are for writing and reading standard Java 167 * containers of arbitrary types. These all revolve around the 168 * {@link #writeValue(Object)} and {@link #readValue(ClassLoader)} methods 169 * which define the types of objects allowed. The container methods are 170 * {@link #writeArray(Object[])}, {@link #readArray(ClassLoader)}, 171 * {@link #writeList(List)}, {@link #readList(List, ClassLoader)}, 172 * {@link #readArrayList(ClassLoader)}, 173 * {@link #writeMap(Map)}, {@link #readMap(Map, ClassLoader)}, 174 * {@link #writeSparseArray(SparseArray)}, 175 * {@link #readSparseArray(ClassLoader)}. 176 */ 177public final class Parcel { 178 private static final boolean DEBUG_RECYCLE = false; 179 180 @SuppressWarnings({"UnusedDeclaration"}) 181 private int mObject; // used by native code 182 @SuppressWarnings({"UnusedDeclaration"}) 183 private int mOwnObject; // used by native code 184 private RuntimeException mStack; 185 186 private static final int POOL_SIZE = 6; 187 private static final Parcel[] sOwnedPool = new Parcel[POOL_SIZE]; 188 private static final Parcel[] sHolderPool = new Parcel[POOL_SIZE]; 189 190 private static final int VAL_NULL = -1; 191 private static final int VAL_STRING = 0; 192 private static final int VAL_INTEGER = 1; 193 private static final int VAL_MAP = 2; 194 private static final int VAL_BUNDLE = 3; 195 private static final int VAL_PARCELABLE = 4; 196 private static final int VAL_SHORT = 5; 197 private static final int VAL_LONG = 6; 198 private static final int VAL_FLOAT = 7; 199 private static final int VAL_DOUBLE = 8; 200 private static final int VAL_BOOLEAN = 9; 201 private static final int VAL_CHARSEQUENCE = 10; 202 private static final int VAL_LIST = 11; 203 private static final int VAL_SPARSEARRAY = 12; 204 private static final int VAL_BYTEARRAY = 13; 205 private static final int VAL_STRINGARRAY = 14; 206 private static final int VAL_IBINDER = 15; 207 private static final int VAL_PARCELABLEARRAY = 16; 208 private static final int VAL_OBJECTARRAY = 17; 209 private static final int VAL_INTARRAY = 18; 210 private static final int VAL_LONGARRAY = 19; 211 private static final int VAL_BYTE = 20; 212 private static final int VAL_SERIALIZABLE = 21; 213 private static final int VAL_SPARSEBOOLEANARRAY = 22; 214 private static final int VAL_BOOLEANARRAY = 23; 215 216 private static final int EX_SECURITY = -1; 217 private static final int EX_BAD_PARCELABLE = -2; 218 private static final int EX_ILLEGAL_ARGUMENT = -3; 219 private static final int EX_NULL_POINTER = -4; 220 private static final int EX_ILLEGAL_STATE = -5; 221 222 public final static Parcelable.Creator<String> STRING_CREATOR 223 = new Parcelable.Creator<String>() { 224 public String createFromParcel(Parcel source) { 225 return source.readString(); 226 } 227 public String[] newArray(int size) { 228 return new String[size]; 229 } 230 }; 231 232 /** 233 * Retrieve a new Parcel object from the pool. 234 */ 235 public static Parcel obtain() { 236 final Parcel[] pool = sOwnedPool; 237 synchronized (pool) { 238 Parcel p; 239 for (int i=0; i<POOL_SIZE; i++) { 240 p = pool[i]; 241 if (p != null) { 242 pool[i] = null; 243 if (DEBUG_RECYCLE) { 244 p.mStack = new RuntimeException(); 245 } 246 return p; 247 } 248 } 249 } 250 return new Parcel(0); 251 } 252 253 /** 254 * Put a Parcel object back into the pool. You must not touch 255 * the object after this call. 256 */ 257 public final void recycle() { 258 if (DEBUG_RECYCLE) mStack = null; 259 freeBuffer(); 260 final Parcel[] pool = mOwnObject != 0 ? sOwnedPool : sHolderPool; 261 synchronized (pool) { 262 for (int i=0; i<POOL_SIZE; i++) { 263 if (pool[i] == null) { 264 pool[i] = this; 265 return; 266 } 267 } 268 } 269 } 270 271 /** 272 * Returns the total amount of data contained in the parcel. 273 */ 274 public final native int dataSize(); 275 276 /** 277 * Returns the amount of data remaining to be read from the 278 * parcel. That is, {@link #dataSize}-{@link #dataPosition}. 279 */ 280 public final native int dataAvail(); 281 282 /** 283 * Returns the current position in the parcel data. Never 284 * more than {@link #dataSize}. 285 */ 286 public final native int dataPosition(); 287 288 /** 289 * Returns the total amount of space in the parcel. This is always 290 * >= {@link #dataSize}. The difference between it and dataSize() is the 291 * amount of room left until the parcel needs to re-allocate its 292 * data buffer. 293 */ 294 public final native int dataCapacity(); 295 296 /** 297 * Change the amount of data in the parcel. Can be either smaller or 298 * larger than the current size. If larger than the current capacity, 299 * more memory will be allocated. 300 * 301 * @param size The new number of bytes in the Parcel. 302 */ 303 public final native void setDataSize(int size); 304 305 /** 306 * Move the current read/write position in the parcel. 307 * @param pos New offset in the parcel; must be between 0 and 308 * {@link #dataSize}. 309 */ 310 public final native void setDataPosition(int pos); 311 312 /** 313 * Change the capacity (current available space) of the parcel. 314 * 315 * @param size The new capacity of the parcel, in bytes. Can not be 316 * less than {@link #dataSize} -- that is, you can not drop existing data 317 * with this method. 318 */ 319 public final native void setDataCapacity(int size); 320 321 /** 322 * Returns the raw bytes of the parcel. 323 * 324 * <p class="note">The data you retrieve here <strong>must not</strong> 325 * be placed in any kind of persistent storage (on local disk, across 326 * a network, etc). For that, you should use standard serialization 327 * or another kind of general serialization mechanism. The Parcel 328 * marshalled representation is highly optimized for local IPC, and as 329 * such does not attempt to maintain compatibility with data created 330 * in different versions of the platform. 331 */ 332 public final native byte[] marshall(); 333 334 /** 335 * Set the bytes in data to be the raw bytes of this Parcel. 336 */ 337 public final native void unmarshall(byte[] data, int offest, int length); 338 339 public final native void appendFrom(Parcel parcel, int offset, int length); 340 341 /** 342 * Report whether the parcel contains any marshalled file descriptors. 343 */ 344 public final native boolean hasFileDescriptors(); 345 346 /** 347 * Store or read an IBinder interface token in the parcel at the current 348 * {@link #dataPosition}. This is used to validate that the marshalled 349 * transaction is intended for the target interface. 350 */ 351 public final native void writeInterfaceToken(String interfaceName); 352 public final native void enforceInterface(String interfaceName); 353 354 /** 355 * Write a byte array into the parcel at the current {#link #dataPosition}, 356 * growing {@link #dataCapacity} if needed. 357 * @param b Bytes to place into the parcel. 358 */ 359 public final void writeByteArray(byte[] b) { 360 writeByteArray(b, 0, (b != null) ? b.length : 0); 361 } 362 363 /** 364 * Write an byte array into the parcel at the current {#link #dataPosition}, 365 * growing {@link #dataCapacity} if needed. 366 * @param b Bytes to place into the parcel. 367 * @param offset Index of first byte to be written. 368 * @param len Number of bytes to write. 369 */ 370 public final void writeByteArray(byte[] b, int offset, int len) { 371 if (b == null) { 372 writeInt(-1); 373 return; 374 } 375 if (b.length < offset + len || len < 0 || offset < 0) { 376 throw new ArrayIndexOutOfBoundsException(); 377 } 378 writeNative(b, offset, len); 379 } 380 381 private native void writeNative(byte[] b, int offset, int len); 382 383 /** 384 * Write an integer value into the parcel at the current dataPosition(), 385 * growing dataCapacity() if needed. 386 */ 387 public final native void writeInt(int val); 388 389 /** 390 * Write a long integer value into the parcel at the current dataPosition(), 391 * growing dataCapacity() if needed. 392 */ 393 public final native void writeLong(long val); 394 395 /** 396 * Write a floating point value into the parcel at the current 397 * dataPosition(), growing dataCapacity() if needed. 398 */ 399 public final native void writeFloat(float val); 400 401 /** 402 * Write a double precision floating point value into the parcel at the 403 * current dataPosition(), growing dataCapacity() if needed. 404 */ 405 public final native void writeDouble(double val); 406 407 /** 408 * Write a string value into the parcel at the current dataPosition(), 409 * growing dataCapacity() if needed. 410 */ 411 public final native void writeString(String val); 412 413 /** 414 * Write an object into the parcel at the current dataPosition(), 415 * growing dataCapacity() if needed. 416 */ 417 public final native void writeStrongBinder(IBinder val); 418 419 /** 420 * Write an object into the parcel at the current dataPosition(), 421 * growing dataCapacity() if needed. 422 */ 423 public final void writeStrongInterface(IInterface val) { 424 writeStrongBinder(val == null ? null : val.asBinder()); 425 } 426 427 /** 428 * Write a FileDescriptor into the parcel at the current dataPosition(), 429 * growing dataCapacity() if needed. 430 */ 431 public final native void writeFileDescriptor(FileDescriptor val); 432 433 /** 434 * Write an byte value into the parcel at the current dataPosition(), 435 * growing dataCapacity() if needed. 436 */ 437 public final void writeByte(byte val) { 438 writeInt(val); 439 } 440 441 /** 442 * Please use {@link #writeBundle} instead. Flattens a Map into the parcel 443 * at the current dataPosition(), 444 * growing dataCapacity() if needed. The Map keys must be String objects. 445 * The Map values are written using {@link #writeValue} and must follow 446 * the specification there. 447 * 448 * <p>It is strongly recommended to use {@link #writeBundle} instead of 449 * this method, since the Bundle class provides a type-safe API that 450 * allows you to avoid mysterious type errors at the point of marshalling. 451 */ 452 public final void writeMap(Map val) { 453 writeMapInternal((Map<String,Object>) val); 454 } 455 456 /** 457 * Flatten a Map into the parcel at the current dataPosition(), 458 * growing dataCapacity() if needed. The Map keys must be String objects. 459 */ 460 /* package */ void writeMapInternal(Map<String,Object> val) { 461 if (val == null) { 462 writeInt(-1); 463 return; 464 } 465 Set<Map.Entry<String,Object>> entries = val.entrySet(); 466 writeInt(entries.size()); 467 for (Map.Entry<String,Object> e : entries) { 468 writeValue(e.getKey()); 469 writeValue(e.getValue()); 470 } 471 } 472 473 /** 474 * Flatten a Bundle into the parcel at the current dataPosition(), 475 * growing dataCapacity() if needed. 476 */ 477 public final void writeBundle(Bundle val) { 478 if (val == null) { 479 writeInt(-1); 480 return; 481 } 482 483 val.writeToParcel(this, 0); 484 } 485 486 /** 487 * Flatten a List into the parcel at the current dataPosition(), growing 488 * dataCapacity() if needed. The List values are written using 489 * {@link #writeValue} and must follow the specification there. 490 */ 491 public final void writeList(List val) { 492 if (val == null) { 493 writeInt(-1); 494 return; 495 } 496 int N = val.size(); 497 int i=0; 498 writeInt(N); 499 while (i < N) { 500 writeValue(val.get(i)); 501 i++; 502 } 503 } 504 505 /** 506 * Flatten an Object array into the parcel at the current dataPosition(), 507 * growing dataCapacity() if needed. The array values are written using 508 * {@link #writeValue} and must follow the specification there. 509 */ 510 public final void writeArray(Object[] val) { 511 if (val == null) { 512 writeInt(-1); 513 return; 514 } 515 int N = val.length; 516 int i=0; 517 writeInt(N); 518 while (i < N) { 519 writeValue(val[i]); 520 i++; 521 } 522 } 523 524 /** 525 * Flatten a generic SparseArray into the parcel at the current 526 * dataPosition(), growing dataCapacity() if needed. The SparseArray 527 * values are written using {@link #writeValue} and must follow the 528 * specification there. 529 */ 530 public final void writeSparseArray(SparseArray<Object> val) { 531 if (val == null) { 532 writeInt(-1); 533 return; 534 } 535 int N = val.size(); 536 writeInt(N); 537 int i=0; 538 while (i < N) { 539 writeInt(val.keyAt(i)); 540 writeValue(val.valueAt(i)); 541 i++; 542 } 543 } 544 545 public final void writeSparseBooleanArray(SparseBooleanArray val) { 546 if (val == null) { 547 writeInt(-1); 548 return; 549 } 550 int N = val.size(); 551 writeInt(N); 552 int i=0; 553 while (i < N) { 554 writeInt(val.keyAt(i)); 555 writeByte((byte)(val.valueAt(i) ? 1 : 0)); 556 i++; 557 } 558 } 559 560 public final void writeBooleanArray(boolean[] val) { 561 if (val != null) { 562 int N = val.length; 563 writeInt(N); 564 for (int i=0; i<N; i++) { 565 writeInt(val[i] ? 1 : 0); 566 } 567 } else { 568 writeInt(-1); 569 } 570 } 571 572 public final boolean[] createBooleanArray() { 573 int N = readInt(); 574 // >>2 as a fast divide-by-4 works in the create*Array() functions 575 // because dataAvail() will never return a negative number. 4 is 576 // the size of a stored boolean in the stream. 577 if (N >= 0 && N <= (dataAvail() >> 2)) { 578 boolean[] val = new boolean[N]; 579 for (int i=0; i<N; i++) { 580 val[i] = readInt() != 0; 581 } 582 return val; 583 } else { 584 return null; 585 } 586 } 587 588 public final void readBooleanArray(boolean[] val) { 589 int N = readInt(); 590 if (N == val.length) { 591 for (int i=0; i<N; i++) { 592 val[i] = readInt() != 0; 593 } 594 } else { 595 throw new RuntimeException("bad array lengths"); 596 } 597 } 598 599 public final void writeCharArray(char[] val) { 600 if (val != null) { 601 int N = val.length; 602 writeInt(N); 603 for (int i=0; i<N; i++) { 604 writeInt((int)val[i]); 605 } 606 } else { 607 writeInt(-1); 608 } 609 } 610 611 public final char[] createCharArray() { 612 int N = readInt(); 613 if (N >= 0 && N <= (dataAvail() >> 2)) { 614 char[] val = new char[N]; 615 for (int i=0; i<N; i++) { 616 val[i] = (char)readInt(); 617 } 618 return val; 619 } else { 620 return null; 621 } 622 } 623 624 public final void readCharArray(char[] val) { 625 int N = readInt(); 626 if (N == val.length) { 627 for (int i=0; i<N; i++) { 628 val[i] = (char)readInt(); 629 } 630 } else { 631 throw new RuntimeException("bad array lengths"); 632 } 633 } 634 635 public final void writeIntArray(int[] val) { 636 if (val != null) { 637 int N = val.length; 638 writeInt(N); 639 for (int i=0; i<N; i++) { 640 writeInt(val[i]); 641 } 642 } else { 643 writeInt(-1); 644 } 645 } 646 647 public final int[] createIntArray() { 648 int N = readInt(); 649 if (N >= 0 && N <= (dataAvail() >> 2)) { 650 int[] val = new int[N]; 651 for (int i=0; i<N; i++) { 652 val[i] = readInt(); 653 } 654 return val; 655 } else { 656 return null; 657 } 658 } 659 660 public final void readIntArray(int[] val) { 661 int N = readInt(); 662 if (N == val.length) { 663 for (int i=0; i<N; i++) { 664 val[i] = readInt(); 665 } 666 } else { 667 throw new RuntimeException("bad array lengths"); 668 } 669 } 670 671 public final void writeLongArray(long[] val) { 672 if (val != null) { 673 int N = val.length; 674 writeInt(N); 675 for (int i=0; i<N; i++) { 676 writeLong(val[i]); 677 } 678 } else { 679 writeInt(-1); 680 } 681 } 682 683 public final long[] createLongArray() { 684 int N = readInt(); 685 // >>3 because stored longs are 64 bits 686 if (N >= 0 && N <= (dataAvail() >> 3)) { 687 long[] val = new long[N]; 688 for (int i=0; i<N; i++) { 689 val[i] = readLong(); 690 } 691 return val; 692 } else { 693 return null; 694 } 695 } 696 697 public final void readLongArray(long[] val) { 698 int N = readInt(); 699 if (N == val.length) { 700 for (int i=0; i<N; i++) { 701 val[i] = readLong(); 702 } 703 } else { 704 throw new RuntimeException("bad array lengths"); 705 } 706 } 707 708 public final void writeFloatArray(float[] val) { 709 if (val != null) { 710 int N = val.length; 711 writeInt(N); 712 for (int i=0; i<N; i++) { 713 writeFloat(val[i]); 714 } 715 } else { 716 writeInt(-1); 717 } 718 } 719 720 public final float[] createFloatArray() { 721 int N = readInt(); 722 // >>2 because stored floats are 4 bytes 723 if (N >= 0 && N <= (dataAvail() >> 2)) { 724 float[] val = new float[N]; 725 for (int i=0; i<N; i++) { 726 val[i] = readFloat(); 727 } 728 return val; 729 } else { 730 return null; 731 } 732 } 733 734 public final void readFloatArray(float[] val) { 735 int N = readInt(); 736 if (N == val.length) { 737 for (int i=0; i<N; i++) { 738 val[i] = readFloat(); 739 } 740 } else { 741 throw new RuntimeException("bad array lengths"); 742 } 743 } 744 745 public final void writeDoubleArray(double[] val) { 746 if (val != null) { 747 int N = val.length; 748 writeInt(N); 749 for (int i=0; i<N; i++) { 750 writeDouble(val[i]); 751 } 752 } else { 753 writeInt(-1); 754 } 755 } 756 757 public final double[] createDoubleArray() { 758 int N = readInt(); 759 // >>3 because stored doubles are 8 bytes 760 if (N >= 0 && N <= (dataAvail() >> 3)) { 761 double[] val = new double[N]; 762 for (int i=0; i<N; i++) { 763 val[i] = readDouble(); 764 } 765 return val; 766 } else { 767 return null; 768 } 769 } 770 771 public final void readDoubleArray(double[] val) { 772 int N = readInt(); 773 if (N == val.length) { 774 for (int i=0; i<N; i++) { 775 val[i] = readDouble(); 776 } 777 } else { 778 throw new RuntimeException("bad array lengths"); 779 } 780 } 781 782 public final void writeStringArray(String[] val) { 783 if (val != null) { 784 int N = val.length; 785 writeInt(N); 786 for (int i=0; i<N; i++) { 787 writeString(val[i]); 788 } 789 } else { 790 writeInt(-1); 791 } 792 } 793 794 public final String[] createStringArray() { 795 int N = readInt(); 796 if (N >= 0) { 797 String[] val = new String[N]; 798 for (int i=0; i<N; i++) { 799 val[i] = readString(); 800 } 801 return val; 802 } else { 803 return null; 804 } 805 } 806 807 public final void readStringArray(String[] val) { 808 int N = readInt(); 809 if (N == val.length) { 810 for (int i=0; i<N; i++) { 811 val[i] = readString(); 812 } 813 } else { 814 throw new RuntimeException("bad array lengths"); 815 } 816 } 817 818 public final void writeBinderArray(IBinder[] val) { 819 if (val != null) { 820 int N = val.length; 821 writeInt(N); 822 for (int i=0; i<N; i++) { 823 writeStrongBinder(val[i]); 824 } 825 } else { 826 writeInt(-1); 827 } 828 } 829 830 public final IBinder[] createBinderArray() { 831 int N = readInt(); 832 if (N >= 0) { 833 IBinder[] val = new IBinder[N]; 834 for (int i=0; i<N; i++) { 835 val[i] = readStrongBinder(); 836 } 837 return val; 838 } else { 839 return null; 840 } 841 } 842 843 public final void readBinderArray(IBinder[] val) { 844 int N = readInt(); 845 if (N == val.length) { 846 for (int i=0; i<N; i++) { 847 val[i] = readStrongBinder(); 848 } 849 } else { 850 throw new RuntimeException("bad array lengths"); 851 } 852 } 853 854 /** 855 * Flatten a List containing a particular object type into the parcel, at 856 * the current dataPosition() and growing dataCapacity() if needed. The 857 * type of the objects in the list must be one that implements Parcelable. 858 * Unlike the generic writeList() method, however, only the raw data of the 859 * objects is written and not their type, so you must use the corresponding 860 * readTypedList() to unmarshall them. 861 * 862 * @param val The list of objects to be written. 863 * 864 * @see #createTypedArrayList 865 * @see #readTypedList 866 * @see Parcelable 867 */ 868 public final <T extends Parcelable> void writeTypedList(List<T> val) { 869 if (val == null) { 870 writeInt(-1); 871 return; 872 } 873 int N = val.size(); 874 int i=0; 875 writeInt(N); 876 while (i < N) { 877 T item = val.get(i); 878 if (item != null) { 879 writeInt(1); 880 item.writeToParcel(this, 0); 881 } else { 882 writeInt(0); 883 } 884 i++; 885 } 886 } 887 888 /** 889 * Flatten a List containing String objects into the parcel, at 890 * the current dataPosition() and growing dataCapacity() if needed. They 891 * can later be retrieved with {@link #createStringArrayList} or 892 * {@link #readStringList}. 893 * 894 * @param val The list of strings to be written. 895 * 896 * @see #createStringArrayList 897 * @see #readStringList 898 */ 899 public final void writeStringList(List<String> val) { 900 if (val == null) { 901 writeInt(-1); 902 return; 903 } 904 int N = val.size(); 905 int i=0; 906 writeInt(N); 907 while (i < N) { 908 writeString(val.get(i)); 909 i++; 910 } 911 } 912 913 /** 914 * Flatten a List containing IBinder objects into the parcel, at 915 * the current dataPosition() and growing dataCapacity() if needed. They 916 * can later be retrieved with {@link #createBinderArrayList} or 917 * {@link #readBinderList}. 918 * 919 * @param val The list of strings to be written. 920 * 921 * @see #createBinderArrayList 922 * @see #readBinderList 923 */ 924 public final void writeBinderList(List<IBinder> val) { 925 if (val == null) { 926 writeInt(-1); 927 return; 928 } 929 int N = val.size(); 930 int i=0; 931 writeInt(N); 932 while (i < N) { 933 writeStrongBinder(val.get(i)); 934 i++; 935 } 936 } 937 938 /** 939 * Flatten a heterogeneous array containing a particular object type into 940 * the parcel, at 941 * the current dataPosition() and growing dataCapacity() if needed. The 942 * type of the objects in the array must be one that implements Parcelable. 943 * Unlike the {@link #writeParcelableArray} method, however, only the 944 * raw data of the objects is written and not their type, so you must use 945 * {@link #readTypedArray} with the correct corresponding 946 * {@link Parcelable.Creator} implementation to unmarshall them. 947 * 948 * @param val The array of objects to be written. 949 * @param parcelableFlags Contextual flags as per 950 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 951 * 952 * @see #readTypedArray 953 * @see #writeParcelableArray 954 * @see Parcelable.Creator 955 */ 956 public final <T extends Parcelable> void writeTypedArray(T[] val, 957 int parcelableFlags) { 958 if (val != null) { 959 int N = val.length; 960 writeInt(N); 961 for (int i=0; i<N; i++) { 962 T item = val[i]; 963 if (item != null) { 964 writeInt(1); 965 item.writeToParcel(this, parcelableFlags); 966 } else { 967 writeInt(0); 968 } 969 } 970 } else { 971 writeInt(-1); 972 } 973 } 974 975 /** 976 * Flatten a generic object in to a parcel. The given Object value may 977 * currently be one of the following types: 978 * 979 * <ul> 980 * <li> null 981 * <li> String 982 * <li> Byte 983 * <li> Short 984 * <li> Integer 985 * <li> Long 986 * <li> Float 987 * <li> Double 988 * <li> Boolean 989 * <li> String[] 990 * <li> boolean[] 991 * <li> byte[] 992 * <li> int[] 993 * <li> long[] 994 * <li> Object[] (supporting objects of the same type defined here). 995 * <li> {@link Bundle} 996 * <li> Map (as supported by {@link #writeMap}). 997 * <li> Any object that implements the {@link Parcelable} protocol. 998 * <li> Parcelable[] 999 * <li> CharSequence (as supported by {@link TextUtils#writeToParcel}). 1000 * <li> List (as supported by {@link #writeList}). 1001 * <li> {@link SparseArray} (as supported by {@link #writeSparseArray}). 1002 * <li> {@link IBinder} 1003 * <li> Any object that implements Serializable (but see 1004 * {@link #writeSerializable} for caveats). Note that all of the 1005 * previous types have relatively efficient implementations for 1006 * writing to a Parcel; having to rely on the generic serialization 1007 * approach is much less efficient and should be avoided whenever 1008 * possible. 1009 * </ul> 1010 */ 1011 public final void writeValue(Object v) { 1012 if (v == null) { 1013 writeInt(VAL_NULL); 1014 } else if (v instanceof String) { 1015 writeInt(VAL_STRING); 1016 writeString((String) v); 1017 } else if (v instanceof Integer) { 1018 writeInt(VAL_INTEGER); 1019 writeInt((Integer) v); 1020 } else if (v instanceof Map) { 1021 writeInt(VAL_MAP); 1022 writeMap((Map) v); 1023 } else if (v instanceof Bundle) { 1024 // Must be before Parcelable 1025 writeInt(VAL_BUNDLE); 1026 writeBundle((Bundle) v); 1027 } else if (v instanceof Parcelable) { 1028 writeInt(VAL_PARCELABLE); 1029 writeParcelable((Parcelable) v, 0); 1030 } else if (v instanceof Short) { 1031 writeInt(VAL_SHORT); 1032 writeInt(((Short) v).intValue()); 1033 } else if (v instanceof Long) { 1034 writeInt(VAL_LONG); 1035 writeLong((Long) v); 1036 } else if (v instanceof Float) { 1037 writeInt(VAL_FLOAT); 1038 writeFloat((Float) v); 1039 } else if (v instanceof Double) { 1040 writeInt(VAL_DOUBLE); 1041 writeDouble((Double) v); 1042 } else if (v instanceof Boolean) { 1043 writeInt(VAL_BOOLEAN); 1044 writeInt((Boolean) v ? 1 : 0); 1045 } else if (v instanceof CharSequence) { 1046 // Must be after String 1047 writeInt(VAL_CHARSEQUENCE); 1048 TextUtils.writeToParcel((CharSequence) v, this, 0); 1049 } else if (v instanceof List) { 1050 writeInt(VAL_LIST); 1051 writeList((List) v); 1052 } else if (v instanceof SparseArray) { 1053 writeInt(VAL_SPARSEARRAY); 1054 writeSparseArray((SparseArray) v); 1055 } else if (v instanceof boolean[]) { 1056 writeInt(VAL_BOOLEANARRAY); 1057 writeBooleanArray((boolean[]) v); 1058 } else if (v instanceof byte[]) { 1059 writeInt(VAL_BYTEARRAY); 1060 writeByteArray((byte[]) v); 1061 } else if (v instanceof String[]) { 1062 writeInt(VAL_STRINGARRAY); 1063 writeStringArray((String[]) v); 1064 } else if (v instanceof IBinder) { 1065 writeInt(VAL_IBINDER); 1066 writeStrongBinder((IBinder) v); 1067 } else if (v instanceof Parcelable[]) { 1068 writeInt(VAL_PARCELABLEARRAY); 1069 writeParcelableArray((Parcelable[]) v, 0); 1070 } else if (v instanceof Object[]) { 1071 writeInt(VAL_OBJECTARRAY); 1072 writeArray((Object[]) v); 1073 } else if (v instanceof int[]) { 1074 writeInt(VAL_INTARRAY); 1075 writeIntArray((int[]) v); 1076 } else if (v instanceof long[]) { 1077 writeInt(VAL_LONGARRAY); 1078 writeLongArray((long[]) v); 1079 } else if (v instanceof Byte) { 1080 writeInt(VAL_BYTE); 1081 writeInt((Byte) v); 1082 } else if (v instanceof Serializable) { 1083 // Must be last 1084 writeInt(VAL_SERIALIZABLE); 1085 writeSerializable((Serializable) v); 1086 } else { 1087 throw new RuntimeException("Parcel: unable to marshal value " + v); 1088 } 1089 } 1090 1091 /** 1092 * Flatten the name of the class of the Parcelable and its contents 1093 * into the parcel. 1094 * 1095 * @param p The Parcelable object to be written. 1096 * @param parcelableFlags Contextual flags as per 1097 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 1098 */ 1099 public final void writeParcelable(Parcelable p, int parcelableFlags) { 1100 if (p == null) { 1101 writeString(null); 1102 return; 1103 } 1104 String name = p.getClass().getName(); 1105 writeString(name); 1106 p.writeToParcel(this, parcelableFlags); 1107 } 1108 1109 /** 1110 * Write a generic serializable object in to a Parcel. It is strongly 1111 * recommended that this method be avoided, since the serialization 1112 * overhead is extremely large, and this approach will be much slower than 1113 * using the other approaches to writing data in to a Parcel. 1114 */ 1115 public final void writeSerializable(Serializable s) { 1116 if (s == null) { 1117 writeString(null); 1118 return; 1119 } 1120 String name = s.getClass().getName(); 1121 writeString(name); 1122 1123 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1124 try { 1125 ObjectOutputStream oos = new ObjectOutputStream(baos); 1126 oos.writeObject(s); 1127 oos.close(); 1128 1129 writeByteArray(baos.toByteArray()); 1130 } catch (IOException ioe) { 1131 throw new RuntimeException("Parcelable encountered " + 1132 "IOException writing serializable object (name = " + name + 1133 ")", ioe); 1134 } 1135 } 1136 1137 /** 1138 * Special function for writing an exception result at the header of 1139 * a parcel, to be used when returning an exception from a transaction. 1140 * Note that this currently only supports a few exception types; any other 1141 * exception will be re-thrown by this function as a RuntimeException 1142 * (to be caught by the system's last-resort exception handling when 1143 * dispatching a transaction). 1144 * 1145 * <p>The supported exception types are: 1146 * <ul> 1147 * <li>{@link BadParcelableException} 1148 * <li>{@link IllegalArgumentException} 1149 * <li>{@link IllegalStateException} 1150 * <li>{@link NullPointerException} 1151 * <li>{@link SecurityException} 1152 * </ul> 1153 * 1154 * @param e The Exception to be written. 1155 * 1156 * @see #writeNoException 1157 * @see #readException 1158 */ 1159 public final void writeException(Exception e) { 1160 int code = 0; 1161 if (e instanceof SecurityException) { 1162 code = EX_SECURITY; 1163 } else if (e instanceof BadParcelableException) { 1164 code = EX_BAD_PARCELABLE; 1165 } else if (e instanceof IllegalArgumentException) { 1166 code = EX_ILLEGAL_ARGUMENT; 1167 } else if (e instanceof NullPointerException) { 1168 code = EX_NULL_POINTER; 1169 } else if (e instanceof IllegalStateException) { 1170 code = EX_ILLEGAL_STATE; 1171 } 1172 writeInt(code); 1173 if (code == 0) { 1174 if (e instanceof RuntimeException) { 1175 throw (RuntimeException) e; 1176 } 1177 throw new RuntimeException(e); 1178 } 1179 writeString(e.getMessage()); 1180 } 1181 1182 /** 1183 * Special function for writing information at the front of the Parcel 1184 * indicating that no exception occurred. 1185 * 1186 * @see #writeException 1187 * @see #readException 1188 */ 1189 public final void writeNoException() { 1190 writeInt(0); 1191 } 1192 1193 /** 1194 * Special function for reading an exception result from the header of 1195 * a parcel, to be used after receiving the result of a transaction. This 1196 * will throw the exception for you if it had been written to the Parcel, 1197 * otherwise return and let you read the normal result data from the Parcel. 1198 * 1199 * @see #writeException 1200 * @see #writeNoException 1201 */ 1202 public final void readException() { 1203 int code = readInt(); 1204 if (code == 0) return; 1205 String msg = readString(); 1206 readException(code, msg); 1207 } 1208 1209 /** 1210 * Use this function for customized exception handling. 1211 * customized method call this method for all unknown case 1212 * @param code exception code 1213 * @param msg exception message 1214 */ 1215 public final void readException(int code, String msg) { 1216 switch (code) { 1217 case EX_SECURITY: 1218 throw new SecurityException(msg); 1219 case EX_BAD_PARCELABLE: 1220 throw new BadParcelableException(msg); 1221 case EX_ILLEGAL_ARGUMENT: 1222 throw new IllegalArgumentException(msg); 1223 case EX_NULL_POINTER: 1224 throw new NullPointerException(msg); 1225 case EX_ILLEGAL_STATE: 1226 throw new IllegalStateException(msg); 1227 } 1228 throw new RuntimeException("Unknown exception code: " + code 1229 + " msg " + msg); 1230 } 1231 1232 /** 1233 * Read an integer value from the parcel at the current dataPosition(). 1234 */ 1235 public final native int readInt(); 1236 1237 /** 1238 * Read a long integer value from the parcel at the current dataPosition(). 1239 */ 1240 public final native long readLong(); 1241 1242 /** 1243 * Read a floating point value from the parcel at the current 1244 * dataPosition(). 1245 */ 1246 public final native float readFloat(); 1247 1248 /** 1249 * Read a double precision floating point value from the parcel at the 1250 * current dataPosition(). 1251 */ 1252 public final native double readDouble(); 1253 1254 /** 1255 * Read a string value from the parcel at the current dataPosition(). 1256 */ 1257 public final native String readString(); 1258 1259 /** 1260 * Read an object from the parcel at the current dataPosition(). 1261 */ 1262 public final native IBinder readStrongBinder(); 1263 1264 /** 1265 * Read a FileDescriptor from the parcel at the current dataPosition(). 1266 */ 1267 public final ParcelFileDescriptor readFileDescriptor() { 1268 FileDescriptor fd = internalReadFileDescriptor(); 1269 return fd != null ? new ParcelFileDescriptor(fd) : null; 1270 } 1271 1272 private native FileDescriptor internalReadFileDescriptor(); 1273 /*package*/ static native FileDescriptor openFileDescriptor(String file, 1274 int mode) throws FileNotFoundException; 1275 /*package*/ static native void closeFileDescriptor(FileDescriptor desc) 1276 throws IOException; 1277 1278 /** 1279 * Read a byte value from the parcel at the current dataPosition(). 1280 */ 1281 public final byte readByte() { 1282 return (byte)(readInt() & 0xff); 1283 } 1284 1285 /** 1286 * Please use {@link #readBundle(ClassLoader)} instead (whose data must have 1287 * been written with {@link #writeBundle}. Read into an existing Map object 1288 * from the parcel at the current dataPosition(). 1289 */ 1290 public final void readMap(Map outVal, ClassLoader loader) { 1291 int N = readInt(); 1292 readMapInternal(outVal, N, loader); 1293 } 1294 1295 /** 1296 * Read into an existing List object from the parcel at the current 1297 * dataPosition(), using the given class loader to load any enclosed 1298 * Parcelables. If it is null, the default class loader is used. 1299 */ 1300 public final void readList(List outVal, ClassLoader loader) { 1301 int N = readInt(); 1302 readListInternal(outVal, N, loader); 1303 } 1304 1305 /** 1306 * Please use {@link #readBundle(ClassLoader)} instead (whose data must have 1307 * been written with {@link #writeBundle}. Read and return a new HashMap 1308 * object from the parcel at the current dataPosition(), using the given 1309 * class loader to load any enclosed Parcelables. Returns null if 1310 * the previously written map object was null. 1311 */ 1312 public final HashMap readHashMap(ClassLoader loader) 1313 { 1314 int N = readInt(); 1315 if (N < 0) { 1316 return null; 1317 } 1318 HashMap m = new HashMap(N); 1319 readMapInternal(m, N, loader); 1320 return m; 1321 } 1322 1323 /** 1324 * Read and return a new Bundle object from the parcel at the current 1325 * dataPosition(). Returns null if the previously written Bundle object was 1326 * null. 1327 */ 1328 public final Bundle readBundle() { 1329 return readBundle(null); 1330 } 1331 1332 /** 1333 * Read and return a new Bundle object from the parcel at the current 1334 * dataPosition(), using the given class loader to initialize the class 1335 * loader of the Bundle for later retrieval of Parcelable objects. 1336 * Returns null if the previously written Bundle object was null. 1337 */ 1338 public final Bundle readBundle(ClassLoader loader) { 1339 int length = readInt(); 1340 if (length < 0) { 1341 return null; 1342 } 1343 1344 final Bundle bundle = new Bundle(this, length); 1345 if (loader != null) { 1346 bundle.setClassLoader(loader); 1347 } 1348 return bundle; 1349 } 1350 1351 /** 1352 * Read and return a byte[] object from the parcel. 1353 */ 1354 public final native byte[] createByteArray(); 1355 1356 /** 1357 * Read a byte[] object from the parcel and copy it into the 1358 * given byte array. 1359 */ 1360 public final void readByteArray(byte[] val) { 1361 // TODO: make this a native method to avoid the extra copy. 1362 byte[] ba = createByteArray(); 1363 if (ba.length == val.length) { 1364 System.arraycopy(ba, 0, val, 0, ba.length); 1365 } else { 1366 throw new RuntimeException("bad array lengths"); 1367 } 1368 } 1369 1370 /** 1371 * Read and return a String[] object from the parcel. 1372 * {@hide} 1373 */ 1374 public final String[] readStringArray() { 1375 String[] array = null; 1376 1377 int length = readInt(); 1378 if (length >= 0) 1379 { 1380 array = new String[length]; 1381 1382 for (int i = 0 ; i < length ; i++) 1383 { 1384 array[i] = readString(); 1385 } 1386 } 1387 1388 return array; 1389 } 1390 1391 /** 1392 * Read and return a new ArrayList object from the parcel at the current 1393 * dataPosition(). Returns null if the previously written list object was 1394 * null. The given class loader will be used to load any enclosed 1395 * Parcelables. 1396 */ 1397 public final ArrayList readArrayList(ClassLoader loader) { 1398 int N = readInt(); 1399 if (N < 0) { 1400 return null; 1401 } 1402 ArrayList l = new ArrayList(N); 1403 readListInternal(l, N, loader); 1404 return l; 1405 } 1406 1407 /** 1408 * Read and return a new Object array from the parcel at the current 1409 * dataPosition(). Returns null if the previously written array was 1410 * null. The given class loader will be used to load any enclosed 1411 * Parcelables. 1412 */ 1413 public final Object[] readArray(ClassLoader loader) { 1414 int N = readInt(); 1415 if (N < 0) { 1416 return null; 1417 } 1418 Object[] l = new Object[N]; 1419 readArrayInternal(l, N, loader); 1420 return l; 1421 } 1422 1423 /** 1424 * Read and return a new SparseArray object from the parcel at the current 1425 * dataPosition(). Returns null if the previously written list object was 1426 * null. The given class loader will be used to load any enclosed 1427 * Parcelables. 1428 */ 1429 public final SparseArray readSparseArray(ClassLoader loader) { 1430 int N = readInt(); 1431 if (N < 0) { 1432 return null; 1433 } 1434 SparseArray sa = new SparseArray(N); 1435 readSparseArrayInternal(sa, N, loader); 1436 return sa; 1437 } 1438 1439 /** 1440 * Read and return a new SparseBooleanArray object from the parcel at the current 1441 * dataPosition(). Returns null if the previously written list object was 1442 * null. 1443 */ 1444 public final SparseBooleanArray readSparseBooleanArray() { 1445 int N = readInt(); 1446 if (N < 0) { 1447 return null; 1448 } 1449 SparseBooleanArray sa = new SparseBooleanArray(N); 1450 readSparseBooleanArrayInternal(sa, N); 1451 return sa; 1452 } 1453 1454 /** 1455 * Read and return a new ArrayList containing a particular object type from 1456 * the parcel that was written with {@link #writeTypedList} at the 1457 * current dataPosition(). Returns null if the 1458 * previously written list object was null. The list <em>must</em> have 1459 * previously been written via {@link #writeTypedList} with the same object 1460 * type. 1461 * 1462 * @return A newly created ArrayList containing objects with the same data 1463 * as those that were previously written. 1464 * 1465 * @see #writeTypedList 1466 */ 1467 public final <T> ArrayList<T> createTypedArrayList(Parcelable.Creator<T> c) { 1468 int N = readInt(); 1469 if (N < 0) { 1470 return null; 1471 } 1472 ArrayList<T> l = new ArrayList<T>(N); 1473 while (N > 0) { 1474 if (readInt() != 0) { 1475 l.add(c.createFromParcel(this)); 1476 } else { 1477 l.add(null); 1478 } 1479 N--; 1480 } 1481 return l; 1482 } 1483 1484 /** 1485 * Read into the given List items containing a particular object type 1486 * that were written with {@link #writeTypedList} at the 1487 * current dataPosition(). The list <em>must</em> have 1488 * previously been written via {@link #writeTypedList} with the same object 1489 * type. 1490 * 1491 * @return A newly created ArrayList containing objects with the same data 1492 * as those that were previously written. 1493 * 1494 * @see #writeTypedList 1495 */ 1496 public final <T> void readTypedList(List<T> list, Parcelable.Creator<T> c) { 1497 int M = list.size(); 1498 int N = readInt(); 1499 int i = 0; 1500 for (; i < M && i < N; i++) { 1501 if (readInt() != 0) { 1502 list.set(i, c.createFromParcel(this)); 1503 } else { 1504 list.set(i, null); 1505 } 1506 } 1507 for (; i<N; i++) { 1508 if (readInt() != 0) { 1509 list.add(c.createFromParcel(this)); 1510 } else { 1511 list.add(null); 1512 } 1513 } 1514 for (; i<M; i++) { 1515 list.remove(N); 1516 } 1517 } 1518 1519 /** 1520 * Read and return a new ArrayList containing String objects from 1521 * the parcel that was written with {@link #writeStringList} at the 1522 * current dataPosition(). Returns null if the 1523 * previously written list object was null. 1524 * 1525 * @return A newly created ArrayList containing strings with the same data 1526 * as those that were previously written. 1527 * 1528 * @see #writeStringList 1529 */ 1530 public final ArrayList<String> createStringArrayList() { 1531 int N = readInt(); 1532 if (N < 0) { 1533 return null; 1534 } 1535 ArrayList<String> l = new ArrayList<String>(N); 1536 while (N > 0) { 1537 l.add(readString()); 1538 N--; 1539 } 1540 return l; 1541 } 1542 1543 /** 1544 * Read and return a new ArrayList containing IBinder objects from 1545 * the parcel that was written with {@link #writeBinderList} at the 1546 * current dataPosition(). Returns null if the 1547 * previously written list object was null. 1548 * 1549 * @return A newly created ArrayList containing strings with the same data 1550 * as those that were previously written. 1551 * 1552 * @see #writeBinderList 1553 */ 1554 public final ArrayList<IBinder> createBinderArrayList() { 1555 int N = readInt(); 1556 if (N < 0) { 1557 return null; 1558 } 1559 ArrayList<IBinder> l = new ArrayList<IBinder>(N); 1560 while (N > 0) { 1561 l.add(readStrongBinder()); 1562 N--; 1563 } 1564 return l; 1565 } 1566 1567 /** 1568 * Read into the given List items String objects that were written with 1569 * {@link #writeStringList} at the current dataPosition(). 1570 * 1571 * @return A newly created ArrayList containing strings with the same data 1572 * as those that were previously written. 1573 * 1574 * @see #writeStringList 1575 */ 1576 public final void readStringList(List<String> list) { 1577 int M = list.size(); 1578 int N = readInt(); 1579 int i = 0; 1580 for (; i < M && i < N; i++) { 1581 list.set(i, readString()); 1582 } 1583 for (; i<N; i++) { 1584 list.add(readString()); 1585 } 1586 for (; i<M; i++) { 1587 list.remove(N); 1588 } 1589 } 1590 1591 /** 1592 * Read into the given List items IBinder objects that were written with 1593 * {@link #writeBinderList} at the current dataPosition(). 1594 * 1595 * @return A newly created ArrayList containing strings with the same data 1596 * as those that were previously written. 1597 * 1598 * @see #writeBinderList 1599 */ 1600 public final void readBinderList(List<IBinder> list) { 1601 int M = list.size(); 1602 int N = readInt(); 1603 int i = 0; 1604 for (; i < M && i < N; i++) { 1605 list.set(i, readStrongBinder()); 1606 } 1607 for (; i<N; i++) { 1608 list.add(readStrongBinder()); 1609 } 1610 for (; i<M; i++) { 1611 list.remove(N); 1612 } 1613 } 1614 1615 /** 1616 * Read and return a new array containing a particular object type from 1617 * the parcel at the current dataPosition(). Returns null if the 1618 * previously written array was null. The array <em>must</em> have 1619 * previously been written via {@link #writeTypedArray} with the same 1620 * object type. 1621 * 1622 * @return A newly created array containing objects with the same data 1623 * as those that were previously written. 1624 * 1625 * @see #writeTypedArray 1626 */ 1627 public final <T> T[] createTypedArray(Parcelable.Creator<T> c) { 1628 int N = readInt(); 1629 if (N < 0) { 1630 return null; 1631 } 1632 T[] l = c.newArray(N); 1633 for (int i=0; i<N; i++) { 1634 if (readInt() != 0) { 1635 l[i] = c.createFromParcel(this); 1636 } 1637 } 1638 return l; 1639 } 1640 1641 public final <T> void readTypedArray(T[] val, Parcelable.Creator<T> c) { 1642 int N = readInt(); 1643 if (N == val.length) { 1644 for (int i=0; i<N; i++) { 1645 if (readInt() != 0) { 1646 val[i] = c.createFromParcel(this); 1647 } else { 1648 val[i] = null; 1649 } 1650 } 1651 } else { 1652 throw new RuntimeException("bad array lengths"); 1653 } 1654 } 1655 1656 /** 1657 * @deprecated 1658 * @hide 1659 */ 1660 @Deprecated 1661 public final <T> T[] readTypedArray(Parcelable.Creator<T> c) { 1662 return createTypedArray(c); 1663 } 1664 1665 /** 1666 * Write a heterogeneous array of Parcelable objects into the Parcel. 1667 * Each object in the array is written along with its class name, so 1668 * that the correct class can later be instantiated. As a result, this 1669 * has significantly more overhead than {@link #writeTypedArray}, but will 1670 * correctly handle an array containing more than one type of object. 1671 * 1672 * @param value The array of objects to be written. 1673 * @param parcelableFlags Contextual flags as per 1674 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 1675 * 1676 * @see #writeTypedArray 1677 */ 1678 public final <T extends Parcelable> void writeParcelableArray(T[] value, 1679 int parcelableFlags) { 1680 if (value != null) { 1681 int N = value.length; 1682 writeInt(N); 1683 for (int i=0; i<N; i++) { 1684 writeParcelable(value[i], parcelableFlags); 1685 } 1686 } else { 1687 writeInt(-1); 1688 } 1689 } 1690 1691 /** 1692 * Read a typed object from a parcel. The given class loader will be 1693 * used to load any enclosed Parcelables. If it is null, the default class 1694 * loader will be used. 1695 */ 1696 public final Object readValue(ClassLoader loader) { 1697 int type = readInt(); 1698 1699 switch (type) { 1700 case VAL_NULL: 1701 return null; 1702 1703 case VAL_STRING: 1704 return readString(); 1705 1706 case VAL_INTEGER: 1707 return readInt(); 1708 1709 case VAL_MAP: 1710 return readHashMap(loader); 1711 1712 case VAL_PARCELABLE: 1713 return readParcelable(loader); 1714 1715 case VAL_SHORT: 1716 return (short) readInt(); 1717 1718 case VAL_LONG: 1719 return readLong(); 1720 1721 case VAL_FLOAT: 1722 return readFloat(); 1723 1724 case VAL_DOUBLE: 1725 return readDouble(); 1726 1727 case VAL_BOOLEAN: 1728 return readInt() == 1; 1729 1730 case VAL_CHARSEQUENCE: 1731 return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this); 1732 1733 case VAL_LIST: 1734 return readArrayList(loader); 1735 1736 case VAL_BOOLEANARRAY: 1737 return createBooleanArray(); 1738 1739 case VAL_BYTEARRAY: 1740 return createByteArray(); 1741 1742 case VAL_STRINGARRAY: 1743 return readStringArray(); 1744 1745 case VAL_IBINDER: 1746 return readStrongBinder(); 1747 1748 case VAL_OBJECTARRAY: 1749 return readArray(loader); 1750 1751 case VAL_INTARRAY: 1752 return createIntArray(); 1753 1754 case VAL_LONGARRAY: 1755 return createLongArray(); 1756 1757 case VAL_BYTE: 1758 return readByte(); 1759 1760 case VAL_SERIALIZABLE: 1761 return readSerializable(); 1762 1763 case VAL_PARCELABLEARRAY: 1764 return readParcelableArray(loader); 1765 1766 case VAL_SPARSEARRAY: 1767 return readSparseArray(loader); 1768 1769 case VAL_SPARSEBOOLEANARRAY: 1770 return readSparseBooleanArray(); 1771 1772 case VAL_BUNDLE: 1773 return readBundle(loader); // loading will be deferred 1774 1775 default: 1776 int off = dataPosition() - 4; 1777 throw new RuntimeException( 1778 "Parcel " + this + ": Unmarshalling unknown type code " + type + " at offset " + off); 1779 } 1780 } 1781 1782 /** 1783 * Read and return a new Parcelable from the parcel. The given class loader 1784 * will be used to load any enclosed Parcelables. If it is null, the default 1785 * class loader will be used. 1786 * @param loader A ClassLoader from which to instantiate the Parcelable 1787 * object, or null for the default class loader. 1788 * @return Returns the newly created Parcelable, or null if a null 1789 * object has been written. 1790 * @throws BadParcelableException Throws BadParcelableException if there 1791 * was an error trying to instantiate the Parcelable. 1792 */ 1793 public final <T extends Parcelable> T readParcelable(ClassLoader loader) { 1794 String name = readString(); 1795 if (name == null) { 1796 return null; 1797 } 1798 Parcelable.Creator<T> creator; 1799 synchronized (mCreators) { 1800 HashMap<String,Parcelable.Creator> map = mCreators.get(loader); 1801 if (map == null) { 1802 map = new HashMap<String,Parcelable.Creator>(); 1803 mCreators.put(loader, map); 1804 } 1805 creator = map.get(name); 1806 if (creator == null) { 1807 try { 1808 Class c = loader == null ? 1809 Class.forName(name) : Class.forName(name, true, loader); 1810 Field f = c.getField("CREATOR"); 1811 creator = (Parcelable.Creator)f.get(null); 1812 } 1813 catch (IllegalAccessException e) { 1814 Log.e("Parcel", "Class not found when unmarshalling: " 1815 + name + ", e: " + e); 1816 throw new BadParcelableException( 1817 "IllegalAccessException when unmarshalling: " + name); 1818 } 1819 catch (ClassNotFoundException e) { 1820 Log.e("Parcel", "Class not found when unmarshalling: " 1821 + name + ", e: " + e); 1822 throw new BadParcelableException( 1823 "ClassNotFoundException when unmarshalling: " + name); 1824 } 1825 catch (ClassCastException e) { 1826 throw new BadParcelableException("Parcelable protocol requires a " 1827 + "Parcelable.Creator object called " 1828 + " CREATOR on class " + name); 1829 } 1830 catch (NoSuchFieldException e) { 1831 throw new BadParcelableException("Parcelable protocol requires a " 1832 + "Parcelable.Creator object called " 1833 + " CREATOR on class " + name); 1834 } 1835 if (creator == null) { 1836 throw new BadParcelableException("Parcelable protocol requires a " 1837 + "Parcelable.Creator object called " 1838 + " CREATOR on class " + name); 1839 } 1840 1841 map.put(name, creator); 1842 } 1843 } 1844 1845 return creator.createFromParcel(this); 1846 } 1847 1848 /** 1849 * Read and return a new Parcelable array from the parcel. 1850 * The given class loader will be used to load any enclosed 1851 * Parcelables. 1852 * @return the Parcelable array, or null if the array is null 1853 */ 1854 public final Parcelable[] readParcelableArray(ClassLoader loader) { 1855 int N = readInt(); 1856 if (N < 0) { 1857 return null; 1858 } 1859 Parcelable[] p = new Parcelable[N]; 1860 for (int i = 0; i < N; i++) { 1861 p[i] = (Parcelable) readParcelable(loader); 1862 } 1863 return p; 1864 } 1865 1866 /** 1867 * Read and return a new Serializable object from the parcel. 1868 * @return the Serializable object, or null if the Serializable name 1869 * wasn't found in the parcel. 1870 */ 1871 public final Serializable readSerializable() { 1872 String name = readString(); 1873 if (name == null) { 1874 // For some reason we were unable to read the name of the Serializable (either there 1875 // is nothing left in the Parcel to read, or the next value wasn't a String), so 1876 // return null, which indicates that the name wasn't found in the parcel. 1877 return null; 1878 } 1879 1880 byte[] serializedData = createByteArray(); 1881 ByteArrayInputStream bais = new ByteArrayInputStream(serializedData); 1882 try { 1883 ObjectInputStream ois = new ObjectInputStream(bais); 1884 return (Serializable) ois.readObject(); 1885 } catch (IOException ioe) { 1886 throw new RuntimeException("Parcelable encountered " + 1887 "IOException reading a Serializable object (name = " + name + 1888 ")", ioe); 1889 } catch (ClassNotFoundException cnfe) { 1890 throw new RuntimeException("Parcelable encountered" + 1891 "ClassNotFoundException reading a Serializable object (name = " 1892 + name + ")", cnfe); 1893 } 1894 } 1895 1896 // Cache of previously looked up CREATOR.createFromParcel() methods for 1897 // particular classes. Keys are the names of the classes, values are 1898 // Method objects. 1899 private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator>> 1900 mCreators = new HashMap<ClassLoader,HashMap<String,Parcelable.Creator>>(); 1901 1902 static protected final Parcel obtain(int obj) { 1903 final Parcel[] pool = sHolderPool; 1904 synchronized (pool) { 1905 Parcel p; 1906 for (int i=0; i<POOL_SIZE; i++) { 1907 p = pool[i]; 1908 if (p != null) { 1909 pool[i] = null; 1910 if (DEBUG_RECYCLE) { 1911 p.mStack = new RuntimeException(); 1912 } 1913 p.init(obj); 1914 return p; 1915 } 1916 } 1917 } 1918 return new Parcel(obj); 1919 } 1920 1921 private Parcel(int obj) { 1922 if (DEBUG_RECYCLE) { 1923 mStack = new RuntimeException(); 1924 } 1925 //Log.i("Parcel", "Initializing obj=0x" + Integer.toHexString(obj), mStack); 1926 init(obj); 1927 } 1928 1929 @Override 1930 protected void finalize() throws Throwable { 1931 if (DEBUG_RECYCLE) { 1932 if (mStack != null) { 1933 Log.w("Parcel", "Client did not call Parcel.recycle()", mStack); 1934 } 1935 } 1936 destroy(); 1937 } 1938 1939 private native void freeBuffer(); 1940 private native void init(int obj); 1941 private native void destroy(); 1942 1943 /* package */ void readMapInternal(Map outVal, int N, 1944 ClassLoader loader) { 1945 while (N > 0) { 1946 Object key = readValue(loader); 1947 Object value = readValue(loader); 1948 outVal.put(key, value); 1949 N--; 1950 } 1951 } 1952 1953 private void readListInternal(List outVal, int N, 1954 ClassLoader loader) { 1955 while (N > 0) { 1956 Object value = readValue(loader); 1957 //Log.d("Parcel", "Unmarshalling value=" + value); 1958 outVal.add(value); 1959 N--; 1960 } 1961 } 1962 1963 private void readArrayInternal(Object[] outVal, int N, 1964 ClassLoader loader) { 1965 for (int i = 0; i < N; i++) { 1966 Object value = readValue(loader); 1967 //Log.d("Parcel", "Unmarshalling value=" + value); 1968 outVal[i] = value; 1969 } 1970 } 1971 1972 private void readSparseArrayInternal(SparseArray outVal, int N, 1973 ClassLoader loader) { 1974 while (N > 0) { 1975 int key = readInt(); 1976 Object value = readValue(loader); 1977 //Log.i("Parcel", "Unmarshalling key=" + key + " value=" + value); 1978 outVal.append(key, value); 1979 N--; 1980 } 1981 } 1982 1983 1984 private void readSparseBooleanArrayInternal(SparseBooleanArray outVal, int N) { 1985 while (N > 0) { 1986 int key = readInt(); 1987 boolean value = this.readByte() == 1; 1988 //Log.i("Parcel", "Unmarshalling key=" + key + " value=" + value); 1989 outVal.append(key, value); 1990 N--; 1991 } 1992 } 1993} 1994