13d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen/*
23d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen * Copyright (C) 2009 The Android Open Source Project
33d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen *
43d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen * Licensed under the Apache License, Version 2.0 (the "License");
53d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen * you may not use this file except in compliance with the License.
63d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen * You may obtain a copy of the License at
73d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen *
83d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen *      http://www.apache.org/licenses/LICENSE-2.0
93d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen *
103d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen * Unless required by applicable law or agreed to in writing, software
113d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen * distributed under the License is distributed on an "AS IS" BASIS,
123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen * See the License for the specific language governing permissions and
143d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen * limitations under the License.
153d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen */
163d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
173d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen//#define LOG_NDEBUG 0
183d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#define LOG_TAG "MetaDataBase"
193d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#include <inttypes.h>
203d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#include <binder/Parcel.h>
213d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#include <utils/KeyedVector.h>
223d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#include <utils/Log.h>
233d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
243d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#include <stdlib.h>
253d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#include <string.h>
263d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
273d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#include <media/stagefright/foundation/ADebug.h>
283d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#include <media/stagefright/foundation/AString.h>
293d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#include <media/stagefright/foundation/hexdump.h>
303d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#include <media/stagefright/MetaDataBase.h>
313d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
323d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissennamespace android {
333d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
343d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstruct MetaDataBase::typed_data {
353d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    typed_data();
363d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    ~typed_data();
373d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
383d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    typed_data(const MetaDataBase::typed_data &);
393d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    typed_data &operator=(const MetaDataBase::typed_data &);
403d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
413d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    void clear();
423d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    void setData(uint32_t type, const void *data, size_t size);
433d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    void getData(uint32_t *type, const void **data, size_t *size) const;
443d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    // may include hexdump of binary data if verbose=true
453d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    String8 asString(bool verbose) const;
463d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
473d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenprivate:
483d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    uint32_t mType;
493d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    size_t mSize;
503d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
513d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    union {
523d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        void *ext_data;
533d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        float reservoir;
543d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    } u;
553d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
563d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    bool usesReservoir() const {
573d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return mSize <= sizeof(u.reservoir);
583d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
593d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
603d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    void *allocateStorage(size_t size);
613d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    void freeStorage();
623d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
633d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    void *storage() {
643d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return usesReservoir() ? &u.reservoir : u.ext_data;
653d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
663d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
673d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    const void *storage() const {
683d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return usesReservoir() ? &u.reservoir : u.ext_data;
693d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
703d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen};
713d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
723d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstruct MetaDataBase::Rect {
733d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    int32_t mLeft, mTop, mRight, mBottom;
743d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen};
753d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
763d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
773d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstruct MetaDataBase::MetaDataInternal {
783d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    KeyedVector<uint32_t, MetaDataBase::typed_data> mItems;
793d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen};
803d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
813d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
823d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco NelissenMetaDataBase::MetaDataBase()
833d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    : mInternalData(new MetaDataInternal()) {
843d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
853d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
863d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco NelissenMetaDataBase::MetaDataBase(const MetaDataBase &from)
873d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    : mInternalData(new MetaDataInternal()) {
883d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    mInternalData->mItems = from.mInternalData->mItems;
893d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
903d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
913d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco NelissenMetaDataBase& MetaDataBase::operator = (const MetaDataBase &rhs) {
923d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    this->mInternalData->mItems = rhs.mInternalData->mItems;
933d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return *this;
943d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
953d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
963d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco NelissenMetaDataBase::~MetaDataBase() {
973d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    clear();
983d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    delete mInternalData;
993d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
1003d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1013d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenvoid MetaDataBase::clear() {
1023d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    mInternalData->mItems.clear();
1033d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
1043d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1053d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::remove(uint32_t key) {
1063d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    ssize_t i = mInternalData->mItems.indexOfKey(key);
1073d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1083d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (i < 0) {
1093d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return false;
1103d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
1113d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    mInternalData->mItems.removeItemsAt(i);
1133d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1143d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return true;
1153d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
1163d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1173d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::setCString(uint32_t key, const char *value) {
1183d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return setData(key, TYPE_C_STRING, value, strlen(value) + 1);
1193d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
1203d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1213d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::setInt32(uint32_t key, int32_t value) {
1223d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return setData(key, TYPE_INT32, &value, sizeof(value));
1233d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
1243d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1253d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::setInt64(uint32_t key, int64_t value) {
1263d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return setData(key, TYPE_INT64, &value, sizeof(value));
1273d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
1283d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1293d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::setFloat(uint32_t key, float value) {
1303d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return setData(key, TYPE_FLOAT, &value, sizeof(value));
1313d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
1323d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1333d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::setPointer(uint32_t key, void *value) {
1343d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return setData(key, TYPE_POINTER, &value, sizeof(value));
1353d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
1363d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1373d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::setRect(
1383d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        uint32_t key,
1393d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        int32_t left, int32_t top,
1403d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        int32_t right, int32_t bottom) {
1413d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    Rect r;
1423d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    r.mLeft = left;
1433d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    r.mTop = top;
1443d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    r.mRight = right;
1453d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    r.mBottom = bottom;
1463d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1473d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return setData(key, TYPE_RECT, &r, sizeof(r));
1483d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
1493d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1503d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen/**
1513d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen * Note that the returned pointer becomes invalid when additional metadata is set.
1523d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen */
1533d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::findCString(uint32_t key, const char **value) const {
1543d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    uint32_t type;
1553d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    const void *data;
1563d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    size_t size;
1573d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (!findData(key, &type, &data, &size) || type != TYPE_C_STRING) {
1583d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return false;
1593d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
1603d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1613d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    *value = (const char *)data;
1623d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1633d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return true;
1643d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
1653d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1663d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::findInt32(uint32_t key, int32_t *value) const {
1673d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    uint32_t type = 0;
1683d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    const void *data;
1693d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    size_t size;
1703d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (!findData(key, &type, &data, &size) || type != TYPE_INT32) {
1713d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return false;
1723d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
1733d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1743d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    CHECK_EQ(size, sizeof(*value));
1753d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1763d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    *value = *(int32_t *)data;
1773d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1783d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return true;
1793d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
1803d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1813d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::findInt64(uint32_t key, int64_t *value) const {
1823d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    uint32_t type = 0;
1833d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    const void *data;
1843d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    size_t size;
1853d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (!findData(key, &type, &data, &size) || type != TYPE_INT64) {
1863d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return false;
1873d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
1883d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1893d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    CHECK_EQ(size, sizeof(*value));
1903d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1913d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    *value = *(int64_t *)data;
1923d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1933d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return true;
1943d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
1953d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
1963d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::findFloat(uint32_t key, float *value) const {
1973d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    uint32_t type = 0;
1983d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    const void *data;
1993d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    size_t size;
2003d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (!findData(key, &type, &data, &size) || type != TYPE_FLOAT) {
2013d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return false;
2023d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
2033d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2043d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    CHECK_EQ(size, sizeof(*value));
2053d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2063d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    *value = *(float *)data;
2073d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2083d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return true;
2093d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
2103d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2113d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::findPointer(uint32_t key, void **value) const {
2123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    uint32_t type = 0;
2133d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    const void *data;
2143d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    size_t size;
2153d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (!findData(key, &type, &data, &size) || type != TYPE_POINTER) {
2163d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return false;
2173d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
2183d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2193d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    CHECK_EQ(size, sizeof(*value));
2203d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2213d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    *value = *(void **)data;
2223d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2233d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return true;
2243d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
2253d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2263d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::findRect(
2273d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        uint32_t key,
2283d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        int32_t *left, int32_t *top,
2293d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        int32_t *right, int32_t *bottom) const {
2303d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    uint32_t type = 0;
2313d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    const void *data;
2323d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    size_t size;
2333d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (!findData(key, &type, &data, &size) || type != TYPE_RECT) {
2343d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return false;
2353d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
2363d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2373d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    CHECK_EQ(size, sizeof(Rect));
2383d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2393d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    const Rect *r = (const Rect *)data;
2403d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    *left = r->mLeft;
2413d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    *top = r->mTop;
2423d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    *right = r->mRight;
2433d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    *bottom = r->mBottom;
2443d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2453d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return true;
2463d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
2473d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2483d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::setData(
2493d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        uint32_t key, uint32_t type, const void *data, size_t size) {
2503d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    bool overwrote_existing = true;
2513d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2523d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    ssize_t i = mInternalData->mItems.indexOfKey(key);
2533d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (i < 0) {
2543d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        typed_data item;
2553d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        i = mInternalData->mItems.add(key, item);
2563d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2573d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        overwrote_existing = false;
2583d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
2593d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2603d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    typed_data &item = mInternalData->mItems.editValueAt(i);
2613d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2623d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    item.setData(type, data, size);
2633d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2643d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return overwrote_existing;
2653d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
2663d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2673d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::findData(uint32_t key, uint32_t *type,
2683d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                        const void **data, size_t *size) const {
2693d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    ssize_t i = mInternalData->mItems.indexOfKey(key);
2703d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2713d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (i < 0) {
2723d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return false;
2733d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
2743d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2753d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    const typed_data &item = mInternalData->mItems.valueAt(i);
2763d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2773d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    item.getData(type, data, size);
2783d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2793d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return true;
2803d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
2813d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2823d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenbool MetaDataBase::hasData(uint32_t key) const {
2833d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    ssize_t i = mInternalData->mItems.indexOfKey(key);
2843d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2853d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (i < 0) {
2863d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return false;
2873d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
2883d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2893d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return true;
2903d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
2913d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2923d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco NelissenMetaDataBase::typed_data::typed_data()
2933d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    : mType(0),
2943d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen      mSize(0) {
2953d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
2963d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
2973d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco NelissenMetaDataBase::typed_data::~typed_data() {
2983d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    clear();
2993d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
3003d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3013d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco NelissenMetaDataBase::typed_data::typed_data(const typed_data &from)
3023d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    : mType(from.mType),
3033d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen      mSize(0) {
3043d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3053d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    void *dst = allocateStorage(from.mSize);
3063d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (dst) {
3073d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        memcpy(dst, from.storage(), mSize);
3083d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
3093d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
3103d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3113d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco NelissenMetaDataBase::typed_data &MetaDataBase::typed_data::operator=(
3123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        const MetaDataBase::typed_data &from) {
3133d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (this != &from) {
3143d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        clear();
3153d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        mType = from.mType;
3163d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        void *dst = allocateStorage(from.mSize);
3173d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        if (dst) {
3183d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            memcpy(dst, from.storage(), mSize);
3193d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        }
3203d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
3213d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3223d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return *this;
3233d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
3243d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3253d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenvoid MetaDataBase::typed_data::clear() {
3263d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    freeStorage();
3273d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3283d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    mType = 0;
3293d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
3303d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3313d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenvoid MetaDataBase::typed_data::setData(
3323d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        uint32_t type, const void *data, size_t size) {
3333d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    clear();
3343d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3353d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    mType = type;
3363d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3373d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    void *dst = allocateStorage(size);
3383d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (dst) {
3393d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        memcpy(dst, data, size);
3403d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
3413d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
3423d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3433d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenvoid MetaDataBase::typed_data::getData(
3443d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        uint32_t *type, const void **data, size_t *size) const {
3453d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    *type = mType;
3463d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    *size = mSize;
3473d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    *data = storage();
3483d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
3493d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3503d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenvoid *MetaDataBase::typed_data::allocateStorage(size_t size) {
3513d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    mSize = size;
3523d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3533d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (usesReservoir()) {
3543d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return &u.reservoir;
3553d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
3563d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3573d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    u.ext_data = malloc(mSize);
3583d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (u.ext_data == NULL) {
3593d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        ALOGE("Couldn't allocate %zu bytes for item", size);
3603d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        mSize = 0;
3613d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
3623d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return u.ext_data;
3633d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
3643d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3653d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenvoid MetaDataBase::typed_data::freeStorage() {
3663d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (!usesReservoir()) {
3673d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        if (u.ext_data) {
3683d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            free(u.ext_data);
3693d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            u.ext_data = NULL;
3703d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        }
3713d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
3723d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3733d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    mSize = 0;
3743d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
3753d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
3763d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco NelissenString8 MetaDataBase::typed_data::asString(bool verbose) const {
3773d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    String8 out;
3783d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    const void *data = storage();
3793d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    switch(mType) {
3803d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        case TYPE_NONE:
3813d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            out = String8::format("no type, size %zu)", mSize);
3823d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            break;
3833d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        case TYPE_C_STRING:
3843d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            out = String8::format("(char*) %s", (const char *)data);
3853d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            break;
3863d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        case TYPE_INT32:
3873d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            out = String8::format("(int32_t) %d", *(int32_t *)data);
3883d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            break;
3893d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        case TYPE_INT64:
3903d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            out = String8::format("(int64_t) %" PRId64, *(int64_t *)data);
3913d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            break;
3923d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        case TYPE_FLOAT:
3933d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            out = String8::format("(float) %f", *(float *)data);
3943d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            break;
3953d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        case TYPE_POINTER:
3963d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            out = String8::format("(void*) %p", *(void **)data);
3973d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            break;
3983d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        case TYPE_RECT:
3993d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        {
4003d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            const Rect *r = (const Rect *)data;
4013d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            out = String8::format("Rect(%d, %d, %d, %d)",
4023d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                                  r->mLeft, r->mTop, r->mRight, r->mBottom);
4033d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            break;
4043d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        }
4053d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
4063d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        default:
4073d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            out = String8::format("(unknown type %d, size %zu)", mType, mSize);
4083d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            if (verbose && mSize <= 48) { // if it's less than three lines of hex data, dump it
4093d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                AString foo;
4103d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                hexdump(data, mSize, 0, &foo);
4113d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                out.append("\n");
4123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                out.append(foo.c_str());
4133d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            }
4143d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            break;
4153d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
4163d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return out;
4173d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
4183d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
4193d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) {
4203d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    s[0] = x >> 24;
4213d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    s[1] = (x >> 16) & 0xff;
4223d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    s[2] = (x >> 8) & 0xff;
4233d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    s[3] = x & 0xff;
4243d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    s[4] = '\0';
4253d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
4263d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
4273d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco NelissenString8 MetaDataBase::toString() const {
4283d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    String8 s;
4293d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    for (int i = mInternalData->mItems.size(); --i >= 0;) {
4303d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        int32_t key = mInternalData->mItems.keyAt(i);
4313d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        char cc[5];
4323d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        MakeFourCCString(key, cc);
4333d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        const typed_data &item = mInternalData->mItems.valueAt(i);
4343d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        s.appendFormat("%s: %s", cc, item.asString(false).string());
4353d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        if (i != 0) {
4363d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            s.append(", ");
4373d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        }
4383d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
4393d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return s;
4403d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
4413d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
4423d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenvoid MetaDataBase::dumpToLog() const {
4433d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    for (int i = mInternalData->mItems.size(); --i >= 0;) {
4443d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        int32_t key = mInternalData->mItems.keyAt(i);
4453d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        char cc[5];
4463d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        MakeFourCCString(key, cc);
4473d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        const typed_data &item = mInternalData->mItems.valueAt(i);
4483d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        ALOGI("%s: %s", cc, item.asString(true /* verbose */).string());
4493d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
4503d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
4513d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
4523d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstatus_t MetaDataBase::writeToParcel(Parcel &parcel) {
4533d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    status_t ret;
4543d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    size_t numItems = mInternalData->mItems.size();
4553d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    ret = parcel.writeUint32(uint32_t(numItems));
4563d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (ret) {
4573d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return ret;
4583d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
4593d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    for (size_t i = 0; i < numItems; i++) {
4603d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        int32_t key = mInternalData->mItems.keyAt(i);
4613d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        const typed_data &item = mInternalData->mItems.valueAt(i);
4623d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        uint32_t type;
4633d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        const void *data;
4643d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        size_t size;
4653d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        item.getData(&type, &data, &size);
4663d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        ret = parcel.writeInt32(key);
4673d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        if (ret) {
4683d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            return ret;
4693d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        }
4703d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        ret = parcel.writeUint32(type);
4713d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        if (ret) {
4723d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            return ret;
4733d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        }
4743d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        if (type == TYPE_NONE) {
4753d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            android::Parcel::WritableBlob blob;
4763d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            ret = parcel.writeUint32(static_cast<uint32_t>(size));
4773d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            if (ret) {
4783d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                return ret;
4793d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            }
4803d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            ret = parcel.writeBlob(size, false, &blob);
4813d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            if (ret) {
4823d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                return ret;
4833d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            }
4843d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            memcpy(blob.data(), data, size);
4853d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            blob.release();
4863d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        } else {
4873d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            ret = parcel.writeByteArray(size, (uint8_t*)data);
4883d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            if (ret) {
4893d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                return ret;
4903d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            }
4913d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        }
4923d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
4933d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return OK;
4943d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
4953d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
4963d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstatus_t MetaDataBase::updateFromParcel(const Parcel &parcel) {
4973d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    uint32_t numItems;
4983d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    if (parcel.readUint32(&numItems) == OK) {
4993d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
5003d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        for (size_t i = 0; i < numItems; i++) {
5013d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            int32_t key;
5023d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            uint32_t type;
5033d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            uint32_t size;
5043d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            status_t ret = parcel.readInt32(&key);
5053d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            ret |= parcel.readUint32(&type);
5063d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            ret |= parcel.readUint32(&size);
5073d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            if (ret != OK) {
5083d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                break;
5093d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            }
5103d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            // copy data from Blob, which may be inline in Parcel storage,
5113d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            // then advance position
5123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            if (type == TYPE_NONE) {
5133d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                android::Parcel::ReadableBlob blob;
5143d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                ret = parcel.readBlob(size, &blob);
5153d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                if (ret != OK) {
5163d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                    break;
5173d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                }
5183d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                setData(key, type, blob.data(), size);
5193d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                blob.release();
5203d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            } else {
5213d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                // copy data directly from Parcel storage, then advance position
5223d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                setData(key, type, parcel.readInplace(size), size);
5233d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            }
5243d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen         }
5253d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
5263d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen        return OK;
5273d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    }
5283d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    ALOGW("no metadata in parcel");
5293d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen    return UNKNOWN_ERROR;
5303d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}
5313d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
5323d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen}  // namespace android
5333d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen
534