diff --git a/libs/utils/Parcel.cpp b/libs/utils/Parcel.cpp
new file mode 100644
index 0000000..3eca4b0
--- /dev/null
+++ b/libs/utils/Parcel.cpp
@@ -0,0 +1,1311 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Parcel"
+//#define LOG_NDEBUG 0
+
+#include <utils/Parcel.h>
+
+#include <utils/Binder.h>
+#include <utils/BpBinder.h>
+#include <utils/Debug.h>
+#include <utils/ProcessState.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <utils/TextOutput.h>
+#include <utils/misc.h>
+
+#include <private/utils/binder_module.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#ifndef INT32_MAX
+#define INT32_MAX ((int32_t)(2147483647))
+#endif
+
+#define LOG_REFS(...)
+//#define LOG_REFS(...) LOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
+
+// ---------------------------------------------------------------------------
+
+#define PAD_SIZE(s) (((s)+3)&~3)
+
+// XXX This can be made public if we want to provide
+// support for typed data.
+struct small_flat_data
+{
+    uint32_t type;
+    uint32_t data;
+};
+
+namespace android {
+
+void acquire_object(const sp<ProcessState>& proc,
+    const flat_binder_object& obj, const void* who)
+{
+    switch (obj.type) {
+        case BINDER_TYPE_BINDER:
+            if (obj.binder) {
+                LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
+                static_cast<IBinder*>(obj.cookie)->incStrong(who);
+            }
+            return;
+        case BINDER_TYPE_WEAK_BINDER:
+            if (obj.binder)
+                static_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
+            return;
+        case BINDER_TYPE_HANDLE: {
+            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
+            if (b != NULL) {
+                LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
+                b->incStrong(who);
+            }
+            return;
+        }
+        case BINDER_TYPE_WEAK_HANDLE: {
+            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
+            if (b != NULL) b.get_refs()->incWeak(who);
+            return;
+        }
+        case BINDER_TYPE_FD: {
+            // intentionally blank -- nothing to do to acquire this, but we do
+            // recognize it as a legitimate object type.
+            return;
+        }
+    }
+
+    LOGD("Invalid object type 0x%08lx", obj.type);
+}
+
+void release_object(const sp<ProcessState>& proc,
+    const flat_binder_object& obj, const void* who)
+{
+    switch (obj.type) {
+        case BINDER_TYPE_BINDER:
+            if (obj.binder) {
+                LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
+                static_cast<IBinder*>(obj.cookie)->decStrong(who);
+            }
+            return;
+        case BINDER_TYPE_WEAK_BINDER:
+            if (obj.binder)
+                static_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
+            return;
+        case BINDER_TYPE_HANDLE: {
+            const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
+            if (b != NULL) {
+                LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
+                b->decStrong(who);
+            }
+            return;
+        }
+        case BINDER_TYPE_WEAK_HANDLE: {
+            const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
+            if (b != NULL) b.get_refs()->decWeak(who);
+            return;
+        }
+        case BINDER_TYPE_FD: {
+            if (obj.cookie != (void*)0) close(obj.handle);
+            return;
+        }
+    }
+
+    LOGE("Invalid object type 0x%08lx", obj.type);
+}
+
+inline static status_t finish_flatten_binder(
+    const sp<IBinder>& binder, const flat_binder_object& flat, Parcel* out)
+{
+    return out->writeObject(flat, false);
+}
+
+status_t flatten_binder(const sp<ProcessState>& proc,
+    const sp<IBinder>& binder, Parcel* out)
+{
+    flat_binder_object obj;
+    
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    if (binder != NULL) {
+        IBinder *local = binder->localBinder();
+        if (!local) {
+            BpBinder *proxy = binder->remoteBinder();
+            if (proxy == NULL) {
+                LOGE("null proxy");
+            }
+            const int32_t handle = proxy ? proxy->handle() : 0;
+            obj.type = BINDER_TYPE_HANDLE;
+            obj.handle = handle;
+            obj.cookie = NULL;
+        } else {
+            obj.type = BINDER_TYPE_BINDER;
+            obj.binder = local->getWeakRefs();
+            obj.cookie = local;
+        }
+    } else {
+        obj.type = BINDER_TYPE_BINDER;
+        obj.binder = NULL;
+        obj.cookie = NULL;
+    }
+    
+    return finish_flatten_binder(binder, obj, out);
+}
+
+status_t flatten_binder(const sp<ProcessState>& proc,
+    const wp<IBinder>& binder, Parcel* out)
+{
+    flat_binder_object obj;
+    
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    if (binder != NULL) {
+        sp<IBinder> real = binder.promote();
+        if (real != NULL) {
+            IBinder *local = real->localBinder();
+            if (!local) {
+                BpBinder *proxy = real->remoteBinder();
+                if (proxy == NULL) {
+                    LOGE("null proxy");
+                }
+                const int32_t handle = proxy ? proxy->handle() : 0;
+                obj.type = BINDER_TYPE_WEAK_HANDLE;
+                obj.handle = handle;
+                obj.cookie = NULL;
+            } else {
+                obj.type = BINDER_TYPE_WEAK_BINDER;
+                obj.binder = binder.get_refs();
+                obj.cookie = binder.unsafe_get();
+            }
+            return finish_flatten_binder(real, obj, out);
+        }
+        
+        // XXX How to deal?  In order to flatten the given binder,
+        // we need to probe it for information, which requires a primary
+        // reference...  but we don't have one.
+        //
+        // The OpenBinder implementation uses a dynamic_cast<> here,
+        // but we can't do that with the different reference counting
+        // implementation we are using.
+        LOGE("Unable to unflatten Binder weak reference!");
+        obj.type = BINDER_TYPE_BINDER;
+        obj.binder = NULL;
+        obj.cookie = NULL;
+        return finish_flatten_binder(NULL, obj, out);
+    
+    } else {
+        obj.type = BINDER_TYPE_BINDER;
+        obj.binder = NULL;
+        obj.cookie = NULL;
+        return finish_flatten_binder(NULL, obj, out);
+    }
+}
+
+inline static status_t finish_unflatten_binder(
+    BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
+{
+    return NO_ERROR;
+}
+    
+status_t unflatten_binder(const sp<ProcessState>& proc,
+    const Parcel& in, sp<IBinder>* out)
+{
+    const flat_binder_object* flat = in.readObject(false);
+    
+    if (flat) {
+        switch (flat->type) {
+            case BINDER_TYPE_BINDER:
+                *out = static_cast<IBinder*>(flat->cookie);
+                return finish_unflatten_binder(NULL, *flat, in);
+            case BINDER_TYPE_HANDLE:
+                *out = proc->getStrongProxyForHandle(flat->handle);
+                return finish_unflatten_binder(
+                    static_cast<BpBinder*>(out->get()), *flat, in);
+        }        
+    }
+    return BAD_TYPE;
+}
+
+status_t unflatten_binder(const sp<ProcessState>& proc,
+    const Parcel& in, wp<IBinder>* out)
+{
+    const flat_binder_object* flat = in.readObject(false);
+    
+    if (flat) {
+        switch (flat->type) {
+            case BINDER_TYPE_BINDER:
+                *out = static_cast<IBinder*>(flat->cookie);
+                return finish_unflatten_binder(NULL, *flat, in);
+            case BINDER_TYPE_WEAK_BINDER:
+                if (flat->binder != NULL) {
+                    out->set_object_and_refs(
+                        static_cast<IBinder*>(flat->cookie),
+                        static_cast<RefBase::weakref_type*>(flat->binder));
+                } else {
+                    *out = NULL;
+                }
+                return finish_unflatten_binder(NULL, *flat, in);
+            case BINDER_TYPE_HANDLE:
+            case BINDER_TYPE_WEAK_HANDLE:
+                *out = proc->getWeakProxyForHandle(flat->handle);
+                return finish_unflatten_binder(
+                    static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
+        }
+    }
+    return BAD_TYPE;
+}
+
+// ---------------------------------------------------------------------------
+
+Parcel::Parcel()
+{
+    initState();
+}
+
+Parcel::~Parcel()
+{
+    freeDataNoInit();
+}
+
+const uint8_t* Parcel::data() const
+{
+    return mData;
+}
+
+size_t Parcel::dataSize() const
+{
+    return (mDataSize > mDataPos ? mDataSize : mDataPos);
+}
+
+size_t Parcel::dataAvail() const
+{
+    // TODO: decide what to do about the possibility that this can
+    // report an available-data size that exceeds a Java int's max
+    // positive value, causing havoc.  Fortunately this will only
+    // happen if someone constructs a Parcel containing more than two
+    // gigabytes of data, which on typical phone hardware is simply
+    // not possible.
+    return dataSize() - dataPosition();
+}
+
+size_t Parcel::dataPosition() const
+{
+    return mDataPos;
+}
+
+size_t Parcel::dataCapacity() const
+{
+    return mDataCapacity;
+}
+
+status_t Parcel::setDataSize(size_t size)
+{
+    status_t err;
+    err = continueWrite(size);
+    if (err == NO_ERROR) {
+        mDataSize = size;
+        LOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
+    }
+    return err;
+}
+
+void Parcel::setDataPosition(size_t pos) const
+{
+    mDataPos = pos;
+    mNextObjectHint = 0;
+}
+
+status_t Parcel::setDataCapacity(size_t size)
+{
+    if (size > mDataSize) return continueWrite(size);
+    return NO_ERROR;
+}
+
+status_t Parcel::setData(const uint8_t* buffer, size_t len)
+{
+    status_t err = restartWrite(len);
+    if (err == NO_ERROR) {
+        memcpy(const_cast<uint8_t*>(data()), buffer, len);
+        mDataSize = len;
+        mFdsKnown = false;
+    }
+    return err;
+}
+
+status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
+{
+    const sp<ProcessState> proc(ProcessState::self());
+    status_t err;
+    uint8_t *data = parcel->mData;
+    size_t *objects = parcel->mObjects;
+    size_t size = parcel->mObjectsSize;
+    int startPos = mDataPos;
+    int firstIndex = -1, lastIndex = -2;
+
+    if (len == 0) {
+        return NO_ERROR;
+    }
+
+    // range checks against the source parcel size
+    if ((offset > parcel->mDataSize)
+            || (len > parcel->mDataSize)
+            || (offset + len > parcel->mDataSize)) {
+        return BAD_VALUE;
+    }
+
+    // Count objects in range
+    for (int i = 0; i < (int) size; i++) {
+        size_t off = objects[i];
+        if ((off >= offset) && (off < offset + len)) {
+            if (firstIndex == -1) {
+                firstIndex = i;
+            }
+            lastIndex = i;
+        }
+    }
+    int numObjects = lastIndex - firstIndex + 1;
+
+    // grow data
+    err = growData(len);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    // append data
+    memcpy(mData + mDataPos, data + offset, len);
+    mDataPos += len;
+    mDataSize += len;
+
+    if (numObjects > 0) {
+        // grow objects
+        if (mObjectsCapacity < mObjectsSize + numObjects) {
+            int newSize = ((mObjectsSize + numObjects)*3)/2;
+            size_t *objects =
+                (size_t*)realloc(mObjects, newSize*sizeof(size_t));
+            if (objects == (size_t*)0) {
+                return NO_MEMORY;
+            }
+            mObjects = objects;
+            mObjectsCapacity = newSize;
+        }
+        
+        // append and acquire objects
+        int idx = mObjectsSize;
+        for (int i = firstIndex; i <= lastIndex; i++) {
+            size_t off = objects[i] - offset + startPos;
+            mObjects[idx++] = off;
+            mObjectsSize++;
+
+            const flat_binder_object* flat
+                = reinterpret_cast<flat_binder_object*>(mData + off);
+            acquire_object(proc, *flat, this);
+
+            // take note if the object is a file descriptor
+            if (flat->type == BINDER_TYPE_FD) {
+                mHasFds = mFdsKnown = true;
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
+bool Parcel::hasFileDescriptors() const
+{
+    if (!mFdsKnown) {
+        scanForFds();
+    }
+    return mHasFds;
+}
+
+status_t Parcel::writeInterfaceToken(const String16& interface)
+{
+    // currently the interface identification token is just its name as a string
+    return writeString16(interface);
+}
+
+bool Parcel::enforceInterface(const String16& interface) const
+{
+    String16 str = readString16();
+    if (str == interface) {
+        return true;
+    } else {
+        LOGW("**** enforceInterface() expected '%s' but read '%s'\n",
+                String8(interface).string(), String8(str).string());
+        return false;
+    }
+} 
+
+const size_t* Parcel::objects() const
+{
+    return mObjects;
+}
+
+size_t Parcel::objectsCount() const
+{
+    return mObjectsSize;
+}
+
+status_t Parcel::errorCheck() const
+{
+    return mError;
+}
+
+void Parcel::setError(status_t err)
+{
+    mError = err;
+}
+
+status_t Parcel::finishWrite(size_t len)
+{
+    //printf("Finish write of %d\n", len);
+    mDataPos += len;
+    LOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
+    if (mDataPos > mDataSize) {
+        mDataSize = mDataPos;
+        LOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
+    }
+    //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
+    return NO_ERROR;
+}
+
+status_t Parcel::writeUnpadded(const void* data, size_t len)
+{
+    size_t end = mDataPos + len;
+    if (end < mDataPos) {
+        // integer overflow
+        return BAD_VALUE;
+    }
+
+    if (end <= mDataCapacity) {
+restart_write:
+        memcpy(mData+mDataPos, data, len);
+        return finishWrite(len);
+    }
+
+    status_t err = growData(len);
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::write(const void* data, size_t len)
+{
+    void* const d = writeInplace(len);
+    if (d) {
+        memcpy(d, data, len);
+        return NO_ERROR;
+    }
+    return mError;
+}
+
+void* Parcel::writeInplace(size_t len)
+{
+    const size_t padded = PAD_SIZE(len);
+
+    // sanity check for integer overflow
+    if (mDataPos+padded < mDataPos) {
+        return NULL;
+    }
+
+    if ((mDataPos+padded) <= mDataCapacity) {
+restart_write:
+        //printf("Writing %ld bytes, padded to %ld\n", len, padded);
+        uint8_t* const data = mData+mDataPos;
+
+        // Need to pad at end?
+        if (padded != len) {
+#if BYTE_ORDER == BIG_ENDIAN
+            static const uint32_t mask[4] = {
+                0x00000000, 0xffffff00, 0xffff0000, 0xff000000
+            };
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN
+            static const uint32_t mask[4] = {
+                0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
+            };
+#endif
+            //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
+            //    *reinterpret_cast<void**>(data+padded-4));
+            *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
+        }
+
+        finishWrite(padded);
+        return data;
+    }
+
+    status_t err = growData(padded);
+    if (err == NO_ERROR) goto restart_write;
+    return NULL;
+}
+
+status_t Parcel::writeInt32(int32_t val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<int32_t*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeInt64(int64_t val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<int64_t*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeFloat(float val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<float*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeDouble(double val)
+{
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<double*>(mData+mDataPos) = val;
+        return finishWrite(sizeof(val));
+    }
+
+    status_t err = growData(sizeof(val));
+    if (err == NO_ERROR) goto restart_write;
+    return err;
+}
+
+status_t Parcel::writeCString(const char* str)
+{
+    return write(str, strlen(str)+1);
+}
+
+status_t Parcel::writeString8(const String8& str)
+{
+    status_t err = writeInt32(str.bytes());
+    if (err == NO_ERROR) {
+        err = write(str.string(), str.bytes()+1);
+    }
+    return err;
+}
+
+status_t Parcel::writeString16(const String16& str)
+{
+    return writeString16(str.string(), str.size());
+}
+
+status_t Parcel::writeString16(const char16_t* str, size_t len)
+{
+    if (str == NULL) return writeInt32(-1);
+    
+    status_t err = writeInt32(len);
+    if (err == NO_ERROR) {
+        len *= sizeof(char16_t);
+        uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
+        if (data) {
+            memcpy(data, str, len);
+            *reinterpret_cast<char16_t*>(data+len) = 0;
+            return NO_ERROR;
+        }
+        err = mError;
+    }
+    return err;
+}
+
+status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
+{
+    return flatten_binder(ProcessState::self(), val, this);
+}
+
+status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
+{
+    return flatten_binder(ProcessState::self(), val, this);
+}
+
+status_t Parcel::writeFileDescriptor(int fd)
+{
+    flat_binder_object obj;
+    obj.type = BINDER_TYPE_FD;
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    obj.handle = fd;
+    obj.cookie = (void*)0;
+    return writeObject(obj, true);
+}
+
+status_t Parcel::writeDupFileDescriptor(int fd)
+{
+    flat_binder_object obj;
+    obj.type = BINDER_TYPE_FD;
+    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    obj.handle = dup(fd);
+    obj.cookie = (void*)1;
+    return writeObject(obj, true);
+}
+
+status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
+{
+    const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
+    const bool enoughObjects = mObjectsSize < mObjectsCapacity;
+    if (enoughData && enoughObjects) {
+restart_write:
+        *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
+        
+        // Need to write meta-data?
+        if (nullMetaData || val.binder != NULL) {
+            mObjects[mObjectsSize] = mDataPos;
+            acquire_object(ProcessState::self(), val, this);
+            mObjectsSize++;
+        }
+        
+        // remember if it's a file descriptor
+        if (val.type == BINDER_TYPE_FD) {
+            mHasFds = mFdsKnown = true;
+        }
+
+        return finishWrite(sizeof(flat_binder_object));
+    }
+
+    if (!enoughData) {
+        const status_t err = growData(sizeof(val));
+        if (err != NO_ERROR) return err;
+    }
+    if (!enoughObjects) {
+        size_t newSize = ((mObjectsSize+2)*3)/2;
+        size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
+        if (objects == NULL) return NO_MEMORY;
+        mObjects = objects;
+        mObjectsCapacity = newSize;
+    }
+    
+    goto restart_write;
+}
+
+
+void Parcel::remove(size_t start, size_t amt)
+{
+    LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
+}
+
+status_t Parcel::read(void* outData, size_t len) const
+{
+    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
+        memcpy(outData, mData+mDataPos, len);
+        mDataPos += PAD_SIZE(len);
+        LOGV("read Setting data pos of %p to %d\n", this, mDataPos);
+        return NO_ERROR;
+    }
+    return NOT_ENOUGH_DATA;
+}
+
+const void* Parcel::readInplace(size_t len) const
+{
+    if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += PAD_SIZE(len);
+        LOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
+        return data;
+    }
+    return NULL;
+}
+
+status_t Parcel::readInt32(int32_t *pArg) const
+{
+    if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int32_t);
+        *pArg =  *reinterpret_cast<const int32_t*>(data);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+int32_t Parcel::readInt32() const
+{
+    if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int32_t);
+        LOGV("readInt32 Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const int32_t*>(data);
+    }
+    return 0;
+}
+
+
+status_t Parcel::readInt64(int64_t *pArg) const
+{
+    if ((mDataPos+sizeof(int64_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int64_t);
+        *pArg = *reinterpret_cast<const int64_t*>(data);
+        LOGV("readInt64 Setting data pos of %p to %d\n", this, mDataPos);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+
+int64_t Parcel::readInt64() const
+{
+    if ((mDataPos+sizeof(int64_t)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(int64_t);
+        LOGV("readInt64 Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const int64_t*>(data);
+    }
+    return 0;
+}
+
+status_t Parcel::readFloat(float *pArg) const
+{
+    if ((mDataPos+sizeof(float)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(float);
+        LOGV("readFloat Setting data pos of %p to %d\n", this, mDataPos);
+        *pArg = *reinterpret_cast<const float*>(data);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+
+float Parcel::readFloat() const
+{
+    if ((mDataPos+sizeof(float)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(float);
+        LOGV("readFloat Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const float*>(data);
+    }
+    return 0;
+}
+
+status_t Parcel::readDouble(double *pArg) const
+{
+    if ((mDataPos+sizeof(double)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(double);
+        LOGV("readDouble Setting data pos of %p to %d\n", this, mDataPos);
+        *pArg = *reinterpret_cast<const double*>(data);
+        return NO_ERROR;
+    } else {
+        return NOT_ENOUGH_DATA;
+    }
+}
+
+
+double Parcel::readDouble() const
+{
+    if ((mDataPos+sizeof(double)) <= mDataSize) {
+        const void* data = mData+mDataPos;
+        mDataPos += sizeof(double);
+        LOGV("readDouble Setting data pos of %p to %d\n", this, mDataPos);
+        return *reinterpret_cast<const double*>(data);
+    }
+    return 0;
+}
+
+
+const char* Parcel::readCString() const
+{
+    const size_t avail = mDataSize-mDataPos;
+    if (avail > 0) {
+        const char* str = reinterpret_cast<const char*>(mData+mDataPos);
+        // is the string's trailing NUL within the parcel's valid bounds?
+        const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
+        if (eos) {
+            const size_t len = eos - str;
+            mDataPos += PAD_SIZE(len+1);
+            LOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
+            return str;
+        }
+    }
+    return NULL;
+}
+
+String8 Parcel::readString8() const
+{
+    int32_t size = readInt32();
+    // watch for potential int overflow adding 1 for trailing NUL
+    if (size > 0 && size < INT32_MAX) {
+        const char* str = (const char*)readInplace(size+1);
+        if (str) return String8(str, size);
+    }
+    return String8();
+}
+
+String16 Parcel::readString16() const
+{
+    size_t len;
+    const char16_t* str = readString16Inplace(&len);
+    if (str) return String16(str, len);
+    LOGE("Reading a NULL string not supported here.");
+    return String16();
+}
+
+const char16_t* Parcel::readString16Inplace(size_t* outLen) const
+{
+    int32_t size = readInt32();
+    // watch for potential int overflow from size+1
+    if (size >= 0 && size < INT32_MAX) {
+        *outLen = size;
+        const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
+        if (str != NULL) {
+            return str;
+        }
+    }
+    *outLen = 0;
+    return NULL;
+}
+
+sp<IBinder> Parcel::readStrongBinder() const
+{
+    sp<IBinder> val;
+    unflatten_binder(ProcessState::self(), *this, &val);
+    return val;
+}
+
+wp<IBinder> Parcel::readWeakBinder() const
+{
+    wp<IBinder> val;
+    unflatten_binder(ProcessState::self(), *this, &val);
+    return val;
+}
+
+int Parcel::readFileDescriptor() const
+{
+    const flat_binder_object* flat = readObject(true);
+    if (flat) {
+        switch (flat->type) {
+            case BINDER_TYPE_FD:
+                //LOGI("Returning file descriptor %ld from parcel %p\n", flat->handle, this);
+                return flat->handle;
+        }        
+    }
+    return BAD_TYPE;
+}
+
+const flat_binder_object* Parcel::readObject(bool nullMetaData) const
+{
+    const size_t DPOS = mDataPos;
+    if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
+        const flat_binder_object* obj
+                = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
+        mDataPos = DPOS + sizeof(flat_binder_object);
+        if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {
+            // When transfering a NULL object, we don't write it into
+            // the object list, so we don't want to check for it when
+            // reading.
+            LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+            return obj;
+        }
+        
+        // Ensure that this object is valid...
+        size_t* const OBJS = mObjects;
+        const size_t N = mObjectsSize;
+        size_t opos = mNextObjectHint;
+        
+        if (N > 0) {
+            LOGV("Parcel %p looking for obj at %d, hint=%d\n",
+                 this, DPOS, opos);
+            
+            // Start at the current hint position, looking for an object at
+            // the current data position.
+            if (opos < N) {
+                while (opos < (N-1) && OBJS[opos] < DPOS) {
+                    opos++;
+                }
+            } else {
+                opos = N-1;
+            }
+            if (OBJS[opos] == DPOS) {
+                // Found it!
+                LOGV("Parcel found obj %d at index %d with forward search",
+                     this, DPOS, opos);
+                mNextObjectHint = opos+1;
+                LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+                return obj;
+            }
+        
+            // Look backwards for it...
+            while (opos > 0 && OBJS[opos] > DPOS) {
+                opos--;
+            }
+            if (OBJS[opos] == DPOS) {
+                // Found it!
+                LOGV("Parcel found obj %d at index %d with backward search",
+                     this, DPOS, opos);
+                mNextObjectHint = opos+1;
+                LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+                return obj;
+            }
+        }
+        LOGW("Attempt to read object from Parcel %p at offset %d that is not in the object list",
+             this, DPOS);
+    }
+    return NULL;
+}
+
+void Parcel::closeFileDescriptors()
+{
+    size_t i = mObjectsSize;
+    if (i > 0) {
+        //LOGI("Closing file descriptors for %d objects...", mObjectsSize);
+    }
+    while (i > 0) {
+        i--;
+        const flat_binder_object* flat
+            = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
+        if (flat->type == BINDER_TYPE_FD) {
+            //LOGI("Closing fd: %ld\n", flat->handle);
+            close(flat->handle);
+        }
+    }
+}
+
+const uint8_t* Parcel::ipcData() const
+{
+    return mData;
+}
+
+size_t Parcel::ipcDataSize() const
+{
+    return (mDataSize > mDataPos ? mDataSize : mDataPos);
+}
+
+const size_t* Parcel::ipcObjects() const
+{
+    return mObjects;
+}
+
+size_t Parcel::ipcObjectsCount() const
+{
+    return mObjectsSize;
+}
+
+void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
+    const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
+{
+    freeDataNoInit();
+    mError = NO_ERROR;
+    mData = const_cast<uint8_t*>(data);
+    mDataSize = mDataCapacity = dataSize;
+    //LOGI("setDataReference Setting data size of %p to %lu (pid=%d)\n", this, mDataSize, getpid());
+    mDataPos = 0;
+    LOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
+    mObjects = const_cast<size_t*>(objects);
+    mObjectsSize = mObjectsCapacity = objectsCount;
+    mNextObjectHint = 0;
+    mOwner = relFunc;
+    mOwnerCookie = relCookie;
+    scanForFds();
+}
+
+void Parcel::print(TextOutput& to, uint32_t flags) const
+{
+    to << "Parcel(";
+    
+    if (errorCheck() != NO_ERROR) {
+        const status_t err = errorCheck();
+        to << "Error: " << (void*)err << " \"" << strerror(-err) << "\"";
+    } else if (dataSize() > 0) {
+        const uint8_t* DATA = data();
+        to << indent << HexDump(DATA, dataSize()) << dedent;
+        const size_t* OBJS = objects();
+        const size_t N = objectsCount();
+        for (size_t i=0; i<N; i++) {
+            const flat_binder_object* flat
+                = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
+            to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
+                << TypeCode(flat->type & 0x7f7f7f00)
+                << " = " << flat->binder;
+        }
+    } else {
+        to << "NULL";
+    }
+    
+    to << ")";
+}
+
+void Parcel::releaseObjects()
+{
+    const sp<ProcessState> proc(ProcessState::self());
+    size_t i = mObjectsSize;
+    uint8_t* const data = mData;
+    size_t* const objects = mObjects;
+    while (i > 0) {
+        i--;
+        const flat_binder_object* flat
+            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
+        release_object(proc, *flat, this);
+    }
+}
+
+void Parcel::acquireObjects()
+{
+    const sp<ProcessState> proc(ProcessState::self());
+    size_t i = mObjectsSize;
+    uint8_t* const data = mData;
+    size_t* const objects = mObjects;
+    while (i > 0) {
+        i--;
+        const flat_binder_object* flat
+            = reinterpret_cast<flat_binder_object*>(data+objects[i]);
+        acquire_object(proc, *flat, this);
+    }
+}
+
+void Parcel::freeData()
+{
+    freeDataNoInit();
+    initState();
+}
+
+void Parcel::freeDataNoInit()
+{
+    if (mOwner) {
+        //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
+        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
+    } else {
+        releaseObjects();
+        if (mData) free(mData);
+        if (mObjects) free(mObjects);
+    }
+}
+
+status_t Parcel::growData(size_t len)
+{
+    size_t newSize = ((mDataSize+len)*3)/2;
+    return (newSize <= mDataSize)
+            ? (status_t) NO_MEMORY
+            : continueWrite(newSize);
+}
+
+status_t Parcel::restartWrite(size_t desired)
+{
+    if (mOwner) {
+        freeData();
+        return continueWrite(desired);
+    }
+    
+    uint8_t* data = (uint8_t*)realloc(mData, desired);
+    if (!data && desired > mDataCapacity) {
+        mError = NO_MEMORY;
+        return NO_MEMORY;
+    }
+    
+    releaseObjects();
+    
+    if (data) {
+        mData = data;
+        mDataCapacity = desired;
+    }
+    
+    mDataSize = mDataPos = 0;
+    LOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
+    LOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
+        
+    free(mObjects);
+    mObjects = NULL;
+    mObjectsSize = mObjectsCapacity = 0;
+    mNextObjectHint = 0;
+    mHasFds = false;
+    mFdsKnown = true;
+    
+    return NO_ERROR;
+}
+
+status_t Parcel::continueWrite(size_t desired)
+{
+    // If shrinking, first adjust for any objects that appear
+    // after the new data size.
+    size_t objectsSize = mObjectsSize;
+    if (desired < mDataSize) {
+        if (desired == 0) {
+            objectsSize = 0;
+        } else {
+            while (objectsSize > 0) {
+                if (mObjects[objectsSize-1] < desired)
+                    break;
+                objectsSize--;
+            }
+        }
+    }
+    
+    if (mOwner) {
+        // If the size is going to zero, just release the owner's data.
+        if (desired == 0) {
+            freeData();
+            return NO_ERROR;
+        }
+
+        // If there is a different owner, we need to take
+        // posession.
+        uint8_t* data = (uint8_t*)malloc(desired);
+        if (!data) {
+            mError = NO_MEMORY;
+            return NO_MEMORY;
+        }
+        size_t* objects = NULL;
+        
+        if (objectsSize) {
+            objects = (size_t*)malloc(objectsSize*sizeof(size_t));
+            if (!objects) {
+                mError = NO_MEMORY;
+                return NO_MEMORY;
+            }
+
+            // Little hack to only acquire references on objects
+            // we will be keeping.
+            size_t oldObjectsSize = mObjectsSize;
+            mObjectsSize = objectsSize;
+            acquireObjects();
+            mObjectsSize = oldObjectsSize;
+        }
+        
+        if (mData) {
+            memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
+        }
+        if (objects && mObjects) {
+            memcpy(objects, mObjects, objectsSize*sizeof(size_t));
+        }
+        //LOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
+        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
+        mOwner = NULL;
+
+        mData = data;
+        mObjects = objects;
+        mDataSize = (mDataSize < desired) ? mDataSize : desired;
+        LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+        mDataCapacity = desired;
+        mObjectsSize = mObjectsCapacity = objectsSize;
+        mNextObjectHint = 0;
+
+    } else if (mData) {
+        if (objectsSize < mObjectsSize) {
+            // Need to release refs on any objects we are dropping.
+            const sp<ProcessState> proc(ProcessState::self());
+            for (size_t i=objectsSize; i<mObjectsSize; i++) {
+                const flat_binder_object* flat
+                    = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
+                if (flat->type == BINDER_TYPE_FD) {
+                    // will need to rescan because we may have lopped off the only FDs
+                    mFdsKnown = false;
+                }
+                release_object(proc, *flat, this);
+            }
+            size_t* objects =
+                (size_t*)realloc(mObjects, objectsSize*sizeof(size_t));
+            if (objects) {
+                mObjects = objects;
+            }
+            mObjectsSize = objectsSize;
+            mNextObjectHint = 0;
+        }
+
+        // We own the data, so we can just do a realloc().
+        if (desired > mDataCapacity) {
+            uint8_t* data = (uint8_t*)realloc(mData, desired);
+            if (data) {
+                mData = data;
+                mDataCapacity = desired;
+            } else if (desired > mDataCapacity) {
+                mError = NO_MEMORY;
+                return NO_MEMORY;
+            }
+        } else {
+            mDataSize = desired;
+            LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+            if (mDataPos > desired) {
+                mDataPos = desired;
+                LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+            }
+        }
+        
+    } else {
+        // This is the first data.  Easy!
+        uint8_t* data = (uint8_t*)malloc(desired);
+        if (!data) {
+            mError = NO_MEMORY;
+            return NO_MEMORY;
+        }
+        
+        if(!(mDataCapacity == 0 && mObjects == NULL
+             && mObjectsCapacity == 0)) {
+            LOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired);
+        }
+        
+        mData = data;
+        mDataSize = mDataPos = 0;
+        LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+        LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+        mDataCapacity = desired;
+    }
+
+    return NO_ERROR;
+}
+
+void Parcel::initState()
+{
+    mError = NO_ERROR;
+    mData = 0;
+    mDataSize = 0;
+    mDataCapacity = 0;
+    mDataPos = 0;
+    LOGV("initState Setting data size of %p to %d\n", this, mDataSize);
+    LOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
+    mObjects = NULL;
+    mObjectsSize = 0;
+    mObjectsCapacity = 0;
+    mNextObjectHint = 0;
+    mHasFds = false;
+    mFdsKnown = true;
+    mOwner = NULL;
+}
+
+void Parcel::scanForFds() const
+{
+    bool hasFds = false;
+    for (size_t i=0; i<mObjectsSize; i++) {
+        const flat_binder_object* flat
+            = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
+        if (flat->type == BINDER_TYPE_FD) {
+            hasFds = true;
+            break;
+        }
+    }
+    mHasFds = hasFds;
+    mFdsKnown = true;
+}
+
+}; // namespace android
