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