`
kuang511111
  • 浏览: 3040 次
社区版块
存档分类
最新评论

android 实现序列化 深度浅析二

 
阅读更多

一.先从Serialize说起

         我们都知道JAVA中的Serialize机制,译成串行化、序列化……,其作用是能将数据对象存入字节流当中,在需要时重新生成对象。主要应用是利用外部存储设备保存对象状态,以及通过网络传输对象等。

 

二.Android中的新的序列化机制

         Android系统中,定位为针对内存受限的设备,因此对性能要求更高,另外系统中采用了新的IPC(进程间通信)机制,必然要求使用性能更出色的对象传输方式。在这样的环境下,Parcel被设计出来,其定位就是轻量级的高效的对象序列化和反序列化机制。

 

三.Parcel类的背后

         Framework中有parcel类,源码路径是:

Frameworks/base/core/java/android/os/Parcel.java

典型的源码片断如下:

 

 

 

[java] view plaincopy
 
  1. /** 
  2.  * Write an integer value into the parcel at the current dataPosition(), 
  3.  * growing dataCapacity() if needed. 
  4.  */  
  5. public final native void writeInt(int val);  
  6.   
  7. /** 
  8.  * Write a long integer value into the parcel at the current dataPosition(), 
  9.  * growing dataCapacity() if needed. 
  10.  */  
  11. public final native void writeLong(long val);  

  

 

 

         从中我们看到,从这个源程序文件中我们看不到真正的功能是如何实现的,必须透过JNI往下走了。于是,Frameworks/base/core/jni/android_util_Binder.cpp中找到了线索

 

[java] view plaincopy
 
  1. static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)  
  2. {  
  3.     Parcel* parcel = parcelForJavaObject(env, clazz);  
  4.     if (parcel != NULL) {  
  5.         const status_t err = parcel->writeInt32(val);  
  6.         if (err != NO_ERROR) {  
  7.             jniThrowException(env, "java/lang/OutOfMemoryError", NULL);  
  8.         }  
  9.     }  
  10. }  
  11.   
  12. static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)  
  13. {  
  14.     Parcel* parcel = parcelForJavaObject(env, clazz);  
  15.     if (parcel != NULL) {  
  16.         const status_t err = parcel->writeInt64(val);  
  17.         if (err != NO_ERROR) {  
  18.             jniThrowException(env, "java/lang/OutOfMemoryError", NULL);  
  19.         }  
  20.     }  
  21. }  

 

  

         从这里我们可以得到的信息是函数的实现依赖于Parcel指针,因此还需要找到Parcel的类定义,注意,这里的类已经是用C++语言实现的了。

         找到Frameworks/base/include/binder/parcel.hFrameworks/base/libs/binder/parcel.cpp。终于找到了最终的实现代码了。

         有兴趣的朋友可以自己读一下,不难理解,这里把基本的思路总结一下:

1.       整个读写全是在内存中进行,主要是通过malloc()realloc()memcpy()等内存操作进行,所以效率比JAVA序列化中使用外部存储器会高很多;

2.       读写时是4字节对齐的,可以看到#define PAD_SIZE(s) (((s)+3)&~3)这句宏定义就是在做这件事情;

3.       如果预分配的空间不够时newSize = ((mDataSize+len)*3)/2;会一次多分配50%

4.       对于普通数据,使用的是mData内存地址,对于IBinder类型的数据以及FileDescriptor使用的是mObjects内存地址。后者是通过flatten_binder()unflatten_binder()实现的,目的是反序列化时读出的对象就是原对象而不用重新new一个新对象。

 

好了,这就是Parcel背后的动作,全是在一块内存里进行读写操作,就不啰嗦了,把parcel的代码贴在这供没有源码的朋友参考吧。接下来我会用一个小DEMO演示一下Parcel类在应用程序中的使用,详见《探索Android中的Parcel机制(下)》。

 

[cpp] view plaincopy
 
  1. /* 
  2.  * Copyright (C) 2005 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. #ifndef ANDROID_PARCEL_H  
  18. #define ANDROID_PARCEL_H  
  19.   
  20. #include <cutils/native_handle.h>  
  21. #include <utils/Errors.h>  
  22. #include <utils/RefBase.h>  
  23. #include <utils/String16.h>  
  24. #include <utils/Vector.h>  
  25.   
  26. // ---------------------------------------------------------------------------  
  27. namespace android {  
  28.   
  29. class IBinder;  
  30. class ProcessState;  
  31. class String8;  
  32. class TextOutput;  
  33. class Flattenable;  
  34.   
  35. struct flat_binder_object;  // defined in support_p/binder_module.h  
  36.   
  37. class Parcel  
  38. {  
  39. public:  
  40.                         Parcel();  
  41.                         ~Parcel();  
  42.       
  43.     const uint8_t*      data() const;  
  44.     size_t              dataSize() const;  
  45.     size_t              dataAvail() const;  
  46.     size_t              dataPosition() const;  
  47.     size_t              dataCapacity() const;  
  48.       
  49.     status_t            setDataSize(size_t size);  
  50.     void                setDataPosition(size_t pos) const;  
  51.     status_t            setDataCapacity(size_t size);  
  52.       
  53.     status_t            setData(const uint8_t* buffer, size_t len);  
  54.   
  55.     status_t            appendFrom(Parcel *parcel, size_t start, size_t len);  
  56.   
  57.     bool                hasFileDescriptors() const;  
  58.   
  59.     status_t            writeInterfaceToken(const String16& interface);  
  60.     bool                enforceInterface(const String16& interface) const;  
  61.     bool                checkInterface(IBinder*) const;      
  62.   
  63.     void                freeData();  
  64.   
  65.     const size_t*       objects() const;  
  66.     size_t              objectsCount() const;  
  67.       
  68.     status_t            errorCheck() const;  
  69.     void                setError(status_t err);  
  70.       
  71.     status_t            write(const void* data, size_t len);  
  72.     void*               writeInplace(size_t len);  
  73.     status_t            writeUnpadded(const void* data, size_t len);  
  74.     status_t            writeInt32(int32_t val);  
  75.     status_t            writeInt64(int64_t val);  
  76.     status_t            writeFloat(float val);  
  77.     status_t            writeDouble(double val);  
  78.     status_t            writeIntPtr(intptr_t val);  
  79.     status_t            writeCString(const char* str);  
  80.     status_t            writeString8(const String8& str);  
  81.     status_t            writeString16(const String16& str);  
  82.     status_t            writeString16(const char16_t* str, size_t len);  
  83.     status_t            writeStrongBinder(const sp<IBinder>& val);  
  84.     status_t            writeWeakBinder(const wp<IBinder>& val);  
  85.     status_t            write(const Flattenable& val);  
  86.   
  87.     // Place a native_handle into the parcel (the native_handle's file-  
  88.     // descriptors are dup'ed, so it is safe to delete the native_handle  
  89.     // when this function returns).   
  90.     // Doesn't take ownership of the native_handle.  
  91.     status_t            writeNativeHandle(const native_handle* handle);  
  92.       
  93.     // Place a file descriptor into the parcel.  The given fd must remain  
  94.     // valid for the lifetime of the parcel.  
  95.     status_t            writeFileDescriptor(int fd);  
  96.       
  97.     // Place a file descriptor into the parcel.  A dup of the fd is made, which  
  98.     // will be closed once the parcel is destroyed.  
  99.     status_t            writeDupFileDescriptor(int fd);  
  100.       
  101.     status_t            writeObject(const flat_binder_object& val, bool nullMetaData);  
  102.   
  103.     void                remove(size_t start, size_t amt);  
  104.       
  105.     status_t            read(void* outData, size_t len) const;  
  106.     const void*         readInplace(size_t len) const;  
  107.     int32_t             readInt32() const;  
  108.     status_t            readInt32(int32_t *pArg) const;  
  109.     int64_t             readInt64() const;  
  110.     status_t            readInt64(int64_t *pArg) const;  
  111.     float               readFloat() const;  
  112.     status_t            readFloat(float *pArg) const;  
  113.     double              readDouble() const;  
  114.     status_t            readDouble(double *pArg) const;  
  115.     intptr_t            readIntPtr() const;  
  116.     status_t            readIntPtr(intptr_t *pArg) const;  
  117.   
  118.     const char*         readCString() const;  
  119.     String8             readString8() const;  
  120.     String16            readString16() const;  
  121.     const char16_t*     readString16Inplace(size_t* outLen) const;  
  122.     sp<IBinder>         readStrongBinder() const;  
  123.     wp<IBinder>         readWeakBinder() const;  
  124.     status_t            read(Flattenable& val) const;  
  125.       
  126.     // Retrieve native_handle from the parcel. This returns a copy of the  
  127.     // parcel's native_handle (the caller takes ownership). The caller  
  128.     // must free the native_handle with native_handle_close() and   
  129.     // native_handle_delete().  
  130.     native_handle*     readNativeHandle() const;  
  131.   
  132.       
  133.     // Retrieve a file descriptor from the parcel.  This returns the raw fd  
  134.     // in the parcel, which you do not own -- use dup() to get your own copy.  
  135.     int                 readFileDescriptor() const;  
  136.       
  137.     const flat_binder_object* readObject(bool nullMetaData) const;  
  138.   
  139.     // Explicitly close all file descriptors in the parcel.  
  140.     void                closeFileDescriptors();  
  141.       
  142.     typedef void        (*release_func)(Parcel* parcel,  
  143.                                         const uint8_t* data, size_t dataSize,  
  144.                                         const size_t* objects, size_t objectsSize,  
  145.                                         void* cookie);  
  146.                           
  147.     const uint8_t*      ipcData() const;  
  148.     size_t              ipcDataSize() const;  
  149.     const size_t*       ipcObjects() const;  
  150.     size_t              ipcObjectsCount() const;  
  151.     void                ipcSetDataReference(const uint8_t* data, size_t dataSize,  
  152.                                             const size_t* objects, size_t objectsCount,  
  153.                                             release_func relFunc, void* relCookie);  
  154.       
  155.     void                print(TextOutput& to, uint32_t flags = 0) const;  
  156.           
  157. private:  
  158.                         Parcel(const Parcel& o);  
  159.     Parcel&             operator=(const Parcel& o);  
  160.       
  161.     status_t            finishWrite(size_t len);  
  162.     void                releaseObjects();  
  163.     void                acquireObjects();  
  164.     status_t            growData(size_t len);  
  165.     status_t            restartWrite(size_t desired);  
  166.     status_t            continueWrite(size_t desired);  
  167.     void                freeDataNoInit();  
  168.     void                initState();  
  169.     void                scanForFds() const;  
  170.                           
  171.     template<class T>  
  172.     status_t            readAligned(T *pArg) const;  
  173.   
  174.     template<class T>   T readAligned() const;  
  175.   
  176.     template<class T>  
  177.     status_t            writeAligned(T val);  
  178.   
  179.     status_t            mError;  
  180.     uint8_t*            mData;  
  181.     size_t              mDataSize;  
  182.     size_t              mDataCapacity;  
  183.     mutable size_t      mDataPos;  
  184.     size_t*             mObjects;  
  185.     size_t              mObjectsSize;  
  186.     size_t              mObjectsCapacity;  
  187.     mutable size_t      mNextObjectHint;  
  188.   
  189.     mutable bool        mFdsKnown;  
  190.     mutable bool        mHasFds;  
  191.       
  192.     release_func        mOwner;  
  193.     void*               mOwnerCookie;  
  194. };  
  195.   
  196. // ---------------------------------------------------------------------------  
  197.   
  198. inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel)  
  199. {  
  200.     parcel.print(to);  
  201.     return to;  
  202. }  
  203.   
  204. // ---------------------------------------------------------------------------  
  205.   
  206. // Generic acquire and release of objects.  
  207. void acquire_object(const sp<ProcessState>& proc,  
  208.                     const flat_binder_object& obj, const void* who);  
  209. void release_object(const sp<ProcessState>& proc,  
  210.                     const flat_binder_object& obj, const void* who);  
  211.   
  212. void flatten_binder(const sp<ProcessState>& proc,  
  213.                     const sp<IBinder>& binder, flat_binder_object* out);  
  214. void flatten_binder(const sp<ProcessState>& proc,  
  215.                     const wp<IBinder>& binder, flat_binder_object* out);  
  216. status_t unflatten_binder(const sp<ProcessState>& proc,  
  217.                           const flat_binder_object& flat, sp<IBinder>* out);  
  218. status_t unflatten_binder(const sp<ProcessState>& proc,  
  219.                           const flat_binder_object& flat, wp<IBinder>* out);  
  220.   
  221. }; // namespace android  
  222.   
  223. // ---------------------------------------------------------------------------  
  224.   
  225. #endif // ANDROID_PARCEL_H  

 

 

 

[cpp] view plaincopy
 
  1. /* 
  2.  * Copyright (C) 2005 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. #define LOG_TAG "Parcel"  
  18. //#define LOG_NDEBUG 0  
  19.   
  20. #include <binder/Parcel.h>  
  21.   
  22. #include <binder/Binder.h>  
  23. #include <binder/BpBinder.h>  
  24. #include <utils/Debug.h>  
  25. #include <binder/ProcessState.h>  
  26. #include <utils/Log.h>  
  27. #include <utils/String8.h>  
  28. #include <utils/String16.h>  
  29. #include <utils/TextOutput.h>  
  30. #include <utils/misc.h>  
  31. #include <utils/Flattenable.h>  
  32.   
  33. #include <private/binder/binder_module.h>  
  34.   
  35. #include <stdio.h>  
  36. #include <stdlib.h>  
  37. #include <stdint.h>  
  38.   
  39. #ifndef INT32_MAX  
  40. #define INT32_MAX ((int32_t)(2147483647))  
  41. #endif  
  42.   
  43. #define LOG_REFS(...)  
  44. //#define LOG_REFS(...) LOG(LOG_DEBUG, "Parcel", __VA_ARGS__)  
  45.   
  46. // ---------------------------------------------------------------------------  
  47.   
  48. #define PAD_SIZE(s) (((s)+3)&~3)  
  49.   
  50. // XXX This can be made public if we want to provide  
  51. // support for typed data.  
  52. struct small_flat_data  
  53. {  
  54.     uint32_t type;  
  55.     uint32_t data;  
  56. };  
  57.   
  58. namespace android {  
  59.   
  60. void acquire_object(const sp<ProcessState>& proc,  
  61.     const flat_binder_object& obj, const void* who)  
  62. {  
  63.     switch (obj.type) {  
  64.         case BINDER_TYPE_BINDER:  
  65.             if (obj.binder) {  
  66.                 LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);  
  67.                 static_cast<IBinder*>(obj.cookie)->incStrong(who);  
  68.             }  
  69.             return;  
  70.         case BINDER_TYPE_WEAK_BINDER:  
  71.             if (obj.binder)  
  72.                 static_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);  
  73.             return;  
  74.         case BINDER_TYPE_HANDLE: {  
  75.             const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);  
  76.             if (b != NULL) {  
  77.                 LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());  
  78.                 b->incStrong(who);  
  79.             }  
  80.             return;  
  81.         }  
  82.         case BINDER_TYPE_WEAK_HANDLE: {  
  83.             const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);  
  84.             if (b != NULL) b.get_refs()->incWeak(who);  
  85.             return;  
  86.         }  
  87.         case BINDER_TYPE_FD: {  
  88.             // intentionally blank -- nothing to do to acquire this, but we do  
  89.             // recognize it as a legitimate object type.  
  90.             return;  
  91.         }  
  92.     }  
  93.   
  94.     LOGD("Invalid object type 0x%08lx", obj.type);  
  95. }  
  96.   
  97. void release_object(const sp<ProcessState>& proc,  
  98.     const flat_binder_object& obj, const void* who)  
  99. {  
  100.     switch (obj.type) {  
  101.         case BINDER_TYPE_BINDER:  
  102.             if (obj.binder) {  
  103.                 LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);  
  104.                 static_cast<IBinder*>(obj.cookie)->decStrong(who);  
  105.             }  
  106.             return;  
  107.         case BINDER_TYPE_WEAK_BINDER:  
  108.             if (obj.binder)  
  109.                 static_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);  
  110.             return;  
  111.         case BINDER_TYPE_HANDLE: {  
  112.             const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);  
  113.             if (b != NULL) {  
  114.                 LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());  
  115.                 b->decStrong(who);  
  116.             }  
  117.             return;  
  118.         }  
  119.         case BINDER_TYPE_WEAK_HANDLE: {  
  120.             const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);  
  121.             if (b != NULL) b.get_refs()->decWeak(who);  
  122.             return;  
  123.         }  
  124.         case BINDER_TYPE_FD: {  
  125.             if (obj.cookie != (void*)0) close(obj.handle);  
  126.             return;  
  127.         }  
  128.     }  
  129.   
  130.     LOGE("Invalid object type 0x%08lx", obj.type);  
  131. }  
  132.   
  133. inline static status_t finish_flatten_binder(  
  134.     const sp<IBinder>& binder, const flat_binder_object& flat, Parcel* out)  
  135. {  
  136.     return out->writeObject(flat, false);  
  137. }  
  138.   
  139. status_t flatten_binder(const sp<ProcessState>& proc,  
  140.     const sp<IBinder>& binder, Parcel* out)  
  141. {  
  142.     flat_binder_object obj;  
  143.       
  144.     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;  
  145.     if (binder != NULL) {  
  146.         IBinder *local = binder->localBinder();  
  147.         if (!local) {  
  148.             BpBinder *proxy = binder->remoteBinder();  
  149.             if (proxy == NULL) {  
  150.                 LOGE("null proxy");  
  151.             }  
  152.             const int32_t handle = proxy ? proxy->handle() : 0;  
  153.             obj.type = BINDER_TYPE_HANDLE;  
  154.             obj.handle = handle;  
  155.             obj.cookie = NULL;  
  156.         } else {  
  157.             obj.type = BINDER_TYPE_BINDER;  
  158.             obj.binder = local->getWeakRefs();  
  159.             obj.cookie = local;  
  160.         }  
  161.     } else {  
  162.         obj.type = BINDER_TYPE_BINDER;  
  163.         obj.binder = NULL;  
  164.         obj.cookie = NULL;  
  165.     }  
  166.       
  167.     return finish_flatten_binder(binder, obj, out);  
  168. }  
  169.   
  170. status_t flatten_binder(const sp<ProcessState>& proc,  
  171.     const wp<IBinder>& binder, Parcel* out)  
  172. {  
  173.     flat_binder_object obj;  
  174.       
  175.     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;  
  176.     if (binder != NULL) {  
  177.         sp<IBinder> real = binder.promote();  
  178.         if (real != NULL) {  
  179.             IBinder *local = real->localBinder();  
  180.             if (!local) {  
  181.                 BpBinder *proxy = real->remoteBinder();  
  182.                 if (proxy == NULL) {  
  183.                     LOGE("null proxy");  
  184.                 }  
  185.                 const int32_t handle = proxy ? proxy->handle() : 0;  
  186.                 obj.type = BINDER_TYPE_WEAK_HANDLE;  
  187.                 obj.handle = handle;  
  188.                 obj.cookie = NULL;  
  189.             } else {  
  190.                 obj.type = BINDER_TYPE_WEAK_BINDER;  
  191.                 obj.binder = binder.get_refs();  
  192.                 obj.cookie = binder.unsafe_get();  
  193.             }  
  194.             return finish_flatten_binder(real, obj, out);  
  195.         }  
  196.           
  197.         // XXX How to deal?  In order to flatten the given binder,  
  198.         // we need to probe it for information, which requires a primary  
  199.         // reference...  but we don't have one.  
  200.         //  
  201.         // The OpenBinder implementation uses a dynamic_cast<> here,  
  202.         // but we can't do that with the different reference counting  
  203.         // implementation we are using.  
  204.         LOGE("Unable to unflatten Binder weak reference!");  
  205.         obj.type = BINDER_TYPE_BINDER;  
  206.         obj.binder = NULL;  
  207.         obj.cookie = NULL;  
  208.         return finish_flatten_binder(NULL, obj, out);  
  209.       
  210.     } else {  
  211.         obj.type = BINDER_TYPE_BINDER;  
  212.         obj.binder = NULL;  
  213.         obj.cookie = NULL;  
  214.         return finish_flatten_binder(NULL, obj, out);  
  215.     }  
  216. }  
  217.   
  218. inline static status_t finish_unflatten_binder(  
  219.     BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)  
  220. {  
  221.     return NO_ERROR;  
  222. }  
  223.       
  224. status_t unflatten_binder(const sp<ProcessState>& proc,  
  225.     const Parcel& in, sp<IBinder>* out)  
  226. {  
  227.     const flat_binder_object* flat = in.readObject(false);  
  228.       
  229.     if (flat) {  
  230.         switch (flat->type) {  
  231.             case BINDER_TYPE_BINDER:  
  232.                 *out = static_cast<IBinder*>(flat->cookie);  
  233.                 return finish_unflatten_binder(NULL, *flat, in);  
  234.             case BINDER_TYPE_HANDLE:  
  235.                 *out = proc->getStrongProxyForHandle(flat->handle);  
  236.                 return finish_unflatten_binder(  
  237.                     static_cast<BpBinder*>(out->get()), *flat, in);  
  238.         }          
  239.     }  
  240.     return BAD_TYPE;  
  241. }  
  242.   
  243. status_t unflatten_binder(const sp<ProcessState>& proc,  
  244.     const Parcel& in, wp<IBinder>* out)  
  245. {  
  246.     const flat_binder_object* flat = in.readObject(false);  
  247.       
  248.     if (flat) {  
  249.         switch (flat->type) {  
  250.             case BINDER_TYPE_BINDER:  
  251.                 *out = static_cast<IBinder*>(flat->cookie);  
  252.                 return finish_unflatten_binder(NULL, *flat, in);  
  253.             case BINDER_TYPE_WEAK_BINDER:  
  254.                 if (flat->binder != NULL) {  
  255.                     out->set_object_and_refs(  
  256.                         static_cast<IBinder*>(flat->cookie),  
  257.                         static_cast<RefBase::weakref_type*>(flat->binder));  
  258.                 } else {  
  259.                     *out = NULL;  
  260.                 }  
  261.                 return finish_unflatten_binder(NULL, *flat, in);  
  262.             case BINDER_TYPE_HANDLE:  
  263.             case BINDER_TYPE_WEAK_HANDLE:  
  264.                 *out = proc->getWeakProxyForHandle(flat->handle);  
  265.                 return finish_unflatten_binder(  
  266.                     static_cast<BpBinder*>(out->unsafe_get()), *flat, in);  
  267.         }  
  268.     }  
  269.     return BAD_TYPE;  
  270. }  
  271.   
  272. // ---------------------------------------------------------------------------  
  273.   
  274. Parcel::Parcel()  
  275. {  
  276.     initState();  
  277. }  
  278.   
  279. Parcel::~Parcel()  
  280. {  
  281.     freeDataNoInit();  
  282. }  
  283.   
  284. const uint8_t* Parcel::data() const  
  285. {  
  286.     return mData;  
  287. }  
  288.   
  289. size_t Parcel::dataSize() const  
  290. {  
  291.     return (mDataSize > mDataPos ? mDataSize : mDataPos);  
  292. }  
  293.   
  294. size_t Parcel::dataAvail() const  
  295. {  
  296.     // TODO: decide what to do about the possibility that this can  
  297.     // report an available-data size that exceeds a Java int's max  
  298.     // positive value, causing havoc.  Fortunately this will only  
  299.     // happen if someone constructs a Parcel containing more than two  
  300.     // gigabytes of data, which on typical phone hardware is simply  
  301.     // not possible.  
  302.     return dataSize() - dataPosition();  
  303. }  
  304.   
  305. size_t Parcel::dataPosition() const  
  306. {  
  307.     return mDataPos;  
  308. }  
  309.   
  310. size_t Parcel::dataCapacity() const  
  311. {  
  312.     return mDataCapacity;  
  313. }  
  314.   
  315. status_t Parcel::setDataSize(size_t size)  
  316. {  
  317.     status_t err;  
  318.     err = continueWrite(size);  
  319.     if (err == NO_ERROR) {  
  320.         mDataSize = size;  
  321.         LOGV("setDataSize Setting data size of %p to %d/n"this, mDataSize);  
  322.     }  
  323.     return err;  
  324. }  
  325.   
  326. void Parcel::setDataPosition(size_t pos) const  
  327. {  
  328.     mDataPos = pos;  
  329.     mNextObjectHint = 0;  
  330. }  
  331.   
  332. status_t Parcel::setDataCapacity(size_t size)  
  333. {  
  334.     if (size > mDataSize) return continueWrite(size);  
  335.     return NO_ERROR;  
  336. }  
  337.   
  338. status_t Parcel::setData(const uint8_t* buffer, size_t len)  
  339. {  
  340.     status_t err = restartWrite(len);  
  341.     if (err == NO_ERROR) {  
  342.         memcpy(const_cast<uint8_t*>(data()), buffer, len);  
  343.         mDataSize = len;  
  344.         mFdsKnown = false;  
  345.     }  
  346.     return err;  
  347. }  
  348.   
  349. status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)  
  350. {  
  351.     const sp<ProcessState> proc(ProcessState::self());  
  352.     status_t err;  
  353.     uint8_t *data = parcel->mData;  
  354.     size_t *objects = parcel->mObjects;  
  355.     size_t size = parcel->mObjectsSize;  
  356.     int startPos = mDataPos;  
  357.     int firstIndex = -1, lastIndex = -2;  
  358.   
  359.     if (len == 0) {  
  360.         return NO_ERROR;  
  361.     }  
  362.   
  363.     // range checks against the source parcel size  
  364.     if ((offset > parcel->mDataSize)  
  365.             || (len > parcel->mDataSize)  
  366.             || (offset + len > parcel->mDataSize)) {  
  367.         return BAD_VALUE;  
  368.     }  
  369.   
  370.     // Count objects in range  
  371.     for (int i = 0; i < (int) size; i++) {  
  372.         size_t off = objects[i];  
  373.         if ((off >= offset) && (off < offset + len)) {  
  374.             if (firstIndex == -1) {  
  375.                 firstIndex = i;  
  376.             }  
  377.             lastIndex = i;  
  378.         }  
  379.     }  
  380.     int numObjects = lastIndex - firstIndex + 1;  
  381.   
  382.     // grow data  
  383.     err = growData(len);  
  384.     if (err != NO_ERROR) {  
  385.         return err;  
  386.     }  
  387.   
  388.     // append data  
  389.     memcpy(mData + mDataPos, data + offset, len);  
  390.     mDataPos += len;  
  391.     mDataSize += len;  
  392.   
  393.     if (numObjects > 0) {  
  394.         // grow objects  
  395.         if (mObjectsCapacity < mObjectsSize + numObjects) {  
  396.             int newSize = ((mObjectsSize + numObjects)*3)/2;  
  397.             size_t *objects =  
  398.                 (size_t*)realloc(mObjects, newSize*sizeof(size_t));  
  399.             if (objects == (size_t*)0) {  
  400.                 return NO_MEMORY;  
  401.             }  
  402.             mObjects = objects;  
  403.             mObjectsCapacity = newSize;  
  404.         }  
  405.           
  406.         // append and acquire objects  
  407.         int idx = mObjectsSize;  
  408.         for (int i = firstIndex; i <= lastIndex; i++) {  
  409.             size_t off = objects[i] - offset + startPos;  
  410.             mObjects[idx++] = off;  
  411.             mObjectsSize++;  
  412.   
  413.             flat_binder_object* flat  
  414.                 = reinterpret_cast<flat_binder_object*>(mData + off);  
  415.             acquire_object(proc, *flat, this);  
  416.   
  417.             if (flat->type == BINDER_TYPE_FD) {  
  418.                 // If this is a file descriptor, we need to dup it so the  
  419.                 // new Parcel now owns its own fd, and can declare that we  
  420.                 // officially know we have fds.  
  421.                 flat->handle = dup(flat->handle);  
  422.                 flat->cookie = (void*)1;  
  423.                 mHasFds = mFdsKnown = true;  
  424.             }  
  425.         }  
  426.     }  
  427.   
  428.     return NO_ERROR;  
  429. }  
  430.   
  431. bool Parcel::hasFileDescriptors() const  
  432. {  
  433.     if (!mFdsKnown) {  
  434.         scanForFds();  
  435.     }  
  436.     return mHasFds;  
  437. }  
  438.   
  439. status_t Parcel::writeInterfaceToken(const String16& interface)  
  440. {  
  441.     // currently the interface identification token is just its name as a string  
  442.     return writeString16(interface);  
  443. }  
  444.   
  445. bool Parcel::checkInterface(IBinder* binder) const  
  446. {  
  447.     return enforceInterface(binder->getInterfaceDescriptor());   
  448. }  
  449.   
  450. bool Parcel::enforceInterface(const String16& interface) const  
  451. {  
  452.     const String16 str(readString16());  
  453.     if (str == interface) {  
  454.         return true;  
  455.     } else {  
  456.         LOGW("**** enforceInterface() expected '%s' but read '%s'/n",  
  457.                 String8(interface).string(), String8(str).string());  
  458.         return false;  
  459.     }  
  460. }   
  461.   
  462. const size_t* Parcel::objects() const  
  463. {  
  464.     return mObjects;  
  465. }  
  466.   
  467. size_t Parcel::objectsCount() const  
  468. {  
  469.     return mObjectsSize;  
  470. }  
  471.   
  472. status_t Parcel::errorCheck() const  
  473. {  
  474.     return mError;  
  475. }  
  476.   
  477. void Parcel::setError(status_t err)  
  478. {  
  479.     mError = err;  
  480. }  
  481.   
  482. status_t Parcel::finishWrite(size_t len)  
  483. {  
  484.     //printf("Finish write of %d/n", len);  
  485.     mDataPos += len;  
  486.     LOGV("finishWrite Setting data pos of %p to %d/n"this, mDataPos);  
  487.     if (mDataPos > mDataSize) {  
  488.         mDataSize = mDataPos;  
  489.         LOGV("finishWrite Setting data size of %p to %d/n"this, mDataSize);  
  490.     }  
  491.     //printf("New pos=%d, size=%d/n", mDataPos, mDataSize);  
  492.     return NO_ERROR;  
  493. }  
  494.   
  495. status_t Parcel::writeUnpadded(const void* data, size_t len)  
  496. {  
  497.     size_t end = mDataPos + len;  
  498.     if (end < mDataPos) {  
  499.         // integer overflow  
  500.         return BAD_VALUE;  
  501.     }  
  502.   
  503.     if (end <= mDataCapacity) {  
  504. restart_write:  
  505.         memcpy(mData+mDataPos, data, len);  
  506.         return finishWrite(len);  
  507.     }  
  508.   
  509.     status_t err = growData(len);  
  510.     if (err == NO_ERROR) goto restart_write;  
  511.     return err;  
  512. }  
  513.   
  514. status_t Parcel::write(const void* data, size_t len)  
  515. {  
  516.     voidconst d = writeInplace(len);  
  517.     if (d) {  
  518.         memcpy(d, data, len);  
  519.         return NO_ERROR;  
  520.     }  
  521.     return mError;  
  522. }  
  523.   
  524. void* Parcel::writeInplace(size_t len)  
  525. {  
  526.     const size_t padded = PAD_SIZE(len);  
  527.   
  528.     // sanity check for integer overflow  
  529.     if (mDataPos+padded < mDataPos) {  
  530.         return NULL;  
  531.     }  
  532.   
  533.     if ((mDataPos+padded) <= mDataCapacity) {  
  534. restart_write:  
  535.         //printf("Writing %ld bytes, padded to %ld/n", len, padded);  
  536.         uint8_t* const data = mData+mDataPos;  
  537.   
  538.         // Need to pad at end?  
  539.         if (padded != len) {  
  540. #if BYTE_ORDER == BIG_ENDIAN  
  541.             static const uint32_t mask[4] = {  
  542.                 0x00000000, 0xffffff00, 0xffff0000, 0xff000000  
  543.             };  
  544. #endif  
  545. #if BYTE_ORDER == LITTLE_ENDIAN  
  546.             static const uint32_t mask[4] = {  
  547.                 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff  
  548.             };  
  549. #endif  
  550.             //printf("Applying pad mask: %p to %p/n", (void*)mask[padded-len],  
  551.             //    *reinterpret_cast<void**>(data+padded-4));  
  552.             *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];  
  553.         }  
  554.   
  555.         finishWrite(padded);  
  556.         return data;  
  557.     }  
  558.   
  559.     status_t err = growData(padded);  
  560.     if (err == NO_ERROR) goto restart_write;  
  561.     return NULL;  
  562. }  
  563.   
  564. status_t Parcel::writeInt32(int32_t val)  
  565. {  
  566.     return writeAligned(val);  
  567. }  
  568.   
  569. status_t Parcel::writeInt64(int64_t val)  
  570. {  
  571.     return writeAligned(val);  
  572. }  
  573.   
  574. status_t Parcel::writeFloat(float val)  
  575. {  
  576.     return writeAligned(val);  
  577. }  
  578.   
  579. status_t Parcel::writeDouble(double val)  
  580. {  
  581.     return writeAligned(val);  
  582. }  
  583.   
  584. status_t Parcel::writeIntPtr(intptr_t val)  
  585. {  
  586.     return writeAligned(val);  
  587. }  
  588.   
  589. status_t Parcel::writeCString(const char* str)  
  590. {  
  591.     return write(str, strlen(str)+1);  
  592. }  
  593.   
  594. status_t Parcel::writeString8(const String8& str)  
  595. {  
  596.     status_t err = writeInt32(str.bytes());  
  597.     if (err == NO_ERROR) {  
  598.         err = write(str.string(), str.bytes()+1);  
  599.     }  
  600.     return err;  
  601. }  
  602.   
  603. status_t Parcel::writeString16(const String16& str)  
  604. {  
  605.     return writeString16(str.string(), str.size());  
  606. }  
  607.   
  608. status_t Parcel::writeString16(const char16_t* str, size_t len)  
  609. {  
  610.     if (str == NULL) return writeInt32(-1);  
  611.       
  612.     status_t err = writeInt32(len);  
  613.     if (err == NO_ERROR) {  
  614.         len *= sizeof(char16_t);  
  615.         uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));  
  616.         if (data) {  
  617.             memcpy(data, str, len);  
  618.             *reinterpret_cast<char16_t*>(data+len) = 0;  
  619.             return NO_ERROR;  
  620.         }  
  621.         err = mError;  
  622.     }  
  623.     return err;  
  624. }  
  625.   
  626. status_t Parcel::writeStrongBinder(const sp<IBinder>& val)  
  627. {  
  628.     return flatten_binder(ProcessState::self(), val, this);  
  629. }  
  630.   
  631. status_t Parcel::writeWeakBinder(const wp<IBinder>& val)  
  632. {  
  633.     return flatten_binder(ProcessState::self(), val, this);  
  634. }  
  635.   
  636. status_t Parcel::writeNativeHandle(const native_handle* handle)  
  637. {  
  638.     if (!handle || handle->version != sizeof(native_handle))  
  639.         return BAD_TYPE;  
  640.   
  641.     status_t err;  
  642.     err = writeInt32(handle->numFds);  
  643.     if (err != NO_ERROR) return err;  
  644.   
  645.     err = writeInt32(handle->numInts);  
  646.     if (err != NO_ERROR) return err;  
  647.   
  648.     for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)  
  649.         err = writeDupFileDescriptor(handle->data[i]);  
  650.   
  651.     if (err != NO_ERROR) {  
  652.         LOGD("write native handle, write dup fd failed");  
  653.         return err;  
  654.     }  
  655.     err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);  
  656.     return err;  
  657. }  
  658.   
  659. status_t Parcel::writeFileDescriptor(int fd)  
  660. {  
  661.     flat_binder_object obj;  
  662.     obj.type = BINDER_TYPE_FD;  
  663.     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;  
  664.     obj.handle = fd;  
  665.     obj.cookie = (void*)0;  
  666.     return writeObject(obj, true);  
  667. }  
  668.   
  669. status_t Parcel::writeDupFileDescriptor(int fd)  
  670. {  
  671.     flat_binder_object obj;  
  672.     obj.type = BINDER_TYPE_FD;  
  673.     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;  
  674.     obj.handle = dup(fd);  
  675.     obj.cookie = (void*)1;  
  676.     return writeObject(obj, true);  
  677. }  
  678.   
  679. status_t Parcel::write(const Flattenable& val)  
  680. {  
  681.     status_t err;  
  682.   
  683.     // size if needed  
  684.     size_t len = val.getFlattenedSize();  
  685.     size_t fd_count = val.getFdCount();  
  686.   
  687.     err = this->writeInt32(len);  
  688.     if (err) return err;  
  689.   
  690.     err = this->writeInt32(fd_count);  
  691.     if (err) return err;  
  692.   
  693.     // payload  
  694.     void* buf = this->writeInplace(PAD_SIZE(len));  
  695.     if (buf == NULL)  
  696.         return BAD_VALUE;  
  697.   
  698.     int* fds = NULL;  
  699.     if (fd_count) {  
  700.         fds = new int[fd_count];  
  701.     }  
  702.   
  703.     err = val.flatten(buf, len, fds, fd_count);  
  704.     for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {  
  705.         err = this->writeDupFileDescriptor( fds[i] );  
  706.     }  
  707.   
  708.     if (fd_count) {  
  709.         delete [] fds;  
  710.     }  
  711.   
  712.     return err;  
  713. }  
  714.   
  715. status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)  
  716. {  
  717.     const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;  
  718.     const bool enoughObjects = mObjectsSize < mObjectsCapacity;  
  719.     if (enoughData && enoughObjects) {  
  720. restart_write:  
  721.         *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;  
  722.           
  723.         // Need to write meta-data?  
  724.         if (nullMetaData || val.binder != NULL) {  
  725.             mObjects[mObjectsSize] = mDataPos;  
  726.             acquire_object(ProcessState::self(), val, this);  
  727.             mObjectsSize++;  
  728.         }  
  729.           
  730.         // remember if it's a file descriptor  
  731.         if (val.type == BINDER_TYPE_FD) {  
  732.             mHasFds = mFdsKnown = true;  
  733.         }  
  734.   
  735.         return finishWrite(sizeof(flat_binder_object));  
  736.     }  
  737.   
  738.     if (!enoughData) {  
  739.         const status_t err = growData(sizeof(val));  
  740.         if (err != NO_ERROR) return err;  
  741.     }  
  742.     if (!enoughObjects) {  
  743.         size_t newSize = ((mObjectsSize+2)*3)/2;  
  744.         size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));  
  745.         if (objects == NULL) return NO_MEMORY;  
  746.         mObjects = objects;  
  747.         mObjectsCapacity = newSize;  
  748.     }  
  749.       
  750.     goto restart_write;  
  751. }  
  752.   
  753. void Parcel::remove(size_t start, size_t amt)  
  754. {  
  755.     LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");  
  756. }  
  757.   
  758. status_t Parcel::read(void* outData, size_t len) const  
  759. {  
  760.     if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {  
  761.         memcpy(outData, mData+mDataPos, len);  
  762.         mDataPos += PAD_SIZE(len);  
  763.         LOGV("read Setting data pos of %p to %d/n"this, mDataPos);  
  764.         return NO_ERROR;  
  765.     }  
  766.     return NOT_ENOUGH_DATA;  
  767. }  
  768.   
  769. const void* Parcel::readInplace(size_t len) const  
  770. {  
  771.     if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {  
  772.         const void* data = mData+mDataPos;  
  773.         mDataPos += PAD_SIZE(len);  
  774.         LOGV("readInplace Setting data pos of %p to %d/n"this, mDataPos);  
  775.         return data;  
  776.     }  
  777.     return NULL;  
  778. }  
  779.   
  780. template<class T>  
  781. status_t Parcel::readAligned(T *pArg) const {  
  782.     COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));  
  783.   
  784.     if ((mDataPos+sizeof(T)) <= mDataSize) {  
  785.         const void* data = mData+mDataPos;  
  786.         mDataPos += sizeof(T);  
  787.         *pArg =  *reinterpret_cast<const T*>(data);  
  788.         return NO_ERROR;  
  789.     } else {  
  790.         return NOT_ENOUGH_DATA;  
  791.     }  
  792. }  
  793.   
  794. template<class T>  
  795. T Parcel::readAligned() const {  
  796.     T result;  
  797.     if (readAligned(&result) != NO_ERROR) {  
  798.         result = 0;  
  799.     }  
  800.   
  801.     return result;  
  802. }  
  803.   
  804. template<class T>  
  805. status_t Parcel::writeAligned(T val) {  
  806.     COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));  
  807.   
  808.     if ((mDataPos+sizeof(val)) <= mDataCapacity) {  
  809. restart_write:  
  810.         *reinterpret_cast<T*>(mData+mDataPos) = val;  
  811.         return finishWrite(sizeof(val));  
  812.     }  
  813.   
  814.     status_t err = growData(sizeof(val));  
  815.     if (err == NO_ERROR) goto restart_write;  
  816.     return err;  
  817. }  
  818.   
  819. status_t Parcel::readInt32(int32_t *pArg) const  
  820. {  
  821.     return readAligned(pArg);  
  822. }  
  823.   
  824. int32_t Parcel::readInt32() const  
  825. {  
  826.     return readAligned<int32_t>();  
  827. }  
  828.   
  829.   
  830. status_t Parcel::readInt64(int64_t *pArg) const  
  831. {  
  832.     return readAligned(pArg);  
  833. }  
  834.   
  835.   
  836. int64_t Parcel::readInt64() const  
  837. {  
  838.     return readAligned<int64_t>();  
  839. }  
  840.   
  841. status_t Parcel::readFloat(float *pArg) const  
  842. {  
  843.     return readAligned(pArg);  
  844. }  
  845.   
  846.   
  847. float Parcel::readFloat() const  
  848. {  
  849.     return readAligned<float>();  
  850. }  
  851.   
  852. status_t Parcel::readDouble(double *pArg) const  
  853. {  
  854.     return readAligned(pArg);  
  855. }  
  856.   
  857.   
  858. double Parcel::readDouble() const  
  859. {  
  860.     return readAligned<double>();  
  861. }  
  862.   
  863. status_t Parcel::readIntPtr(intptr_t *pArg) const  
  864. {  
  865.     return readAligned(pArg);  
  866. }  
  867.   
  868.   
  869. intptr_t Parcel::readIntPtr() const  
  870. {  
  871.     return readAligned<intptr_t>();  
  872. }  
  873.   
  874.   
  875. const char* Parcel::readCString() const  
  876. {  
  877.     const size_t avail = mDataSize-mDataPos;  
  878.     if (avail > 0) {  
  879.         const char* str = reinterpret_cast<const char*>(mData+mDataPos);  
  880.         // is the string's trailing NUL within the parcel's valid bounds?  
  881.         const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));  
  882.         if (eos) {  
  883.             const size_t len = eos - str;  
  884.             mDataPos += PAD_SIZE(len+1);  
  885.             LOGV("readCString Setting data pos of %p to %d/n"this, mDataPos);  
  886.             return str;  
  887.         }  
  888.     }  
  889.     return NULL;  
  890. }  
  891.   
  892. String8 Parcel::readString8() const  
  893. {  
  894.     int32_t size = readInt32();  
  895.     // watch for potential int overflow adding 1 for trailing NUL  
  896.     if (size > 0 && size < INT32_MAX) {  
  897.         const char* str = (const char*)readInplace(size+1);  
  898.         if (str) return String8(str, size);  
  899.     }  
  900.     return String8();  
  901. }  
  902.   
  903. String16 Parcel::readString16() const  
  904. {  
  905.     size_t len;  
  906.     const char16_t* str = readString16Inplace(&len);  
  907.     if (str) return String16(str, len);  
  908.     LOGE("Reading a NULL string not supported here.");  
  909.     return String16();  
  910. }  
  911.   
  912. const char16_t* Parcel::readString16Inplace(size_t* outLen) const  
  913. {  
  914.     int32_t size = readInt32();  
  915.     // watch for potential int overflow from size+1  
  916.     if (size >= 0 && size < INT32_MAX) {  
  917.         *outLen = size;  
  918.         const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));  
  919.         if (str != NULL) {  
  920.             return str;  
  921.         }  
  922.     }  
  923.     *outLen = 0;  
  924.     return NULL;  
  925. }  
  926.   
  927. sp<IBinder> Parcel::readStrongBinder() const  
  928. {  
  929.     sp<IBinder> val;  
  930.     unflatten_binder(ProcessState::self(), *this, &val);  
  931.     return val;  
  932. }  
  933.   
  934. wp<IBinder> Parcel::readWeakBinder() const  
  935. {  
  936.     wp<IBinder> val;  
  937.     unflatten_binder(ProcessState::self(), *this, &val);  
  938.     return val;  
  939. }  
  940.   
  941.   
  942. native_handle* Parcel::readNativeHandle() const  
  943. {  
  944.     int numFds, numInts;  
  945.     status_t err;  
  946.     err = readInt32(&numFds);  
  947.     if (err != NO_ERROR) return 0;  
  948.     err = readInt32(&numInts);  
  949.     if (err != NO_ERROR) return 0;  
  950.   
  951.     native_handle* h = native_handle_create(numFds, numInts);  
  952.     for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {  
  953.         h->data[i] = dup(readFileDescriptor());  
  954.         if (h->data[i] < 0) err = BAD_VALUE;  
  955.     }  
  956.     err = read(h->data + numFds, sizeof(int)*numInts);  
  957.     if (err != NO_ERROR) {  
  958.         native_handle_close(h);  
  959.         native_handle_delete(h);  
  960.         h = 0;  
  961.     }  
  962.     return h;  
  963. }  
  964.   
  965.   
  966. int Parcel::readFileDescriptor() const  
  967. {  
  968.     const flat_binder_object* flat = readObject(true);  
  969.     if (flat) {  
  970.         switch (flat->type) {  
  971.             case BINDER_TYPE_FD:  
  972.                 //LOGI("Returning file descriptor %ld from parcel %p/n", flat->handle, this);  
  973.                 return flat->handle;  
  974.         }          
  975.     }  
  976.     return BAD_TYPE;  
  977. }  
  978.   
  979. status_t Parcel::read(Flattenable& val) const  
  980. {  
  981.     // size  
  982.     const size_t len = this->readInt32();  
  983.     const size_t fd_count = this->readInt32();  
  984.   
  985.     // payload  
  986.     void const* buf = this->readInplace(PAD_SIZE(len));  
  987.     if (buf == NULL)  
  988.         return BAD_VALUE;  
  989.   
  990.     int* fds = NULL;  
  991.     if (fd_count) {  
  992.         fds = new int[fd_count];  
  993.     }  
  994.   
  995.     status_t err = NO_ERROR;  
  996.     for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {  
  997.         fds[i] = dup(this->readFileDescriptor());  
  998.         if (fds[i] < 0) err = BAD_VALUE;  
  999.     }  
  1000.   
  1001.     if (err == NO_ERROR) {  
  1002.         err = val.unflatten(buf, len, fds, fd_count);  
  1003.     }  
  1004.   
  1005.     if (fd_count) {  
  1006.         delete [] fds;  
  1007.     }  
  1008.   
  1009.     return err;  
  1010. }  
  1011. const flat_binder_object* Parcel::readObject(bool nullMetaData) const  
  1012. {  
  1013.     const size_t DPOS = mDataPos;  
  1014.     if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {  
  1015.         const flat_binder_object* obj  
  1016.                 = reinterpret_cast<const flat_binder_object*>(mData+DPOS);  
  1017.         mDataPos = DPOS + sizeof(flat_binder_object);  
  1018.         if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {  
  1019.             // When transferring a NULL object, we don't write it into  
  1020.             // the object list, so we don't want to check for it when  
  1021.             // reading.  
  1022.             LOGV("readObject Setting data pos of %p to %d/n"this, mDataPos);  
  1023.             return obj;  
  1024.         }  
  1025.           
  1026.         // Ensure that this object is valid...  
  1027.         size_tconst OBJS = mObjects;  
  1028.         const size_t N = mObjectsSize;  
  1029.         size_t opos = mNextObjectHint;  
  1030.           
  1031.         if (N > 0) {  
  1032.             LOGV("Parcel %p looking for obj at %d, hint=%d/n",  
  1033.                  this, DPOS, opos);  
  1034.               
  1035.             // Start at the current hint position, looking for an object at  
  1036.             // the current data position.  
  1037.             if (opos < N) {  
  1038.                 while (opos < (N-1) && OBJS[opos] < DPOS) {  
  1039.                     opos++;  
  1040.                 }  
  1041.             } else {  
  1042.                 opos = N-1;  
  1043.             }  
  1044.             if (OBJS[opos] == DPOS) {  
  1045.                 // Found it!  
  1046.                 LOGV("Parcel found obj %d at index %d with forward search",  
  1047.                      this, DPOS, opos);  
  1048.                 mNextObjectHint = opos+1;  
  1049.                 LOGV("readObject Setting data pos of %p to %d/n"this, mDataPos);  
  1050.                 return obj;  
  1051.             }  
  1052.           
  1053.             // Look backwards for it...  
  1054.             while (opos > 0 && OBJS[opos] > DPOS) {  
  1055.                 opos--;  
  1056.             }  
  1057.             if (OBJS[opos] == DPOS) {  
  1058.                 // Found it!  
  1059.                 LOGV("Parcel found obj %d at index %d with backward search",  
  1060.                      this, DPOS, opos);  
  1061.                 mNextObjectHint = opos+1;  
  1062.                 LOGV("readObject Setting data pos of %p to %d/n"this, mDataPos);  
  1063.                 return obj;  
  1064.             }  
  1065.         }  
  1066.         LOGW("Attempt to read object from Parcel %p at offset %d that is not in the object list",  
  1067.              this, DPOS);  
  1068.     }  
  1069.     return NULL;  
  1070. }  
  1071.   
  1072. void Parcel::closeFileDescriptors()  
  1073. {  
  1074.     size_t i = mObjectsSize;  
  1075.     if (i > 0) {  
  1076.         //LOGI("Closing file descriptors for %d objects...", mObjectsSize);  
  1077.     }  
  1078.     while (i > 0) {  
  1079.         i--;  
  1080.         const flat_binder_object* flat  
  1081.             = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);  
  1082.         if (flat->type == BINDER_TYPE_FD) {  
  1083.             //LOGI("Closing fd: %ld/n", flat->handle);  
  1084.             close(flat->handle);  
  1085.         }  
  1086.     }  
  1087. }  
  1088.   
  1089. const uint8_t* Parcel::ipcData() const  
  1090. {  
  1091.     return mData;  
  1092. }  
  1093.   
  1094. size_t Parcel::ipcDataSize() const  
  1095. {  
  1096.     return (mDataSize > mDataPos ? mDataSize : mDataPos);  
  1097. }  
  1098.   
  1099. const size_t* Parcel::ipcObjects() const  
  1100. {  
  1101.     return mObjects;  
  1102. }  
  1103.   
  1104. size_t Parcel::ipcObjectsCount() const  
  1105. {  
  1106.     return mObjectsSize;  
  1107. }  
  1108.   
  1109. void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,  
  1110.     const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)  
  1111. {  
  1112.     freeDataNoInit();  
  1113.     mError = NO_ERROR;  
  1114.     mData = const_cast<uint8_t*>(data);  
  1115.     mDataSize = mDataCapacity = dataSize;  
  1116.     //LOGI("setDataReference Setting data size of %p to %lu (pid=%d)/n", this, mDataSize, getpid());  
  1117.     mDataPos = 0;  
  1118.     LOGV("setDataReference Setting data pos of %p to %d/n"this, mDataPos);  
  1119.     mObjects = const_cast<size_t*>(objects);  
  1120.     mObjectsSize = mObjectsCapacity = objectsCount;  
  1121.     mNextObjectHint = 0;  
  1122.     mOwner = relFunc;  
  1123.     mOwnerCookie = relCookie;  
  1124.     scanForFds();  
  1125. }  
  1126.   
  1127. void Parcel::print(TextOutput& to, uint32_t flags) const  
  1128. {  
  1129.     to << "Parcel(";  
  1130.       
  1131.     if (errorCheck() != NO_ERROR) {  
  1132.         const status_t err = errorCheck();  
  1133.         to << "Error: " << (void*)err << " /"" << strerror(-err) << "/"";  
  1134.     } else if (dataSize() > 0) {  
  1135.         const uint8_t* DATA = data();  
  1136.         to << indent << HexDump(DATA, dataSize()) << dedent;  
  1137.         const size_t* OBJS = objects();  
  1138.         const size_t N = objectsCount();  
  1139.         for (size_t i=0; i<N; i++) {  
  1140.             const flat_binder_object* flat  
  1141.                 = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);  
  1142.             to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "  
  1143.                 << TypeCode(flat->type & 0x7f7f7f00)  
  1144.                 << " = " << flat->binder;  
  1145.         }  
  1146.     } else {  
  1147.         to << "NULL";  
  1148.     }  
  1149.       
  1150.     to << ")";  
  1151. }  
  1152.   
  1153. void Parcel::releaseObjects()  
  1154. {  
  1155.     const sp<ProcessState> proc(ProcessState::self());  
  1156.     size_t i = mObjectsSize;  
  1157.     uint8_t* const data = mData;  
  1158.     size_tconst objects = mObjects;  
  1159.     while (i > 0) {  
  1160.         i--;  
  1161.         const flat_binder_object* flat  
  1162.             = reinterpret_cast<flat_binder_object*>(data+objects[i]);  
  1163.         release_object(proc, *flat, this);  
  1164.     }  
  1165. }  
  1166.   
  1167. void Parcel::acquireObjects()  
  1168. {  
  1169.     const sp<ProcessState> proc(ProcessState::self());  
  1170.     size_t i = mObjectsSize;  
  1171.     uint8_t* const data = mData;  
  1172.     size_tconst objects = mObjects;  
  1173.     while (i > 0) {  
  1174.         i--;  
  1175.         const flat_binder_object* flat  
  1176.             = reinterpret_cast<flat_binder_object*>(data+objects[i]);  
  1177.         acquire_object(proc, *flat, this);  
  1178.     }  
  1179. }  
  1180.   
  1181. void Parcel::freeData()  
  1182. {  
  1183.     freeDataNoInit();  
  1184.     initState();  
  1185. }  
  1186.   
  1187. void Parcel::freeDataNoInit()  
  1188. {  
  1189.     if (mOwner) {  
  1190.         //LOGI("Freeing data ref of %p (pid=%d)/n", this, getpid());  
  1191.         mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);  
  1192.     } else {  
  1193.         releaseObjects();  
  1194.         if (mData) free(mData);  
  1195.         if (mObjects) free(mObjects);  
  1196.     }  
  1197. }  
  1198.   
  1199. status_t Parcel::growData(size_t len)  
  1200. {  
  1201.     size_t newSize = ((mDataSize+len)*3)/2;  
  1202.     return (newSize <= mDataSize)  
  1203.             ? (status_t) NO_MEMORY  
  1204.             : continueWrite(newSize);  
  1205. }  
  1206.   
  1207. status_t Parcel::restartWrite(size_t desired)  
  1208. {  
  1209.     if (mOwner) {  
  1210.         freeData();  
  1211.         return continueWrite(desired);  
  1212.     }  
  1213.       
  1214.     uint8_t* data = (uint8_t*)realloc(mData, desired);  
  1215.     if (!data && desired > mDataCapacity) {  
  1216.         mError = NO_MEMORY;  
  1217.         return NO_MEMORY;  
  1218.     }  
  1219.       
  1220.     releaseObjects();  
  1221.       
  1222.     if (data) {  
  1223.         mData = data;  
  1224.         mDataCapacity = desired;  
  1225.     }  
  1226.       
  1227.     mDataSize = mDataPos = 0;  
  1228.     LOGV("restartWrite Setting data size of %p to %d/n"this, mDataSize);  
  1229.     LOGV("restartWrite Setting data pos of %p to %d/n"this, mDataPos);  
  1230.           
  1231.     free(mObjects);  
  1232.     mObjects = NULL;  
  1233.     mObjectsSize = mObjectsCapacity = 0;  
  1234.     mNextObjectHint = 0;  
  1235.     mHasFds = false;  
  1236.     mFdsKnown = true;  
  1237.       
  1238.     return NO_ERROR;  
  1239. }  
  1240.   
  1241. status_t Parcel::continueWrite(size_t desired)  
  1242. {  
  1243.     // If shrinking, first adjust for any objects that appear  
  1244.     // after the new data size.  
  1245.     size_t objectsSize = mObjectsSize;  
  1246.     if (desired < mDataSize) {  
  1247.         if (desired == 0) {  
  1248.             objectsSize = 0;  
  1249.         } else {  
  1250.             while (objectsSize > 0) {  
  1251.                 if (mObjects[objectsSize-1] < desired)  
  1252.                     break;  
  1253.                 objectsSize--;  
  1254.             }  
  1255.         }  
  1256.     }  
  1257.       
  1258.     if (mOwner) {  
  1259.         // If the size is going to zero, just release the owner's data.  
  1260.         if (desired == 0) {  
  1261.             freeData();  
  1262.             return NO_ERROR;  
  1263.         }  
  1264.   
  1265.         // If there is a different owner, we need to take  
  1266.         // posession.  
  1267.         uint8_t* data = (uint8_t*)malloc(desired);  
  1268.         if (!data) {  
  1269.             mError = NO_MEMORY;  
  1270.             return NO_MEMORY;  
  1271.         }  
  1272.         size_t* objects = NULL;  
  1273.           
  1274.         if (objectsSize) {  
  1275.             objects = (size_t*)malloc(objectsSize*sizeof(size_t));  
  1276.             if (!objects) {  
  1277.                 mError = NO_MEMORY;  
  1278.                 return NO_MEMORY;  
  1279.             }  
  1280.   
  1281.             // Little hack to only acquire references on objects  
  1282.             // we will be keeping.  
  1283.             size_t oldObjectsSize = mObjectsSize;  
  1284.             mObjectsSize = objectsSize;  
  1285.             acquireObjects();  
  1286.             mObjectsSize = oldObjectsSize;  
  1287.         }  
  1288.           
  1289.         if (mData) {  
  1290.             memcpy(data, mData, mDataSize < desired ? mDataSize : desired);  
  1291.         }  
  1292.         if (objects && mObjects) {  
  1293.             memcpy(objects, mObjects, objectsSize*sizeof(size_t));  
  1294.         }  
  1295.         //LOGI("Freeing data ref of %p (pid=%d)/n", this, getpid());  
  1296.         mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);  
  1297.         mOwner = NULL;  
  1298.   
  1299.         mData = data;  
  1300.         mObjects = objects;  
  1301.         mDataSize = (mDataSize < desired) ? mDataSize : desired;  
  1302.         LOGV("continueWrite Setting data size of %p to %d/n"this, mDataSize);  
  1303.         mDataCapacity = desired;  
  1304.         mObjectsSize = mObjectsCapacity = objectsSize;  
  1305.         mNextObjectHint = 0;  
  1306.   
  1307.     } else if (mData) {  
  1308.         if (objectsSize < mObjectsSize) {  
  1309.             // Need to release refs on any objects we are dropping.  
  1310.             const sp<ProcessState> proc(ProcessState::self());  
  1311.             for (size_t i=objectsSize; i<mObjectsSize; i++) {  
  1312.                 const flat_binder_object* flat  
  1313.                     = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);  
  1314.                 if (flat->type == BINDER_TYPE_FD) {  
  1315.                     // will need to rescan because we may have lopped off the only FDs  
  1316.                     mFdsKnown = false;  
  1317.                 }  
  1318.                 release_object(proc, *flat, this);  
  1319.             }  
  1320.             size_t* objects =  
  1321.                 (size_t*)realloc(mObjects, objectsSize*sizeof(size_t));  
  1322.             if (objects) {  
  1323.                 mObjects = objects;  
  1324.             }  
  1325.             mObjectsSize = objectsSize;  
  1326.             mNextObjectHint = 0;  
  1327.         }  
  1328.   
  1329.         // We own the data, so we can just do a realloc().  
  1330.         if (desired > mDataCapacity) {  
  1331.             uint8_t* data = (uint8_t*)realloc(mData, desired);  
  1332.             if (data) {  
  1333.                 mData = data;  
  1334.                 mDataCapacity = desired;  
  1335.             } else if (desired > mDataCapacity) {  
  1336.                 mError = NO_MEMORY;  
  1337.                 return NO_MEMORY;  
  1338.             }  
  1339.         } else {  
  1340.             mDataSize = desired;  
  1341.             LOGV("continueWrite Setting data size of %p to %d/n"this, mDataSize);  
  1342.             if (mDataPos > desired) {  
  1343.                 mDataPos = desired;  
  1344.                 LOGV("continueWrite Setting data pos of %p to %d/n"this, mDataPos);  
  1345.             }  
  1346.         }  
  1347.           
  1348.     } else {  
  1349.         // This is the first data.  Easy!  
  1350.         uint8_t* data = (uint8_t*)malloc(desired);  
  1351.         if (!data) {  
  1352.             mError = NO_MEMORY;  
  1353.             return NO_MEMORY;  
  1354.         }  
  1355.           
  1356.         if(!(mDataCapacity == 0 && mObjects == NULL  
  1357.              && mObjectsCapacity == 0)) {  
  1358.             LOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired);  
  1359.         }  
  1360.           
  1361.         mData = data;  
  1362.         mDataSize = mDataPos = 0;  
  1363.         LOGV("continueWrite Setting data size of %p to %d/n"this, mDataSize);  
  1364.         LOGV("continueWrite Setting data pos of %p to %d/n"this, mDataPos);  
  1365.         mDataCapacity = desired;  
  1366.     }  
  1367.   
  1368.     return NO_ERROR;  
  1369. }  
  1370.   
  1371. void Parcel::initState()  
  1372. {  
  1373.     mError = NO_ERROR;  
  1374.     mData = 0;  
  1375.     mDataSize = 0;  
  1376.     mDataCapacity = 0;  
  1377.     mDataPos = 0;  
  1378.     LOGV("initState Setting data size of %p to %d/n"this, mDataSize);  
  1379.     LOGV("initState Setting data pos of %p to %d/n"this, mDataPos);  
  1380.     mObjects = NULL;  
  1381.     mObjectsSize = 0;  
  1382.     mObjectsCapacity = 0;  
  1383.     mNextObjectHint = 0;  
  1384.     mHasFds = false;  
  1385.     mFdsKnown = true;  
  1386.     mOwner = NULL;  
  1387. }  
  1388.   
  1389. void Parcel::scanForFds() const  
  1390. {  
  1391.     bool hasFds = false;  
  1392.     for (size_t i=0; i<mObjectsSize; i++) {  
  1393.         const flat_binder_object* flat  
  1394.             = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);  
  1395.         if (flat->type == BINDER_TYPE_FD) {  
  1396.             hasFds = true;  
  1397.             break;  
  1398.         }  
  1399.     }  
  1400.     mHasFds = hasFds;  
  1401.     mFdsKnown = true;  
  1402. }  
  1403.   
  1404. }; // namespace android  

 

 

         本文的源码使用的是Android 2.1版本。

查看原文

分享到:
评论

相关推荐

    android序列化实现

    在Android开发中,数据的序列化是一个非常重要的概念,它涉及到数据的持久化存储和跨进程通信。序列化是将对象的状态转化为可存储或可传输的形式的过程,而在Android中,我们通常会用到两种主要的序列化方式:...

    android 对象序列化

    2. 实现Parcelable接口:这是Android特有的序列化方式,相比于Serializable,Parcelable在性能上更优,尤其是在大量数据传递和频繁序列化操作时。但实现Parcelable接口需要编写更多的代码,对开发者的要求也更高。 ...

    Android对象序列化的代码例子

    在Android开发中,对象序列化是一项重要的技术,它允许我们将对象的状态转化为可存储或传输的格式,例如保存到文件、数据库或通过网络进行传递。Android提供了两种主要的对象序列化方式:Parcelable和Serializable。...

    Android 序列化对象存储到sharepreference

    在Android开发中,序列化(Serialization)是一种将对象转换为可传输或存储格式的过程,而SharedPreferences则是一个轻量级的数据存储机制,常用于保存应用程序的简单配置数据。本篇文章将详细探讨如何将Android序列...

    Json反序列化

    二、为什么要进行JSON反序列化? 1. 提高效率:直接操作反序列化后的对象比解析JSON字符串更高效,避免了逐字符解析和构建数据结构的时间消耗。 2. 易于使用:反序列化后的数据可以直接与编程语言的内置类型交互,...

    诠释Android中序列化的原理与机制

    在Android开发中,序列化是将对象转换为字节流的过程,以便于存储、传输或在网络间传递。本文将深入探讨Android中两种主要的序列化方式:Serializable和Parcelable,并解析它们的工作原理及优缺点。 首先,我们来...

    Android Parcelable序列化自定义类集合在Activity间传递

    `Parcelable`是Android提供的一种高效的数据序列化方式,相比`Serializable`,它的序列化和反序列化速度更快,但实现过程相对复杂。 标题"Android Parcelable序列化自定义类集合在Activity间传递"所涉及的知识点...

    android webservice 对象序列化例子

    在“Test”这个文件中,可能包含了一个简单的Android项目,演示了如何使用Ksoap2来序列化对象并调用Web服务。项目可能包含了以下部分: - Activity:负责发起请求和处理响应。 - WebService类:封装了与Web服务交互...

    Android序列化——Serializable与Parcelable

    Parcelable是Android特有的序列化方式,相比Serializable,它的性能更好,但是实现较为复杂。你需要手动编写序列化和反序列化的代码,使用`writeToParcel()`和`Creator`接口。 优点: - 性能高效,Parcelable比...

    java序列化和反序列化的方法

    在 Java 中,序列化和反序列化是通过实现 Serializable 接口来实现的。Serializable 接口是一个标记接口,不包含任何方法,但它告诉 Java虚拟机(JVM)该类可以被序列化。 在上面的代码中,我们可以看到 ...

    Android序列化传递数据

    序列化是将对象转换为可存储或传输格式的过程,而在Android中,有两种主要的序列化方式:Parcelable和Serializable。下面将详细介绍这两种序列化机制及其在数据传递中的应用。 **Parcelable** 是Android特有的序列...

    android XML文件解析和序列化 demo

    Android并没有内置的XML序列化库,但可以借助第三方库如XStream或Jackson,或者手动实现序列化。手动实现通常涉及创建`toString()`方法,将对象属性转化为XML格式的字符串。 2. **Gson**: 虽然Gson主要用于JSON序列...

    Android 之 Parcelable 序列化

    在Android开发中,数据序列化是一个非常重要的概念,它允许对象的状态被保存和恢复,以便在不同的时间点或不同的环境中重建对象。Parcelable是Android平台提供的一种高效的数据序列化方式,比传统的Serializable接口...

    Android中的序列化浅析

    在Android系统中关于序列化的方法一般有两种,分别是实现Serializable接口和Parcelable接口,其中Serializable接口是来自Java中的序列化接口,而Parcelable是Android自带的序列化接口。 上述的两种序列化接口都有各自...

    C#的控件使用:树形图TreeView如何实现序列化和反序列化.rar

    2. **实现序列化**:在`TreeNodeModel`类中实现`IXmlSerializable`接口的方法`GetXml()`和`ReadXml()`. `GetXml()`方法用于将对象转换为XML字符串,`ReadXml()`方法用于从XML字符串中恢复对象。 3. **遍历`TreeView...

    IDEA中实体类实现了序列化接口

    ### IDEA中实体类实现序列化接口与序列化ID生成 #### 一、序言 在Java开发中,序列化是一项非常重要的技术,它允许将对象的状态转换为字节流,从而方便在网络上传输或者存储到磁盘上。为了保证序列化的兼容性与...

    Android-Android上的Java对象反序列化

    在Android平台上,Java对象反序列化是一个常见的操作,它涉及到将序列化的数据转换回原来的对象实例。这在数据存储、网络通信以及跨进程通信(IPC)等场景中扮演着重要角色。本文将深入探讨Android上Java对象反序列...

    java序列化实现演示

    在Java中,如果一个类需要支持序列化,它应该实现`java.io.Serializable`接口。 在Java序列化过程中,`serialVersionUID`扮演着至关重要的角色。`serialVersionUID`是一个长期不变的标识符,用于验证序列化版本的...

    android XML简单序列化

    XML序列化是Android开发中的一个重要概念,特别是在处理数据存储或网络通信时。XML因其结构清晰、易读性强的特性,常被用作数据交换格式。本教程将详细讲解Android中XML序列化的基础知识,并通过一个简单案例来加深...

    C#和Java的序列化反序列化

    在C#中,我们可以使用.NET框架提供的`System.Runtime.Serialization.Formatters.Binary.BinaryFormatter`类来进行二进制序列化,或者使用`System.Xml.Serialization.XmlSerializer`来进行XML序列化。而在Java中,...

Global site tag (gtag.js) - Google Analytics