1 /*
2 * Copyright (c) 2025 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 "unified_data_parameter_parse.h"
17
18 #include <cinttypes>
19
20 #include "array_wrapper.h"
21 #include "bool_wrapper.h"
22 #include "byte_wrapper.h"
23 #include "double_wrapper.h"
24 #include "int_wrapper.h"
25 #include "long_wrapper.h"
26 #include "string_wrapper.h"
27 #include "udmf_log.h"
28 #include "utils.h"
29 #include "want_params_wrapper.h"
30
31 namespace OHOS {
32 namespace UDMF {
33
34 const int8_t I32_TYPE = 0;
35 const int8_t I64_TYPE = 1;
36 const int8_t DOUBLE_TYPE = 2;
37 const int8_t BOOL_TYPE = 3;
38 const int8_t STR_TYPE = 4;
39 const int8_t UINT8_ARRAY_TYPE = 5;
40
41 constexpr int32_t NO_ERROR = 0;
42 constexpr int32_t ERR_UDMF_FAILED = -1;
43 constexpr int32_t ERR_NO_MEMORY = -2;
44
45 const int32_t NONE_VALUE = 1;
46 using WantParams = OHOS::AAFwk::WantParams;
47
ClearParametersPtr(CParameters ** ptr,int count,bool isKey)48 void ClearParametersPtr(CParameters **ptr, int count, bool isKey)
49 {
50 CParameters *p = *ptr;
51 for (int i = 0; i < count; i++) {
52 free(p[i].key);
53 free(p[i].value);
54 p[i].key = nullptr;
55 p[i].value = nullptr;
56 }
57 if (!isKey) {
58 free(p[count].key);
59 p[count].key = nullptr;
60 }
61 free(*ptr);
62 *ptr = nullptr;
63 }
64
65 // WantParameters -> CArrParameters
InnerWrapWantParamsString(WantParams & wantParams,CParameters * p)66 int32_t InnerWrapWantParamsString(WantParams &wantParams, CParameters *p)
67 {
68 auto value = wantParams.GetParam(p->key);
69 AAFwk::IString *ao = AAFwk::IString::Query(value);
70 if (ao == nullptr) {
71 LOGE("No value");
72 return NONE_VALUE;
73 }
74 std::string natValue = OHOS::AAFwk::String::Unbox(ao);
75 p->value = Utils::MallocCString(natValue);
76 p->size = static_cast<int64_t>(natValue.length()) + 1;
77 p->valueType = STR_TYPE;
78 return NO_ERROR;
79 }
80
81 template <class TBase, class T, class NativeT>
InnerWrapWantParamsT(WantParams & wantParams,CParameters * p)82 int32_t InnerWrapWantParamsT(WantParams &wantParams, CParameters *p)
83 {
84 auto value = wantParams.GetParam(p->key);
85 TBase *ao = TBase::Query(value);
86 if (ao == nullptr) {
87 LOGE("No value");
88 return NONE_VALUE;
89 }
90 NativeT natValue = T::Unbox(ao);
91 NativeT *ptr = static_cast<NativeT*>(malloc(sizeof(NativeT)));
92 if (ptr == nullptr) {
93 return ERR_NO_MEMORY;
94 }
95 *ptr = natValue;
96 p->value = static_cast<void*>(ptr);
97 p->size = sizeof(NativeT);
98 return NO_ERROR;
99 }
100
101 template <class TBase, class T, class NativeT>
InnerWrapWantParamsArrayT(sptr<AAFwk::IArray> & ao,CParameters * p)102 int32_t InnerWrapWantParamsArrayT(sptr<AAFwk::IArray> &ao, CParameters*p)
103 {
104 long size = 0;
105 if (ao->GetLength(size) != ERR_OK) {
106 LOGE("fail to get length");
107 return ERR_UDMF_FAILED;
108 }
109 if (size == 0) {
110 return ERR_UDMF_FAILED;
111 }
112 NativeT *arrP = static_cast<NativeT*>(malloc(sizeof(NativeT) * size));
113 if (arrP == nullptr) {
114 LOGE("fail to malloc");
115 return ERR_NO_MEMORY;
116 }
117 for (long i = 0; i < size; i++) {
118 sptr<AAFwk::IInterface> iface = nullptr;
119 if (ao->Get(i, iface) == ERR_OK) {
120 TBase *iValue = TBase::Query(iface);
121 if (iValue != nullptr) {
122 arrP[i] = T::Unbox(iValue);
123 }
124 }
125 }
126 p->size = size;
127 p->value = static_cast<void*>(arrP);
128 return NO_ERROR;
129 }
130
InnerSetWantParamsArrayByte(const std::string & key,const std::vector<uint8_t> & value,AAFwk::WantParams & wantParams)131 bool InnerSetWantParamsArrayByte(const std::string &key, const std::vector<uint8_t> &value,
132 AAFwk::WantParams &wantParams)
133 {
134 size_t size = value.size();
135 sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IByte);
136 if (ao != nullptr) {
137 for (size_t i = 0; i < size; i++) {
138 ao->Set(i, AAFwk::Integer::Box(value[i]));
139 }
140 wantParams.SetParam(key, ao);
141 return true;
142 } else {
143 return false;
144 }
145 }
146
InnerWrapWantParamsArray(WantParams & wantParams,sptr<AAFwk::IArray> & ao,CParameters * p)147 int32_t InnerWrapWantParamsArray(WantParams &wantParams, sptr<AAFwk::IArray> &ao, CParameters *p)
148 {
149 LOGI("%{public}s called, key=%{public}s", __func__, p->key);
150 if (AAFwk::Array::IsByteArray(ao)) {
151 p->valueType = UINT8_ARRAY_TYPE;
152 return InnerWrapWantParamsArrayT<AAFwk::IByte, AAFwk::Byte, uint8_t>(ao, p);
153 }
154 return ERR_UDMF_FAILED;
155 }
156
SetDataParameters(CArrParameters parameters,WantParams & wantP)157 void SetDataParameters(CArrParameters parameters, WantParams &wantP)
158 {
159 for (int i = 0; i < parameters.size; i++) {
160 auto head = parameters.head + i;
161 auto key = std::string(head->key);
162 if (head->valueType == I32_TYPE) {
163 wantP.SetParam(key, OHOS::AAFwk::Integer::Box(*static_cast<int32_t*>(head->value)));
164 } else if (head->valueType == I64_TYPE) {
165 wantP.SetParam(key, OHOS::AAFwk::Integer::Box(*static_cast<int64_t*>(head->value)));
166 } else if (head->valueType == DOUBLE_TYPE) {
167 wantP.SetParam(key, OHOS::AAFwk::Double::Box(*static_cast<double*>(head->value)));
168 } else if (head->valueType == STR_TYPE) {
169 wantP.SetParam(key, OHOS::AAFwk::String::Box(std::string(static_cast<char*>(head->value))));
170 } else if (head->valueType == BOOL_TYPE) {
171 wantP.SetParam(key, OHOS::AAFwk::Boolean::Box(*static_cast<bool*>(head->value)));
172 } else if (head->valueType == UINT8_ARRAY_TYPE) {
173 uint8_t *intArr = static_cast<uint8_t*>(head->value);
174 std::vector<uint8_t> intVec(intArr, intArr + head->size);
175 InnerSetWantParamsArrayByte(key, intVec, wantP);
176 } else {
177 LOGE("wrong type!");
178 }
179 }
180 }
181
ParseParameters(WantParams & wantP,CArrParameters & parameters,int32_t & code)182 void ParseParameters(WantParams &wantP, CArrParameters ¶meters, int32_t &code)
183 {
184 if (code != NO_ERROR) {
185 return;
186 }
187 std::map<std::string, sptr<OHOS::AAFwk::IInterface>> paramsMap = wantP.GetParams();
188 int count = 0;
189 auto size = static_cast<int64_t>(paramsMap.size());
190 if (size == 0) {
191 return;
192 }
193 parameters.head = static_cast<CParameters*>(malloc(sizeof(CParameters) * size));
194 if (parameters.head == nullptr) {
195 code = ERR_NO_MEMORY;
196 return;
197 }
198 parameters.size = size;
199 for (auto iter = paramsMap.begin(); iter != paramsMap.end(); iter++) {
200 auto ptr = parameters.head + count;
201 ptr->key = Utils::MallocCString(iter->first);
202 if (ptr->key == nullptr) {
203 code = ERR_NO_MEMORY;
204 return ClearParametersPtr(¶meters.head, count, true);
205 }
206 ptr->value = nullptr;
207 ptr->size = 0;
208 if (AAFwk::IString::Query(iter->second) != nullptr) {
209 code = InnerWrapWantParamsString(wantP, ptr);
210 } else if (AAFwk::IBoolean::Query(iter->second) != nullptr) {
211 ptr->valueType = BOOL_TYPE;
212 code = InnerWrapWantParamsT<AAFwk::IBoolean, AAFwk::Boolean, bool>(wantP, ptr);
213 } else if (AAFwk::IInteger::Query(iter->second) != nullptr) {
214 ptr->valueType = I32_TYPE;
215 code = InnerWrapWantParamsT<AAFwk::IInteger, AAFwk::Integer, int>(wantP, ptr);
216 } else if (AAFwk::ILong::Query(iter->second) != nullptr) {
217 ptr->valueType = I64_TYPE;
218 code = InnerWrapWantParamsT<AAFwk::ILong, AAFwk::Long, long>(wantP, ptr);
219 } else if (AAFwk::IDouble::Query(iter->second) != nullptr) {
220 ptr->valueType = DOUBLE_TYPE;
221 code = InnerWrapWantParamsT<AAFwk::IDouble, AAFwk::Double, double>(wantP, ptr);
222 } else if (AAFwk::IArray::Query(iter->second) != nullptr) {
223 AAFwk::IArray *ao = AAFwk::IArray::Query(iter->second);
224 sptr<AAFwk::IArray> array(ao);
225 code = InnerWrapWantParamsArray(wantP, array, ptr);
226 }
227 if (code == ERR_NO_MEMORY || code == ERR_UDMF_FAILED) {
228 return ClearParametersPtr(¶meters.head, count, false);
229 }
230 count++;
231 }
232 }
233 } // namespace UDMF
234 } // namespace OHOS