• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     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 
ExtraGet(const std::string & key,int32_t & value) const126 GSError BufferExtraDataImpl::ExtraGet(const std::string &key, int32_t &value) const
127 {
128     return ExtraGet<int32_t>(key, ExtraDataType::i32, value);
129 }
130 
ExtraGet(const std::string & key,int64_t & value) const131 GSError BufferExtraDataImpl::ExtraGet(const std::string &key, int64_t &value) const
132 {
133     return ExtraGet<int64_t>(key, ExtraDataType::i64, value);
134 }
135 
ExtraGet(const std::string & key,double & value) const136 GSError BufferExtraDataImpl::ExtraGet(const std::string &key, double &value) const
137 {
138     return ExtraGet<double>(key, ExtraDataType::f64, value);
139 }
140 
ExtraGet(const std::string & key,std::string & value) const141 GSError BufferExtraDataImpl::ExtraGet(const std::string &key, std::string &value) const
142 {
143     return ExtraGet<std::string>(key, ExtraDataType::string, value);
144 }
145 
ExtraSet(const std::string & key,int32_t value)146 GSError BufferExtraDataImpl::ExtraSet(const std::string &key, int32_t value)
147 {
148     return ExtraSet(key, ExtraDataType::i32, value);
149 }
150 
ExtraSet(const std::string & key,int64_t value)151 GSError BufferExtraDataImpl::ExtraSet(const std::string &key, int64_t value)
152 {
153     return ExtraSet(key, ExtraDataType::i64, value);
154 }
155 
ExtraSet(const std::string & key,double value)156 GSError BufferExtraDataImpl::ExtraSet(const std::string &key, double value)
157 {
158     return ExtraSet(key, ExtraDataType::f64, value);
159 }
160 
ExtraSet(const std::string & key,const std::string & value)161 GSError BufferExtraDataImpl::ExtraSet(const std::string &key, const std::string& value)
162 {
163     return ExtraSet(key, ExtraDataType::string, value);
164 }
165 
166 template<class T>
ExtraGet(const std::string & key,ExtraDataType type,T & value) const167 GSError 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 
ExtraSet(const std::string & key,ExtraDataType type,const std::any & val)185 GSError 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