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