1 /*
2 * Copyright (c) 2021-2022 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 "array_wrapper.h"
17 #include <cstdint>
18 #include "ability_base_log_wrapper.h"
19 #include "bool_wrapper.h"
20 #include "zchar_wrapper.h"
21 #include "byte_wrapper.h"
22 #include "double_wrapper.h"
23 #include "float_wrapper.h"
24 #include "int_wrapper.h"
25 #include "long_wrapper.h"
26 #include "short_wrapper.h"
27 #include "string_wrapper.h"
28 #include "want_params_wrapper.h"
29
30 namespace OHOS {
31 namespace AAFwk {
32 IINTERFACE_IMPL_1(Array, Object, IArray);
33
34 constexpr int32_t MAX_ARRAY_SIZE = 50 * 1024 * 1024;
35
Array(long size,const InterfaceID & id)36 Array::Array(long size, const InterfaceID &id) : typeId_(id)
37 {
38 size_ = size > MAX_ARRAY_SIZE ? MAX_ARRAY_SIZE : size;
39 for (long i = 0; i < size_; i++) {
40 values_.push_back(nullptr);
41 }
42 }
43
Get(long index,sptr<IInterface> & value)44 ErrCode Array::Get(long index, /* [in] */
45 sptr<IInterface> &value) /* [out] */
46 {
47 if (index < 0 || index >= size_) {
48 value = nullptr;
49 return ERR_INVALID_VALUE;
50 }
51 value = values_[index];
52 return ERR_OK;
53 }
54
GetLength(long & size)55 ErrCode Array::GetLength(long &size) /* [out] */
56 {
57 size = size_;
58 if (size_ < 0 || size_ > MAX_ARRAY_SIZE) {
59 return ERR_INVALID_VALUE;
60 }
61 return ERR_OK;
62 }
63
GetType(InterfaceID & id)64 ErrCode Array::GetType(InterfaceID &id) /* [out] */
65 {
66 VALIDATE_NOT_NULL(&id);
67
68 id = typeId_;
69 return ERR_OK;
70 }
71
Set(long index,IInterface * value)72 ErrCode Array::Set(long index, /* [in] */
73 IInterface *value) /* [in] */
74 {
75 if (index < 0 || index >= size_) {
76 return ERR_INVALID_VALUE;
77 }
78 values_[index] = value;
79 return ERR_OK;
80 }
81
Equals(IObject & other)82 bool Array::Equals(IObject &other) /* [in] */
83 {
84 Array *otherObj = static_cast<Array *>(IArray::Query(&other));
85 if (otherObj == nullptr) {
86 return false;
87 }
88
89 if (this == otherObj) {
90 return true;
91 }
92
93 if (otherObj->size_ != size_ || otherObj->typeId_ != typeId_) {
94 return false;
95 }
96
97 if (size_ < 0 || size_ > INT_MAX) {
98 return false;
99 }
100
101 for (long i = 0; i < size_; i++) {
102 if (!Object::Equals(*(values_[i].GetRefPtr()), *(otherObj->values_[i].GetRefPtr()))) {
103 return false;
104 }
105 }
106 return true;
107 }
108
ToString()109 std::string Array::ToString()
110 {
111 std::string result;
112 if (typeId_ == g_IID_IString) {
113 result += String::SIGNATURE;
114 } else if (typeId_ == g_IID_IBoolean) {
115 result += Boolean::SIGNATURE;
116 } else if (typeId_ == g_IID_IByte) {
117 result += Byte::SIGNATURE;
118 } else if (typeId_ == g_IID_IShort) {
119 result += Short::SIGNATURE;
120 } else if (typeId_ == g_IID_IInteger) {
121 result += Integer::SIGNATURE;
122 } else if (typeId_ == g_IID_ILong) {
123 result += Long::SIGNATURE;
124 } else if (typeId_ == g_IID_IFloat) {
125 result += Float::SIGNATURE;
126 } else if (typeId_ == g_IID_IDouble) {
127 result += Double::SIGNATURE;
128 } else if (typeId_ == g_IID_IArray) {
129 result += Array::SIGNATURE;
130 } else if (typeId_ == g_IID_IChar) {
131 result += Char::SIGNATURE;
132 } else if (typeId_ == g_IID_IWantParams) {
133 result += WantParamWrapper::SIGNATURE;
134 } else {
135 result += "";
136 }
137
138 result += std::to_string(size_) + "{";
139 for (long i = 0; i < size_; i++) {
140 result += Object::ToString(*(values_[i].GetRefPtr()));
141 if (i < size_ - 1) {
142 result += ",";
143 }
144 }
145 result += "}";
146 return result;
147 }
148
ParseString(const std::string & values,long size)149 sptr<IArray> Array::ParseString(const std::string &values, long size)
150 {
151 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IString);
152 if (array != nullptr) {
153 auto func = [](const std::string &str) -> sptr<IInterface> { return String::Parse(str); };
154 ParseElement(array, func, values, size);
155 }
156 return array;
157 }
158
ParseBoolean(const std::string & values,long size)159 sptr<IArray> Array::ParseBoolean(const std::string &values, long size)
160 {
161 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IBoolean);
162 if (array != nullptr) {
163 auto func = [](const std::string &str) -> sptr<IInterface> { return Boolean::Parse(str); };
164 ParseElement(array, func, values, size);
165 }
166 return array;
167 }
168
ParseByte(const std::string & values,long size)169 sptr<IArray> Array::ParseByte(const std::string &values, long size)
170 {
171 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IByte);
172 if (array != nullptr) {
173 auto func = [](const std::string &str) -> sptr<IInterface> { return Byte::Parse(str); };
174 ParseElement(array, func, values, size);
175 }
176 return array;
177 }
178
ParseShort(const std::string & values,long size)179 sptr<IArray> Array::ParseShort(const std::string &values, long size)
180 {
181 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IShort);
182 if (array != nullptr) {
183 auto func = [](const std::string &str) -> sptr<IInterface> { return Short::Parse(str); };
184 ParseElement(array, func, values, size);
185 }
186 return array;
187 }
188
ParseInteger(const std::string & values,long size)189 sptr<IArray> Array::ParseInteger(const std::string &values, long size)
190 {
191 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IInteger);
192 if (array != nullptr) {
193 auto func = [](const std::string &str) -> sptr<IInterface> { return Integer::Parse(str); };
194 ParseElement(array, func, values, size);
195 }
196 return array;
197 }
198
ParseLong(const std::string & values,long size)199 sptr<IArray> Array::ParseLong(const std::string &values, long size)
200 {
201 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_ILong);
202 if (array != nullptr) {
203 auto func = [](const std::string &str) -> sptr<IInterface> { return Long::Parse(str); };
204 ParseElement(array, func, values, size);
205 }
206 return array;
207 }
208
ParseFloat(const std::string & values,long size)209 sptr<IArray> Array::ParseFloat(const std::string &values, long size)
210 {
211 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IFloat);
212 if (array != nullptr) {
213 auto func = [](const std::string &str) -> sptr<IInterface> { return Float::Parse(str); };
214 ParseElement(array, func, values, size);
215 }
216 return array;
217 }
218
ParseDouble(const std::string & values,long size)219 sptr<IArray> Array::ParseDouble(const std::string &values, long size)
220 {
221 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IDouble);
222 if (array != nullptr) {
223 auto func = [](const std::string &str) -> sptr<IInterface> { return Double::Parse(str); };
224 ParseElement(array, func, values, size);
225 }
226 return array;
227 }
ParseChar(const std::string & values,long size)228 sptr<IArray> Array::ParseChar(const std::string &values, long size)
229 {
230 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IChar);
231 if (array != nullptr) {
232 auto func = [](const std::string &str) -> sptr<IInterface> { return Char::Parse(str); };
233 ParseElement(array, func, values, size);
234 }
235 return array;
236 }
ParseArray(const std::string & values,long size)237 sptr<IArray> Array::ParseArray(const std::string &values, long size)
238 {
239 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IArray);
240 if (array != nullptr) {
241 auto func = [](const std::string &str) -> sptr<IInterface> { return Array::Parse(str); };
242 ParseElement(array, func, values, size);
243 }
244 return array;
245 }
246
ParseWantParams(const std::string & values,long size)247 sptr<IArray> Array::ParseWantParams(const std::string &values, long size)
248 {
249 sptr<IArray> array = sptr<Array>::MakeSptr(size, g_IID_IWantParams);
250 if (array != nullptr) {
251 auto func = [](const std::string &str) -> sptr<IInterface> { return WantParamWrapper::Parse(str); };
252 ParseElement(array, func, values, size);
253 }
254 return array;
255 }
256
Parse(const std::string & arrayStr)257 sptr<IArray> Array::Parse(const std::string &arrayStr) /* [in] */
258 {
259 char signature = arrayStr[0];
260 if (signature != String::SIGNATURE && signature != Boolean::SIGNATURE && signature != Byte::SIGNATURE &&
261 signature != Short::SIGNATURE && signature != Integer::SIGNATURE && signature != Long::SIGNATURE &&
262 signature != Float::SIGNATURE && signature != Double::SIGNATURE && signature != Array::SIGNATURE &&
263 signature != Char::SIGNATURE && signature != WantParamWrapper::SIGNATURE) {
264 return nullptr;
265 }
266
267 std::size_t idx = arrayStr.find("{");
268 if (idx == std::string::npos) {
269 return nullptr;
270 }
271 if (arrayStr[arrayStr.length() - 1] != '}') {
272 return nullptr;
273 }
274 long size = 0;
275 try {
276 size = std::stol(arrayStr.substr(1, idx - 1));
277 } catch (...) {
278 ABILITYBASE_LOGE("failed to convert to long: %{public}s", arrayStr.substr(1, idx - 1).c_str());
279 return nullptr;
280 }
281
282 idx += 1;
283 std::string values = arrayStr.substr(idx, arrayStr.length() - 1 - idx);
284
285 switch (signature) {
286 case Char::SIGNATURE:
287 return ParseChar(values, size);
288 case String::SIGNATURE:
289 return ParseString(values, size);
290 case Boolean::SIGNATURE:
291 return ParseBoolean(values, size);
292 case Byte::SIGNATURE:
293 return ParseByte(values, size);
294 case Short::SIGNATURE:
295 return ParseShort(values, size);
296 case Integer::SIGNATURE:
297 return ParseInteger(values, size);
298 case Long::SIGNATURE:
299 return ParseLong(values, size);
300 case Float::SIGNATURE:
301 return ParseFloat(values, size);
302 case Double::SIGNATURE:
303 return ParseDouble(values, size);
304 case Array::SIGNATURE:
305 return ParseArray(values, size);
306 case WantParamWrapper::SIGNATURE:
307 return ParseWantParams(values, size);
308 default:
309 break;
310 }
311 return nullptr;
312 }
313
ParseElement(IArray * array,std::function<sptr<IInterface> (std::string &)> func,const std::string & values,long size)314 void Array::ParseElement(IArray *array, /* [in] */
315 std::function<sptr<IInterface>(std::string &)> func, /* [in] */
316 const std::string &values, /* [in] */
317 long size) /* [in] */
318 {
319 if (array == nullptr) {
320 return;
321 }
322
323 std::size_t beginIdx = 0;
324 std::size_t endIdx;
325 for (long i = 0; i < size; i++) {
326 std::string valueStr;
327 if (i < size - 1) {
328 endIdx = values.find(",", beginIdx);
329 if (endIdx == std::string::npos) {
330 valueStr = values.substr(beginIdx);
331 } else {
332 valueStr = values.substr(beginIdx, endIdx - beginIdx);
333 beginIdx = endIdx + 1;
334 }
335 } else {
336 valueStr = values.substr(beginIdx, values.length() - beginIdx);
337 }
338 array->Set(i, func(valueStr));
339 }
340 }
341
IsBooleanArray(IArray * array)342 bool Array::IsBooleanArray(IArray *array) /* [in] */
343 {
344 InterfaceID typeId;
345 array->GetType(typeId);
346 return typeId == g_IID_IBoolean;
347 }
348
IsCharArray(IArray * array)349 bool Array::IsCharArray(IArray *array) /* [in] */
350 {
351 InterfaceID typeId;
352 array->GetType(typeId);
353 return typeId == g_IID_IChar;
354 }
355
IsByteArray(IArray * array)356 bool Array::IsByteArray(IArray *array) /* [in] */
357 {
358 InterfaceID typeId;
359 array->GetType(typeId);
360 return typeId == g_IID_IByte;
361 }
362
IsShortArray(IArray * array)363 bool Array::IsShortArray(IArray *array) /* [in] */
364 {
365 InterfaceID typeId;
366 array->GetType(typeId);
367 return typeId == g_IID_IShort;
368 }
369
IsIntegerArray(IArray * array)370 bool Array::IsIntegerArray(IArray *array) /* [in] */
371 {
372 InterfaceID typeId;
373 array->GetType(typeId);
374 return typeId == g_IID_IInteger;
375 }
376
IsLongArray(IArray * array)377 bool Array::IsLongArray(IArray *array) /* [in] */
378 {
379 InterfaceID typeId;
380 array->GetType(typeId);
381 return typeId == g_IID_ILong;
382 }
383
IsFloatArray(IArray * array)384 bool Array::IsFloatArray(IArray *array) /* [in] */
385 {
386 InterfaceID typeId;
387 array->GetType(typeId);
388 return typeId == g_IID_IFloat;
389 }
390
IsDoubleArray(IArray * array)391 bool Array::IsDoubleArray(IArray *array) /* [in] */
392 {
393 InterfaceID typeId;
394 array->GetType(typeId);
395 return typeId == g_IID_IDouble;
396 }
397
IsStringArray(IArray * array)398 bool Array::IsStringArray(IArray *array) /* [in] */
399 {
400 InterfaceID typeId;
401 array->GetType(typeId);
402 return typeId == g_IID_IString;
403 }
404
IsWantParamsArray(IArray * array)405 bool Array::IsWantParamsArray(IArray *array) /* [in] */
406 {
407 InterfaceID typeId;
408 array->GetType(typeId);
409 return typeId == g_IID_IWantParams;
410 }
411
ForEach(IArray * array,std::function<void (IInterface *)> func)412 void Array::ForEach(IArray *array, /* [in] */
413 std::function<void(IInterface *)> func) /* [in] */
414 {
415 long size;
416 array->GetLength(size);
417 for (long i = 0; i < size; i++) {
418 sptr<IInterface> object;
419 array->Get(i, object);
420 func(object);
421 }
422 }
423 } // namespace AAFwk
424 } // namespace OHOS
425