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 "map_data_sequenceable.h" 17#include "hdi_log.h" 18#include <message_parcel.h> 19namespace OHOS { 20namespace HDI { 21namespace Camera { 22namespace V1_0 { 23constexpr int32_t BUFFER_DATA_MAGIC = 0x4567; 24constexpr int32_t BUFFER_MAX_USER_DATA_COUNT = 1000; 25 26enum ErrorCode : int32_t { 27 ERROR_OK = 0, 28 ERROR_INTERNAL = -1, 29 ERROR_NO_ENTRY = -2, 30 ERROR_TYPE_ERROR = -3, 31 ERROR_OUT_OF_RANGE = -4, 32}; 33 34#define SET_DATA_FROM_POINTER(data, pointer) do { \ 35 if ((pointer) != nullptr) { \ 36 (data) = *(pointer); \ 37 } \ 38} while (0) 39 40sptr<MapDataSequenceable> MapDataSequenceable::Unmarshalling(Parcel &parcel) 41{ 42 int32_t magic; 43 if (parcel.ReadInt32(magic) == false || magic != BUFFER_DATA_MAGIC) { 44 HDI_CAMERA_LOGW("read failed, magic is error"); 45 return nullptr; 46 } 47 48 int32_t size = parcel.ReadInt32(); 49 if (size > BUFFER_MAX_USER_DATA_COUNT) { 50 HDI_CAMERA_LOGE("Too much data obtained from Parcel"); 51 return nullptr; 52 } 53 sptr<MapDataSequenceable> sequenceData(new MapDataSequenceable()); 54 55 int32_t ret = ERROR_OK; 56 for (int32_t i = 0; i < size; i++) { 57 auto key = parcel.ReadString(); 58 auto type = static_cast<MapDataType>(parcel.ReadInt32()); 59 switch (type) { 60 case MapDataType::I32: { 61 ret = sequenceData->Set(key, type, parcel.ReadInt32()); 62 break; 63 } 64 case MapDataType::I64: { 65 ret = sequenceData->Set(key, type, parcel.ReadInt64()); 66 break; 67 } 68 case MapDataType::F64: { 69 ret = sequenceData->Set(key, type, parcel.ReadDouble()); 70 break; 71 } 72 case MapDataType::STRING: { 73 ret = sequenceData->Set(key, type, parcel.ReadString()); 74 break; 75 } 76 default: break; 77 } 78 79 if (ret != ERROR_OK) { 80 HDI_CAMERA_LOGE("Set extra data failed, return %{public}d", ret); 81 return nullptr; 82 } 83 } 84 return sequenceData; 85} 86 87bool MapDataSequenceable::Marshalling(Parcel &parcel) const 88{ 89 OHOS::MessageParcel &dataParcel = static_cast<OHOS::MessageParcel &>(parcel); 90 std::lock_guard<std::mutex> lockGuard(mtx_); 91 dataParcel.WriteInt32(BUFFER_DATA_MAGIC); 92 dataParcel.WriteInt32(datas_.size()); 93 for (const auto &[key, data] : datas_) { 94 dataParcel.WriteString(key); 95 dataParcel.WriteInt32(static_cast<int32_t>(data.type)); 96 switch (data.type) { 97 case MapDataType::I32: { 98 int32_t i32 = -1; 99 auto pVal = std::any_cast<int32_t>(&data.val); 100 SET_DATA_FROM_POINTER(i32, pVal); 101 dataParcel.WriteInt32(i32); 102 break; 103 } 104 case MapDataType::I64: { 105 int64_t i64 = -1; 106 auto pVal = std::any_cast<int64_t>(&data.val); 107 SET_DATA_FROM_POINTER(i64, pVal); 108 dataParcel.WriteInt64(i64); 109 break; 110 } 111 case MapDataType::F64: { 112 double f64 = -1; 113 auto pVal = std::any_cast<double>(&data.val); 114 SET_DATA_FROM_POINTER(f64, pVal); 115 dataParcel.WriteDouble(f64); 116 break; 117 } 118 case MapDataType::STRING: { 119 std::string string = "-1"; 120 auto pVal = std::any_cast<std::string>(&data.val); 121 SET_DATA_FROM_POINTER(string, pVal); 122 dataParcel.WriteString(string); 123 break; 124 } 125 default: 126 break; 127 } 128 } 129 return true; 130} 131 132int32_t MapDataSequenceable::Get(const std::string &key, int32_t &value) const 133{ 134 return Get<int32_t>(key, MapDataType::I32, value); 135} 136 137int32_t MapDataSequenceable::Get(const std::string &key, int64_t &value) const 138{ 139 return Get<int64_t>(key, MapDataType::I64, value); 140} 141 142int32_t MapDataSequenceable::Get(const std::string &key, double &value) const 143{ 144 return Get<double>(key, MapDataType::F64, value); 145} 146 147int32_t MapDataSequenceable::Get(const std::string &key, std::string &value) const 148{ 149 return Get<std::string>(key, MapDataType::STRING, value); 150} 151 152int32_t MapDataSequenceable::Set(const std::string &key, int32_t value) 153{ 154 return Set(key, MapDataType::I32, value); 155} 156 157int32_t MapDataSequenceable::Set(const std::string &key, int64_t value) 158{ 159 return Set(key, MapDataType::I64, value); 160} 161 162int32_t MapDataSequenceable::Set(const std::string &key, double value) 163{ 164 return Set(key, MapDataType::F64, value); 165} 166 167int32_t MapDataSequenceable::Set(const std::string &key, const std::string& value) 168{ 169 return Set(key, MapDataType::STRING, value); 170} 171 172template<class T> 173int32_t MapDataSequenceable::Get(const std::string &key, MapDataType type, T &value) const 174{ 175 std::lock_guard<std::mutex> lockGuard(mtx_); 176 auto it = datas_.find(key); 177 if (it == datas_.end()) { 178 return ERROR_NO_ENTRY; 179 } 180 if (it->second.type != type) { 181 return ERROR_TYPE_ERROR; 182 } 183 auto pVal = std::any_cast<T>(&it->second.val); 184 if (pVal == nullptr) { 185 return ERROR_TYPE_ERROR; 186 } 187 value = *pVal; 188 return ERROR_OK; 189} 190 191int32_t MapDataSequenceable::Set(const std::string &key, MapDataType type, const std::any& val) 192{ 193 std::lock_guard<std::mutex> lockGuard(mtx_); 194 auto it = datas_.find(key); 195 if (it == datas_.end() && datas_.size() > BUFFER_MAX_USER_DATA_COUNT) { 196 HDI_CAMERA_LOGW("SurfaceBuffer has too many extra data, cannot save one more!!!"); 197 return ERROR_OUT_OF_RANGE; 198 } 199 datas_[key].type = type; 200 datas_[key].val = val; 201 return ERROR_OK; 202} 203 204} 205} 206} 207}