MetaData.cpp revision 20111aa043c5f404472bc63b90bc5aad906b1101
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <assert.h>
18#include <stdlib.h>
19#include <string.h>
20
21#include <media/stagefright/MetaData.h>
22
23namespace android {
24
25MetaData::MetaData() {
26}
27
28MetaData::MetaData(const MetaData &from)
29    : RefBase(),
30      mItems(from.mItems) {
31}
32
33MetaData::~MetaData() {
34    clear();
35}
36
37void MetaData::clear() {
38    mItems.clear();
39}
40
41bool MetaData::remove(uint32_t key) {
42    ssize_t i = mItems.indexOfKey(key);
43
44    if (i < 0) {
45        return false;
46    }
47
48    mItems.removeItemsAt(i);
49
50    return true;
51}
52
53bool MetaData::setCString(uint32_t key, const char *value) {
54    return setData(key, TYPE_C_STRING, value, strlen(value) + 1);
55}
56
57bool MetaData::setInt32(uint32_t key, int32_t value) {
58    return setData(key, TYPE_INT32, &value, sizeof(value));
59}
60
61bool MetaData::setFloat(uint32_t key, float value) {
62    return setData(key, TYPE_FLOAT, &value, sizeof(value));
63}
64
65bool MetaData::setPointer(uint32_t key, void *value) {
66    return setData(key, TYPE_POINTER, &value, sizeof(value));
67}
68
69bool MetaData::findCString(uint32_t key, const char **value) {
70    uint32_t type;
71    const void *data;
72    size_t size;
73    if (!findData(key, &type, &data, &size) || type != TYPE_C_STRING) {
74        return false;
75    }
76
77    *value = (const char *)data;
78
79    return true;
80}
81
82bool MetaData::findInt32(uint32_t key, int32_t *value) {
83    uint32_t type;
84    const void *data;
85    size_t size;
86    if (!findData(key, &type, &data, &size) || type != TYPE_INT32) {
87        return false;
88    }
89
90    assert(size == sizeof(*value));
91
92    *value = *(int32_t *)data;
93
94    return true;
95}
96
97bool MetaData::findFloat(uint32_t key, float *value) {
98    uint32_t type;
99    const void *data;
100    size_t size;
101    if (!findData(key, &type, &data, &size) || type != TYPE_FLOAT) {
102        return false;
103    }
104
105    assert(size == sizeof(*value));
106
107    *value = *(float *)data;
108
109    return true;
110}
111
112bool MetaData::findPointer(uint32_t key, void **value) {
113    uint32_t type;
114    const void *data;
115    size_t size;
116    if (!findData(key, &type, &data, &size) || type != TYPE_POINTER) {
117        return false;
118    }
119
120    assert(size == sizeof(*value));
121
122    *value = *(void **)data;
123
124    return true;
125}
126
127bool MetaData::setData(
128        uint32_t key, uint32_t type, const void *data, size_t size) {
129    bool overwrote_existing = true;
130
131    ssize_t i = mItems.indexOfKey(key);
132    if (i < 0) {
133        typed_data item;
134        i = mItems.add(key, item);
135
136        overwrote_existing = false;
137    }
138
139    typed_data &item = mItems.editValueAt(i);
140
141    item.setData(type, data, size);
142
143    return overwrote_existing;
144}
145
146bool MetaData::findData(uint32_t key, uint32_t *type,
147                        const void **data, size_t *size) const {
148    ssize_t i = mItems.indexOfKey(key);
149
150    if (i < 0) {
151        return false;
152    }
153
154    const typed_data &item = mItems.valueAt(i);
155
156    item.getData(type, data, size);
157
158    return true;
159}
160
161MetaData::typed_data::typed_data()
162    : mType(0),
163      mSize(0) {
164}
165
166MetaData::typed_data::~typed_data() {
167    clear();
168}
169
170MetaData::typed_data::typed_data(const typed_data &from)
171    : mType(from.mType),
172      mSize(0) {
173    allocateStorage(from.mSize);
174    memcpy(storage(), from.storage(), mSize);
175}
176
177MetaData::typed_data &MetaData::typed_data::operator=(
178        const MetaData::typed_data &from) {
179    if (this != &from) {
180        clear();
181        mType = from.mType;
182        allocateStorage(from.mSize);
183        memcpy(storage(), from.storage(), mSize);
184    }
185
186    return *this;
187}
188
189void MetaData::typed_data::clear() {
190    freeStorage();
191
192    mType = 0;
193}
194
195void MetaData::typed_data::setData(
196        uint32_t type, const void *data, size_t size) {
197    clear();
198
199    mType = type;
200    allocateStorage(size);
201    memcpy(storage(), data, size);
202}
203
204void MetaData::typed_data::getData(
205        uint32_t *type, const void **data, size_t *size) const {
206    *type = mType;
207    *size = mSize;
208    *data = storage();
209}
210
211void MetaData::typed_data::allocateStorage(size_t size) {
212    mSize = size;
213
214    if (usesReservoir()) {
215        return;
216    }
217
218    u.ext_data = malloc(mSize);
219}
220
221void MetaData::typed_data::freeStorage() {
222    if (!usesReservoir()) {
223        if (u.ext_data) {
224            free(u.ext_data);
225        }
226    }
227
228    mSize = 0;
229}
230
231}  // namespace android
232
233