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