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>
19 namespace OHOS {
20 namespace HDI {
21 namespace Camera {
22 namespace V1_0 {
23 constexpr int32_t BUFFER_DATA_MAGIC = 0x4567;
24 constexpr int32_t BUFFER_MAX_USER_DATA_COUNT = 1000;
25
26 enum 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
Unmarshalling(Parcel & parcel)40 sptr<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
Marshalling(Parcel & parcel) const87 bool 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
Get(const std::string & key,int32_t & value) const132 int32_t MapDataSequenceable::Get(const std::string &key, int32_t &value) const
133 {
134 return Get<int32_t>(key, MapDataType::I32, value);
135 }
136
Get(const std::string & key,int64_t & value) const137 int32_t MapDataSequenceable::Get(const std::string &key, int64_t &value) const
138 {
139 return Get<int64_t>(key, MapDataType::I64, value);
140 }
141
Get(const std::string & key,double & value) const142 int32_t MapDataSequenceable::Get(const std::string &key, double &value) const
143 {
144 return Get<double>(key, MapDataType::F64, value);
145 }
146
Get(const std::string & key,std::string & value) const147 int32_t MapDataSequenceable::Get(const std::string &key, std::string &value) const
148 {
149 return Get<std::string>(key, MapDataType::STRING, value);
150 }
151
Set(const std::string & key,int32_t value)152 int32_t MapDataSequenceable::Set(const std::string &key, int32_t value)
153 {
154 return Set(key, MapDataType::I32, value);
155 }
156
Set(const std::string & key,int64_t value)157 int32_t MapDataSequenceable::Set(const std::string &key, int64_t value)
158 {
159 return Set(key, MapDataType::I64, value);
160 }
161
Set(const std::string & key,double value)162 int32_t MapDataSequenceable::Set(const std::string &key, double value)
163 {
164 return Set(key, MapDataType::F64, value);
165 }
166
Set(const std::string & key,const std::string & value)167 int32_t MapDataSequenceable::Set(const std::string &key, const std::string& value)
168 {
169 return Set(key, MapDataType::STRING, value);
170 }
171
172 template<class T>
Get(const std::string & key,MapDataType type,T & value) const173 int32_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
Set(const std::string & key,MapDataType type,const std::any & val)191 int32_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 }