120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen//#define LOG_NDEBUG 0
18feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen#define LOG_TAG "MetaData"
19377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT#include <inttypes.h>
20feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen#include <utils/Log.h>
21feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen
2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h>
2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h>
2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
2656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#include <media/stagefright/foundation/AString.h>
2756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#include <media/stagefright/foundation/hexdump.h>
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h>
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMetaData::MetaData() {
3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMetaData::MetaData(const MetaData &from)
3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : RefBase(),
3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mItems(from.mItems) {
3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMetaData::~MetaData() {
4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    clear();
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MetaData::clear() {
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mItems.clear();
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberbool MetaData::remove(uint32_t key) {
4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    ssize_t i = mItems.indexOfKey(key);
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (i < 0) {
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return false;
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mItems.removeItemsAt(i);
5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return true;
5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberbool MetaData::setCString(uint32_t key, const char *value) {
6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return setData(key, TYPE_C_STRING, value, strlen(value) + 1);
6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberbool MetaData::setInt32(uint32_t key, int32_t value) {
6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return setData(key, TYPE_INT32, &value, sizeof(value));
6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huberbool MetaData::setInt64(uint32_t key, int64_t value) {
6948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    return setData(key, TYPE_INT64, &value, sizeof(value));
7048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber}
7148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber
7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberbool MetaData::setFloat(uint32_t key, float value) {
7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return setData(key, TYPE_FLOAT, &value, sizeof(value));
7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberbool MetaData::setPointer(uint32_t key, void *value) {
7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return setData(key, TYPE_POINTER, &value, sizeof(value));
7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
80f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huberbool MetaData::setRect(
81f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        uint32_t key,
82f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        int32_t left, int32_t top,
83f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        int32_t right, int32_t bottom) {
84f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    Rect r;
85f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    r.mLeft = left;
86f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    r.mTop = top;
87f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    r.mRight = right;
88f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    r.mBottom = bottom;
89f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
90f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    return setData(key, TYPE_RECT, &r, sizeof(r));
91f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber}
92f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
934256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen/**
944256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen * Note that the returned pointer becomes invalid when additional metadata is set.
954256c970ad90bc555eccfd585048669bb69bca1cMarco Nelissen */
962cf9c5073ca3342ee52673ad68763fadd2c2be79James Dongbool MetaData::findCString(uint32_t key, const char **value) {
9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint32_t type;
9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const void *data;
9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size;
10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (!findData(key, &type, &data, &size) || type != TYPE_C_STRING) {
10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return false;
10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *value = (const char *)data;
10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return true;
10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1092cf9c5073ca3342ee52673ad68763fadd2c2be79James Dongbool MetaData::findInt32(uint32_t key, int32_t *value) {
1105b5d1f87f1cfdd631c5d4ea5c60e1dae910a9203Marco Nelissen    uint32_t type = 0;
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const void *data;
11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size;
11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (!findData(key, &type, &data, &size) || type != TYPE_INT32) {
11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return false;
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1170c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK_EQ(size, sizeof(*value));
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *value = *(int32_t *)data;
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return true;
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1242cf9c5073ca3342ee52673ad68763fadd2c2be79James Dongbool MetaData::findInt64(uint32_t key, int64_t *value) {
1255b5d1f87f1cfdd631c5d4ea5c60e1dae910a9203Marco Nelissen    uint32_t type = 0;
12648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    const void *data;
12748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    size_t size;
12848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    if (!findData(key, &type, &data, &size) || type != TYPE_INT64) {
12948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber        return false;
13048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    }
13148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber
13248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    CHECK_EQ(size, sizeof(*value));
13348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber
13448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    *value = *(int64_t *)data;
13548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber
13648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber    return true;
13748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber}
13848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber
1392cf9c5073ca3342ee52673ad68763fadd2c2be79James Dongbool MetaData::findFloat(uint32_t key, float *value) {
1405b5d1f87f1cfdd631c5d4ea5c60e1dae910a9203Marco Nelissen    uint32_t type = 0;
14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const void *data;
14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size;
14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (!findData(key, &type, &data, &size) || type != TYPE_FLOAT) {
14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return false;
14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1470c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK_EQ(size, sizeof(*value));
14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *value = *(float *)data;
15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return true;
15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1542cf9c5073ca3342ee52673ad68763fadd2c2be79James Dongbool MetaData::findPointer(uint32_t key, void **value) {
1555b5d1f87f1cfdd631c5d4ea5c60e1dae910a9203Marco Nelissen    uint32_t type = 0;
15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const void *data;
15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size;
15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (!findData(key, &type, &data, &size) || type != TYPE_POINTER) {
15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return false;
16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1620c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK_EQ(size, sizeof(*value));
16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *value = *(void **)data;
16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return true;
16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
169f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huberbool MetaData::findRect(
170f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        uint32_t key,
171f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        int32_t *left, int32_t *top,
1722cf9c5073ca3342ee52673ad68763fadd2c2be79James Dong        int32_t *right, int32_t *bottom) {
1735b5d1f87f1cfdd631c5d4ea5c60e1dae910a9203Marco Nelissen    uint32_t type = 0;
174f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    const void *data;
175f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    size_t size;
176f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    if (!findData(key, &type, &data, &size) || type != TYPE_RECT) {
177f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        return false;
178f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
179f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
180f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    CHECK_EQ(size, sizeof(Rect));
181f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
182f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    const Rect *r = (const Rect *)data;
183f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    *left = r->mLeft;
184f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    *top = r->mTop;
185f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    *right = r->mRight;
186f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    *bottom = r->mBottom;
187f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
188f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    return true;
189f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber}
190f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberbool MetaData::setData(
19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t key, uint32_t type, const void *data, size_t size) {
19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    bool overwrote_existing = true;
19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    ssize_t i = mItems.indexOfKey(key);
19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (i < 0) {
19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        typed_data item;
19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        i = mItems.add(key, item);
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        overwrote_existing = false;
20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    typed_data &item = mItems.editValueAt(i);
20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    item.setData(type, data, size);
20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return overwrote_existing;
20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberbool MetaData::findData(uint32_t key, uint32_t *type,
21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                        const void **data, size_t *size) const {
21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    ssize_t i = mItems.indexOfKey(key);
21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (i < 0) {
21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return false;
21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    const typed_data &item = mItems.valueAt(i);
21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    item.getData(type, data, size);
22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return true;
22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
225328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhébool MetaData::hasData(uint32_t key) const {
226328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    ssize_t i = mItems.indexOfKey(key);
227328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
228328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    if (i < 0) {
229328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé        return false;
230328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    }
231328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
232328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé    return true;
233328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé}
234328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé
23520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMetaData::typed_data::typed_data()
23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mType(0),
23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSize(0) {
23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
24020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMetaData::typed_data::~typed_data() {
24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    clear();
24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
24420111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMetaData::typed_data::typed_data(const typed_data &from)
24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mType(from.mType),
24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSize(0) {
247f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen
248f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen    void *dst = allocateStorage(from.mSize);
249f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen    if (dst) {
250f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen        memcpy(dst, from.storage(), mSize);
251f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen    }
25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25420111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMetaData::typed_data &MetaData::typed_data::operator=(
25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const MetaData::typed_data &from) {
25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (this != &from) {
25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        clear();
25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mType = from.mType;
259f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen        void *dst = allocateStorage(from.mSize);
260f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen        if (dst) {
261f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen            memcpy(dst, from.storage(), mSize);
262f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen        }
26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return *this;
26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MetaData::typed_data::clear() {
26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    freeStorage();
27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mType = 0;
27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MetaData::typed_data::setData(
27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t type, const void *data, size_t size) {
27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    clear();
27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mType = type;
279f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen
280f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen    void *dst = allocateStorage(size);
281f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen    if (dst) {
282f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen        memcpy(dst, data, size);
283566c70caff87c710e659c5aaad0692e031d93dedMarco Nelissen    }
28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MetaData::typed_data::getData(
28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t *type, const void **data, size_t *size) const {
28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *type = mType;
28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *size = mSize;
29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *data = storage();
29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
293f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissenvoid *MetaData::typed_data::allocateStorage(size_t size) {
29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSize = size;
29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (usesReservoir()) {
297f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen        return &u.reservoir;
29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    u.ext_data = malloc(mSize);
301f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen    if (u.ext_data == NULL) {
302f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen        ALOGE("Couldn't allocate %zu bytes for item", size);
303f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen        mSize = 0;
304f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen    }
305f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen    return u.ext_data;
30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MetaData::typed_data::freeStorage() {
30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (!usesReservoir()) {
31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (u.ext_data) {
31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            free(u.ext_data);
312fca812565cebd229fba8be32bad14983c5252a7bChrister Fletcher            u.ext_data = NULL;
31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSize = 0;
31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31969d3d8a9540b0da787ea0beccad2517f057dd54dMarco NelissenString8 MetaData::typed_data::asString(bool verbose) const {
320feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen    String8 out;
321feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen    const void *data = storage();
322feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen    switch(mType) {
323feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        case TYPE_NONE:
324377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT            out = String8::format("no type, size %zu)", mSize);
325feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            break;
326feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        case TYPE_C_STRING:
327feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            out = String8::format("(char*) %s", (const char *)data);
328feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            break;
329feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        case TYPE_INT32:
330feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            out = String8::format("(int32_t) %d", *(int32_t *)data);
331feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            break;
332feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        case TYPE_INT64:
333377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT            out = String8::format("(int64_t) %" PRId64, *(int64_t *)data);
334feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            break;
335feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        case TYPE_FLOAT:
336feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            out = String8::format("(float) %f", *(float *)data);
337feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            break;
338feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        case TYPE_POINTER:
339feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            out = String8::format("(void*) %p", *(void **)data);
340feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            break;
341feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        case TYPE_RECT:
342feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        {
343feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            const Rect *r = (const Rect *)data;
344feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            out = String8::format("Rect(%d, %d, %d, %d)",
345feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen                                  r->mLeft, r->mTop, r->mRight, r->mBottom);
346feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            break;
347feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        }
348feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen
349feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        default:
350377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT            out = String8::format("(unknown type %d, size %zu)", mType, mSize);
35169d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen            if (verbose && mSize <= 48) { // if it's less than three lines of hex data, dump it
35256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                AString foo;
35356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                hexdump(data, mSize, 0, &foo);
35456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                out.append("\n");
35556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                out.append(foo.c_str());
35656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
357feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen            break;
358feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen    }
359feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen    return out;
360feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen}
361feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen
362feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissenstatic void MakeFourCCString(uint32_t x, char *s) {
363feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen    s[0] = x >> 24;
364feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen    s[1] = (x >> 16) & 0xff;
365feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen    s[2] = (x >> 8) & 0xff;
366feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen    s[3] = x & 0xff;
367feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen    s[4] = '\0';
368feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen}
369feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen
37069d3d8a9540b0da787ea0beccad2517f057dd54dMarco NelissenString8 MetaData::toString() const {
37169d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    String8 s;
37269d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    for (int i = mItems.size(); --i >= 0;) {
37369d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        int32_t key = mItems.keyAt(i);
37469d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        char cc[5];
37569d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        MakeFourCCString(key, cc);
37669d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        const typed_data &item = mItems.valueAt(i);
37769d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        s.appendFormat("%s: %s", cc, item.asString(false).string());
37869d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        if (i != 0) {
37969d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen            s.append(", ");
38069d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        }
38169d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    }
38269d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen    return s;
38369d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen}
384feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissenvoid MetaData::dumpToLog() const {
385feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen    for (int i = mItems.size(); --i >= 0;) {
386feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        int32_t key = mItems.keyAt(i);
387feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        char cc[5];
388feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        MakeFourCCString(key, cc);
389feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen        const typed_data &item = mItems.valueAt(i);
39069d3d8a9540b0da787ea0beccad2517f057dd54dMarco Nelissen        ALOGI("%s: %s", cc, item.asString(true /* verbose */).string());
391feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen    }
392feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen}
393feba11fd788c99b0b63e0bce724730817688d82fMarco Nelissen
394b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenstatus_t MetaData::writeToParcel(Parcel &parcel) {
395b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    size_t numItems = mItems.size();
396b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    parcel.writeUint32(uint32_t(numItems));
397b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    for (size_t i = 0; i < numItems; i++) {
398b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        int32_t key = mItems.keyAt(i);
399b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        const typed_data &item = mItems.valueAt(i);
400b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        uint32_t type;
401b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        const void *data;
402b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        size_t size;
403b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        item.getData(&type, &data, &size);
404b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        parcel.writeInt32(key);
405b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        parcel.writeUint32(type);
406b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        parcel.writeByteArray(size, (uint8_t*)data);
407b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
408b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    return OK;
409b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
410b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
411b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissenstatus_t MetaData::updateFromParcel(const Parcel &parcel) {
412b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    uint32_t numItems;
413b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    if (parcel.readUint32(&numItems) == OK) {
414b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
415b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        for (size_t i = 0; i < numItems; i++) {
416b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            int32_t key;
417b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            uint32_t type;
418b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            uint32_t size;
419b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            status_t ret = parcel.readInt32(&key);
420b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ret |= parcel.readUint32(&type);
421b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            ret |= parcel.readUint32(&size);
422b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            if (ret != OK) {
423b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen                break;
424b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            }
425b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            // copy data directly from Parcel storage, then advance position
426b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen            setData(key, type, parcel.readInplace(size), size);
427b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen         }
428b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
429b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen        return OK;
430b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    }
431b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    ALOGW("no metadata in parcel");
432b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    return UNKNOWN_ERROR;
433b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
434b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
435b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
436b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen/* static */
437b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<MetaData> MetaData::createFromParcel(const Parcel &parcel) {
438b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
439b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    sp<MetaData> meta = new MetaData();
440b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    meta->updateFromParcel(parcel);
441b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    return meta;
442b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen}
443b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
444b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
445b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen
44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
448