1 /* 2 * Copyright (C) 2010 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_UTILS_FLATTENABLE_H 18 #define ANDROID_UTILS_FLATTENABLE_H 19 20 21 #include <stdint.h> 22 #include <sys/types.h> 23 #include <utils/Errors.h> 24 25 namespace android { 26 27 /* 28 * The Flattenable interface allows an object to serialize itself out 29 * to a byte-buffer and an array of file descriptors. 30 */ 31 32 class Flattenable 33 { 34 public: 35 // size in bytes of the flattened object 36 virtual size_t getFlattenedSize() const = 0; 37 38 // number of file descriptors to flatten 39 virtual size_t getFdCount() const = 0; 40 41 // flattens the object into buffer. 42 // size should be at least of getFlattenedSize() 43 // file descriptors are written in the fds[] array but ownership is 44 // not transfered (ie: they must be dupped by the caller of 45 // flatten() if needed). 46 virtual status_t flatten(void* buffer, size_t size, 47 int fds[], size_t count) const = 0; 48 49 // unflattens the object from buffer. 50 // size should be equal to the value of getFlattenedSize() when the 51 // object was flattened. 52 // unflattened file descriptors are found in the fds[] array and 53 // don't need to be dupped(). ie: the caller of unflatten doesn't 54 // keep ownership. If a fd is not retained by unflatten() it must be 55 // explicitly closed. 56 virtual status_t unflatten(void const* buffer, size_t size, 57 int fds[], size_t count) = 0; 58 59 protected: 60 virtual ~Flattenable() = 0; 61 62 }; 63 64 /* 65 * LightFlattenable is a protocol allowing object to serialize themselves out 66 * to a byte-buffer. 67 * 68 * LightFlattenable objects must implement this protocol. 69 * 70 * LightFlattenable doesn't require the object to be virtual. 71 */ 72 template <typename T> 73 class LightFlattenable { 74 public: 75 // returns whether this object always flatten into the same size. 76 // for efficiency, this should always be inline. 77 inline bool isFixedSize() const; 78 79 // returns size in bytes of the flattened object. must be a constant. 80 inline size_t getSize() const; 81 82 // flattens the object into buffer. 83 inline status_t flatten(void* buffer) const; 84 85 // unflattens the object from buffer of given size. 86 inline status_t unflatten(void const* buffer, size_t size); 87 }; 88 89 template <typename T> 90 inline bool LightFlattenable<T>::isFixedSize() const { 91 return static_cast<T const*>(this)->T::isFixedSize(); 92 } 93 template <typename T> 94 inline size_t LightFlattenable<T>::getSize() const { 95 return static_cast<T const*>(this)->T::getSize(); 96 } 97 template <typename T> 98 inline status_t LightFlattenable<T>::flatten(void* buffer) const { 99 return static_cast<T const*>(this)->T::flatten(buffer); 100 } 101 template <typename T> 102 inline status_t LightFlattenable<T>::unflatten(void const* buffer, size_t size) { 103 return static_cast<T*>(this)->T::unflatten(buffer, size); 104 } 105 106 /* 107 * LightFlattenablePod is an implementation of the LightFlattenable protocol 108 * for POD (plain-old-data) objects. 109 */ 110 template <typename T> 111 class LightFlattenablePod : public LightFlattenable<T> { 112 public: 113 inline bool isFixedSize() const { 114 return true; 115 } 116 117 inline size_t getSize() const { 118 return sizeof(T); 119 } 120 inline status_t flatten(void* buffer) const { 121 *reinterpret_cast<T*>(buffer) = *static_cast<T const*>(this); 122 return NO_ERROR; 123 } 124 inline status_t unflatten(void const* buffer, size_t) { 125 *static_cast<T*>(this) = *reinterpret_cast<T const*>(buffer); 126 return NO_ERROR; 127 } 128 }; 129 130 131 }; // namespace android 132 133 134 #endif /* ANDROID_UTILS_FLATTENABLE_H */ 135