• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
isFixedSize()90 inline bool LightFlattenable<T>::isFixedSize() const {
91     return static_cast<T const*>(this)->T::isFixedSize();
92 }
93 template <typename T>
getSize()94 inline size_t LightFlattenable<T>::getSize() const {
95     return static_cast<T const*>(this)->T::getSize();
96 }
97 template <typename T>
flatten(void * buffer)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>
unflatten(void const * buffer,size_t size)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:
isFixedSize()113     inline bool isFixedSize() const {
114         return true;
115     }
116 
getSize()117     inline size_t getSize() const {
118         return sizeof(T);
119     }
flatten(void * buffer)120     inline status_t flatten(void* buffer) const {
121         *reinterpret_cast<T*>(buffer) = *static_cast<T const*>(this);
122         return NO_ERROR;
123     }
unflatten(void const * buffer,size_t)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