• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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