Parcel.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
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 private 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 if (val.mParcelledData != null) { 484 int length = val.mParcelledData.dataSize(); 485 appendFrom(val.mParcelledData, 0, length); 486 } else { 487 writeInt(-1); // dummy, will hold length 488 int oldPos = dataPosition(); 489 writeInt(0x4C444E42); // 'B' 'N' 'D' 'L' 490 491 writeMapInternal(val.mMap); 492 int newPos = dataPosition(); 493 494 // Backpatch length 495 setDataPosition(oldPos - 4); 496 int length = newPos - oldPos; 497 writeInt(length); 498 setDataPosition(newPos); 499 } 500 } 501 502 /** 503 * Flatten a List into the parcel at the current dataPosition(), growing 504 * dataCapacity() if needed. The List values are written using 505 * {@link #writeValue} and must follow the specification there. 506 */ 507 public final void writeList(List val) { 508 if (val == null) { 509 writeInt(-1); 510 return; 511 } 512 int N = val.size(); 513 int i=0; 514 writeInt(N); 515 while (i < N) { 516 writeValue(val.get(i)); 517 i++; 518 } 519 } 520 521 /** 522 * Flatten an Object array into the parcel at the current dataPosition(), 523 * growing dataCapacity() if needed. The array values are written using 524 * {@link #writeValue} and must follow the specification there. 525 */ 526 public final void writeArray(Object[] val) { 527 if (val == null) { 528 writeInt(-1); 529 return; 530 } 531 int N = val.length; 532 int i=0; 533 writeInt(N); 534 while (i < N) { 535 writeValue(val[i]); 536 i++; 537 } 538 } 539 540 /** 541 * Flatten a generic SparseArray into the parcel at the current 542 * dataPosition(), growing dataCapacity() if needed. The SparseArray 543 * values are written using {@link #writeValue} and must follow the 544 * specification there. 545 */ 546 public final void writeSparseArray(SparseArray<Object> val) { 547 if (val == null) { 548 writeInt(-1); 549 return; 550 } 551 int N = val.size(); 552 writeInt(N); 553 int i=0; 554 while (i < N) { 555 writeInt(val.keyAt(i)); 556 writeValue(val.valueAt(i)); 557 i++; 558 } 559 } 560 561 public final void writeSparseBooleanArray(SparseBooleanArray val) { 562 if (val == null) { 563 writeInt(-1); 564 return; 565 } 566 int N = val.size(); 567 writeInt(N); 568 int i=0; 569 while (i < N) { 570 writeInt(val.keyAt(i)); 571 writeByte((byte)(val.valueAt(i) ? 1 : 0)); 572 i++; 573 } 574 } 575 576 public final void writeBooleanArray(boolean[] val) { 577 if (val != null) { 578 int N = val.length; 579 writeInt(N); 580 for (int i=0; i<N; i++) { 581 writeInt(val[i] ? 1 : 0); 582 } 583 } else { 584 writeInt(-1); 585 } 586 } 587 588 public final boolean[] createBooleanArray() { 589 int N = readInt(); 590 // >>2 as a fast divide-by-4 works in the create*Array() functions 591 // because dataAvail() will never return a negative number. 4 is 592 // the size of a stored boolean in the stream. 593 if (N >= 0 && N <= (dataAvail() >> 2)) { 594 boolean[] val = new boolean[N]; 595 for (int i=0; i<N; i++) { 596 val[i] = readInt() != 0; 597 } 598 return val; 599 } else { 600 return null; 601 } 602 } 603 604 public final void readBooleanArray(boolean[] val) { 605 int N = readInt(); 606 if (N == val.length) { 607 for (int i=0; i<N; i++) { 608 val[i] = readInt() != 0; 609 } 610 } else { 611 throw new RuntimeException("bad array lengths"); 612 } 613 } 614 615 public final void writeCharArray(char[] val) { 616 if (val != null) { 617 int N = val.length; 618 writeInt(N); 619 for (int i=0; i<N; i++) { 620 writeInt((int)val[i]); 621 } 622 } else { 623 writeInt(-1); 624 } 625 } 626 627 public final char[] createCharArray() { 628 int N = readInt(); 629 if (N >= 0 && N <= (dataAvail() >> 2)) { 630 char[] val = new char[N]; 631 for (int i=0; i<N; i++) { 632 val[i] = (char)readInt(); 633 } 634 return val; 635 } else { 636 return null; 637 } 638 } 639 640 public final void readCharArray(char[] val) { 641 int N = readInt(); 642 if (N == val.length) { 643 for (int i=0; i<N; i++) { 644 val[i] = (char)readInt(); 645 } 646 } else { 647 throw new RuntimeException("bad array lengths"); 648 } 649 } 650 651 public final void writeIntArray(int[] val) { 652 if (val != null) { 653 int N = val.length; 654 writeInt(N); 655 for (int i=0; i<N; i++) { 656 writeInt(val[i]); 657 } 658 } else { 659 writeInt(-1); 660 } 661 } 662 663 public final int[] createIntArray() { 664 int N = readInt(); 665 if (N >= 0 && N <= (dataAvail() >> 2)) { 666 int[] val = new int[N]; 667 for (int i=0; i<N; i++) { 668 val[i] = readInt(); 669 } 670 return val; 671 } else { 672 return null; 673 } 674 } 675 676 public final void readIntArray(int[] val) { 677 int N = readInt(); 678 if (N == val.length) { 679 for (int i=0; i<N; i++) { 680 val[i] = readInt(); 681 } 682 } else { 683 throw new RuntimeException("bad array lengths"); 684 } 685 } 686 687 public final void writeLongArray(long[] val) { 688 if (val != null) { 689 int N = val.length; 690 writeInt(N); 691 for (int i=0; i<N; i++) { 692 writeLong(val[i]); 693 } 694 } else { 695 writeInt(-1); 696 } 697 } 698 699 public final long[] createLongArray() { 700 int N = readInt(); 701 // >>3 because stored longs are 64 bits 702 if (N >= 0 && N <= (dataAvail() >> 3)) { 703 long[] val = new long[N]; 704 for (int i=0; i<N; i++) { 705 val[i] = readLong(); 706 } 707 return val; 708 } else { 709 return null; 710 } 711 } 712 713 public final void readLongArray(long[] val) { 714 int N = readInt(); 715 if (N == val.length) { 716 for (int i=0; i<N; i++) { 717 val[i] = readLong(); 718 } 719 } else { 720 throw new RuntimeException("bad array lengths"); 721 } 722 } 723 724 public final void writeFloatArray(float[] val) { 725 if (val != null) { 726 int N = val.length; 727 writeInt(N); 728 for (int i=0; i<N; i++) { 729 writeFloat(val[i]); 730 } 731 } else { 732 writeInt(-1); 733 } 734 } 735 736 public final float[] createFloatArray() { 737 int N = readInt(); 738 // >>2 because stored floats are 4 bytes 739 if (N >= 0 && N <= (dataAvail() >> 2)) { 740 float[] val = new float[N]; 741 for (int i=0; i<N; i++) { 742 val[i] = readFloat(); 743 } 744 return val; 745 } else { 746 return null; 747 } 748 } 749 750 public final void readFloatArray(float[] val) { 751 int N = readInt(); 752 if (N == val.length) { 753 for (int i=0; i<N; i++) { 754 val[i] = readFloat(); 755 } 756 } else { 757 throw new RuntimeException("bad array lengths"); 758 } 759 } 760 761 public final void writeDoubleArray(double[] val) { 762 if (val != null) { 763 int N = val.length; 764 writeInt(N); 765 for (int i=0; i<N; i++) { 766 writeDouble(val[i]); 767 } 768 } else { 769 writeInt(-1); 770 } 771 } 772 773 public final double[] createDoubleArray() { 774 int N = readInt(); 775 // >>3 because stored doubles are 8 bytes 776 if (N >= 0 && N <= (dataAvail() >> 3)) { 777 double[] val = new double[N]; 778 for (int i=0; i<N; i++) { 779 val[i] = readDouble(); 780 } 781 return val; 782 } else { 783 return null; 784 } 785 } 786 787 public final void readDoubleArray(double[] val) { 788 int N = readInt(); 789 if (N == val.length) { 790 for (int i=0; i<N; i++) { 791 val[i] = readDouble(); 792 } 793 } else { 794 throw new RuntimeException("bad array lengths"); 795 } 796 } 797 798 public final void writeStringArray(String[] val) { 799 if (val != null) { 800 int N = val.length; 801 writeInt(N); 802 for (int i=0; i<N; i++) { 803 writeString(val[i]); 804 } 805 } else { 806 writeInt(-1); 807 } 808 } 809 810 public final String[] createStringArray() { 811 int N = readInt(); 812 if (N >= 0) { 813 String[] val = new String[N]; 814 for (int i=0; i<N; i++) { 815 val[i] = readString(); 816 } 817 return val; 818 } else { 819 return null; 820 } 821 } 822 823 public final void readStringArray(String[] val) { 824 int N = readInt(); 825 if (N == val.length) { 826 for (int i=0; i<N; i++) { 827 val[i] = readString(); 828 } 829 } else { 830 throw new RuntimeException("bad array lengths"); 831 } 832 } 833 834 public final void writeBinderArray(IBinder[] val) { 835 if (val != null) { 836 int N = val.length; 837 writeInt(N); 838 for (int i=0; i<N; i++) { 839 writeStrongBinder(val[i]); 840 } 841 } else { 842 writeInt(-1); 843 } 844 } 845 846 public final IBinder[] createBinderArray() { 847 int N = readInt(); 848 if (N >= 0) { 849 IBinder[] val = new IBinder[N]; 850 for (int i=0; i<N; i++) { 851 val[i] = readStrongBinder(); 852 } 853 return val; 854 } else { 855 return null; 856 } 857 } 858 859 public final void readBinderArray(IBinder[] val) { 860 int N = readInt(); 861 if (N == val.length) { 862 for (int i=0; i<N; i++) { 863 val[i] = readStrongBinder(); 864 } 865 } else { 866 throw new RuntimeException("bad array lengths"); 867 } 868 } 869 870 /** 871 * Flatten a List containing a particular object type into the parcel, at 872 * the current dataPosition() and growing dataCapacity() if needed. The 873 * type of the objects in the list must be one that implements Parcelable. 874 * Unlike the generic writeList() method, however, only the raw data of the 875 * objects is written and not their type, so you must use the corresponding 876 * readTypedList() to unmarshall them. 877 * 878 * @param val The list of objects to be written. 879 * 880 * @see #createTypedArrayList 881 * @see #readTypedList 882 * @see Parcelable 883 */ 884 public final <T extends Parcelable> void writeTypedList(List<T> val) { 885 if (val == null) { 886 writeInt(-1); 887 return; 888 } 889 int N = val.size(); 890 int i=0; 891 writeInt(N); 892 while (i < N) { 893 T item = val.get(i); 894 if (item != null) { 895 writeInt(1); 896 item.writeToParcel(this, 0); 897 } else { 898 writeInt(0); 899 } 900 i++; 901 } 902 } 903 904 /** 905 * Flatten a List containing String objects into the parcel, at 906 * the current dataPosition() and growing dataCapacity() if needed. They 907 * can later be retrieved with {@link #createStringArrayList} or 908 * {@link #readStringList}. 909 * 910 * @param val The list of strings to be written. 911 * 912 * @see #createStringArrayList 913 * @see #readStringList 914 */ 915 public final void writeStringList(List<String> val) { 916 if (val == null) { 917 writeInt(-1); 918 return; 919 } 920 int N = val.size(); 921 int i=0; 922 writeInt(N); 923 while (i < N) { 924 writeString(val.get(i)); 925 i++; 926 } 927 } 928 929 /** 930 * Flatten a List containing IBinder objects into the parcel, at 931 * the current dataPosition() and growing dataCapacity() if needed. They 932 * can later be retrieved with {@link #createBinderArrayList} or 933 * {@link #readBinderList}. 934 * 935 * @param val The list of strings to be written. 936 * 937 * @see #createBinderArrayList 938 * @see #readBinderList 939 */ 940 public final void writeBinderList(List<IBinder> val) { 941 if (val == null) { 942 writeInt(-1); 943 return; 944 } 945 int N = val.size(); 946 int i=0; 947 writeInt(N); 948 while (i < N) { 949 writeStrongBinder(val.get(i)); 950 i++; 951 } 952 } 953 954 /** 955 * Flatten a heterogeneous array containing a particular object type into 956 * the parcel, at 957 * the current dataPosition() and growing dataCapacity() if needed. The 958 * type of the objects in the array must be one that implements Parcelable. 959 * Unlike the {@link #writeParcelableArray} method, however, only the 960 * raw data of the objects is written and not their type, so you must use 961 * {@link #readTypedArray} with the correct corresponding 962 * {@link Parcelable.Creator} implementation to unmarshall them. 963 * 964 * @param val The array of objects to be written. 965 * @param parcelableFlags Contextual flags as per 966 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 967 * 968 * @see #readTypedArray 969 * @see #writeParcelableArray 970 * @see Parcelable.Creator 971 */ 972 public final <T extends Parcelable> void writeTypedArray(T[] val, 973 int parcelableFlags) { 974 if (val != null) { 975 int N = val.length; 976 writeInt(N); 977 for (int i=0; i<N; i++) { 978 T item = val[i]; 979 if (item != null) { 980 writeInt(1); 981 item.writeToParcel(this, parcelableFlags); 982 } else { 983 writeInt(0); 984 } 985 } 986 } else { 987 writeInt(-1); 988 } 989 } 990 991 /** 992 * Flatten a generic object in to a parcel. The given Object value may 993 * currently be one of the following types: 994 * 995 * <ul> 996 * <li> null 997 * <li> String 998 * <li> Byte 999 * <li> Short 1000 * <li> Integer 1001 * <li> Long 1002 * <li> Float 1003 * <li> Double 1004 * <li> Boolean 1005 * <li> String[] 1006 * <li> boolean[] 1007 * <li> byte[] 1008 * <li> int[] 1009 * <li> long[] 1010 * <li> Object[] (supporting objects of the same type defined here). 1011 * <li> {@link Bundle} 1012 * <li> Map (as supported by {@link #writeMap}). 1013 * <li> Any object that implements the {@link Parcelable} protocol. 1014 * <li> Parcelable[] 1015 * <li> CharSequence (as supported by {@link TextUtils#writeToParcel}). 1016 * <li> List (as supported by {@link #writeList}). 1017 * <li> {@link SparseArray} (as supported by {@link #writeSparseArray}). 1018 * <li> {@link IBinder} 1019 * <li> Any object that implements Serializable (but see 1020 * {@link #writeSerializable} for caveats). Note that all of the 1021 * previous types have relatively efficient implementations for 1022 * writing to a Parcel; having to rely on the generic serialization 1023 * approach is much less efficient and should be avoided whenever 1024 * possible. 1025 * </ul> 1026 */ 1027 public final void writeValue(Object v) { 1028 if (v == null) { 1029 writeInt(VAL_NULL); 1030 } else if (v instanceof String) { 1031 writeInt(VAL_STRING); 1032 writeString((String) v); 1033 } else if (v instanceof Integer) { 1034 writeInt(VAL_INTEGER); 1035 writeInt((Integer) v); 1036 } else if (v instanceof Map) { 1037 writeInt(VAL_MAP); 1038 writeMap((Map) v); 1039 } else if (v instanceof Bundle) { 1040 // Must be before Parcelable 1041 writeInt(VAL_BUNDLE); 1042 writeBundle((Bundle) v); 1043 } else if (v instanceof Parcelable) { 1044 writeInt(VAL_PARCELABLE); 1045 writeParcelable((Parcelable) v, 0); 1046 } else if (v instanceof Short) { 1047 writeInt(VAL_SHORT); 1048 writeInt(((Short) v).intValue()); 1049 } else if (v instanceof Long) { 1050 writeInt(VAL_LONG); 1051 writeLong((Long) v); 1052 } else if (v instanceof Float) { 1053 writeInt(VAL_FLOAT); 1054 writeFloat((Float) v); 1055 } else if (v instanceof Double) { 1056 writeInt(VAL_DOUBLE); 1057 writeDouble((Double) v); 1058 } else if (v instanceof Boolean) { 1059 writeInt(VAL_BOOLEAN); 1060 writeInt((Boolean) v ? 1 : 0); 1061 } else if (v instanceof CharSequence) { 1062 // Must be after String 1063 writeInt(VAL_CHARSEQUENCE); 1064 TextUtils.writeToParcel((CharSequence) v, this, 0); 1065 } else if (v instanceof List) { 1066 writeInt(VAL_LIST); 1067 writeList((List) v); 1068 } else if (v instanceof SparseArray) { 1069 writeInt(VAL_SPARSEARRAY); 1070 writeSparseArray((SparseArray) v); 1071 } else if (v instanceof boolean[]) { 1072 writeInt(VAL_BOOLEANARRAY); 1073 writeBooleanArray((boolean[]) v); 1074 } else if (v instanceof byte[]) { 1075 writeInt(VAL_BYTEARRAY); 1076 writeByteArray((byte[]) v); 1077 } else if (v instanceof String[]) { 1078 writeInt(VAL_STRINGARRAY); 1079 writeStringArray((String[]) v); 1080 } else if (v instanceof IBinder) { 1081 writeInt(VAL_IBINDER); 1082 writeStrongBinder((IBinder) v); 1083 } else if (v instanceof Parcelable[]) { 1084 writeInt(VAL_PARCELABLEARRAY); 1085 writeParcelableArray((Parcelable[]) v, 0); 1086 } else if (v instanceof Object[]) { 1087 writeInt(VAL_OBJECTARRAY); 1088 writeArray((Object[]) v); 1089 } else if (v instanceof int[]) { 1090 writeInt(VAL_INTARRAY); 1091 writeIntArray((int[]) v); 1092 } else if (v instanceof long[]) { 1093 writeInt(VAL_LONGARRAY); 1094 writeLongArray((long[]) v); 1095 } else if (v instanceof Byte) { 1096 writeInt(VAL_BYTE); 1097 writeInt((Byte) v); 1098 } else if (v instanceof Serializable) { 1099 // Must be last 1100 writeInt(VAL_SERIALIZABLE); 1101 writeSerializable((Serializable) v); 1102 } else { 1103 throw new RuntimeException("Parcel: unable to marshal value " + v); 1104 } 1105 } 1106 1107 /** 1108 * Flatten the name of the class of the Parcelable and its contents 1109 * into the parcel. 1110 * 1111 * @param p The Parcelable object to be written. 1112 * @param parcelableFlags Contextual flags as per 1113 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 1114 */ 1115 public final void writeParcelable(Parcelable p, int parcelableFlags) { 1116 if (p == null) { 1117 writeString(null); 1118 return; 1119 } 1120 String name = p.getClass().getName(); 1121 writeString(name); 1122 p.writeToParcel(this, parcelableFlags); 1123 } 1124 1125 /** 1126 * Write a generic serializable object in to a Parcel. It is strongly 1127 * recommended that this method be avoided, since the serialization 1128 * overhead is extremely large, and this approach will be much slower than 1129 * using the other approaches to writing data in to a Parcel. 1130 */ 1131 public final void writeSerializable(Serializable s) { 1132 if (s == null) { 1133 writeString(null); 1134 return; 1135 } 1136 String name = s.getClass().getName(); 1137 writeString(name); 1138 1139 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1140 try { 1141 ObjectOutputStream oos = new ObjectOutputStream(baos); 1142 oos.writeObject(s); 1143 oos.close(); 1144 1145 writeByteArray(baos.toByteArray()); 1146 } catch (IOException ioe) { 1147 throw new RuntimeException("Parcelable encountered " + 1148 "IOException writing serializable object (name = " + name + 1149 ")", ioe); 1150 } 1151 } 1152 1153 /** 1154 * Special function for writing an exception result at the header of 1155 * a parcel, to be used when returning an exception from a transaction. 1156 * Note that this currently only supports a few exception types; any other 1157 * exception will be re-thrown by this function as a RuntimeException 1158 * (to be caught by the system's last-resort exception handling when 1159 * dispatching a transaction). 1160 * 1161 * <p>The supported exception types are: 1162 * <ul> 1163 * <li>{@link BadParcelableException} 1164 * <li>{@link IllegalArgumentException} 1165 * <li>{@link IllegalStateException} 1166 * <li>{@link NullPointerException} 1167 * <li>{@link SecurityException} 1168 * </ul> 1169 * 1170 * @param e The Exception to be written. 1171 * 1172 * @see #writeNoException 1173 * @see #readException 1174 */ 1175 public final void writeException(Exception e) { 1176 int code = 0; 1177 if (e instanceof SecurityException) { 1178 code = EX_SECURITY; 1179 } else if (e instanceof BadParcelableException) { 1180 code = EX_BAD_PARCELABLE; 1181 } else if (e instanceof IllegalArgumentException) { 1182 code = EX_ILLEGAL_ARGUMENT; 1183 } else if (e instanceof NullPointerException) { 1184 code = EX_NULL_POINTER; 1185 } else if (e instanceof IllegalStateException) { 1186 code = EX_ILLEGAL_STATE; 1187 } 1188 writeInt(code); 1189 if (code == 0) { 1190 if (e instanceof RuntimeException) { 1191 throw (RuntimeException) e; 1192 } 1193 throw new RuntimeException(e); 1194 } 1195 writeString(e.getMessage()); 1196 } 1197 1198 /** 1199 * Special function for writing information at the front of the Parcel 1200 * indicating that no exception occurred. 1201 * 1202 * @see #writeException 1203 * @see #readException 1204 */ 1205 public final void writeNoException() { 1206 writeInt(0); 1207 } 1208 1209 /** 1210 * Special function for reading an exception result from the header of 1211 * a parcel, to be used after receiving the result of a transaction. This 1212 * will throw the exception for you if it had been written to the Parcel, 1213 * otherwise return and let you read the normal result data from the Parcel. 1214 * 1215 * @see #writeException 1216 * @see #writeNoException 1217 */ 1218 public final void readException() { 1219 int code = readInt(); 1220 if (code == 0) return; 1221 String msg = readString(); 1222 readException(code, msg); 1223 } 1224 1225 /** 1226 * Use this function for customized exception handling. 1227 * customized method call this method for all unknown case 1228 * @param code exception code 1229 * @param msg exception message 1230 */ 1231 public final void readException(int code, String msg) { 1232 switch (code) { 1233 case EX_SECURITY: 1234 throw new SecurityException(msg); 1235 case EX_BAD_PARCELABLE: 1236 throw new BadParcelableException(msg); 1237 case EX_ILLEGAL_ARGUMENT: 1238 throw new IllegalArgumentException(msg); 1239 case EX_NULL_POINTER: 1240 throw new NullPointerException(msg); 1241 case EX_ILLEGAL_STATE: 1242 throw new IllegalStateException(msg); 1243 } 1244 throw new RuntimeException("Unknown exception code: " + code 1245 + " msg " + msg); 1246 } 1247 1248 /** 1249 * Read an integer value from the parcel at the current dataPosition(). 1250 */ 1251 public final native int readInt(); 1252 1253 /** 1254 * Read a long integer value from the parcel at the current dataPosition(). 1255 */ 1256 public final native long readLong(); 1257 1258 /** 1259 * Read a floating point value from the parcel at the current 1260 * dataPosition(). 1261 */ 1262 public final native float readFloat(); 1263 1264 /** 1265 * Read a double precision floating point value from the parcel at the 1266 * current dataPosition(). 1267 */ 1268 public final native double readDouble(); 1269 1270 /** 1271 * Read a string value from the parcel at the current dataPosition(). 1272 */ 1273 public final native String readString(); 1274 1275 /** 1276 * Read an object from the parcel at the current dataPosition(). 1277 */ 1278 public final native IBinder readStrongBinder(); 1279 1280 /** 1281 * Read a FileDescriptor from the parcel at the current dataPosition(). 1282 */ 1283 public final ParcelFileDescriptor readFileDescriptor() { 1284 FileDescriptor fd = internalReadFileDescriptor(); 1285 return fd != null ? new ParcelFileDescriptor(fd) : null; 1286 } 1287 1288 private native FileDescriptor internalReadFileDescriptor(); 1289 /*package*/ static native FileDescriptor openFileDescriptor(String file, 1290 int mode) throws FileNotFoundException; 1291 /*package*/ static native void closeFileDescriptor(FileDescriptor desc) 1292 throws IOException; 1293 1294 /** 1295 * Read a byte value from the parcel at the current dataPosition(). 1296 */ 1297 public final byte readByte() { 1298 return (byte)(readInt() & 0xff); 1299 } 1300 1301 /** 1302 * Please use {@link #readBundle(ClassLoader)} instead (whose data must have 1303 * been written with {@link #writeBundle}. Read into an existing Map object 1304 * from the parcel at the current dataPosition(). 1305 */ 1306 public final void readMap(Map outVal, ClassLoader loader) { 1307 int N = readInt(); 1308 readMapInternal(outVal, N, loader); 1309 } 1310 1311 /** 1312 * Read into an existing List object from the parcel at the current 1313 * dataPosition(), using the given class loader to load any enclosed 1314 * Parcelables. If it is null, the default class loader is used. 1315 */ 1316 public final void readList(List outVal, ClassLoader loader) { 1317 int N = readInt(); 1318 readListInternal(outVal, N, loader); 1319 } 1320 1321 /** 1322 * Please use {@link #readBundle(ClassLoader)} instead (whose data must have 1323 * been written with {@link #writeBundle}. Read and return a new HashMap 1324 * object from the parcel at the current dataPosition(), using the given 1325 * class loader to load any enclosed Parcelables. Returns null if 1326 * the previously written map object was null. 1327 */ 1328 public final HashMap readHashMap(ClassLoader loader) 1329 { 1330 int N = readInt(); 1331 if (N < 0) { 1332 return null; 1333 } 1334 HashMap m = new HashMap(N); 1335 readMapInternal(m, N, loader); 1336 return m; 1337 } 1338 1339 /** 1340 * Read and return a new Bundle object from the parcel at the current 1341 * dataPosition(). Returns null if the previously written Bundle object was 1342 * null. 1343 */ 1344 public final Bundle readBundle() { 1345 return readBundle(null); 1346 } 1347 1348 /** 1349 * Read and return a new Bundle object from the parcel at the current 1350 * dataPosition(), using the given class loader to initialize the class 1351 * loader of the Bundle for later retrieval of Parcelable objects. 1352 * Returns null if the previously written Bundle object was null. 1353 */ 1354 public final Bundle readBundle(ClassLoader loader) { 1355 int offset = dataPosition(); 1356 int length = readInt(); 1357 if (length < 0) { 1358 return null; 1359 } 1360 int magic = readInt(); 1361 if (magic != 0x4C444E42) { 1362 //noinspection ThrowableInstanceNeverThrown 1363 String st = Log.getStackTraceString(new RuntimeException()); 1364 Log.e("Bundle", "readBundle: bad magic number"); 1365 Log.e("Bundle", "readBundle: trace = " + st); 1366 } 1367 1368 // Advance within this Parcel 1369 setDataPosition(offset + length + 4); 1370 1371 Parcel p = new Parcel(0); 1372 p.setDataPosition(0); 1373 p.appendFrom(this, offset, length + 4); 1374 p.setDataPosition(0); 1375 final Bundle bundle = new Bundle(p); 1376 if (loader != null) { 1377 bundle.setClassLoader(loader); 1378 } 1379 return bundle; 1380 } 1381 1382 /** 1383 * Read and return a new Bundle object from the parcel at the current 1384 * dataPosition(). Returns null if the previously written Bundle object was 1385 * null. The returned bundle will have its contents fully unpacked using 1386 * the given ClassLoader. 1387 */ 1388 /* package */ Bundle readBundleUnpacked(ClassLoader loader) { 1389 int length = readInt(); 1390 if (length == -1) { 1391 return null; 1392 } 1393 int magic = readInt(); 1394 if (magic != 0x4C444E42) { 1395 //noinspection ThrowableInstanceNeverThrown 1396 String st = Log.getStackTraceString(new RuntimeException()); 1397 Log.e("Bundle", "readBundleUnpacked: bad magic number"); 1398 Log.e("Bundle", "readBundleUnpacked: trace = " + st); 1399 } 1400 Bundle m = new Bundle(loader); 1401 int N = readInt(); 1402 if (N < 0) { 1403 return null; 1404 } 1405 readMapInternal(m.mMap, N, loader); 1406 return m; 1407 } 1408 1409 /** 1410 * Read and return a byte[] object from the parcel. 1411 */ 1412 public final native byte[] createByteArray(); 1413 1414 /** 1415 * Read a byte[] object from the parcel and copy it into the 1416 * given byte array. 1417 */ 1418 public final void readByteArray(byte[] val) { 1419 // TODO: make this a native method to avoid the extra copy. 1420 byte[] ba = createByteArray(); 1421 if (ba.length == val.length) { 1422 System.arraycopy(ba, 0, val, 0, ba.length); 1423 } else { 1424 throw new RuntimeException("bad array lengths"); 1425 } 1426 } 1427 1428 /** 1429 * Read and return a String[] object from the parcel. 1430 * {@hide} 1431 */ 1432 public final String[] readStringArray() { 1433 String[] array = null; 1434 1435 int length = readInt(); 1436 if (length >= 0) 1437 { 1438 array = new String[length]; 1439 1440 for (int i = 0 ; i < length ; i++) 1441 { 1442 array[i] = readString(); 1443 } 1444 } 1445 1446 return array; 1447 } 1448 1449 /** 1450 * Read and return a new ArrayList object from the parcel at the current 1451 * dataPosition(). Returns null if the previously written list object was 1452 * null. The given class loader will be used to load any enclosed 1453 * Parcelables. 1454 */ 1455 public final ArrayList readArrayList(ClassLoader loader) { 1456 int N = readInt(); 1457 if (N < 0) { 1458 return null; 1459 } 1460 ArrayList l = new ArrayList(N); 1461 readListInternal(l, N, loader); 1462 return l; 1463 } 1464 1465 /** 1466 * Read and return a new Object array from the parcel at the current 1467 * dataPosition(). Returns null if the previously written array was 1468 * null. The given class loader will be used to load any enclosed 1469 * Parcelables. 1470 */ 1471 public final Object[] readArray(ClassLoader loader) { 1472 int N = readInt(); 1473 if (N < 0) { 1474 return null; 1475 } 1476 Object[] l = new Object[N]; 1477 readArrayInternal(l, N, loader); 1478 return l; 1479 } 1480 1481 /** 1482 * Read and return a new SparseArray object from the parcel at the current 1483 * dataPosition(). Returns null if the previously written list object was 1484 * null. The given class loader will be used to load any enclosed 1485 * Parcelables. 1486 */ 1487 public final SparseArray readSparseArray(ClassLoader loader) { 1488 int N = readInt(); 1489 if (N < 0) { 1490 return null; 1491 } 1492 SparseArray sa = new SparseArray(N); 1493 readSparseArrayInternal(sa, N, loader); 1494 return sa; 1495 } 1496 1497 /** 1498 * Read and return a new SparseBooleanArray object from the parcel at the current 1499 * dataPosition(). Returns null if the previously written list object was 1500 * null. 1501 */ 1502 public final SparseBooleanArray readSparseBooleanArray() { 1503 int N = readInt(); 1504 if (N < 0) { 1505 return null; 1506 } 1507 SparseBooleanArray sa = new SparseBooleanArray(N); 1508 readSparseBooleanArrayInternal(sa, N); 1509 return sa; 1510 } 1511 1512 /** 1513 * Read and return a new ArrayList containing a particular object type from 1514 * the parcel that was written with {@link #writeTypedList} at the 1515 * current dataPosition(). Returns null if the 1516 * previously written list object was null. The list <em>must</em> have 1517 * previously been written via {@link #writeTypedList} with the same object 1518 * type. 1519 * 1520 * @return A newly created ArrayList containing objects with the same data 1521 * as those that were previously written. 1522 * 1523 * @see #writeTypedList 1524 */ 1525 public final <T> ArrayList<T> createTypedArrayList(Parcelable.Creator<T> c) { 1526 int N = readInt(); 1527 if (N < 0) { 1528 return null; 1529 } 1530 ArrayList<T> l = new ArrayList<T>(N); 1531 while (N > 0) { 1532 if (readInt() != 0) { 1533 l.add(c.createFromParcel(this)); 1534 } else { 1535 l.add(null); 1536 } 1537 N--; 1538 } 1539 return l; 1540 } 1541 1542 /** 1543 * Read into the given List items containing a particular object type 1544 * that were written with {@link #writeTypedList} at the 1545 * current dataPosition(). The list <em>must</em> have 1546 * previously been written via {@link #writeTypedList} with the same object 1547 * type. 1548 * 1549 * @return A newly created ArrayList containing objects with the same data 1550 * as those that were previously written. 1551 * 1552 * @see #writeTypedList 1553 */ 1554 public final <T> void readTypedList(List<T> list, Parcelable.Creator<T> c) { 1555 int M = list.size(); 1556 int N = readInt(); 1557 int i = 0; 1558 for (; i < M && i < N; i++) { 1559 if (readInt() != 0) { 1560 list.set(i, c.createFromParcel(this)); 1561 } else { 1562 list.set(i, null); 1563 } 1564 } 1565 for (; i<N; i++) { 1566 if (readInt() != 0) { 1567 list.add(c.createFromParcel(this)); 1568 } else { 1569 list.add(null); 1570 } 1571 } 1572 for (; i<M; i++) { 1573 list.remove(N); 1574 } 1575 } 1576 1577 /** 1578 * Read and return a new ArrayList containing String objects from 1579 * the parcel that was written with {@link #writeStringList} at the 1580 * current dataPosition(). Returns null if the 1581 * previously written list object was null. 1582 * 1583 * @return A newly created ArrayList containing strings with the same data 1584 * as those that were previously written. 1585 * 1586 * @see #writeStringList 1587 */ 1588 public final ArrayList<String> createStringArrayList() { 1589 int N = readInt(); 1590 if (N < 0) { 1591 return null; 1592 } 1593 ArrayList<String> l = new ArrayList<String>(N); 1594 while (N > 0) { 1595 l.add(readString()); 1596 N--; 1597 } 1598 return l; 1599 } 1600 1601 /** 1602 * Read and return a new ArrayList containing IBinder objects from 1603 * the parcel that was written with {@link #writeBinderList} at the 1604 * current dataPosition(). Returns null if the 1605 * previously written list object was null. 1606 * 1607 * @return A newly created ArrayList containing strings with the same data 1608 * as those that were previously written. 1609 * 1610 * @see #writeBinderList 1611 */ 1612 public final ArrayList<IBinder> createBinderArrayList() { 1613 int N = readInt(); 1614 if (N < 0) { 1615 return null; 1616 } 1617 ArrayList<IBinder> l = new ArrayList<IBinder>(N); 1618 while (N > 0) { 1619 l.add(readStrongBinder()); 1620 N--; 1621 } 1622 return l; 1623 } 1624 1625 /** 1626 * Read into the given List items String objects that were written with 1627 * {@link #writeStringList} at the current dataPosition(). 1628 * 1629 * @return A newly created ArrayList containing strings with the same data 1630 * as those that were previously written. 1631 * 1632 * @see #writeStringList 1633 */ 1634 public final void readStringList(List<String> list) { 1635 int M = list.size(); 1636 int N = readInt(); 1637 int i = 0; 1638 for (; i < M && i < N; i++) { 1639 list.set(i, readString()); 1640 } 1641 for (; i<N; i++) { 1642 list.add(readString()); 1643 } 1644 for (; i<M; i++) { 1645 list.remove(N); 1646 } 1647 } 1648 1649 /** 1650 * Read into the given List items IBinder objects that were written with 1651 * {@link #writeBinderList} at the current dataPosition(). 1652 * 1653 * @return A newly created ArrayList containing strings with the same data 1654 * as those that were previously written. 1655 * 1656 * @see #writeBinderList 1657 */ 1658 public final void readBinderList(List<IBinder> list) { 1659 int M = list.size(); 1660 int N = readInt(); 1661 int i = 0; 1662 for (; i < M && i < N; i++) { 1663 list.set(i, readStrongBinder()); 1664 } 1665 for (; i<N; i++) { 1666 list.add(readStrongBinder()); 1667 } 1668 for (; i<M; i++) { 1669 list.remove(N); 1670 } 1671 } 1672 1673 /** 1674 * Read and return a new array containing a particular object type from 1675 * the parcel at the current dataPosition(). Returns null if the 1676 * previously written array was null. The array <em>must</em> have 1677 * previously been written via {@link #writeTypedArray} with the same 1678 * object type. 1679 * 1680 * @return A newly created array containing objects with the same data 1681 * as those that were previously written. 1682 * 1683 * @see #writeTypedArray 1684 */ 1685 public final <T> T[] createTypedArray(Parcelable.Creator<T> c) { 1686 int N = readInt(); 1687 if (N < 0) { 1688 return null; 1689 } 1690 T[] l = c.newArray(N); 1691 for (int i=0; i<N; i++) { 1692 if (readInt() != 0) { 1693 l[i] = c.createFromParcel(this); 1694 } 1695 } 1696 return l; 1697 } 1698 1699 public final <T> void readTypedArray(T[] val, Parcelable.Creator<T> c) { 1700 int N = readInt(); 1701 if (N == val.length) { 1702 for (int i=0; i<N; i++) { 1703 if (readInt() != 0) { 1704 val[i] = c.createFromParcel(this); 1705 } else { 1706 val[i] = null; 1707 } 1708 } 1709 } else { 1710 throw new RuntimeException("bad array lengths"); 1711 } 1712 } 1713 1714 /** 1715 * @deprecated 1716 * @hide 1717 */ 1718 @Deprecated 1719 public final <T> T[] readTypedArray(Parcelable.Creator<T> c) { 1720 return createTypedArray(c); 1721 } 1722 1723 /** 1724 * Write a heterogeneous array of Parcelable objects into the Parcel. 1725 * Each object in the array is written along with its class name, so 1726 * that the correct class can later be instantiated. As a result, this 1727 * has significantly more overhead than {@link #writeTypedArray}, but will 1728 * correctly handle an array containing more than one type of object. 1729 * 1730 * @param value The array of objects to be written. 1731 * @param parcelableFlags Contextual flags as per 1732 * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}. 1733 * 1734 * @see #writeTypedArray 1735 */ 1736 public final <T extends Parcelable> void writeParcelableArray(T[] value, 1737 int parcelableFlags) { 1738 if (value != null) { 1739 int N = value.length; 1740 writeInt(N); 1741 for (int i=0; i<N; i++) { 1742 writeParcelable(value[i], parcelableFlags); 1743 } 1744 } else { 1745 writeInt(-1); 1746 } 1747 } 1748 1749 /** 1750 * Read a typed object from a parcel. The given class loader will be 1751 * used to load any enclosed Parcelables. If it is null, the default class 1752 * loader will be used. 1753 */ 1754 public final Object readValue(ClassLoader loader) { 1755 int type = readInt(); 1756 1757 switch (type) { 1758 case VAL_NULL: 1759 return null; 1760 1761 case VAL_STRING: 1762 return readString(); 1763 1764 case VAL_INTEGER: 1765 return readInt(); 1766 1767 case VAL_MAP: 1768 return readHashMap(loader); 1769 1770 case VAL_PARCELABLE: 1771 return readParcelable(loader); 1772 1773 case VAL_SHORT: 1774 return (short) readInt(); 1775 1776 case VAL_LONG: 1777 return readLong(); 1778 1779 case VAL_FLOAT: 1780 return readFloat(); 1781 1782 case VAL_DOUBLE: 1783 return readDouble(); 1784 1785 case VAL_BOOLEAN: 1786 return readInt() == 1; 1787 1788 case VAL_CHARSEQUENCE: 1789 return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this); 1790 1791 case VAL_LIST: 1792 return readArrayList(loader); 1793 1794 case VAL_BOOLEANARRAY: 1795 return createBooleanArray(); 1796 1797 case VAL_BYTEARRAY: 1798 return createByteArray(); 1799 1800 case VAL_STRINGARRAY: 1801 return readStringArray(); 1802 1803 case VAL_IBINDER: 1804 return readStrongBinder(); 1805 1806 case VAL_OBJECTARRAY: 1807 return readArray(loader); 1808 1809 case VAL_INTARRAY: 1810 return createIntArray(); 1811 1812 case VAL_LONGARRAY: 1813 return createLongArray(); 1814 1815 case VAL_BYTE: 1816 return readByte(); 1817 1818 case VAL_SERIALIZABLE: 1819 return readSerializable(); 1820 1821 case VAL_PARCELABLEARRAY: 1822 return readParcelableArray(loader); 1823 1824 case VAL_SPARSEARRAY: 1825 return readSparseArray(loader); 1826 1827 case VAL_SPARSEBOOLEANARRAY: 1828 return readSparseBooleanArray(); 1829 1830 case VAL_BUNDLE: 1831 return readBundle(loader); // loading will be deferred 1832 1833 default: 1834 int off = dataPosition() - 4; 1835 throw new RuntimeException( 1836 "Parcel " + this + ": Unmarshalling unknown type code " + type + " at offset " + off); 1837 } 1838 } 1839 1840 /** 1841 * Read and return a new Parcelable from the parcel. The given class loader 1842 * will be used to load any enclosed Parcelables. If it is null, the default 1843 * class loader will be used. 1844 * @param loader A ClassLoader from which to instantiate the Parcelable 1845 * object, or null for the default class loader. 1846 * @return Returns the newly created Parcelable, or null if a null 1847 * object has been written. 1848 * @throws BadParcelableException Throws BadParcelableException if there 1849 * was an error trying to instantiate the Parcelable. 1850 */ 1851 public final <T extends Parcelable> T readParcelable(ClassLoader loader) { 1852 String name = readString(); 1853 if (name == null) { 1854 return null; 1855 } 1856 Parcelable.Creator<T> creator; 1857 synchronized (mCreators) { 1858 HashMap<String,Parcelable.Creator> map = mCreators.get(loader); 1859 if (map == null) { 1860 map = new HashMap<String,Parcelable.Creator>(); 1861 mCreators.put(loader, map); 1862 } 1863 creator = map.get(name); 1864 if (creator == null) { 1865 try { 1866 Class c = loader == null ? 1867 Class.forName(name) : Class.forName(name, true, loader); 1868 Field f = c.getField("CREATOR"); 1869 creator = (Parcelable.Creator)f.get(null); 1870 } 1871 catch (IllegalAccessException e) { 1872 Log.e("Parcel", "Class not found when unmarshalling: " 1873 + name + ", e: " + e); 1874 throw new BadParcelableException( 1875 "IllegalAccessException when unmarshalling: " + name); 1876 } 1877 catch (ClassNotFoundException e) { 1878 Log.e("Parcel", "Class not found when unmarshalling: " 1879 + name + ", e: " + e); 1880 throw new BadParcelableException( 1881 "ClassNotFoundException when unmarshalling: " + name); 1882 } 1883 catch (ClassCastException e) { 1884 throw new BadParcelableException("Parcelable protocol requires a " 1885 + "Parcelable.Creator object called " 1886 + " CREATOR on class " + name); 1887 } 1888 catch (NoSuchFieldException e) { 1889 throw new BadParcelableException("Parcelable protocol requires a " 1890 + "Parcelable.Creator object called " 1891 + " CREATOR on class " + name); 1892 } 1893 if (creator == null) { 1894 throw new BadParcelableException("Parcelable protocol requires a " 1895 + "Parcelable.Creator object called " 1896 + " CREATOR on class " + name); 1897 } 1898 1899 map.put(name, creator); 1900 } 1901 } 1902 1903 return creator.createFromParcel(this); 1904 } 1905 1906 /** 1907 * Read and return a new Parcelable array from the parcel. 1908 * The given class loader will be used to load any enclosed 1909 * Parcelables. 1910 * @return the Parcelable array, or null if the array is null 1911 */ 1912 public final Parcelable[] readParcelableArray(ClassLoader loader) { 1913 int N = readInt(); 1914 if (N < 0) { 1915 return null; 1916 } 1917 Parcelable[] p = new Parcelable[N]; 1918 for (int i = 0; i < N; i++) { 1919 p[i] = (Parcelable) readParcelable(loader); 1920 } 1921 return p; 1922 } 1923 1924 /** 1925 * Read and return a new Serializable object from the parcel. 1926 * @return the Serializable object, or null if the Serializable name 1927 * wasn't found in the parcel. 1928 */ 1929 public final Serializable readSerializable() { 1930 String name = readString(); 1931 if (name == null) { 1932 // For some reason we were unable to read the name of the Serializable (either there 1933 // is nothing left in the Parcel to read, or the next value wasn't a String), so 1934 // return null, which indicates that the name wasn't found in the parcel. 1935 return null; 1936 } 1937 1938 byte[] serializedData = createByteArray(); 1939 ByteArrayInputStream bais = new ByteArrayInputStream(serializedData); 1940 try { 1941 ObjectInputStream ois = new ObjectInputStream(bais); 1942 return (Serializable) ois.readObject(); 1943 } catch (IOException ioe) { 1944 throw new RuntimeException("Parcelable encountered " + 1945 "IOException reading a Serializable object (name = " + name + 1946 ")", ioe); 1947 } catch (ClassNotFoundException cnfe) { 1948 throw new RuntimeException("Parcelable encountered" + 1949 "ClassNotFoundException reading a Serializable object (name = " 1950 + name + ")", cnfe); 1951 } 1952 } 1953 1954 // Cache of previously looked up CREATOR.createFromParcel() methods for 1955 // particular classes. Keys are the names of the classes, values are 1956 // Method objects. 1957 private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator>> 1958 mCreators = new HashMap<ClassLoader,HashMap<String,Parcelable.Creator>>(); 1959 1960 static protected final Parcel obtain(int obj) { 1961 final Parcel[] pool = sHolderPool; 1962 synchronized (pool) { 1963 Parcel p; 1964 for (int i=0; i<POOL_SIZE; i++) { 1965 p = pool[i]; 1966 if (p != null) { 1967 pool[i] = null; 1968 if (DEBUG_RECYCLE) { 1969 p.mStack = new RuntimeException(); 1970 } 1971 p.init(obj); 1972 return p; 1973 } 1974 } 1975 } 1976 return new Parcel(obj); 1977 } 1978 1979 private Parcel(int obj) { 1980 if (DEBUG_RECYCLE) { 1981 mStack = new RuntimeException(); 1982 } 1983 //Log.i("Parcel", "Initializing obj=0x" + Integer.toHexString(obj), mStack); 1984 init(obj); 1985 } 1986 1987 @Override 1988 protected void finalize() throws Throwable { 1989 if (DEBUG_RECYCLE) { 1990 if (mStack != null) { 1991 Log.w("Parcel", "Client did not call Parcel.recycle()", mStack); 1992 } 1993 } 1994 destroy(); 1995 } 1996 1997 private native void freeBuffer(); 1998 private native void init(int obj); 1999 private native void destroy(); 2000 2001 private void readMapInternal(Map outVal, int N, 2002 ClassLoader loader) { 2003 while (N > 0) { 2004 Object key = readValue(loader); 2005 Object value = readValue(loader); 2006 outVal.put(key, value); 2007 N--; 2008 } 2009 } 2010 2011 private void readListInternal(List outVal, int N, 2012 ClassLoader loader) { 2013 while (N > 0) { 2014 Object value = readValue(loader); 2015 //Log.d("Parcel", "Unmarshalling value=" + value); 2016 outVal.add(value); 2017 N--; 2018 } 2019 } 2020 2021 private void readArrayInternal(Object[] outVal, int N, 2022 ClassLoader loader) { 2023 for (int i = 0; i < N; i++) { 2024 Object value = readValue(loader); 2025 //Log.d("Parcel", "Unmarshalling value=" + value); 2026 outVal[i] = value; 2027 } 2028 } 2029 2030 private void readSparseArrayInternal(SparseArray outVal, int N, 2031 ClassLoader loader) { 2032 while (N > 0) { 2033 int key = readInt(); 2034 Object value = readValue(loader); 2035 //Log.i("Parcel", "Unmarshalling key=" + key + " value=" + value); 2036 outVal.append(key, value); 2037 N--; 2038 } 2039 } 2040 2041 2042 private void readSparseBooleanArrayInternal(SparseBooleanArray outVal, int N) { 2043 while (N > 0) { 2044 int key = readInt(); 2045 boolean value = this.readByte() == 1; 2046 //Log.i("Parcel", "Unmarshalling key=" + key + " value=" + value); 2047 outVal.append(key, value); 2048 N--; 2049 } 2050 } 2051} 2052