private static final String LOG_TAG = "Bundle";
public static final Bundle EMPTY;
+ static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'
+
static {
EMPTY = new Bundle();
EMPTY.mMap = ArrayMap.EMPTY;
if (mParcelledData != null) {
int length = mParcelledData.dataSize();
parcel.writeInt(length);
- parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
+ parcel.writeInt(BUNDLE_MAGIC);
parcel.appendFrom(mParcelledData, 0, length);
} else {
parcel.writeInt(-1); // dummy, will hold length
- parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
+ parcel.writeInt(BUNDLE_MAGIC);
int oldPos = parcel.dataPosition();
parcel.writeArrayMapInternal(mMap);
void readFromParcelInner(Parcel parcel, int length) {
int magic = parcel.readInt();
- if (magic != 0x4C444E42) {
+ if (magic != BUNDLE_MAGIC) {
//noinspection ThrowableInstanceNeverThrown
- String st = Log.getStackTraceString(new RuntimeException());
- Log.e("Bundle", "readBundle: bad magic number");
- Log.e("Bundle", "readBundle: trace = " + st);
+ throw new IllegalStateException("Bad magic number for Bundle: 0x"
+ + Integer.toHexString(magic));
}
// Advance within this Parcel
p.setDataPosition(0);
p.appendFrom(parcel, offset, length);
p.setDataPosition(0);
-
- mParcelledData = p;
- mHasFds = p.hasFileDescriptors();
- mFdsKnown = true;
+
+ if (mMap != null) {
+ // It is not allowed to have a Bundle with both a map and a parcel, so if we
+ // already have a map then we need to immediately unparcel into it. This also
+ // lets us know we need to go through the slow path of unparceling, since the
+ // map may already contains some data so the two need to be merged.
+ if (mFdsKnown) {
+ mHasFds |= p.hasFileDescriptors();
+ }
+ int N = p.readInt();
+ p.readArrayMapSafelyInternal(mMap, N, mClassLoader);
+ p.recycle();
+ } else {
+ mParcelledData = p;
+ mHasFds = p.hasFileDescriptors();
+ mFdsKnown = true;
+ }
}
@Override
*/
public final class Parcel {
private static final boolean DEBUG_RECYCLE = false;
+ private static final boolean DEBUG_ARRAY_MAP = false;
private static final String TAG = "Parcel";
@SuppressWarnings({"UnusedDeclaration"})
}
final int N = val.size();
writeInt(N);
+ if (DEBUG_ARRAY_MAP) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Log.d(TAG, "Writing " + N + " ArrayMap entries", here);
+ }
for (int i=0; i<N; i++) {
+ if (DEBUG_ARRAY_MAP) Log.d(TAG, " Write #" + i + ": key=0x"
+ + (val.keyAt(i) != null ? val.keyAt(i).hashCode() : 0) + " " + val.keyAt(i));
writeValue(val.keyAt(i));
writeValue(val.valueAt(i));
}
/* package */ void readArrayMapInternal(ArrayMap outVal, int N,
ClassLoader loader) {
+ if (DEBUG_ARRAY_MAP) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Log.d(TAG, "Reading " + N + " ArrayMap entries", here);
+ }
while (N > 0) {
Object key = readValue(loader);
+ if (DEBUG_ARRAY_MAP) Log.d(TAG, " Read #" + (N-1) + ": key=0x"
+ + (key != null ? key.hashCode() : 0) + " " + key);
Object value = readValue(loader);
outVal.append(key, value);
N--;
}
}
+ /* package */ void readArrayMapSafelyInternal(ArrayMap outVal, int N,
+ ClassLoader loader) {
+ if (DEBUG_ARRAY_MAP) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Log.d(TAG, "Reading safely " + N + " ArrayMap entries", here);
+ }
+ while (N > 0) {
+ Object key = readValue(loader);
+ if (DEBUG_ARRAY_MAP) Log.d(TAG, " Read safe #" + (N-1) + ": key=0x"
+ + (key != null ? key.hashCode() : 0) + " " + key);
+ Object value = readValue(loader);
+ outVal.put(key, value);
+ N--;
+ }
+ }
+
private void readListInternal(List outVal, int N,
ClassLoader loader) {
while (N > 0) {