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