Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2497a152 authored by Mathias Agopian's avatar Mathias Agopian Committed by Alex Ray
Browse files

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
parent 6454f461
Loading
Loading
Loading
Loading
+72 −0
Original line number Diff line number Diff line
@@ -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