1/*
2 * Copyright (c) 2020 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "format.h"
17#include <cstdio>
18#include "media_log.h"
19
20namespace OHOS {
21namespace Media {
22const char *CODEC_MIME = "mime";
23const char *MIME_AUDIO_AAC = "audio/mp4a-latm";
24const char *MIME_AUDIO_RAW = "audio/raw";
25const char *PAUSE_AFTER_PLAY = "pause_after_play";
26
27#define SET_INT32_FORMAT(type, func)   \
28do { \
29    type val;                    \
30    if (formatData->func(val)) { \
31        PutIntValue(key, val);     \
32    } \
33} while (0)
34
35#define SET_INT64_FORMAT(type, func)   \
36do { \
37    type val;                    \
38    if (formatData->func(val)) { \
39        PutLongValue(key, val);     \
40    } \
41} while (0)
42
43#define SET_FLOAT_FORMAT(type, func)   \
44do { \
45    type val;                    \
46    if (formatData->func(val)) { \
47        PutFloatValue(key, val);     \
48    } \
49} while (0)
50
51#define SET_DOUBLE_FORMAT(type, func)   \
52do { \
53    type val;                    \
54    if (formatData->func(val)) { \
55        PutDoubleValue(key, val);     \
56    } \
57} while (0)
58
59#define SET_STRING_FORMAT(type, func)   \
60do { \
61    type val;                    \
62    if (formatData->func(val)) { \
63        PutStringValue(key, val);     \
64    } \
65} while (0)
66
67// For Class FormatData
68FormatData::FormatData() : type_(FORMAT_TYPE_NONE), val_({ 0 })
69{}
70
71FormatData::FormatData(FormatDataType type) : type_(type), val_({ 0 })
72{}
73
74FormatData::~FormatData()
75{
76    if (type_ == FORMAT_TYPE_STRING) {
77        if (val_.stringVal != nullptr) {
78            delete val_.stringVal;
79        }
80    }
81}
82
83bool FormatData::SetValue(int32_t val)
84{
85    if (type_ != FORMAT_TYPE_INT32) {
86        MEDIA_ERR_LOG("FormatData set int32 value error, current type is %u", type_);
87        return false;
88    }
89    val_.int32Val = val;
90    return true;
91}
92
93bool FormatData::SetValue(int64_t val)
94{
95    if (type_ != FORMAT_TYPE_INT64) {
96        MEDIA_ERR_LOG("FormatData set int64 value error, current type is %u", type_);
97        return false;
98    }
99    val_.int64Val = val;
100    return true;
101}
102
103bool FormatData::SetValue(float val)
104{
105    if (type_ != FORMAT_TYPE_FLOAT) {
106        MEDIA_ERR_LOG("FormatData set float value error, current type is %u", type_);
107        return false;
108    }
109    val_.floatVal = val;
110    return true;
111}
112
113bool FormatData::SetValue(double val)
114{
115    if (type_ != FORMAT_TYPE_DOUBLE) {
116        MEDIA_ERR_LOG("FormatData set double value error, current type is %u", type_);
117        return false;
118    }
119    val_.doubleVal = val;
120    return true;
121}
122
123bool FormatData::SetValue(const std::string &val)
124{
125    if (type_ != FORMAT_TYPE_STRING) {
126        MEDIA_ERR_LOG("FormatData set string value error, current type is %u", type_);
127        return false;
128    }
129    val_.stringVal = new (std::nothrow) std::string();
130    if (val_.stringVal == nullptr) {
131        type_ = FORMAT_TYPE_NONE;
132        MEDIA_ERR_LOG("FormatData set string value error, new string failed");
133        return false;
134    }
135    *(val_.stringVal) = val;
136    return true;
137}
138
139bool FormatData::GetInt32Value(int32_t &val) const
140{
141    if (type_ != FORMAT_TYPE_INT32) {
142        MEDIA_ERR_LOG("FormatData get int32 value error, current type is %u", type_);
143        return false;
144    }
145    val = val_.int32Val;
146    return true;
147}
148
149bool FormatData::GetInt64Value(int64_t &val) const
150{
151    if (type_ != FORMAT_TYPE_INT64) {
152        MEDIA_ERR_LOG("FormatData get int64 value error, current type is %u", type_);
153        return false;
154    }
155    val = val_.int64Val;
156    return true;
157}
158
159bool FormatData::GetFloatValue(float &val) const
160{
161    if (type_ != FORMAT_TYPE_FLOAT) {
162        MEDIA_ERR_LOG("FormatData get float value error, current type is %u", type_);
163        return false;
164    }
165    val = val_.floatVal;
166    return true;
167}
168
169bool FormatData::GetDoubleValue(double &val) const
170{
171    if (type_ != FORMAT_TYPE_DOUBLE) {
172        MEDIA_ERR_LOG("FormatData get double value error, current type is %u", type_);
173        return false;
174    }
175    val = val_.doubleVal;
176    return true;
177}
178
179bool FormatData::GetStringValue(std::string &val) const
180{
181    if (type_ != FORMAT_TYPE_STRING) {
182        MEDIA_ERR_LOG("FormatData get string value error, current type is %u", type_);
183        return false;
184    }
185    if (val_.stringVal == nullptr) {
186        MEDIA_ERR_LOG("FormatData get string value error, stringVal is null");
187        return false;
188    }
189    val = *(val_.stringVal);
190    return true;
191}
192
193// For Class Format
194Format::Format()
195{}
196
197Format::~Format()
198{
199    for (auto &iter : formatMap_) {
200        if (iter.second != nullptr) {
201            delete iter.second;
202        }
203    }
204    formatMap_.clear();
205}
206
207bool Format::PutIntValue(const std::string &key, int32_t value)
208{
209    return SetFormatCommon(key, value, FORMAT_TYPE_INT32);
210}
211
212bool Format::PutLongValue(const std::string &key, int64_t value)
213{
214    return SetFormatCommon(key, value, FORMAT_TYPE_INT64);
215}
216
217bool Format::PutFloatValue(const std::string &key, float value)
218{
219    return SetFormatCommon(key, value, FORMAT_TYPE_FLOAT);
220}
221
222bool Format::PutDoubleValue(const std::string &key, double value)
223{
224    return SetFormatCommon(key, value, FORMAT_TYPE_DOUBLE);
225}
226
227bool Format::PutStringValue(const std::string &key, const std::string &value)
228{
229    return SetFormatCommon(key, value, FORMAT_TYPE_STRING);
230}
231
232template<typename T>
233bool Format::SetFormatCommon(const std::string &key, const T &value, FormatDataType type)
234{
235    auto iter = formatMap_.find(key);
236    if (iter != formatMap_.end()) {
237        delete iter->second;
238        iter->second = nullptr;
239        formatMap_.erase(iter);
240    }
241    FormatData *data = new (std::nothrow) FormatData(type);
242    if (data == nullptr) {
243        MEDIA_ERR_LOG("Format::SetFormatCommon new FormatData failed");
244        return false;
245    }
246    if (!data->SetValue(value)) {
247        MEDIA_ERR_LOG("Format::SetFormatCommon failed. Key: %s", key.c_str());
248        delete data;
249        return false;
250    }
251    formatMap_[key] = data;
252    return true;
253}
254
255bool Format::GetStringValue(const std::string &key, std::string &value) const
256{
257    auto iter = formatMap_.find(key);
258    if (iter == formatMap_.end() || iter->second == nullptr) {
259        MEDIA_DEBUG_LOG("Format::GetFormat failed. Key: %s", key.c_str());
260        return false;
261    }
262
263    return (*iter->second).GetStringValue(value);
264}
265
266bool Format::GetIntValue(const std::string &key, int32_t &value) const
267{
268    auto iter = formatMap_.find(key);
269    if ((iter == formatMap_.end()) || (iter->second == nullptr)) {
270        MEDIA_DEBUG_LOG("Format::GetFormat failed. Key: %s", key.c_str());
271        return false;
272    }
273
274    return (*iter->second).GetInt32Value(value);
275}
276
277bool Format::GetLongValue(const std::string &key, int64_t &value) const
278{
279    auto iter = formatMap_.find(key);
280    if ((iter == formatMap_.end()) || (iter->second == nullptr)) {
281        MEDIA_DEBUG_LOG("Format::GetFormat failed. Key: %s", key.c_str());
282        return false;
283    }
284
285    return (*iter->second).GetInt64Value(value);
286}
287
288bool Format::GetFloatValue(const std::string &key, float &value) const
289{
290    auto iter = formatMap_.find(key);
291    if ((iter == formatMap_.end()) || (iter->second == nullptr)) {
292        MEDIA_DEBUG_LOG("Format::GetFormat failed. Key: %s", key.c_str());
293        return false;
294    }
295
296    return (*iter->second).GetFloatValue(value);
297}
298
299bool Format::GetDoubleValue(const std::string &key, double &value) const
300{
301    auto iter = formatMap_.find(key);
302    if ((iter == formatMap_.end()) || (iter->second == nullptr)) {
303        MEDIA_DEBUG_LOG("Format::GetFormat failed. Key: %s", key.c_str());
304        return false;
305    }
306
307    return (*iter->second).GetDoubleValue(value);
308}
309
310const std::map<std::string, FormatData *> &Format::GetFormatMap() const
311{
312    return formatMap_;
313}
314
315bool Format::CopyFrom(const Format &format)
316{
317    MEDIA_INFO_LOG("CopyFrom begin");
318    std::map<std::string, FormatData *> formatMap = format.GetFormatMap();
319    for (auto &iter : formatMap) {
320        std::string key = iter.first;
321        FormatData *formatData = iter.second;
322        if (formatData == nullptr) {
323            MEDIA_ERR_LOG("CopyFrom FormatData is null, key is %s", key.c_str());
324            continue;
325        }
326        FormatDataType type = formatData->GetType();
327        switch (type) {
328            case FORMAT_TYPE_INT32: {
329                SET_INT32_FORMAT(int32_t, GetInt32Value);
330                break;
331            }
332            case FORMAT_TYPE_INT64: {
333                SET_INT64_FORMAT(int64_t, GetInt64Value);
334                break;
335            }
336            case FORMAT_TYPE_FLOAT: {
337                SET_FLOAT_FORMAT(float, GetFloatValue);
338                break;
339            }
340            case FORMAT_TYPE_DOUBLE: {
341                SET_DOUBLE_FORMAT(double, GetDoubleValue);
342                break;
343            }
344            case FORMAT_TYPE_STRING: {
345                SET_STRING_FORMAT(std::string, GetStringValue);
346                break;
347            }
348            default: {
349                MEDIA_ERR_LOG("CopyFrom unknown type, type is %d", type);
350                break;
351            }
352        }
353    }
354    return true;
355}
356}  // namespace Media
357}  // namespace OHOS
358