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

Commit 6d611a89 authored by Mathias Agopian's avatar Mathias Agopian Committed by Alex Ray
Browse files

Make Flattenable not virtual (libutils)

Making an object Flattenable doesn't force it to
become virtual anymore. For instance, Fence and GraphicBuffer
are now non-virtual classes.

Also change Flatennable protocol a bit so that it updates
its parameters (pointers, sizes) to make it easier
to implement a flattenable in terms of other flattenables.

Change-Id: Ie81dc7637180b3c2cfcbaf644f8987ca804eb891
parent 0d8f3d6c
Loading
Loading
Loading
Loading
+6 −14
Original line number Original line Diff line number Diff line
@@ -33,7 +33,8 @@ namespace android {
// and then reloaded in a subsequent execution of the program.  This
// and then reloaded in a subsequent execution of the program.  This
// serialization is non-portable and the data should only be used by the device
// serialization is non-portable and the data should only be used by the device
// that generated it.
// that generated it.
class BlobCache : public RefBase, public Flattenable {
class BlobCache : public RefBase {

public:
public:


    // Create an empty blob cache. The blob cache will cache key/value pairs
    // Create an empty blob cache. The blob cache will cache key/value pairs
@@ -78,14 +79,10 @@ public:
    //   0 <= valueSize
    //   0 <= valueSize
    size_t get(const void* key, size_t keySize, void* value, size_t valueSize);
    size_t get(const void* key, size_t keySize, void* value, size_t valueSize);



    // getFlattenedSize returns the number of bytes needed to store the entire
    // getFlattenedSize returns the number of bytes needed to store the entire
    // serialized cache.
    // serialized cache.
    virtual size_t getFlattenedSize() const;
    size_t getFlattenedSize() const;

    // getFdCount returns the number of file descriptors that will result from
    // flattening the cache.  This will always return 0 so as to allow the
    // flattened cache to be saved to disk and then later restored.
    virtual size_t getFdCount() const;


    // flatten serializes the current contents of the cache into the memory
    // flatten serializes the current contents of the cache into the memory
    // pointed to by 'buffer'.  The serialized cache contents can later be
    // pointed to by 'buffer'.  The serialized cache contents can later be
@@ -94,9 +91,7 @@ public:
    //
    //
    // Preconditions:
    // Preconditions:
    //   size >= this.getFlattenedSize()
    //   size >= this.getFlattenedSize()
    //   count == 0
    status_t flatten(void* buffer, size_t size) const;
    virtual status_t flatten(void* buffer, size_t size, int fds[],
            size_t count) const;


    // unflatten replaces the contents of the cache with the serialized cache
    // unflatten replaces the contents of the cache with the serialized cache
    // contents in the memory pointed to by 'buffer'.  The previous contents of
    // contents in the memory pointed to by 'buffer'.  The previous contents of
@@ -104,10 +99,7 @@ public:
    // unflattening the serialized cache contents then the BlobCache will be
    // unflattening the serialized cache contents then the BlobCache will be
    // left in an empty state.
    // left in an empty state.
    //
    //
    // Preconditions:
    status_t unflatten(void const* buffer, size_t size);
    //   count == 0
    virtual status_t unflatten(void const* buffer, size_t size, int fds[],
            size_t count);


private:
private:
    // Copying is disallowed.
    // Copying is disallowed.
+86 −25
Original line number Original line Diff line number Diff line
@@ -21,30 +21,75 @@
#include <stdint.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/types.h>
#include <utils/Errors.h>
#include <utils/Errors.h>
#include <utils/Debug.h>


namespace android {
namespace android {



class FlattenableUtils {
public:
    template<int N>
    static size_t align(size_t size) {
        COMPILE_TIME_ASSERT_FUNCTION_SCOPE( !(N & (N-1)) );
        return (size + (N-1)) & ~(N-1);
    }

    template<int N>
    static size_t align(void*& buffer) {
        COMPILE_TIME_ASSERT_FUNCTION_SCOPE( !(N & (N-1)) );
        intptr_t b = intptr_t(buffer);
        buffer = (void*)((intptr_t(buffer) + (N-1)) & ~(N-1));
        return size_t(intptr_t(buffer) - b);
    }

    static void advance(void*& buffer, size_t& size, size_t offset) {
        buffer = reinterpret_cast<void*>( intptr_t(buffer) + offset );
        size -= offset;
    }

    static void advance(void const*& buffer, size_t& size, size_t offset) {
        buffer = reinterpret_cast<void const*>( intptr_t(buffer) + offset );
        size -= offset;
    }

    // write a POD structure
    template<typename T>
    static void write(void*& buffer, size_t& size, const T& value) {
        *static_cast<T*>(buffer) = value;
        advance(buffer, size, sizeof(T));
    }

    // read a POD structure
    template<typename T>
    static void read(void const*& buffer, size_t& size, T& value) {
        value = *static_cast<T const*>(buffer);
        advance(buffer, size, sizeof(T));
    }
};


/*
/*
 * The Flattenable interface allows an object to serialize itself out
 * The Flattenable protocol allows an object to serialize itself out
 * to a byte-buffer and an array of file descriptors.
 * to a byte-buffer and an array of file descriptors.
 * Flattenable objects must implement this protocol.
 */
 */


class Flattenable
template <typename T>
{
class Flattenable {
public:
public:
    // size in bytes of the flattened object
    // size in bytes of the flattened object
    virtual size_t getFlattenedSize() const = 0;
    inline size_t getFlattenedSize() const;


    // number of file descriptors to flatten
    // number of file descriptors to flatten
    virtual size_t getFdCount() const = 0;
    inline size_t getFdCount() const;


    // flattens the object into buffer.
    // flattens the object into buffer.
    // size should be at least of getFlattenedSize()
    // size should be at least of getFlattenedSize()
    // file descriptors are written in the fds[] array but ownership is
    // file descriptors are written in the fds[] array but ownership is
    // not transfered (ie: they must be dupped by the caller of
    // not transfered (ie: they must be dupped by the caller of
    // flatten() if needed).
    // flatten() if needed).
    virtual status_t flatten(void* buffer, size_t size,
    inline status_t flatten(void*& buffer, size_t& size,
            int fds[], size_t count) const = 0;
            int*& fds, size_t& count) const;


    // unflattens the object from buffer.
    // unflattens the object from buffer.
    // size should be equal to the value of getFlattenedSize() when the
    // size should be equal to the value of getFlattenedSize() when the
@@ -53,21 +98,34 @@ public:
    // don't need to be dupped(). ie: the caller of unflatten doesn't
    // don't need to be dupped(). ie: the caller of unflatten doesn't
    // keep ownership. If a fd is not retained by unflatten() it must be
    // keep ownership. If a fd is not retained by unflatten() it must be
    // explicitly closed.
    // explicitly closed.
    virtual status_t unflatten(void const* buffer, size_t size,
    inline status_t unflatten(void const*& buffer, size_t& size,
            int fds[], size_t count) = 0;
            int const*& fds, size_t& count);

protected:
    virtual ~Flattenable() = 0;

};
};


template<typename T>
inline size_t Flattenable<T>::getFlattenedSize() const {
    return static_cast<T const*>(this)->T::getFlattenedSize();
}
template<typename T>
inline size_t Flattenable<T>::getFdCount() const {
    return static_cast<T const*>(this)->T::getFdCount();
}
template<typename T>
inline status_t Flattenable<T>::flatten(
        void*& buffer, size_t& size, int*& fds, size_t& count) const {
    return static_cast<T const*>(this)->T::flatten(buffer, size, fds, count);
}
template<typename T>
inline status_t Flattenable<T>::unflatten(
        void const*& buffer, size_t& size, int const*& fds, size_t& count) {
    return static_cast<T*>(this)->T::unflatten(buffer, size, fds, count);
}

/*
/*
 * LightFlattenable is a protocol allowing object to serialize themselves out
 * LightFlattenable is a protocol allowing object to serialize themselves out
 * to a byte-buffer.
 * to a byte-buffer. Because it doesn't handle file-descriptors,
 *
 * LightFlattenable is usually more size efficient than Flattenable.
 * LightFlattenable objects must implement this protocol.
 * LightFlattenable objects must implement this protocol.
 *
 * LightFlattenable doesn't require the object to be virtual.
 */
 */
template <typename T>
template <typename T>
class LightFlattenable {
class LightFlattenable {
@@ -77,10 +135,10 @@ public:
    inline bool isFixedSize() const;
    inline bool isFixedSize() const;


    // returns size in bytes of the flattened object. must be a constant.
    // returns size in bytes of the flattened object. must be a constant.
    inline size_t getSize() const;
    inline size_t getFlattenedSize() const;


    // flattens the object into buffer.
    // flattens the object into buffer.
    inline status_t flatten(void* buffer) const;
    inline status_t flatten(void* buffer, size_t size) const;


    // unflattens the object from buffer of given size.
    // unflattens the object from buffer of given size.
    inline status_t unflatten(void const* buffer, size_t size);
    inline status_t unflatten(void const* buffer, size_t size);
@@ -91,12 +149,12 @@ inline bool LightFlattenable<T>::isFixedSize() const {
    return static_cast<T const*>(this)->T::isFixedSize();
    return static_cast<T const*>(this)->T::isFixedSize();
}
}
template <typename T>
template <typename T>
inline size_t LightFlattenable<T>::getSize() const {
inline size_t LightFlattenable<T>::getFlattenedSize() const {
    return static_cast<T const*>(this)->T::getSize();
    return static_cast<T const*>(this)->T::getFlattenedSize();
}
}
template <typename T>
template <typename T>
inline status_t LightFlattenable<T>::flatten(void* buffer) const {
inline status_t LightFlattenable<T>::flatten(void* buffer, size_t size) const {
    return static_cast<T const*>(this)->T::flatten(buffer);
    return static_cast<T const*>(this)->T::flatten(buffer, size);
}
}
template <typename T>
template <typename T>
inline status_t LightFlattenable<T>::unflatten(void const* buffer, size_t size) {
inline status_t LightFlattenable<T>::unflatten(void const* buffer, size_t size) {
@@ -106,6 +164,8 @@ inline status_t LightFlattenable<T>::unflatten(void const* buffer, size_t size)
/*
/*
 * LightFlattenablePod is an implementation of the LightFlattenable protocol
 * LightFlattenablePod is an implementation of the LightFlattenable protocol
 * for POD (plain-old-data) objects.
 * for POD (plain-old-data) objects.
 * Simply derive from LightFlattenablePod<Foo> to make Foo flattenable; no
 * need to implement any methods; obviously Foo must be a POD structure.
 */
 */
template <typename T>
template <typename T>
class LightFlattenablePod : public LightFlattenable<T> {
class LightFlattenablePod : public LightFlattenable<T> {
@@ -114,10 +174,11 @@ public:
        return true;
        return true;
    }
    }


    inline size_t getSize() const {
    inline size_t getFlattenedSize() const {
        return sizeof(T);
        return sizeof(T);
    }
    }
    inline status_t flatten(void* buffer) const {
    inline status_t flatten(void* buffer, size_t size) const {
        if (size < sizeof(T)) return NO_MEMORY;
        *reinterpret_cast<T*>(buffer) = *static_cast<T const*>(this);
        *reinterpret_cast<T*>(buffer) = *static_cast<T const*>(this);
        return NO_ERROR;
        return NO_ERROR;
    }
    }
+0 −1
Original line number Original line Diff line number Diff line
@@ -22,7 +22,6 @@ commonSources:= \
	BlobCache.cpp \
	BlobCache.cpp \
	CallStack.cpp \
	CallStack.cpp \
	FileMap.cpp \
	FileMap.cpp \
	Flattenable.cpp \
	JenkinsHash.cpp \
	JenkinsHash.cpp \
	LinearAllocator.cpp \
	LinearAllocator.cpp \
	LinearTransform.cpp \
	LinearTransform.cpp \
+2 −18
Original line number Original line Diff line number Diff line
@@ -176,17 +176,7 @@ size_t BlobCache::getFlattenedSize() const {
    return size;
    return size;
}
}


size_t BlobCache::getFdCount() const {
status_t BlobCache::flatten(void* buffer, size_t size) const {
    return 0;
}

status_t BlobCache::flatten(void* buffer, size_t size, int fds[], size_t count)
        const {
    if (count != 0) {
        ALOGE("flatten: nonzero fd count: %zu", count);
        return BAD_VALUE;
    }

    // Write the cache header
    // Write the cache header
    if (size < sizeof(Header)) {
    if (size < sizeof(Header)) {
        ALOGE("flatten: not enough room for cache header");
        ALOGE("flatten: not enough room for cache header");
@@ -228,16 +218,10 @@ status_t BlobCache::flatten(void* buffer, size_t size, int fds[], size_t count)
    return OK;
    return OK;
}
}


status_t BlobCache::unflatten(void const* buffer, size_t size, int fds[],
status_t BlobCache::unflatten(void const* buffer, size_t size) {
        size_t count) {
    // All errors should result in the BlobCache being in an empty state.
    // All errors should result in the BlobCache being in an empty state.
    mCacheEntries.clear();
    mCacheEntries.clear();


    if (count != 0) {
        ALOGE("unflatten: nonzero fd count: %zu", count);
        return BAD_VALUE;
    }

    // Read the cache header
    // Read the cache header
    if (size < sizeof(Header)) {
    if (size < sizeof(Header)) {
        ALOGE("unflatten: not enough room for cache header");
        ALOGE("unflatten: not enough room for cache header");

libs/utils/Flattenable.cpp

deleted100644 → 0
+0 −24
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <utils/Flattenable.h>

namespace android {

Flattenable::~Flattenable() {
}

}; // namespace android