1/* 2 * Copyright (c) 2021 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 "buffer_extra_data_impl.h" 17#include <message_parcel.h> 18#include "buffer_log.h" 19 20namespace OHOS { 21namespace { 22constexpr int32_t BUFFER_EXTRA_DATA_MAGIC = 0x4567; 23} // namespace 24 25GSError BufferExtraDataImpl::ReadFromParcel(MessageParcel &parcel) 26{ 27 int32_t magic = 0; 28 if (parcel.ReadInt32(magic) == false || magic != BUFFER_EXTRA_DATA_MAGIC) { 29 BLOGW("read failed, magic: %{public}d", magic); 30 return GSERROR_INTERNAL; 31 } 32 33 int32_t size = parcel.ReadInt32(); 34 if (size > SURFACE_MAX_USER_DATA_COUNT) { 35 BLOGE("ReadFromParcel size: %{public}d", size); 36 return GSERROR_INTERNAL; 37 } 38 39 GSError ret = GSERROR_OK; 40 for (int32_t i = 0; i < size; i++) { 41 auto key = parcel.ReadString(); 42 auto type = static_cast<ExtraDataType>(parcel.ReadInt32()); 43 switch (type) { 44 case ExtraDataType::i32: { 45 ret = ExtraSet(key, type, parcel.ReadInt32()); 46 break; 47 } 48 case ExtraDataType::i64: { 49 ret = ExtraSet(key, type, parcel.ReadInt64()); 50 break; 51 } 52 case ExtraDataType::f64: { 53 ret = ExtraSet(key, type, parcel.ReadDouble()); 54 break; 55 } 56 case ExtraDataType::string: { 57 ret = ExtraSet(key, type, parcel.ReadString()); 58 break; 59 } 60 default: break; 61 } 62 63 if (ret != GSERROR_OK) { 64 BLOGE("ExtraSet failed, ret %{public}d", ret); 65 break; 66 } 67 } 68 return ret; 69} 70 71GSError BufferExtraDataImpl::WriteToParcel(MessageParcel &parcel) 72{ 73 std::lock_guard<std::mutex> lockGuard(mtx_); 74 if (!parcel.WriteInt32(BUFFER_EXTRA_DATA_MAGIC) || !parcel.WriteInt32(datas_.size())) { 75 return GSERROR_BINDER; 76 } 77 bool ipcRet = true; 78 for (const auto &[key, data] : datas_) { 79 if (!parcel.WriteString(key) || !parcel.WriteInt32(static_cast<int32_t>(data.type))) { 80 return GSERROR_BINDER; 81 } 82 switch (data.type) { 83 case ExtraDataType::i32: { 84 int32_t i32 = -1; 85 auto pVal = std::any_cast<int32_t>(&data.val); 86 if (pVal != nullptr) { 87 i32 = *pVal; 88 } 89 ipcRet = parcel.WriteInt32(i32); 90 break; 91 } 92 case ExtraDataType::i64: { 93 int64_t i64 = -1; 94 auto pVal = std::any_cast<int64_t>(&data.val); 95 if (pVal != nullptr) { 96 i64 = *pVal; 97 } 98 ipcRet = parcel.WriteInt64(i64); 99 break; 100 } 101 case ExtraDataType::f64: { 102 double f64 = -1; 103 auto pVal = std::any_cast<double>(&data.val); 104 if (pVal != nullptr) { 105 f64 = *pVal; 106 } 107 ipcRet = parcel.WriteDouble(f64); 108 break; 109 } 110 case ExtraDataType::string: { 111 std::string string = "-1"; 112 auto pVal = std::any_cast<std::string>(&data.val); 113 if (pVal != nullptr) { 114 string = *pVal; 115 } 116 ipcRet = parcel.WriteString(string); 117 break; 118 } 119 default: 120 break; 121 } 122 } 123 return ipcRet ? GSERROR_OK : GSERROR_BINDER; 124} 125 126GSError BufferExtraDataImpl::ExtraGet(const std::string &key, int32_t &value) const 127{ 128 return ExtraGet<int32_t>(key, ExtraDataType::i32, value); 129} 130 131GSError BufferExtraDataImpl::ExtraGet(const std::string &key, int64_t &value) const 132{ 133 return ExtraGet<int64_t>(key, ExtraDataType::i64, value); 134} 135 136GSError BufferExtraDataImpl::ExtraGet(const std::string &key, double &value) const 137{ 138 return ExtraGet<double>(key, ExtraDataType::f64, value); 139} 140 141GSError BufferExtraDataImpl::ExtraGet(const std::string &key, std::string &value) const 142{ 143 return ExtraGet<std::string>(key, ExtraDataType::string, value); 144} 145 146GSError BufferExtraDataImpl::ExtraSet(const std::string &key, int32_t value) 147{ 148 return ExtraSet(key, ExtraDataType::i32, value); 149} 150 151GSError BufferExtraDataImpl::ExtraSet(const std::string &key, int64_t value) 152{ 153 return ExtraSet(key, ExtraDataType::i64, value); 154} 155 156GSError BufferExtraDataImpl::ExtraSet(const std::string &key, double value) 157{ 158 return ExtraSet(key, ExtraDataType::f64, value); 159} 160 161GSError BufferExtraDataImpl::ExtraSet(const std::string &key, const std::string& value) 162{ 163 return ExtraSet(key, ExtraDataType::string, value); 164} 165 166template<class T> 167GSError BufferExtraDataImpl::ExtraGet(const std::string &key, ExtraDataType type, T &value) const 168{ 169 std::lock_guard<std::mutex> lockGuard(mtx_); 170 auto it = datas_.find(key); 171 if (it == datas_.end()) { 172 return GSERROR_NO_ENTRY; 173 } 174 if (it->second.type != type) { 175 return GSERROR_TYPE_ERROR; 176 } 177 auto pVal = std::any_cast<T>(&it->second.val); 178 if (pVal == nullptr) { 179 return GSERROR_TYPE_ERROR; 180 } 181 value = *pVal; 182 return GSERROR_OK; 183} 184 185GSError BufferExtraDataImpl::ExtraSet(const std::string &key, ExtraDataType type, const std::any& val) 186{ 187 std::lock_guard<std::mutex> lockGuard(mtx_); 188 auto it = datas_.find(key); 189 if (it == datas_.end() && datas_.size() > SURFACE_MAX_USER_DATA_COUNT) { 190 BLOGW("SurfaceBuffer has too many extra data, cannot save one more!!!"); 191 return GSERROR_OUT_OF_RANGE; 192 } 193 datas_[key].type = type; 194 datas_[key].val = val; 195 return GSERROR_OK; 196} 197} // namespace OHOS 198