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