| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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> | 
| Mathias Agopian | 8683fca | 2012-08-12 19:37:16 -0700 | [diff] [blame] | 25 | #include <utils/Flattenable.h> | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 26 |  | 
 | 27 | // --------------------------------------------------------------------------- | 
 | 28 | namespace android { | 
 | 29 |  | 
| Mathias Agopian | e142428 | 2013-07-29 21:24:40 -0700 | [diff] [blame] | 30 | template <typename T> class Flattenable; | 
| Mathias Agopian | 8683fca | 2012-08-12 19:37:16 -0700 | [diff] [blame] | 31 | template <typename T> class LightFlattenable; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 32 | class IBinder; | 
| Brad Fitzpatrick | 70081a1 | 2010-07-27 09:49:11 -0700 | [diff] [blame] | 33 | class IPCThreadState; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 34 | class ProcessState; | 
 | 35 | class String8; | 
 | 36 | class TextOutput; | 
 | 37 |  | 
 | 38 | struct flat_binder_object;  // defined in support_p/binder_module.h | 
 | 39 |  | 
| Mathias Agopian | e142428 | 2013-07-29 21:24:40 -0700 | [diff] [blame] | 40 | class Parcel { | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 41 | public: | 
| Jeff Brown | 5707dbf | 2011-09-23 21:17:56 -0700 | [diff] [blame] | 42 |     class ReadableBlob; | 
 | 43 |     class WritableBlob; | 
 | 44 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 45 |                         Parcel(); | 
 | 46 |                         ~Parcel(); | 
 | 47 |      | 
 | 48 |     const uint8_t*      data() const; | 
 | 49 |     size_t              dataSize() const; | 
 | 50 |     size_t              dataAvail() const; | 
 | 51 |     size_t              dataPosition() const; | 
 | 52 |     size_t              dataCapacity() const; | 
| Dianne Hackborn | 8938ed2 | 2011-09-28 23:19:47 -0400 | [diff] [blame] | 53 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 54 |     status_t            setDataSize(size_t size); | 
 | 55 |     void                setDataPosition(size_t pos) const; | 
 | 56 |     status_t            setDataCapacity(size_t size); | 
 | 57 |      | 
 | 58 |     status_t            setData(const uint8_t* buffer, size_t len); | 
 | 59 |  | 
| Andreas Huber | 51faf46 | 2011-04-13 10:21:56 -0700 | [diff] [blame] | 60 |     status_t            appendFrom(const Parcel *parcel, | 
 | 61 |                                    size_t start, size_t len); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 62 |  | 
| Dianne Hackborn | 7746cc3 | 2011-10-03 21:09:35 -0700 | [diff] [blame] | 63 |     bool                pushAllowFds(bool allowFds); | 
 | 64 |     void                restoreAllowFds(bool lastValue); | 
| Dianne Hackborn | 8938ed2 | 2011-09-28 23:19:47 -0400 | [diff] [blame] | 65 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 66 |     bool                hasFileDescriptors() const; | 
 | 67 |  | 
| Brad Fitzpatrick | 702ea9d | 2010-06-18 13:07:53 -0700 | [diff] [blame] | 68 |     // Writes the RPC header. | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 69 |     status_t            writeInterfaceToken(const String16& interface); | 
| Brad Fitzpatrick | a877cd8 | 2010-07-07 16:06:39 -0700 | [diff] [blame] | 70 |  | 
| Brad Fitzpatrick | 702ea9d | 2010-06-18 13:07:53 -0700 | [diff] [blame] | 71 |     // Parses the RPC header, returning true if the interface name | 
 | 72 |     // in the header matches the expected interface from the caller. | 
| Brad Fitzpatrick | 70081a1 | 2010-07-27 09:49:11 -0700 | [diff] [blame] | 73 |     // | 
 | 74 |     // Additionally, enforceInterface does part of the work of | 
 | 75 |     // propagating the StrictMode policy mask, populating the current | 
 | 76 |     // IPCThreadState, which as an optimization may optionally be | 
 | 77 |     // passed in. | 
| Brad Fitzpatrick | a877cd8 | 2010-07-07 16:06:39 -0700 | [diff] [blame] | 78 |     bool                enforceInterface(const String16& interface, | 
| Brad Fitzpatrick | 70081a1 | 2010-07-27 09:49:11 -0700 | [diff] [blame] | 79 |                                          IPCThreadState* threadState = NULL) const; | 
| Brad Fitzpatrick | 702ea9d | 2010-06-18 13:07:53 -0700 | [diff] [blame] | 80 |     bool                checkInterface(IBinder*) const; | 
| Mathias Agopian | 83c0446 | 2009-05-22 19:00:22 -0700 | [diff] [blame] | 81 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 82 |     void                freeData(); | 
 | 83 |  | 
 | 84 |     const size_t*       objects() const; | 
 | 85 |     size_t              objectsCount() const; | 
 | 86 |      | 
 | 87 |     status_t            errorCheck() const; | 
 | 88 |     void                setError(status_t err); | 
 | 89 |      | 
 | 90 |     status_t            write(const void* data, size_t len); | 
 | 91 |     void*               writeInplace(size_t len); | 
 | 92 |     status_t            writeUnpadded(const void* data, size_t len); | 
 | 93 |     status_t            writeInt32(int32_t val); | 
 | 94 |     status_t            writeInt64(int64_t val); | 
 | 95 |     status_t            writeFloat(float val); | 
 | 96 |     status_t            writeDouble(double val); | 
| Andreas Huber | 84a6d04 | 2009-08-17 13:33:27 -0700 | [diff] [blame] | 97 |     status_t            writeIntPtr(intptr_t val); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 98 |     status_t            writeCString(const char* str); | 
 | 99 |     status_t            writeString8(const String8& str); | 
 | 100 |     status_t            writeString16(const String16& str); | 
 | 101 |     status_t            writeString16(const char16_t* str, size_t len); | 
 | 102 |     status_t            writeStrongBinder(const sp<IBinder>& val); | 
 | 103 |     status_t            writeWeakBinder(const wp<IBinder>& val); | 
| Marco Nelissen | 708cc79 | 2013-10-16 10:57:51 -0700 | [diff] [blame] | 104 |     status_t            writeInt32Array(size_t len, const int32_t *val); | 
| Marco Nelissen | f0190bf | 2014-03-13 14:17:40 -0700 | [diff] [blame] | 105 |     status_t            writeByteArray(size_t len, const uint8_t *val); | 
| Mathias Agopian | e142428 | 2013-07-29 21:24:40 -0700 | [diff] [blame] | 106 |  | 
 | 107 |     template<typename T> | 
 | 108 |     status_t            write(const Flattenable<T>& val); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 109 |  | 
| Mathias Agopian | 8683fca | 2012-08-12 19:37:16 -0700 | [diff] [blame] | 110 |     template<typename T> | 
 | 111 |     status_t            write(const LightFlattenable<T>& val); | 
 | 112 |  | 
 | 113 |  | 
| Mathias Agopian | a47f02a | 2009-05-21 16:29:38 -0700 | [diff] [blame] | 114 |     // Place a native_handle into the parcel (the native_handle's file- | 
 | 115 |     // descriptors are dup'ed, so it is safe to delete the native_handle | 
 | 116 |     // when this function returns).  | 
 | 117 |     // Doesn't take ownership of the native_handle. | 
 | 118 |     status_t            writeNativeHandle(const native_handle* handle); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 119 |      | 
 | 120 |     // Place a file descriptor into the parcel.  The given fd must remain | 
 | 121 |     // valid for the lifetime of the parcel. | 
| Jeff Brown | 93ff1f9 | 2011-11-04 19:01:44 -0700 | [diff] [blame] | 122 |     // The Parcel does not take ownership of the given fd unless you ask it to. | 
 | 123 |     status_t            writeFileDescriptor(int fd, bool takeOwnership = false); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 124 |      | 
 | 125 |     // Place a file descriptor into the parcel.  A dup of the fd is made, which | 
 | 126 |     // will be closed once the parcel is destroyed. | 
 | 127 |     status_t            writeDupFileDescriptor(int fd); | 
| Jeff Brown | 5707dbf | 2011-09-23 21:17:56 -0700 | [diff] [blame] | 128 |  | 
 | 129 |     // Writes a blob to the parcel. | 
 | 130 |     // If the blob is small, then it is stored in-place, otherwise it is | 
 | 131 |     // transferred by way of an anonymous shared memory region. | 
 | 132 |     // The caller should call release() on the blob after writing its contents. | 
 | 133 |     status_t            writeBlob(size_t len, WritableBlob* outBlob); | 
 | 134 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 135 |     status_t            writeObject(const flat_binder_object& val, bool nullMetaData); | 
 | 136 |  | 
| Brad Fitzpatrick | 837a0d0 | 2010-07-13 15:33:35 -0700 | [diff] [blame] | 137 |     // Like Parcel.java's writeNoException().  Just writes a zero int32. | 
 | 138 |     // Currently the native implementation doesn't do any of the StrictMode | 
 | 139 |     // stack gathering and serialization that the Java implementation does. | 
 | 140 |     status_t            writeNoException(); | 
 | 141 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 142 |     void                remove(size_t start, size_t amt); | 
 | 143 |      | 
 | 144 |     status_t            read(void* outData, size_t len) const; | 
 | 145 |     const void*         readInplace(size_t len) const; | 
 | 146 |     int32_t             readInt32() const; | 
 | 147 |     status_t            readInt32(int32_t *pArg) const; | 
 | 148 |     int64_t             readInt64() const; | 
 | 149 |     status_t            readInt64(int64_t *pArg) const; | 
 | 150 |     float               readFloat() const; | 
 | 151 |     status_t            readFloat(float *pArg) const; | 
 | 152 |     double              readDouble() const; | 
 | 153 |     status_t            readDouble(double *pArg) const; | 
| Andreas Huber | 84a6d04 | 2009-08-17 13:33:27 -0700 | [diff] [blame] | 154 |     intptr_t            readIntPtr() const; | 
 | 155 |     status_t            readIntPtr(intptr_t *pArg) const; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 156 |  | 
 | 157 |     const char*         readCString() const; | 
 | 158 |     String8             readString8() const; | 
 | 159 |     String16            readString16() const; | 
 | 160 |     const char16_t*     readString16Inplace(size_t* outLen) const; | 
 | 161 |     sp<IBinder>         readStrongBinder() const; | 
 | 162 |     wp<IBinder>         readWeakBinder() const; | 
| Mathias Agopian | e142428 | 2013-07-29 21:24:40 -0700 | [diff] [blame] | 163 |  | 
 | 164 |     template<typename T> | 
 | 165 |     status_t            read(Flattenable<T>& val) const; | 
| Brad Fitzpatrick | 837a0d0 | 2010-07-13 15:33:35 -0700 | [diff] [blame] | 166 |  | 
| Mathias Agopian | 8683fca | 2012-08-12 19:37:16 -0700 | [diff] [blame] | 167 |     template<typename T> | 
 | 168 |     status_t            read(LightFlattenable<T>& val) const; | 
 | 169 |  | 
| Brad Fitzpatrick | 837a0d0 | 2010-07-13 15:33:35 -0700 | [diff] [blame] | 170 |     // Like Parcel.java's readExceptionCode().  Reads the first int32 | 
 | 171 |     // off of a Parcel's header, returning 0 or the negative error | 
 | 172 |     // code on exceptions, but also deals with skipping over rich | 
 | 173 |     // response headers.  Callers should use this to read & parse the | 
 | 174 |     // response headers rather than doing it by hand. | 
 | 175 |     int32_t             readExceptionCode() const; | 
 | 176 |  | 
| Mathias Agopian | a47f02a | 2009-05-21 16:29:38 -0700 | [diff] [blame] | 177 |     // Retrieve native_handle from the parcel. This returns a copy of the | 
 | 178 |     // parcel's native_handle (the caller takes ownership). The caller | 
 | 179 |     // must free the native_handle with native_handle_close() and  | 
 | 180 |     // native_handle_delete(). | 
 | 181 |     native_handle*     readNativeHandle() const; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 182 |  | 
 | 183 |      | 
 | 184 |     // Retrieve a file descriptor from the parcel.  This returns the raw fd | 
 | 185 |     // in the parcel, which you do not own -- use dup() to get your own copy. | 
 | 186 |     int                 readFileDescriptor() const; | 
| Jeff Brown | 5707dbf | 2011-09-23 21:17:56 -0700 | [diff] [blame] | 187 |  | 
 | 188 |     // Reads a blob from the parcel. | 
 | 189 |     // The caller should call release() on the blob after reading its contents. | 
 | 190 |     status_t            readBlob(size_t len, ReadableBlob* outBlob) const; | 
 | 191 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 192 |     const flat_binder_object* readObject(bool nullMetaData) const; | 
 | 193 |  | 
 | 194 |     // Explicitly close all file descriptors in the parcel. | 
 | 195 |     void                closeFileDescriptors(); | 
 | 196 |      | 
 | 197 |     typedef void        (*release_func)(Parcel* parcel, | 
 | 198 |                                         const uint8_t* data, size_t dataSize, | 
 | 199 |                                         const size_t* objects, size_t objectsSize, | 
 | 200 |                                         void* cookie); | 
 | 201 |                          | 
 | 202 |     const uint8_t*      ipcData() const; | 
 | 203 |     size_t              ipcDataSize() const; | 
 | 204 |     const size_t*       ipcObjects() const; | 
 | 205 |     size_t              ipcObjectsCount() const; | 
 | 206 |     void                ipcSetDataReference(const uint8_t* data, size_t dataSize, | 
 | 207 |                                             const size_t* objects, size_t objectsCount, | 
 | 208 |                                             release_func relFunc, void* relCookie); | 
 | 209 |      | 
 | 210 |     void                print(TextOutput& to, uint32_t flags = 0) const; | 
| Jeff Brown | 5707dbf | 2011-09-23 21:17:56 -0700 | [diff] [blame] | 211 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 212 | private: | 
 | 213 |                         Parcel(const Parcel& o); | 
 | 214 |     Parcel&             operator=(const Parcel& o); | 
 | 215 |      | 
 | 216 |     status_t            finishWrite(size_t len); | 
 | 217 |     void                releaseObjects(); | 
 | 218 |     void                acquireObjects(); | 
 | 219 |     status_t            growData(size_t len); | 
 | 220 |     status_t            restartWrite(size_t desired); | 
 | 221 |     status_t            continueWrite(size_t desired); | 
 | 222 |     void                freeDataNoInit(); | 
 | 223 |     void                initState(); | 
 | 224 |     void                scanForFds() const; | 
 | 225 |                          | 
| Andreas Huber | 84a6d04 | 2009-08-17 13:33:27 -0700 | [diff] [blame] | 226 |     template<class T> | 
 | 227 |     status_t            readAligned(T *pArg) const; | 
 | 228 |  | 
 | 229 |     template<class T>   T readAligned() const; | 
 | 230 |  | 
 | 231 |     template<class T> | 
 | 232 |     status_t            writeAligned(T val); | 
 | 233 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 234 |     status_t            mError; | 
 | 235 |     uint8_t*            mData; | 
 | 236 |     size_t              mDataSize; | 
 | 237 |     size_t              mDataCapacity; | 
 | 238 |     mutable size_t      mDataPos; | 
 | 239 |     size_t*             mObjects; | 
 | 240 |     size_t              mObjectsSize; | 
 | 241 |     size_t              mObjectsCapacity; | 
 | 242 |     mutable size_t      mNextObjectHint; | 
 | 243 |  | 
 | 244 |     mutable bool        mFdsKnown; | 
 | 245 |     mutable bool        mHasFds; | 
| Dianne Hackborn | 8938ed2 | 2011-09-28 23:19:47 -0400 | [diff] [blame] | 246 |     bool                mAllowFds; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 247 |      | 
 | 248 |     release_func        mOwner; | 
 | 249 |     void*               mOwnerCookie; | 
| Jeff Brown | 5707dbf | 2011-09-23 21:17:56 -0700 | [diff] [blame] | 250 |  | 
 | 251 |     class Blob { | 
 | 252 |     public: | 
 | 253 |         Blob(); | 
 | 254 |         ~Blob(); | 
 | 255 |  | 
 | 256 |         void release(); | 
 | 257 |         inline size_t size() const { return mSize; } | 
 | 258 |  | 
 | 259 |     protected: | 
 | 260 |         void init(bool mapped, void* data, size_t size); | 
 | 261 |         void clear(); | 
 | 262 |  | 
 | 263 |         bool mMapped; | 
 | 264 |         void* mData; | 
 | 265 |         size_t mSize; | 
 | 266 |     }; | 
 | 267 |  | 
| Mathias Agopian | e142428 | 2013-07-29 21:24:40 -0700 | [diff] [blame] | 268 |     class FlattenableHelperInterface { | 
 | 269 |     protected: | 
 | 270 |         ~FlattenableHelperInterface() { } | 
 | 271 |     public: | 
 | 272 |         virtual size_t getFlattenedSize() const = 0; | 
 | 273 |         virtual size_t getFdCount() const = 0; | 
 | 274 |         virtual status_t flatten(void* buffer, size_t size, int* fds, size_t count) const = 0; | 
 | 275 |         virtual status_t unflatten(void const* buffer, size_t size, int const* fds, size_t count) = 0; | 
 | 276 |     }; | 
 | 277 |  | 
 | 278 |     template<typename T> | 
 | 279 |     class FlattenableHelper : public FlattenableHelperInterface { | 
 | 280 |         friend class Parcel; | 
 | 281 |         const Flattenable<T>& val; | 
 | 282 |         explicit FlattenableHelper(const Flattenable<T>& val) : val(val) { } | 
 | 283 |  | 
 | 284 |     public: | 
 | 285 |         virtual size_t getFlattenedSize() const { | 
 | 286 |             return val.getFlattenedSize(); | 
 | 287 |         } | 
 | 288 |         virtual size_t getFdCount() const { | 
 | 289 |             return val.getFdCount(); | 
 | 290 |         } | 
 | 291 |         virtual status_t flatten(void* buffer, size_t size, int* fds, size_t count) const { | 
 | 292 |             return val.flatten(buffer, size, fds, count); | 
 | 293 |         } | 
 | 294 |         virtual status_t unflatten(void const* buffer, size_t size, int const* fds, size_t count) { | 
 | 295 |             return const_cast<Flattenable<T>&>(val).unflatten(buffer, size, fds, count); | 
 | 296 |         } | 
 | 297 |     }; | 
 | 298 |     status_t write(const FlattenableHelperInterface& val); | 
 | 299 |     status_t read(FlattenableHelperInterface& val) const; | 
 | 300 |  | 
| Jeff Brown | 5707dbf | 2011-09-23 21:17:56 -0700 | [diff] [blame] | 301 | public: | 
 | 302 |     class ReadableBlob : public Blob { | 
 | 303 |         friend class Parcel; | 
 | 304 |     public: | 
 | 305 |         inline const void* data() const { return mData; } | 
 | 306 |     }; | 
 | 307 |  | 
 | 308 |     class WritableBlob : public Blob { | 
 | 309 |         friend class Parcel; | 
 | 310 |     public: | 
 | 311 |         inline void* data() { return mData; } | 
 | 312 |     }; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 313 | }; | 
 | 314 |  | 
 | 315 | // --------------------------------------------------------------------------- | 
 | 316 |  | 
| Mathias Agopian | 8683fca | 2012-08-12 19:37:16 -0700 | [diff] [blame] | 317 | template<typename T> | 
| Mathias Agopian | e142428 | 2013-07-29 21:24:40 -0700 | [diff] [blame] | 318 | status_t Parcel::write(const Flattenable<T>& val) { | 
 | 319 |     const FlattenableHelper<T> helper(val); | 
 | 320 |     return write(helper); | 
 | 321 | } | 
 | 322 |  | 
 | 323 | template<typename T> | 
| Mathias Agopian | 8683fca | 2012-08-12 19:37:16 -0700 | [diff] [blame] | 324 | status_t Parcel::write(const LightFlattenable<T>& val) { | 
| Mathias Agopian | e142428 | 2013-07-29 21:24:40 -0700 | [diff] [blame] | 325 |     size_t size(val.getFlattenedSize()); | 
| Mathias Agopian | 8683fca | 2012-08-12 19:37:16 -0700 | [diff] [blame] | 326 |     if (!val.isFixedSize()) { | 
 | 327 |         status_t err = writeInt32(size); | 
 | 328 |         if (err != NO_ERROR) { | 
 | 329 |             return err; | 
 | 330 |         } | 
 | 331 |     } | 
| Mathias Agopian | 2098517 | 2012-08-31 14:25:22 -0700 | [diff] [blame] | 332 |     if (size) { | 
 | 333 |         void* buffer = writeInplace(size); | 
| Mathias Agopian | e142428 | 2013-07-29 21:24:40 -0700 | [diff] [blame] | 334 |         if (buffer == NULL) | 
 | 335 |             return NO_MEMORY; | 
 | 336 |         return val.flatten(buffer, size); | 
| Mathias Agopian | 2098517 | 2012-08-31 14:25:22 -0700 | [diff] [blame] | 337 |     } | 
 | 338 |     return NO_ERROR; | 
| Mathias Agopian | 8683fca | 2012-08-12 19:37:16 -0700 | [diff] [blame] | 339 | } | 
 | 340 |  | 
 | 341 | template<typename T> | 
| Mathias Agopian | e142428 | 2013-07-29 21:24:40 -0700 | [diff] [blame] | 342 | status_t Parcel::read(Flattenable<T>& val) const { | 
 | 343 |     FlattenableHelper<T> helper(val); | 
 | 344 |     return read(helper); | 
 | 345 | } | 
 | 346 |  | 
 | 347 | template<typename T> | 
| Mathias Agopian | 8683fca | 2012-08-12 19:37:16 -0700 | [diff] [blame] | 348 | status_t Parcel::read(LightFlattenable<T>& val) const { | 
 | 349 |     size_t size; | 
 | 350 |     if (val.isFixedSize()) { | 
| Mathias Agopian | e142428 | 2013-07-29 21:24:40 -0700 | [diff] [blame] | 351 |         size = val.getFlattenedSize(); | 
| Mathias Agopian | 8683fca | 2012-08-12 19:37:16 -0700 | [diff] [blame] | 352 |     } else { | 
 | 353 |         int32_t s; | 
 | 354 |         status_t err = readInt32(&s); | 
 | 355 |         if (err != NO_ERROR) { | 
 | 356 |             return err; | 
 | 357 |         } | 
 | 358 |         size = s; | 
 | 359 |     } | 
| Mathias Agopian | 2098517 | 2012-08-31 14:25:22 -0700 | [diff] [blame] | 360 |     if (size) { | 
 | 361 |         void const* buffer = readInplace(size); | 
 | 362 |         return buffer == NULL ? NO_MEMORY : | 
 | 363 |                 val.unflatten(buffer, size); | 
 | 364 |     } | 
 | 365 |     return NO_ERROR; | 
| Mathias Agopian | 8683fca | 2012-08-12 19:37:16 -0700 | [diff] [blame] | 366 | } | 
 | 367 |  | 
 | 368 | // --------------------------------------------------------------------------- | 
 | 369 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 370 | inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel) | 
 | 371 | { | 
 | 372 |     parcel.print(to); | 
 | 373 |     return to; | 
 | 374 | } | 
 | 375 |  | 
 | 376 | // --------------------------------------------------------------------------- | 
 | 377 |  | 
 | 378 | // Generic acquire and release of objects. | 
 | 379 | void acquire_object(const sp<ProcessState>& proc, | 
 | 380 |                     const flat_binder_object& obj, const void* who); | 
 | 381 | void release_object(const sp<ProcessState>& proc, | 
 | 382 |                     const flat_binder_object& obj, const void* who); | 
 | 383 |  | 
 | 384 | void flatten_binder(const sp<ProcessState>& proc, | 
 | 385 |                     const sp<IBinder>& binder, flat_binder_object* out); | 
 | 386 | void flatten_binder(const sp<ProcessState>& proc, | 
 | 387 |                     const wp<IBinder>& binder, flat_binder_object* out); | 
 | 388 | status_t unflatten_binder(const sp<ProcessState>& proc, | 
 | 389 |                           const flat_binder_object& flat, sp<IBinder>* out); | 
 | 390 | status_t unflatten_binder(const sp<ProcessState>& proc, | 
 | 391 |                           const flat_binder_object& flat, wp<IBinder>* out); | 
 | 392 |  | 
 | 393 | }; // namespace android | 
 | 394 |  | 
 | 395 | // --------------------------------------------------------------------------- | 
 | 396 |  | 
 | 397 | #endif // ANDROID_PARCEL_H |