improve [un]marshalling of non-binder objects

this change introduces a new class LightFlattenable<> which is
a protocol to flatten simple objects that don't require
binders or file descriptors; the benefit of this protocol is that
it doesn't require the objects to have a virtual table and give us
a consitant way of doing this.

we also introduce an implementation of this protocol for
POD structures, LightFlattenablePod<>.

Parcel has been update to handle this protocol automatically.

Sensor, Rect, Point and Region now use this new protocol.

Change-Id: Icb3ce7fa1d785249eb666f39c2129f2fc143ea4a
This commit is contained in:
Mathias Agopian 2012-08-12 19:37:16 -07:00 committed by Alex Ray
parent 6454f46166
commit 2497a1524d
1 changed files with 72 additions and 0 deletions

View File

@ -24,6 +24,11 @@
namespace android {
/*
* The Flattenable interface allows an object to serialize itself out
* to a byte-buffer and an array of file descriptors.
*/
class Flattenable
{
public:
@ -56,6 +61,73 @@ protected:
};
/*
* LightFlattenable is a protocol allowing object to serialize themselves out
* to a byte-buffer.
*
* LightFlattenable objects must implement this protocol.
*
* LightFlattenable doesn't require the object to be virtual.
*/
template <typename T>
class LightFlattenable {
public:
// returns whether this object always flatten into the same size.
// for efficiency, this should always be inline.
inline bool isFixedSize() const;
// returns size in bytes of the flattened object. must be a constant.
inline size_t getSize() const;
// flattens the object into buffer.
inline status_t flatten(void* buffer) const;
// unflattens the object from buffer of given size.
inline status_t unflatten(void const* buffer, size_t size);
};
template <typename T>
inline bool LightFlattenable<T>::isFixedSize() const {
return static_cast<T const*>(this)->T::isFixedSize();
}
template <typename T>
inline size_t LightFlattenable<T>::getSize() const {
return static_cast<T const*>(this)->T::getSize();
}
template <typename T>
inline status_t LightFlattenable<T>::flatten(void* buffer) const {
return static_cast<T const*>(this)->T::flatten(buffer);
}
template <typename T>
inline status_t LightFlattenable<T>::unflatten(void const* buffer, size_t size) {
return static_cast<T*>(this)->T::unflatten(buffer, size);
}
/*
* LightFlattenablePod is an implementation of the LightFlattenable protocol
* for POD (plain-old-data) objects.
*/
template <typename T>
class LightFlattenablePod : public LightFlattenable<T> {
public:
inline bool isFixedSize() const {
return true;
}
inline size_t getSize() const {
return sizeof(T);
}
inline status_t flatten(void* buffer) const {
*reinterpret_cast<T*>(buffer) = *static_cast<T const*>(this);
return NO_ERROR;
}
inline status_t unflatten(void const* buffer, size_t) {
*static_cast<T*>(this) = *reinterpret_cast<T const*>(buffer);
return NO_ERROR;
}
};
}; // namespace android