1/*
2 * Copyright (C) 2023 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 "meta/format.h"
17#include <sstream>
18#include "common/log.h"
19#include "common/status.h"
20#include "meta/meta.h"
21#include "securec.h"
22
23namespace {
24constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_FOUNDATION, "Format" };
25}
26
27namespace {
28using namespace OHOS::Media;
29using FormatDataMap = Format::FormatDataMap;
30constexpr size_t BUFFER_SIZE_MAX = 1 * 1024 * 1024;
31
32void CopyFormatVectorMap(const Format::FormatVectorMap &from, Format::FormatVectorMap &to)
33{
34    to = from;
35}
36
37#ifdef MEDIA_OHOS
38bool PutIntValueToFormatMap(FormatDataMap &formatMap, const std::string_view &key, int32_t value)
39{
40    FormatData data;
41    data.type = FORMAT_TYPE_INT32;
42    data.val.int32Val = value;
43    auto ret = formatMap.insert(std::make_pair(std::string(key), data));
44    return ret.second;
45}
46
47bool PutLongValueToFormatMap(FormatDataMap &formatMap, const std::string_view &key, int64_t value)
48{
49    FormatData data;
50    data.type = FORMAT_TYPE_INT64;
51    data.val.int64Val = value;
52    auto ret = formatMap.insert(std::make_pair(std::string(key), data));
53    return ret.second;
54}
55
56bool PutFloatValueToFormatMap(FormatDataMap &formatMap, const std::string_view &key, float value)
57{
58    FormatData data;
59    data.type = FORMAT_TYPE_FLOAT;
60    data.val.floatVal = value;
61    auto ret = formatMap.insert(std::make_pair(std::string(key), data));
62    return ret.second;
63}
64
65bool PutDoubleValueToFormatMap(FormatDataMap &formatMap, const std::string_view &key, double value)
66{
67    FormatData data;
68    data.type = FORMAT_TYPE_DOUBLE;
69    data.val.doubleVal = value;
70    auto ret = formatMap.insert(std::make_pair(std::string(key), data));
71    return ret.second;
72}
73
74bool PutStringValueToFormatMap(FormatDataMap &formatMap, const std::string_view &key, const std::string_view &value)
75{
76    FormatData data;
77    data.type = FORMAT_TYPE_STRING;
78    data.stringVal = value;
79    auto ret = formatMap.insert(std::make_pair(std::string(key), data));
80    return ret.second;
81}
82
83bool PutBufferToFormatMap(FormatDataMap &formatMap, const std::string_view &key, uint8_t *addr, size_t size)
84{
85    FormatData data;
86    FALSE_RETURN_V_MSG_E(addr != nullptr, false, "PutBuffer error, addr is nullptr");
87    data.type = FORMAT_TYPE_ADDR;
88    data.addr = addr;
89    data.size = size;
90    auto ret = formatMap.insert(std::make_pair(std::string(key), data));
91    return ret.second;
92}
93#endif
94} // namespace
95
96namespace OHOS {
97namespace Media {
98Format::~Format()
99{
100    this->meta_ = nullptr;
101}
102
103Format::Format()
104{
105    this->meta_ = std::make_shared<Meta>();
106}
107
108Format::Format(const Format &rhs)
109{
110    FALSE_RETURN_W(&rhs != this);
111    this->meta_ = std::make_shared<Meta>();
112
113    FALSE_RETURN_W(this->meta_ != nullptr);
114    FALSE_RETURN_W(rhs.meta_ != nullptr);
115    *(this->meta_) = *(rhs.meta_);
116    CopyFormatVectorMap(rhs.formatVecMap_, formatVecMap_);
117}
118
119Format::Format(Format &&rhs) noexcept
120{
121    this->meta_ = rhs.meta_;
122    std::swap(formatVecMap_, rhs.formatVecMap_);
123}
124
125Format &Format::operator=(const Format &rhs)
126{
127    FALSE_RETURN_V_W(&rhs != this, *this);
128
129    FALSE_RETURN_V_W(this->meta_ != nullptr, *this);
130    FALSE_RETURN_V_W(rhs.meta_ != nullptr, *this);
131    *(this->meta_) = *(rhs.meta_);
132    CopyFormatVectorMap(rhs.formatVecMap_, this->formatVecMap_);
133    return *this;
134}
135
136Format &Format::operator=(Format &&rhs) noexcept
137{
138    FALSE_RETURN_V(&rhs != this, *this);
139    this->meta_ = rhs.meta_;
140    std::swap(this->formatVecMap_, rhs.formatVecMap_);
141    return *this;
142}
143
144bool Format::PutIntValue(const std::string_view &key, int32_t value)
145{
146    auto defaultValue = GetDefaultAnyValueOpt(key.data());
147    if (defaultValue != std::nullopt) {
148        auto isSameType =
149            Any::IsSameTypeWith<int32_t>(defaultValue.value()) ||
150            Any::IsSameTypeWith<bool>(defaultValue.value()) || IsIntEnum(key.data());
151        FALSE_RETURN_V_MSG_E(isSameType, false, "Key's value type does not match int32, key: %{public}s", key.data());
152    }
153
154    return SetMetaData(*meta_, std::string(key), value);
155}
156
157bool Format::PutLongValue(const std::string_view &key, int64_t value)
158{
159    auto defaultValue = GetDefaultAnyValueOpt(key.data());
160    if (defaultValue != std::nullopt) {
161        auto isSameType =
162            Any::IsSameTypeWith<int64_t>(defaultValue.value()) || IsLongEnum(key.data());
163        FALSE_RETURN_V_MSG_E(isSameType, false, "Key's value type does not match int64, key: %{public}s", key.data());
164    }
165    return SetMetaData(*meta_, std::string(key), value);
166}
167
168bool Format::PutFloatValue(const std::string_view &key, float value)
169{
170    auto defaultValue = GetDefaultAnyValueOpt(key.data());
171    if (defaultValue != std::nullopt) {
172        auto isSameType = Any::IsSameTypeWith<float>(defaultValue.value());
173        FALSE_RETURN_V_MSG_E(isSameType, false, "Key's value type does not match float, key: %{public}s", key.data());
174    }
175
176    meta_->SetData(std::string(key), value);
177    return true;
178}
179
180bool Format::PutDoubleValue(const std::string_view &key, double value)
181{
182    auto defaultValue = GetDefaultAnyValueOpt(key.data());
183    if (defaultValue != std::nullopt) {
184        auto isSameType = Any::IsSameTypeWith<double>(defaultValue.value());
185        FALSE_RETURN_V_MSG_E(isSameType, false, "Key's value type does not match double, key: %{public}s", key.data());
186    }
187
188    meta_->SetData(std::string(key), value);
189    return true;
190}
191
192bool Format::PutStringValue(const std::string_view &key, const std::string_view &value)
193{
194    auto defaultValue = GetDefaultAnyValueOpt(key.data());
195    if (defaultValue != std::nullopt) {
196        auto isSameType = Any::IsSameTypeWith<std::string>(defaultValue.value());
197        FALSE_RETURN_V_MSG_E(isSameType, false, "Key's value type does not match string, key: %{public}s", key.data());
198    }
199
200    meta_->SetData(std::string(key), std::string(value));
201    return true;
202}
203
204bool Format::PutBuffer(const std::string_view &key, const uint8_t *addr, size_t size)
205{
206    auto defaultValue = GetDefaultAnyValueOpt(key.data());
207    if (defaultValue != std::nullopt) {
208        auto isSameType = Any::IsSameTypeWith<std::vector<uint8_t>>(defaultValue.value());
209        FALSE_RETURN_V_MSG_E(isSameType, false, "Key's value type does not match buffer, key: %{public}s", key.data());
210    }
211    FALSE_RETURN_V_MSG_E(addr != nullptr, false, "PutBuffer error, addr is nullptr");
212    FALSE_RETURN_V_MSG_E(size <= BUFFER_SIZE_MAX, false, "PutBuffer input size failed. Key: " PUBLIC_LOG_S, key.data());
213
214    auto iter = meta_->Find(std::string(key));
215    if (iter == meta_->end()) {
216        std::vector<uint8_t> value(addr, addr + size);
217        meta_->SetData(std::string(key), std::move(value));
218        return true;
219    }
220    Any *value = const_cast<Any *>(&(iter->second));
221    auto tmpVector = AnyCast<std::vector<uint8_t>>(value);
222    FALSE_RETURN_V_MSG_E(tmpVector != nullptr, false, "Any value is invalid. Key: " PUBLIC_LOG_S, key.data());
223
224    tmpVector->resize(size);
225    uint8_t *anyAddr = tmpVector->data();
226    auto error = memcpy_s(anyAddr, size, addr, size);
227    FALSE_RETURN_V_MSG_E(error == EOK, false, "PutBuffer memcpy_s failed, error: %{public}s", strerror(error));
228
229    auto formatMapIter = formatMap_.find(key);
230    if (formatMapIter != formatMap_.end()) {
231        formatMap_.erase(formatMapIter);
232        PutBufferToFormatMap(formatMap_, key, anyAddr, size);
233    }
234    return true;
235}
236
237bool Format::GetIntValue(const std::string_view &key, int32_t &value) const
238{
239    return GetMetaData(*meta_, std::string(key), value);
240}
241
242bool Format::GetLongValue(const std::string_view &key, int64_t &value) const
243{
244    return GetMetaData(*meta_, std::string(key), value);
245}
246
247bool Format::GetFloatValue(const std::string_view &key, float &value) const
248{
249    return meta_->GetData(std::string(key), value);
250}
251
252bool Format::GetDoubleValue(const std::string_view &key, double &value) const
253{
254    return meta_->GetData(std::string(key), value);
255}
256
257bool Format::GetStringValue(const std::string_view &key, std::string &value) const
258{
259    return meta_->GetData(std::string(key), value);
260}
261
262bool Format::GetBuffer(const std::string_view &key, uint8_t **addr, size_t &size) const
263{
264    using Buf = std::vector<uint8_t>;
265    auto iter = meta_->Find(std::string(key));
266    if ((iter != meta_->end()) && Any::IsSameTypeWith<Buf>(iter->second)) {
267        Any *value = const_cast<Any *>(&(iter->second));
268        if (AnyCast<Buf>(value) != nullptr) {
269            *addr = (AnyCast<Buf>(value))->data();
270            size = (AnyCast<Buf>(value))->size();
271            return true;
272        }
273    }
274    return false;
275}
276
277bool Format::PutFormatVector(const std::string_view &key, std::vector<Format> &value)
278{
279    RemoveKey(key);
280    auto ret = formatVecMap_.insert(std::make_pair(std::string(key), value));
281    return ret.second;
282}
283
284bool Format::GetFormatVector(const std::string_view &key, std::vector<Format> &value) const
285{
286    auto iter = formatVecMap_.find(key);
287    FALSE_RETURN_V_MSG_E(iter != formatVecMap_.end(),
288        false, "GetFormatVector failed. Key: %{public}s", key.data());
289    value.assign(iter->second.begin(), iter->second.end());
290    return true;
291}
292
293bool Format::ContainKey(const std::string_view &key) const
294{
295    auto iter = meta_->Find(std::string(key));
296    if (iter != meta_->end()) {
297        return true;
298    }
299    auto vecMapIter = formatVecMap_.find(key);
300    return vecMapIter != formatVecMap_.end();
301}
302
303FormatDataType Format::GetValueType(const std::string_view &key) const
304{
305    auto iter = meta_->Find(std::string(key));
306    if (iter != meta_->end()) {
307        if (Any::IsSameTypeWith<int32_t>(iter->second)) {
308            return FORMAT_TYPE_INT32;
309        } else if (Any::IsSameTypeWith<int64_t>(iter->second)) {
310            return FORMAT_TYPE_INT64;
311        } else if (Any::IsSameTypeWith<float>(iter->second)) {
312            return FORMAT_TYPE_FLOAT;
313        } else if (Any::IsSameTypeWith<double>(iter->second)) {
314            return FORMAT_TYPE_DOUBLE;
315        } else if (Any::IsSameTypeWith<std::string>(iter->second)) {
316            return FORMAT_TYPE_STRING;
317        } else if (Any::IsSameTypeWith<std::vector<uint8_t>>(iter->second)) {
318            return FORMAT_TYPE_ADDR;
319        } else {
320            int64_t valueTemp;
321            bool isLongValue = GetMetaData(*meta_, std::string(key), valueTemp);
322            return isLongValue ? FORMAT_TYPE_INT64 : FORMAT_TYPE_INT32;
323        }
324    }
325    return FORMAT_TYPE_NONE;
326}
327
328void Format::RemoveKey(const std::string_view &key)
329{
330    meta_->Remove(std::string(key));
331
332    auto vecMapIter = formatVecMap_.find(key);
333    if (vecMapIter != formatVecMap_.end()) {
334        formatVecMap_.erase(vecMapIter);
335    }
336}
337
338const Format::FormatDataMap &Format::GetFormatMap() const
339{
340#ifdef MEDIA_OHOS
341    FormatDataMap formatTemp;
342    bool ret = true;
343    for (auto iter = meta_->begin(); iter != meta_->end(); ++iter) {
344        switch (GetValueType(iter->first)) {
345            case FORMAT_TYPE_INT32:
346                ret = PutIntValueToFormatMap(formatTemp, iter->first, AnyCast<int32_t>(iter->second));
347                break;
348            case FORMAT_TYPE_INT64:
349                ret = PutLongValueToFormatMap(formatTemp, iter->first, AnyCast<int64_t>(iter->second));
350                break;
351            case FORMAT_TYPE_FLOAT:
352                ret = PutFloatValueToFormatMap(formatTemp, iter->first, AnyCast<float>(iter->second));
353                break;
354            case FORMAT_TYPE_DOUBLE:
355                ret = PutDoubleValueToFormatMap(formatTemp, iter->first, AnyCast<double>(iter->second));
356                break;
357            case FORMAT_TYPE_STRING:
358                ret = PutStringValueToFormatMap(formatTemp, iter->first, AnyCast<std::string>(iter->second));
359                break;
360            case FORMAT_TYPE_ADDR: {
361                Any *value = const_cast<Any *>(&(iter->second));
362                uint8_t *addr = (AnyCast<std::vector<uint8_t>>(value))->data();
363                size_t size = (AnyCast<std::vector<uint8_t>>(value))->size();
364                ret = PutBufferToFormatMap(formatTemp, iter->first, addr, size);
365                break;
366            }
367            default:
368                MEDIA_LOG_E("Format::Stringify failed. Key: %{public}s", iter->first.c_str());
369        }
370        FALSE_LOG_MSG(ret, "Put value to formatMap failed, key = %{public}s", iter->first.c_str());
371    }
372    FormatDataMap *formatMapRef = const_cast<FormatDataMap *>(&formatMap_);
373    swap(formatTemp, *formatMapRef);
374#endif
375    return formatMap_;
376}
377
378const Format::FormatVectorMap &Format::GetFormatVectorMap() const
379{
380    return formatVecMap_;
381}
382
383std::string Format::Stringify() const
384{
385    std::stringstream dumpStream;
386    for (auto iter = meta_->begin(); iter != meta_->end(); ++iter) {
387        switch (GetValueType(iter->first)) {
388            case FORMAT_TYPE_INT32:
389                dumpStream << iter->first << " = " << std::to_string(AnyCast<int32_t>(iter->second)) << " | ";
390                break;
391            case FORMAT_TYPE_INT64:
392                dumpStream << iter->first << " = " << std::to_string(AnyCast<int64_t>(iter->second)) << " | ";
393                break;
394            case FORMAT_TYPE_FLOAT:
395                dumpStream << iter->first << " = " << std::to_string(AnyCast<float>(iter->second)) << " | ";
396                break;
397            case FORMAT_TYPE_DOUBLE:
398                dumpStream << iter->first << " = " << std::to_string(AnyCast<double>(iter->second)) << " | ";
399                break;
400            case FORMAT_TYPE_STRING:
401                dumpStream << iter->first << " = " << AnyCast<std::string>(iter->second) << " | ";
402                break;
403            case FORMAT_TYPE_ADDR: {
404                Any *value = const_cast<Any *>(&(iter->second));
405                if (AnyCast<std::vector<uint8_t>>(value) != nullptr) {
406                    dumpStream << iter->first << ", bufferSize = " << (AnyCast<std::vector<uint8_t>>(value))->size()
407                            << " | ";
408                }
409                break;
410            }
411            default:
412                MEDIA_LOG_E("Format::Stringify failed. Key: %{public}s", iter->first.c_str());
413        }
414    }
415    return dumpStream.str();
416}
417
418std::shared_ptr<Meta> Format::GetMeta()
419{
420    return meta_;
421}
422
423bool Format::SetMeta(std::shared_ptr<Meta> meta)
424{
425    FALSE_RETURN_V(meta != nullptr, false);
426    if (meta.use_count() > 1) {
427        *meta_ = *meta;
428    } else {
429        meta_ = meta;
430    }
431    return true;
432}
433} // namespace Media
434} // namespace OHOS