Support for marshalling pointers / intptr_t in Parcel.

Some refactoring to eliminate code duplication in Parcel implementation.
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 58c2d9a..ba6c711 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -74,6 +74,7 @@
     status_t            writeInt64(int64_t val);
     status_t            writeFloat(float val);
     status_t            writeDouble(double val);
+    status_t            writeIntPtr(intptr_t val);
     status_t            writeCString(const char* str);
     status_t            writeString8(const String8& str);
     status_t            writeString16(const String16& str);
@@ -109,6 +110,8 @@
     status_t            readFloat(float *pArg) const;
     double              readDouble() const;
     status_t            readDouble(double *pArg) const;
+    intptr_t            readIntPtr() const;
+    status_t            readIntPtr(intptr_t *pArg) const;
 
     const char*         readCString() const;
     String8             readString8() const;
@@ -163,6 +166,14 @@
     void                initState();
     void                scanForFds() const;
                         
+    template<class T>
+    status_t            readAligned(T *pArg) const;
+
+    template<class T>   T readAligned() const;
+
+    template<class T>
+    status_t            writeAligned(T val);
+
     status_t            mError;
     uint8_t*            mData;
     size_t              mDataSize;
diff --git a/include/utils/Debug.h b/include/utils/Debug.h
index 21d04bd..d9ed32d 100644
--- a/include/utils/Debug.h
+++ b/include/utils/Debug.h
@@ -29,6 +29,8 @@
 #define COMPILE_TIME_ASSERT(_exp) \
     template class CompileTimeAssert< (_exp) >;
 #endif
+#define COMPILE_TIME_ASSERT_FUNCTION_SCOPE(_exp) \
+    CompileTimeAssert<( _exp )>();
 
 // ---------------------------------------------------------------------------
 
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 785a3c5..e397bce 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -562,54 +562,27 @@
 
 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;
+    return writeAligned(val);
 }
 
 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;
+    return writeAligned(val);
 }
 
 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;
+    return writeAligned(val);
 }
 
 status_t Parcel::writeDouble(double val)
 {
-    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
-restart_write:
-        *reinterpret_cast<double*>(mData+mDataPos) = val;
-        return finishWrite(sizeof(val));
-    }
+    return writeAligned(val);
+}
 
-    status_t err = growData(sizeof(val));
-    if (err == NO_ERROR) goto restart_write;
-    return err;
+status_t Parcel::writeIntPtr(intptr_t val)
+{
+    return writeAligned(val);
 }
 
 status_t Parcel::writeCString(const char* str)
@@ -768,103 +741,98 @@
     return NULL;
 }
 
-status_t Parcel::readInt32(int32_t *pArg) const
-{
-    if ((mDataPos+sizeof(int32_t)) <= mDataSize) {
+template<class T>
+status_t Parcel::readAligned(T *pArg) const {
+    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
+
+    if ((mDataPos+sizeof(T)) <= mDataSize) {
         const void* data = mData+mDataPos;
-        mDataPos += sizeof(int32_t);
-        *pArg =  *reinterpret_cast<const int32_t*>(data);
+        mDataPos += sizeof(T);
+        *pArg =  *reinterpret_cast<const T*>(data);
         return NO_ERROR;
     } else {
         return NOT_ENOUGH_DATA;
     }
 }
 
+template<class T>
+T Parcel::readAligned() const {
+    T result;
+    if (readAligned(&result) != NO_ERROR) {
+        result = 0;
+    }
+
+    return result;
+}
+
+template<class T>
+status_t Parcel::writeAligned(T val) {
+    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
+
+    if ((mDataPos+sizeof(val)) <= mDataCapacity) {
+restart_write:
+        *reinterpret_cast<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::readInt32(int32_t *pArg) const
+{
+    return readAligned(pArg);
+}
+
 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;
+    return readAligned<int32_t>();
 }
 
 
 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;
-    }
+    return readAligned(pArg);
 }
 
 
 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;
+    return readAligned<int64_t>();
 }
 
 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;
-    }
+    return readAligned(pArg);
 }
 
 
 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;
+    return readAligned<float>();
 }
 
 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;
-    }
+    return readAligned(pArg);
 }
 
 
 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;
+    return readAligned<double>();
+}
+
+status_t Parcel::readIntPtr(intptr_t *pArg) const
+{
+    return readAligned(pArg);
+}
+
+
+intptr_t Parcel::readIntPtr() const
+{
+    return readAligned<intptr_t>();
 }
 
 
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index ec3241c..10bebd0 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -45,16 +45,6 @@
             displayWidth, displayHeight);
 }
 
-static void *readVoidStar(const Parcel *parcel) {
-    // FIX if sizeof(void *) != sizeof(int32)
-    return (void *)parcel->readInt32();
-}
-
-static void writeVoidStar(void *x, Parcel *parcel) {
-    // FIX if sizeof(void *) != sizeof(int32)
-    parcel->writeInt32((int32_t)x);
-}
-
 class BpOMX : public BpInterface<IOMX> {
 public:
     BpOMX(const sp<IBinder> &impl)
@@ -86,7 +76,7 @@
 
         status_t err = reply.readInt32();
         if (err == OK) {
-            *node = readVoidStar(&reply);
+            *node = (void*)reply.readIntPtr();
         } else {
             *node = 0;
         }
@@ -97,7 +87,7 @@
     virtual status_t free_node(node_id node) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         remote()->transact(FREE_NODE, data, &reply);
 
         return reply.readInt32();
@@ -107,7 +97,7 @@
             node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(cmd);
         data.writeInt32(param);
         remote()->transact(SEND_COMMAND, data, &reply);
@@ -120,7 +110,7 @@
             void *params, size_t size) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(index);
         data.writeInt32(size);
         data.write(params, size);
@@ -141,7 +131,7 @@
             const void *params, size_t size) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(index);
         data.writeInt32(size);
         data.write(params, size);
@@ -155,7 +145,7 @@
             void *params, size_t size) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(index);
         data.writeInt32(size);
         data.write(params, size);
@@ -176,7 +166,7 @@
             const void *params, size_t size) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(index);
         data.writeInt32(size);
         data.write(params, size);
@@ -190,7 +180,7 @@
             buffer_id *buffer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(port_index);
         data.writeStrongBinder(params->asBinder());
         remote()->transact(USE_BUFFER, data, &reply);
@@ -202,7 +192,7 @@
             return err;
         }
 
-        *buffer = readVoidStar(&reply);
+        *buffer = (void*)reply.readIntPtr();
 
         return err;
     }
@@ -212,7 +202,7 @@
             buffer_id *buffer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(port_index);
         data.writeInt32(size);
         remote()->transact(ALLOC_BUFFER, data, &reply);
@@ -224,7 +214,7 @@
             return err;
         }
 
-        *buffer = readVoidStar(&reply);
+        *buffer = (void*)reply.readIntPtr();
 
         return err;
     }
@@ -234,7 +224,7 @@
             buffer_id *buffer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(port_index);
         data.writeStrongBinder(params->asBinder());
         remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply);
@@ -246,7 +236,7 @@
             return err;
         }
 
-        *buffer = readVoidStar(&reply);
+        *buffer = (void*)reply.readIntPtr();
 
         return err;
     }
@@ -255,9 +245,9 @@
             node_id node, OMX_U32 port_index, buffer_id buffer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeInt32(port_index);
-        writeVoidStar(buffer, &data);
+        data.writeIntPtr((intptr_t)buffer);
         remote()->transact(FREE_BUFFER, data, &reply);
 
         return reply.readInt32();
@@ -267,7 +257,7 @@
             node_id node, const sp<IOMXObserver> &observer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeStrongBinder(observer->asBinder());
         remote()->transact(OBSERVE_NODE, data, &reply);
 
@@ -277,8 +267,8 @@
     virtual void fill_buffer(node_id node, buffer_id buffer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
-        writeVoidStar(buffer, &data);
+        data.writeIntPtr((intptr_t)node);
+        data.writeIntPtr((intptr_t)buffer);
         remote()->transact(FILL_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
@@ -289,8 +279,8 @@
             OMX_U32 flags, OMX_TICKS timestamp) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
-        writeVoidStar(buffer, &data);
+        data.writeIntPtr((intptr_t)node);
+        data.writeIntPtr((intptr_t)buffer);
         data.writeInt32(range_offset);
         data.writeInt32(range_length);
         data.writeInt32(flags);
@@ -304,7 +294,7 @@
             OMX_INDEXTYPE *index) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
-        writeVoidStar(node, &data);
+        data.writeIntPtr((intptr_t)node);
         data.writeCString(parameter_name);
 
         remote()->transact(GET_EXTENSION_INDEX, data, &reply);
@@ -379,7 +369,7 @@
             status_t err = allocate_node(data.readCString(), &node);
             reply->writeInt32(err);
             if (err == OK) {
-                writeVoidStar(node, reply);
+                reply->writeIntPtr((intptr_t)node);
             }
                 
             return NO_ERROR;
@@ -389,7 +379,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
 
             reply->writeInt32(free_node(node));
                 
@@ -400,7 +390,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
 
             OMX_COMMANDTYPE cmd =
                 static_cast<OMX_COMMANDTYPE>(data.readInt32());
@@ -415,7 +405,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
 
             size_t size = data.readInt32();
@@ -442,7 +432,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
 
             size_t size = data.readInt32();
@@ -457,7 +447,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
 
             size_t size = data.readInt32();
@@ -484,7 +474,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
 
             size_t size = data.readInt32();
@@ -499,7 +489,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_U32 port_index = data.readInt32();
             sp<IMemory> params =
                 interface_cast<IMemory>(data.readStrongBinder());
@@ -509,7 +499,7 @@
             reply->writeInt32(err);
 
             if (err == OK) {
-                writeVoidStar(buffer, reply);
+                reply->writeIntPtr((intptr_t)buffer);
             }
 
             return NO_ERROR;
@@ -519,7 +509,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_U32 port_index = data.readInt32();
             size_t size = data.readInt32();
 
@@ -528,7 +518,7 @@
             reply->writeInt32(err);
 
             if (err == OK) {
-                writeVoidStar(buffer, reply);
+                reply->writeIntPtr((intptr_t)buffer);
             }
 
             return NO_ERROR;
@@ -538,7 +528,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_U32 port_index = data.readInt32();
             sp<IMemory> params =
                 interface_cast<IMemory>(data.readStrongBinder());
@@ -550,7 +540,7 @@
             reply->writeInt32(err);
 
             if (err == OK) {
-                writeVoidStar(buffer, reply);
+                reply->writeIntPtr((intptr_t)buffer);
             }
 
             return NO_ERROR;
@@ -560,9 +550,9 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             OMX_U32 port_index = data.readInt32();
-            buffer_id buffer = readVoidStar(&data);
+            buffer_id buffer = (void*)data.readIntPtr();
             reply->writeInt32(free_buffer(node, port_index, buffer));
 
             return NO_ERROR;
@@ -572,7 +562,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             sp<IOMXObserver> observer =
                 interface_cast<IOMXObserver>(data.readStrongBinder());
             reply->writeInt32(observe_node(node, observer));
@@ -584,8 +574,8 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
-            buffer_id buffer = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
+            buffer_id buffer = (void*)data.readIntPtr();
             fill_buffer(node, buffer);
 
             return NO_ERROR;
@@ -595,8 +585,8 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
-            buffer_id buffer = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
+            buffer_id buffer = (void*)data.readIntPtr();
             OMX_U32 range_offset = data.readInt32();
             OMX_U32 range_length = data.readInt32();
             OMX_U32 flags = data.readInt32();
@@ -613,7 +603,7 @@
         {
             CHECK_INTERFACE(IOMX, data, reply);
 
-            node_id node = readVoidStar(&data);
+            node_id node = (void*)data.readIntPtr();
             const char *parameter_name = data.readCString();
             
             OMX_INDEXTYPE index;
@@ -711,7 +701,7 @@
     virtual void render(IOMX::buffer_id buffer) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMXRenderer::getInterfaceDescriptor());
-        writeVoidStar(buffer, &data);
+        data.writeIntPtr((intptr_t)buffer);
 
         // NOTE: Do NOT make this a ONE_WAY call, it must be synchronous
         // so that the caller knows when to recycle the buffer.
@@ -728,7 +718,7 @@
         {
             CHECK_INTERFACE(IOMXRenderer, data, reply);
 
-            IOMX::buffer_id buffer = readVoidStar(&data);
+            IOMX::buffer_id buffer = (void*)data.readIntPtr();
 
             render(buffer);