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 
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_FOUNDATION, "Format" };
25 }
26 
27 namespace {
28 using namespace OHOS::Media;
29 using FormatDataMap = Format::FormatDataMap;
30 constexpr size_t BUFFER_SIZE_MAX = 1 * 1024 * 1024;
31 
CopyFormatVectorMap(const Format::FormatVectorMap & from,Format::FormatVectorMap & to)32 void CopyFormatVectorMap(const Format::FormatVectorMap &from, Format::FormatVectorMap &to)
33 {
34     to = from;
35 }
36 
37 #ifdef MEDIA_OHOS
PutIntValueToFormatMap(FormatDataMap & formatMap,const std::string_view & key,int32_t value)38 bool 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 
PutLongValueToFormatMap(FormatDataMap & formatMap,const std::string_view & key,int64_t value)47 bool 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 
PutFloatValueToFormatMap(FormatDataMap & formatMap,const std::string_view & key,float value)56 bool 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 
PutDoubleValueToFormatMap(FormatDataMap & formatMap,const std::string_view & key,double value)65 bool 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 
PutStringValueToFormatMap(FormatDataMap & formatMap,const std::string_view & key,const std::string_view & value)74 bool 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 
PutBufferToFormatMap(FormatDataMap & formatMap,const std::string_view & key,uint8_t * addr,size_t size)83 bool 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 
96 namespace OHOS {
97 namespace Media {
~Format()98 Format::~Format()
99 {
100     this->meta_ = nullptr;
101 }
102 
Format()103 Format::Format()
104 {
105     this->meta_ = std::make_shared<Meta>();
106 }
107 
Format(const Format & rhs)108 Format::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 
Format(Format && rhs)119 Format::Format(Format &&rhs) noexcept
120 {
121     this->meta_ = rhs.meta_;
122     std::swap(formatVecMap_, rhs.formatVecMap_);
123 }
124 
operator =(const Format & rhs)125 Format &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 
operator =(Format && rhs)136 Format &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 
PutIntValue(const std::string_view & key,int32_t value)144 bool 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 
PutLongValue(const std::string_view & key,int64_t value)157 bool 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 
PutFloatValue(const std::string_view & key,float value)168 bool 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 
PutDoubleValue(const std::string_view & key,double value)180 bool 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 
PutStringValue(const std::string_view & key,const std::string_view & value)192 bool 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 
PutBuffer(const std::string_view & key,const uint8_t * addr,size_t size)204 bool 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 
GetIntValue(const std::string_view & key,int32_t & value) const237 bool Format::GetIntValue(const std::string_view &key, int32_t &value) const
238 {
239     return GetMetaData(*meta_, std::string(key), value);
240 }
241 
GetLongValue(const std::string_view & key,int64_t & value) const242 bool Format::GetLongValue(const std::string_view &key, int64_t &value) const
243 {
244     return GetMetaData(*meta_, std::string(key), value);
245 }
246 
GetFloatValue(const std::string_view & key,float & value) const247 bool Format::GetFloatValue(const std::string_view &key, float &value) const
248 {
249     return meta_->GetData(std::string(key), value);
250 }
251 
GetDoubleValue(const std::string_view & key,double & value) const252 bool Format::GetDoubleValue(const std::string_view &key, double &value) const
253 {
254     return meta_->GetData(std::string(key), value);
255 }
256 
GetStringValue(const std::string_view & key,std::string & value) const257 bool Format::GetStringValue(const std::string_view &key, std::string &value) const
258 {
259     return meta_->GetData(std::string(key), value);
260 }
261 
GetBuffer(const std::string_view & key,uint8_t ** addr,size_t & size) const262 bool 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 
PutFormatVector(const std::string_view & key,std::vector<Format> & value)277 bool 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 
GetFormatVector(const std::string_view & key,std::vector<Format> & value) const284 bool 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 
ContainKey(const std::string_view & key) const293 bool 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 
GetValueType(const std::string_view & key) const303 FormatDataType 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 
RemoveKey(const std::string_view & key)328 void 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 
GetFormatMap() const338 const 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 
GetFormatVectorMap() const378 const Format::FormatVectorMap &Format::GetFormatVectorMap() const
379 {
380     return formatVecMap_;
381 }
382 
Stringify() const383 std::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 
GetMeta()418 std::shared_ptr<Meta> Format::GetMeta()
419 {
420     return meta_;
421 }
422 
SetMeta(std::shared_ptr<Meta> meta)423 bool 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