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
20 namespace OHOS {
21 namespace {
22 constexpr int32_t BUFFER_EXTRA_DATA_MAGIC = 0x4567;
23 } // namespace
24
ReadFromParcel(MessageParcel & parcel)25 GSError 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
WriteToParcel(MessageParcel & parcel)71 GSError BufferExtraDataImpl::WriteToParcel(MessageParcel &parcel)
72 {
73 std::lock_guard<std::mutex> lockGuard(mtx_);
74 parcel.WriteInt32(BUFFER_EXTRA_DATA_MAGIC);
75 parcel.WriteInt32(datas_.size());
76 for (const auto &[key, data] : datas_) {
77 parcel.WriteString(key);
78 parcel.WriteInt32(static_cast<int32_t>(data.type));
79 switch (data.type) {
80 case ExtraDataType::i32: {
81 int32_t i32 = -1;
82 auto pVal = std::any_cast<int32_t>(&data.val);
83 if (pVal != nullptr) {
84 i32 = *pVal;
85 }
86 parcel.WriteInt32(i32);
87 break;
88 }
89 case ExtraDataType::i64: {
90 int64_t i64 = -1;
91 auto pVal = std::any_cast<int64_t>(&data.val);
92 if (pVal != nullptr) {
93 i64 = *pVal;
94 }
95 parcel.WriteInt64(i64);
96 break;
97 }
98 case ExtraDataType::f64: {
99 double f64 = -1;
100 auto pVal = std::any_cast<double>(&data.val);
101 if (pVal != nullptr) {
102 f64 = *pVal;
103 }
104 parcel.WriteDouble(f64);
105 break;
106 }
107 case ExtraDataType::string: {
108 std::string string = "-1";
109 auto pVal = std::any_cast<std::string>(&data.val);
110 if (pVal != nullptr) {
111 string = *pVal;
112 }
113 parcel.WriteString(string);
114 break;
115 }
116 default:
117 break;
118 }
119 }
120 return GSERROR_OK;
121 }
122
ExtraGet(const std::string & key,int32_t & value) const123 GSError BufferExtraDataImpl::ExtraGet(const std::string &key, int32_t &value) const
124 {
125 return ExtraGet<int32_t>(key, ExtraDataType::i32, value);
126 }
127
ExtraGet(const std::string & key,int64_t & value) const128 GSError BufferExtraDataImpl::ExtraGet(const std::string &key, int64_t &value) const
129 {
130 return ExtraGet<int64_t>(key, ExtraDataType::i64, value);
131 }
132
ExtraGet(const std::string & key,double & value) const133 GSError BufferExtraDataImpl::ExtraGet(const std::string &key, double &value) const
134 {
135 return ExtraGet<double>(key, ExtraDataType::f64, value);
136 }
137
ExtraGet(const std::string & key,std::string & value) const138 GSError BufferExtraDataImpl::ExtraGet(const std::string &key, std::string &value) const
139 {
140 return ExtraGet<std::string>(key, ExtraDataType::string, value);
141 }
142
ExtraSet(const std::string & key,int32_t value)143 GSError BufferExtraDataImpl::ExtraSet(const std::string &key, int32_t value)
144 {
145 return ExtraSet(key, ExtraDataType::i32, value);
146 }
147
ExtraSet(const std::string & key,int64_t value)148 GSError BufferExtraDataImpl::ExtraSet(const std::string &key, int64_t value)
149 {
150 return ExtraSet(key, ExtraDataType::i64, value);
151 }
152
ExtraSet(const std::string & key,double value)153 GSError BufferExtraDataImpl::ExtraSet(const std::string &key, double value)
154 {
155 return ExtraSet(key, ExtraDataType::f64, value);
156 }
157
ExtraSet(const std::string & key,const std::string & value)158 GSError BufferExtraDataImpl::ExtraSet(const std::string &key, const std::string& value)
159 {
160 return ExtraSet(key, ExtraDataType::string, value);
161 }
162
163 template<class T>
ExtraGet(const std::string & key,ExtraDataType type,T & value) const164 GSError BufferExtraDataImpl::ExtraGet(const std::string &key, ExtraDataType type, T &value) const
165 {
166 std::lock_guard<std::mutex> lockGuard(mtx_);
167 auto it = datas_.find(key);
168 if (it == datas_.end()) {
169 return GSERROR_NO_ENTRY;
170 }
171 if (it->second.type != type) {
172 return GSERROR_TYPE_ERROR;
173 }
174 auto pVal = std::any_cast<T>(&it->second.val);
175 if (pVal == nullptr) {
176 return GSERROR_TYPE_ERROR;
177 }
178 value = *pVal;
179 return GSERROR_OK;
180 }
181
ExtraSet(const std::string & key,ExtraDataType type,const std::any & val)182 GSError BufferExtraDataImpl::ExtraSet(const std::string &key, ExtraDataType type, const std::any& val)
183 {
184 std::lock_guard<std::mutex> lockGuard(mtx_);
185 auto it = datas_.find(key);
186 if (it == datas_.end() && datas_.size() > SURFACE_MAX_USER_DATA_COUNT) {
187 BLOGW("SurfaceBuffer has too many extra data, cannot save one more!!!");
188 return GSERROR_OUT_OF_RANGE;
189 }
190 datas_[key].type = type;
191 datas_[key].val = val;
192 return GSERROR_OK;
193 }
194 } // namespace OHOS
195