• 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 "pac_map.h"
17 
18 #include <cstdlib>
19 #include <iomanip>
20 #include <iostream>
21 #include <json/json.h>
22 #include <memory>
23 #include <regex>
24 #include <sstream>
25 #include <string>
26 
27 #include "bool_wrapper.h"
28 #include "byte_wrapper.h"
29 #include "double_wrapper.h"
30 #include "float_wrapper.h"
31 #include "int_wrapper.h"
32 #include "long_wrapper.h"
33 #include "short_wrapper.h"
34 #include "string_wrapper.h"
35 #include "user_object_base.h"
36 #include "user_object_wrapper.h"
37 #include "zchar_wrapper.h"
38 #include "array_wrapper.h"
39 #include "parcel_macro_base.h"
40 #include "string_ex.h"
41 
42 using IUserObject = OHOS::AAFwk::IUserObject;
43 using InterfaceID = OHOS::AAFwk::InterfaceID;
44 using Short = OHOS::AAFwk::Short;
45 using Integer = OHOS::AAFwk::Integer;
46 using Long = OHOS::AAFwk::Long;
47 using Boolean = OHOS::AAFwk::Boolean;
48 using Char = OHOS::AAFwk::Char;
49 using Byte = OHOS::AAFwk::Byte;
50 using Float = OHOS::AAFwk::Float;
51 using Double = OHOS::AAFwk::Double;
52 using String = OHOS::AAFwk::String;
53 
54 namespace OHOS {
55 namespace AppExecFwk {
56 namespace {
57 const int MAX_ARRAY_ALLOW_SIZE = 1024;
58 const int FLOAT_PRECISION = 7;
59 const int DOUBLE_PRECISION = 17;
60 const std::regex NUMBER_REGEX("^[-+]?([0-9]+)([.]([0-9]+))?$");
61 };  // namespace
62 
63 #define PAC_MAP_PUT_VALUE(id, iid, key, value, mapList) \
64     do {                                                \
65         RemoveData(mapList, key);                       \
66         sptr<iid> val = id::Box(value);                 \
67         (mapList).emplace(key, val);                    \
68     } while (0);
69 
70 #define PAC_MAP_GET_VALUE(id, key, value, mapList, defaultValue)      \
71     do {                                                              \
72         auto it = (mapList).find(key);                                \
73         if (it != (mapList).end()) {                                  \
74             if (id::Query(it->second.GetRefPtr()) != nullptr) {       \
75                 sptr<id> idValue = id::Query(it->second.GetRefPtr()); \
76                 value retVal = 0;                                     \
77                 idValue->GetValue(retVal);                            \
78                 return retVal;                                        \
79             }                                                         \
80             return defaultValue;                                      \
81         }                                                             \
82     } while (0);
83 
84 #define PAC_MAP_GET_STRING_VALUE(id, key, value, mapList, defaultValue) \
85     do {                                                                \
86         auto it = (mapList).find(key);                                  \
87         if (it != (mapList).end()) {                                    \
88             if (id::Query((it)->second.GetRefPtr()) != nullptr) {       \
89                 sptr<id> idValue = id::Query(it->second.GetRefPtr());   \
90                 value retVal;                                           \
91                 idValue->GetString(retVal);                             \
92                 return retVal;                                          \
93             }                                                           \
94             return defaultValue;                                        \
95         }                                                               \
96     } while (0);
97 
98 #define PAC_MAP_ADD_ARRAY(id, key, value, mapList)                                           \
99     do {                                                                                     \
100         RemoveData(mapList, key);                                                            \
101         std::size_t size = (value).size();                                                     \
102         sptr<IArray> ao = new Array(size, g_IID_##I##id);                                    \
103         for (std::size_t i = 0; i < size; i++) {                                             \
104             ao->Set(i, id::Box((value)[i]));                                                 \
105         }                                                                                    \
106         (mapList).emplace(key, sptr<IInterface>(static_cast<IInterface *>(ao.GetRefPtr()))); \
107     } while (0);
108 
109 #define GET_PAC_MAP_ARRAY(id, mapList, key, value)                                 \
110     do {                                                                           \
111         auto it = (mapList).find(key);                                             \
112         if (it != (mapList).end()) {                                               \
113             if (IArray::Query(it->second.GetRefPtr()) != nullptr) {                \
114                 if (Array::Is##id##Array(IArray::Query(it->second.GetRefPtr()))) { \
115                     auto func = [ & ](IInterface * object) {                       \
116                         if (I##id::Query(object) != nullptr) {                     \
117                             (value).push_back(id::Unbox(I##id::Query(object)));    \
118                         }                                                          \
119                     };                                                             \
120                     Array::ForEach(IArray::Query(it->second.GetRefPtr()), func);   \
121                 }                                                                  \
122             }                                                                      \
123         }                                                                          \
124     } while (0);
125 
126 template<typename IClassName, typename baseValue>
GetBaseDataValue(OHOS::AAFwk::IInterface * baseObj,Json::Value & json,int type)127 static void GetBaseDataValue(OHOS::AAFwk::IInterface *baseObj, Json::Value &json, int type)
128 {
129     IClassName *data = IClassName::Query(baseObj);
130     baseValue val = 0;
131     if (data != nullptr) {
132         data->GetValue(val);
133     }
134     json["data"] = val;
135     json["type"] = type;
136 }
137 #define GET_BASE_DATA_VALUE(id, it, value, json, type)        \
138     do {                                                      \
139         I##id *data = I##id::Query((it)->second.GetRefPtr()); \
140         value val = 0;                                        \
141         data->GetValue(val);                                  \
142         (json)["data"] = val;                                 \
143         (json)["type"] = type;                                \
144     } while (0);
145 
146 template<typename RawType>
147 static std::string RawTypeToString(const RawType value, unsigned int precisionAfterPoint);
148 
149 template<typename IClassName, typename ClassName, typename baseValue>
GetBaseFloatDoubleDataValue(OHOS::AAFwk::IInterface * baseObj,Json::Value & json,int type,int precision)150 static void GetBaseFloatDoubleDataValue(OHOS::AAFwk::IInterface *baseObj, Json::Value &json, int type, int precision)
151 {
152     IClassName *data = IClassName::Query(baseObj);
153     if (data != nullptr) {
154         baseValue val = ClassName::Unbox(data);
155         json["data"] = RawTypeToString<baseValue>(val, precision);
156         json["type"] = type;
157     }
158 }
159 #define GET_BASE_FLOAT_DOUBLE_DATA_VALUE(iid, id, it, value, precision, json, type) \
160     do {                                                                            \
161         iid *data = iid::Query((it)->second);                                       \
162         if (data != nullptr) {                                                      \
163             value val = id::Unbox(data);                                            \
164             (json)["data"] = RawTypeToString<value>(val, precision);                \
165             (json)["type"] = type;                                                  \
166         }                                                                           \
167     } while (0);
168 
169 #define GET_BASE_STRING_DATA_VALUE(id, it, value, json, type) \
170     do {                                                      \
171         I##id *data = I##id::Query((it)->second.GetRefPtr()); \
172         value val;                                            \
173         data->GetString(val);                                 \
174         (json)["data"] = val;                                 \
175         (json)["type"] = type;                                \
176     } while (0);
177 
178 #define GET_BASE_LONG_DATA_VALUE(id, it, value, json, type)   \
179     do {                                                      \
180         I##id *data = I##id::Query((it)->second.GetRefPtr()); \
181         value val = 0;                                        \
182         data->GetValue(val);                                  \
183         (json)["data"] = std::to_string(val);                 \
184         (json)["type"] = type;                                \
185     } while (0);
186 
187 template<typename IClassName, typename ClassName, typename valueType>
PacmapGetArrayVal(OHOS::AAFwk::IInterface * ao,std::vector<valueType> & array)188 static void PacmapGetArrayVal(OHOS::AAFwk::IInterface *ao, std::vector<valueType> &array)
189 {
190     if (ao == nullptr) {
191         return;
192     }
193     if (IArray::Query(ao) != nullptr) {
194         auto func = [&array](AAFwk::IInterface *object) {
195             if (object != nullptr) {
196                 IClassName *value = IClassName::Query(object);
197                 if (value != nullptr) {
198                     array.emplace_back(ClassName::Unbox(value));
199                 }
200             }
201         };
202         Array::ForEach(IArray::Query(ao), func);
203     }
204 }
205 #define PAC_MAP_GET_ARRAY_VAL(idInterface, id, ao, array)                  \
206     do {                                                                   \
207         if ((ao) == nullptr) {                                             \
208             return false;                                                  \
209         }                                                                  \
210         if (IArray::Query((it)->second.GetRefPtr()) != nullptr) {          \
211             auto func = [ & ](AAFwk::IInterface * object) {                \
212                 if (object != nullptr) {                                   \
213                     idInterface *value = idInterface::Query(object);       \
214                     if (value != nullptr) {                                \
215                         (array).emplace_back(id::Unbox(value));            \
216                     }                                                      \
217                 }                                                          \
218             };                                                             \
219             Array::ForEach(IArray::Query((it)->second.GetRefPtr()), func); \
220         }                                                                  \
221     } while (0);
222 
223 using namespace OHOS::AAFwk;
224 IINTERFACE_IMPL_1(PacMap, Object, IPacMap);
225 /**
226  * @brief A replication structure with deep copy.
227  */
PacMap(const PacMap & other)228 PacMap::PacMap(const PacMap &other)
229 {
230     std::lock_guard<std::mutex> mLock(mapLock_);
231     dataList_.clear();
232     std::string str = MapListToString(other.dataList_);
233     StringToMapList(str, dataList_);
234 }
235 
~PacMap()236 PacMap::~PacMap()
237 {
238     Clear();
239 }
240 
241 /**
242  * @brief A overload operation with shallow copy.
243  */
operator =(const PacMap & other)244 PacMap &PacMap::operator=(const PacMap &other)
245 {
246     if (&other != this) {
247         dataList_.clear();
248         std::string str = MapListToString(other.dataList_);
249         StringToMapList(str, dataList_);
250     }
251     return *this;
252 }
253 
254 /**
255  * @brief Clear all key-value pairs and free resources.
256  */
Clear(void)257 void PacMap::Clear(void)
258 {
259     std::lock_guard<std::mutex> mLock(mapLock_);
260     dataList_.clear();
261 }
262 
263 /**
264  * @brief Creates and returns a copy of this object with shallow copy.
265  *
266  * @return A clone of this instance.
267  */
Clone(void)268 PacMap PacMap::Clone(void)
269 {
270     std::lock_guard<std::mutex> mLock(mapLock_);
271     PacMap pac_map;
272     std::string currentString = MapListToString(dataList_);
273     StringToMapList(currentString, pac_map.dataList_);
274     return pac_map;
275 }
276 
277 /**
278  * @brief Creates a deep copy of this PacMap object with deep copy.
279  *
280  * @return
281  */
DeepCopy(void)282 PacMap PacMap::DeepCopy(void)
283 {
284     std::lock_guard<std::mutex> mLock(mapLock_);
285     PacMap pac_map;
286     std::string str = MapListToString(dataList_);
287     StringToMapList(str, pac_map.dataList_);
288     return pac_map;
289 }
290 
DeepCopy(PacMap & other)291 void PacMap::DeepCopy(PacMap &other)
292 {
293     std::lock_guard<std::mutex> mLock(mapLock_);
294     dataList_.clear();
295     StringToMapList(MapListToString(other.dataList_), dataList_);
296 }
297 
298 /**
299  * @brief Adds a short value matching a specified key.
300  * @param key A specified key.
301  * @param value The value that matches the specified key.
302  */
PutShortValue(const std::string & key,short value)303 void PacMap::PutShortValue(const std::string &key, short value)
304 {
305     std::lock_guard<std::mutex> mLock(mapLock_);
306     InnerPutShortValue(dataList_, key, value);
307 }
InnerPutShortValue(PacMapList & mapList,const std::string & key,short value)308 void PacMap::InnerPutShortValue(PacMapList &mapList, const std::string &key, short value)
309 {
310     PAC_MAP_PUT_VALUE(Short, IShort, key, value, mapList)
311 }
312 /**
313  * @brief Adds a integer value matching a specified key.
314  * @param key A specified key.
315  * @param value The value that matches the specified key.
316  */
PutIntValue(const std::string & key,int value)317 void PacMap::PutIntValue(const std::string &key, int value)
318 {
319     std::lock_guard<std::mutex> mLock(mapLock_);
320     InnerPutIntValue(dataList_, key, value);
321 }
InnerPutIntValue(PacMapList & mapList,const std::string & key,int value)322 void PacMap::InnerPutIntValue(PacMapList &mapList, const std::string &key, int value)
323 {
324     PAC_MAP_PUT_VALUE(Integer, IInteger, key, value, mapList)
325 }
326 /**
327  * @brief Adds a long value matching a specified key.
328  * @param key A specified key.
329  * @param value The value that matches the specified key.
330  */
PutLongValue(const std::string & key,long value)331 void PacMap::PutLongValue(const std::string &key, long value)
332 {
333     std::lock_guard<std::mutex> mLock(mapLock_);
334     InnerPutLongValue(dataList_, key, value);
335 }
InnerPutLongValue(PacMapList & mapList,const std::string & key,long value)336 void PacMap::InnerPutLongValue(PacMapList &mapList, const std::string &key, long value)
337 {
338     PAC_MAP_PUT_VALUE(Long, ILong, key, value, mapList)
339 }
340 /**
341  * @brief Adds a boolean value matching a specified key.
342  * @param key A specified key.
343  * @param value The value that matches the specified key.
344  */
PutBooleanValue(const std::string & key,bool value)345 void PacMap::PutBooleanValue(const std::string &key, bool value)
346 {
347     std::lock_guard<std::mutex> mLock(mapLock_);
348     InnerPutBooleanValue(dataList_, key, value);
349 }
InnerPutBooleanValue(PacMapList & mapList,const std::string & key,bool value)350 void PacMap::InnerPutBooleanValue(PacMapList &mapList, const std::string &key, bool value)
351 {
352     PAC_MAP_PUT_VALUE(Boolean, IBoolean, key, value, mapList)
353 }
354 /**
355  * @brief Adds a char value matching a specified key.
356  * @param key A specified key.
357  * @param value The value that matches the specified key.
358  */
PutCharValue(const std::string & key,char value)359 void PacMap::PutCharValue(const std::string &key, char value)
360 {
361     std::lock_guard<std::mutex> mLock(mapLock_);
362     InnerPutCharValue(dataList_, key, value);
363 }
InnerPutCharValue(PacMapList & mapList,const std::string & key,char value)364 void PacMap::InnerPutCharValue(PacMapList &mapList, const std::string &key, char value)
365 {
366     PAC_MAP_PUT_VALUE(Char, IChar, key, value, mapList)
367 }
368 
369 /**
370  * @brief Adds a byte value matching a specified key.
371  * @param key A specified key.
372  * @param value The value that matches the specified key.
373  */
PutByteValue(const std::string & key,AAFwk::byte value)374 void PacMap::PutByteValue(const std::string &key, AAFwk::byte value)
375 {
376     std::lock_guard<std::mutex> mLock(mapLock_);
377     InnerPutByteValue(dataList_, key, value);
378 }
InnerPutByteValue(PacMapList & mapList,const std::string & key,AAFwk::byte value)379 void PacMap::InnerPutByteValue(PacMapList &mapList, const std::string &key, AAFwk::byte value)
380 {
381     PAC_MAP_PUT_VALUE(Byte, IByte, key, value, mapList)
382 }
383 /**
384  * @brief Adds a float value matching a specified key.
385  * @param key A specified key.
386  * @param value The value that matches the specified key.
387  */
PutFloatValue(const std::string & key,float value)388 void PacMap::PutFloatValue(const std::string &key, float value)
389 {
390     std::lock_guard<std::mutex> mLock(mapLock_);
391     InnerPutFloatValue(dataList_, key, value);
392 }
InnerPutFloatValue(PacMapList & mapList,const std::string & key,float value)393 void PacMap::InnerPutFloatValue(PacMapList &mapList, const std::string &key, float value)
394 {
395     PAC_MAP_PUT_VALUE(Float, IFloat, key, value, mapList)
396 }
397 
398 /**
399  * @brief Adds a double value matching a specified key.
400  * @param key A specified key.
401  * @param value The value that matches the specified key.
402  */
PutDoubleValue(const std::string & key,double value)403 void PacMap::PutDoubleValue(const std::string &key, double value)
404 {
405     std::lock_guard<std::mutex> mLock(mapLock_);
406     InnerPutDoubleValue(dataList_, key, value);
407 }
InnerPutDoubleValue(PacMapList & mapList,const std::string & key,double value)408 void PacMap::InnerPutDoubleValue(PacMapList &mapList, const std::string &key, double value)
409 {
410     PAC_MAP_PUT_VALUE(Double, IDouble, key, value, mapList)
411 }
412 /**
413  * @brief Adds a string {std::string} value matching a specified key.
414  * @param key A specified key.
415  * @param value The value that matches the specified key.
416  */
PutStringValue(const std::string & key,const std::string & value)417 void PacMap::PutStringValue(const std::string &key, const std::string &value)
418 {
419     std::lock_guard<std::mutex> mLock(mapLock_);
420     InnerPutStringValue(dataList_, key, value);
421 }
InnerPutStringValue(PacMapList & mapList,const std::string & key,const std::string & value)422 void PacMap::InnerPutStringValue(PacMapList &mapList, const std::string &key, const std::string &value)
423 {
424     PAC_MAP_PUT_VALUE(String, IString, key, value, mapList);
425 }
426 
427 /**
428  * @brief Adds an object value matching a specified key. The object must be a subclass of UserObjectBase.
429  * @param key A specified key.
430  * @param value A smart pointer to the object that matches the specified key.
431  */
PutObject(const std::string & key,const std::shared_ptr<UserObjectBase> & value)432 void PacMap::PutObject(const std::string &key, const std::shared_ptr<UserObjectBase> &value)
433 {
434     if (value == nullptr) {
435         return;
436     }
437     std::lock_guard<std::mutex> mLock(mapLock_);
438     InnerPutObject(dataList_, key, value);
439 }
InnerPutObject(PacMapList & mapList,const std::string & key,const std::shared_ptr<UserObjectBase> & value)440 void PacMap::InnerPutObject(PacMapList &mapList, const std::string &key, const std::shared_ptr<UserObjectBase> &value)
441 {
442     RemoveData(mapList, key);
443     sptr<IUserObject> valObject = OHOS::AAFwk::UserObject::Box(value);
444     if (valObject == nullptr) {
445         return;
446     }
447     mapList.emplace(key, valObject);
448 }
449 /**
450  * @brief Adds an PacMap value matching a specified key.
451  * @param key A specified key.
452  * @param value The value that matches the specified key.
453  */
PutPacMap(const std::string & key,const PacMap & value)454 bool PacMap::PutPacMap(const std::string &key, const PacMap &value)
455 {
456     std::lock_guard<std::mutex> mLock(mapLock_);
457     return InnerPutPacMap(dataList_, key, const_cast<PacMap &>(value));
458 }
InnerPutPacMap(PacMapList & mapList,const std::string & key,PacMap & value)459 bool PacMap::InnerPutPacMap(PacMapList &mapList, const std::string &key, PacMap &value)
460 {
461     RemoveData(mapList, key);
462     sptr<IPacMap> pacMap = new (std::nothrow) PacMap(value);
463     if (pacMap != nullptr) {
464         mapList.emplace(key, pacMap);
465         return true;
466     }
467     return false;
468 }
469 /**
470  * @brief Adds some short values matching a specified key.
471  * @param key A specified key.
472  * @param value Store a list of short values.
473  */
PutShortValueArray(const std::string & key,const std::vector<short> & value)474 void PacMap::PutShortValueArray(const std::string &key, const std::vector<short> &value)
475 {
476     std::lock_guard<std::mutex> mLock(mapLock_);
477     InnerPutShortValueArray(dataList_, key, value);
478 }
InnerPutShortValueArray(PacMapList & mapList,const std::string & key,const std::vector<short> & value)479 void PacMap::InnerPutShortValueArray(PacMapList &mapList, const std::string &key, const std::vector<short> &value)
480 {
481     PAC_MAP_ADD_ARRAY(Short, key, value, mapList)
482 }
483 /**
484  * @brief Adds some integer values matching a specified key.
485  * @param key A specified key.
486  * @param value Store a list of integer values.
487  */
PutIntValueArray(const std::string & key,const std::vector<int> & value)488 void PacMap::PutIntValueArray(const std::string &key, const std::vector<int> &value)
489 {
490     std::lock_guard<std::mutex> mLock(mapLock_);
491     InnerPutIntValueArray(dataList_, key, value);
492 }
InnerPutIntValueArray(PacMapList & mapList,const std::string & key,const std::vector<int> & value)493 void PacMap::InnerPutIntValueArray(PacMapList &mapList, const std::string &key, const std::vector<int> &value)
494 {
495     PAC_MAP_ADD_ARRAY(Integer, key, value, mapList)
496 }
497 /**
498  * @brief Adds some long values matching a specified key.
499  * @param key A specified key.
500  * @param value Store a list of long values.
501  */
PutLongValueArray(const std::string & key,const std::vector<long> & value)502 void PacMap::PutLongValueArray(const std::string &key, const std::vector<long> &value)
503 {
504     std::lock_guard<std::mutex> mLock(mapLock_);
505     InnerPutLongValueArray(dataList_, key, value);
506 }
InnerPutLongValueArray(PacMapList & mapList,const std::string & key,const std::vector<long> & value)507 void PacMap::InnerPutLongValueArray(PacMapList &mapList, const std::string &key, const std::vector<long> &value)
508 {
509     PAC_MAP_ADD_ARRAY(Long, key, value, mapList)
510 }
511 /**
512  * @brief Adds some boolean values matching a specified key.
513  * @param key A specified key.
514  * @param value Store a list of boolean values.
515  */
PutBooleanValueArray(const std::string & key,const std::vector<bool> & value)516 void PacMap::PutBooleanValueArray(const std::string &key, const std::vector<bool> &value)
517 {
518     std::lock_guard<std::mutex> mLock(mapLock_);
519     InnerPutBooleanValueArray(dataList_, key, value);
520 }
InnerPutBooleanValueArray(PacMapList & mapList,const std::string & key,const std::vector<bool> & value)521 void PacMap::InnerPutBooleanValueArray(PacMapList &mapList, const std::string &key, const std::vector<bool> &value)
522 {
523     PAC_MAP_ADD_ARRAY(Boolean, key, value, mapList)
524 }
525 /**
526  * @brief Adds some char values matching a specified key.
527  * @param key A specified key.
528  * @param value Store a list of char values.
529  */
PutCharValueArray(const std::string & key,const std::vector<char> & value)530 void PacMap::PutCharValueArray(const std::string &key, const std::vector<char> &value)
531 {
532     std::lock_guard<std::mutex> mLock(mapLock_);
533     InnerPutCharValueArray(dataList_, key, value);
534 }
InnerPutCharValueArray(PacMapList & mapList,const std::string & key,const std::vector<char> & value)535 void PacMap::InnerPutCharValueArray(PacMapList &mapList, const std::string &key, const std::vector<char> &value)
536 {
537     PAC_MAP_ADD_ARRAY(Char, key, value, mapList)
538 }
539 /**
540  * @brief Adds some byte values matching a specified key.
541  * @param key A specified key.
542  * @param value Store a list of byte values.
543  */
PutByteValueArray(const std::string & key,const std::vector<AAFwk::byte> & value)544 void PacMap::PutByteValueArray(const std::string &key, const std::vector<AAFwk::byte> &value)
545 {
546     std::lock_guard<std::mutex> mLock(mapLock_);
547     InnerPutByteValueArray(dataList_, key, value);
548 }
InnerPutByteValueArray(PacMapList & mapList,const std::string & key,const std::vector<AAFwk::byte> & value)549 void PacMap::InnerPutByteValueArray(PacMapList &mapList, const std::string &key, const std::vector<AAFwk::byte> &value)
550 {
551     PAC_MAP_ADD_ARRAY(Byte, key, value, mapList)
552 }
553 /**
554  * @brief Adds some float values matching a specified key.
555  * @param key A specified key.
556  * @param value Store a list of float values.
557  */
PutFloatValueArray(const std::string & key,const std::vector<float> & value)558 void PacMap::PutFloatValueArray(const std::string &key, const std::vector<float> &value)
559 {
560     std::lock_guard<std::mutex> mLock(mapLock_);
561     InnerPutFloatValueArray(dataList_, key, value);
562 }
InnerPutFloatValueArray(PacMapList & mapList,const std::string & key,const std::vector<float> & value)563 void PacMap::InnerPutFloatValueArray(PacMapList &mapList, const std::string &key, const std::vector<float> &value)
564 {
565     PAC_MAP_ADD_ARRAY(Float, key, value, mapList)
566 }
567 /**
568  * @brief Adds some double values matching a specified key.
569  * @param key A specified key.
570  * @param value Store a list of double values.
571  */
PutDoubleValueArray(const std::string & key,const std::vector<double> & value)572 void PacMap::PutDoubleValueArray(const std::string &key, const std::vector<double> &value)
573 {
574     std::lock_guard<std::mutex> mLock(mapLock_);
575     InnerPutDoubleValueArray(dataList_, key, value);
576 }
InnerPutDoubleValueArray(PacMapList & mapList,const std::string & key,const std::vector<double> & value)577 void PacMap::InnerPutDoubleValueArray(PacMapList &mapList, const std::string &key, const std::vector<double> &value)
578 {
579     PAC_MAP_ADD_ARRAY(Double, key, value, mapList)
580 }
581 /**
582  * @brief Adds some string {std::string} values matching a specified key.
583  * @param key A specified key.
584  * @param value Store a list of string values.
585  */
PutStringValueArray(const std::string & key,const std::vector<std::string> & value)586 void PacMap::PutStringValueArray(const std::string &key, const std::vector<std::string> &value)
587 {
588     std::lock_guard<std::mutex> mLock(mapLock_);
589     InnerPutStringValueArray(dataList_, key, value);
590 }
InnerPutStringValueArray(PacMapList & mapList,const std::string & key,const std::vector<std::string> & value)591 void PacMap::InnerPutStringValueArray(
592     PacMapList &mapList, const std::string &key, const std::vector<std::string> &value)
593 {
594     PAC_MAP_ADD_ARRAY(String, key, value, mapList)
595 }
596 /**
597  * @brief Inserts all key-value pairs of a map object into the built-in data object.
598  * Duplicate key values will be replaced.
599  * @param mapData Store a list of key-value pairs.
600  */
PutAll(std::map<std::string,PacMapObject::INTERFACE> & mapData)601 void PacMap::PutAll(std::map<std::string, PacMapObject::INTERFACE> &mapData)
602 {
603     std::lock_guard<std::mutex> mLock(mapLock_);
604     dataList_.clear();
605     StringToMapList(MapListToString(mapData), dataList_);
606 }
607 
608 /**
609  * @brief Saves the data in a PacMap object to the current object. Duplicate key values will be replaced.
610  * @param pacMap Store the date of PacMap.
611  */
PutAll(PacMap & pacMap)612 void PacMap::PutAll(PacMap &pacMap)
613 {
614     std::lock_guard<std::mutex> mLock(mapLock_);
615     dataList_.clear();
616     StringToMapList(MapListToString(pacMap.dataList_), dataList_);
617 }
618 
619 /**
620  * @brief Obtains the int value matching a specified key.
621  * @param key A specified key.
622  * @param defaultValue The return value when the function fails.
623  * @return If the match is successful, return the value matching the key, otherwise return the @a defaultValue.
624  */
GetIntValue(const std::string & key,int defaultValue)625 int PacMap::GetIntValue(const std::string &key, int defaultValue)
626 {
627     std::lock_guard<std::mutex> mLock(mapLock_);
628     PAC_MAP_GET_VALUE(IInteger, key, int, dataList_, defaultValue)
629     return defaultValue;
630 }
631 
632 /**
633  * @brief Obtains the short value matching a specified key.
634  * @param key A specified key.
635  * @param defaultValue The return value when the function fails.
636  * @return If the match is successful, return the value matching the key, otherwise return the @a defaultValue.
637  */
GetShortValue(const std::string & key,short defaultValue)638 short PacMap::GetShortValue(const std::string &key, short defaultValue)
639 {
640     std::lock_guard<std::mutex> mLock(mapLock_);
641     PAC_MAP_GET_VALUE(IShort, key, short, dataList_, defaultValue)
642     return defaultValue;
643 }
644 
645 /**
646  * @brief Obtains the boolean value matching a specified key.
647  * @param key A specified key.
648  * @param defaultValue The return value when the function fails.
649  * @return If the match is successful, return the value matching the key, otherwise return the @a defaultValue.
650  */
GetBooleanValue(const std::string & key,bool defaultValue)651 bool PacMap::GetBooleanValue(const std::string &key, bool defaultValue)
652 {
653     std::lock_guard<std::mutex> mLock(mapLock_);
654     PAC_MAP_GET_VALUE(IBoolean, key, bool, dataList_, defaultValue)
655     return defaultValue;
656 }
657 
658 /**
659  * @brief Obtains the long value matching a specified key.
660  * @param key A specified key.
661  * @param defaultValue The return value when the function fails.
662  * @return If the match is successful, return the value matching the key, otherwise return the @a defaultValue.
663  */
GetLongValue(const std::string & key,long defaultValue)664 long PacMap::GetLongValue(const std::string &key, long defaultValue)
665 {
666     std::lock_guard<std::mutex> mLock(mapLock_);
667     PAC_MAP_GET_VALUE(ILong, key, long, dataList_, defaultValue)
668     return defaultValue;
669 }
670 
671 /**
672  * @brief Obtains the char value matching a specified key.
673  * @param key A specified key.
674  * @param defaultValue The return value when the function fails.
675  * @return If the match is successful, return the value matching the key, otherwise return the @a defaultValue.
676  */
GetCharValue(const std::string & key,char defaultValue)677 char PacMap::GetCharValue(const std::string &key, char defaultValue)
678 {
679     std::lock_guard<std::mutex> mLock(mapLock_);
680     PAC_MAP_GET_VALUE(IChar, key, zchar, dataList_, defaultValue)
681     return defaultValue;
682 }
683 
684 /**
685  * @brief Obtains the byte value matching a specified key.
686  * @param key A specified key.
687  * @param defaultValue The return value when the function fails.
688  * @return If the match is successful, return the value matching the key, otherwise return the @a defaultValue.
689  */
GetByteValue(const std::string & key,AAFwk::byte defaultValue)690 AAFwk::byte PacMap::GetByteValue(const std::string &key, AAFwk::byte defaultValue)
691 {
692     std::lock_guard<std::mutex> mLock(mapLock_);
693     PAC_MAP_GET_VALUE(IByte, key, byte, dataList_, defaultValue)
694     return defaultValue;
695 }
696 
697 /**
698  * @brief Obtains the float value matching a specified key.
699  * @param key A specified key.
700  * @param defaultValue The return value when the function fails.
701  * @return If the match is successful, return the value matching the key, otherwise return the @a defaultValue.
702  */
GetFloatValue(const std::string & key,float defaultValue)703 float PacMap::GetFloatValue(const std::string &key, float defaultValue)
704 {
705     std::lock_guard<std::mutex> mLock(mapLock_);
706     PAC_MAP_GET_VALUE(IFloat, key, float, dataList_, defaultValue)
707     return defaultValue;
708 }
709 
710 /**
711  * @brief Obtains the double value matching a specified key.
712  * @param key A specified key.
713  * @param defaultValue The return value when the function fails.
714  * @return If the match is successful, return the value matching the key, otherwise return the @a defaultValue.
715  */
GetDoubleValue(const std::string & key,double defaultValue)716 double PacMap::GetDoubleValue(const std::string &key, double defaultValue)
717 {
718     std::lock_guard<std::mutex> mLock(mapLock_);
719     PAC_MAP_GET_VALUE(IDouble, key, double, dataList_, defaultValue)
720     return defaultValue;
721 }
722 
723 /**
724  * @brief Obtains the string {std::string} value matching a specified key.
725  * @param key A specified key.
726  * @param defaultValue The return value when the function fails.
727  * @return If the match is successful, return the value matching the key, otherwise return the @a defaultValue.
728  */
GetStringValue(const std::string & key,const std::string & defaultValue)729 std::string PacMap::GetStringValue(const std::string &key, const std::string &defaultValue)
730 {
731     std::lock_guard<std::mutex> mLock(mapLock_);
732     PAC_MAP_GET_STRING_VALUE(IString, key, std::string, dataList_, defaultValue)
733     return defaultValue;
734 }
735 
736 /**
737  * @brief Obtains some int values matching a specified key.
738  * @param key A specified key.
739  * @param value Save the returned int values.
740  */
GetIntValueArray(const std::string & key,std::vector<int> & value)741 void PacMap::GetIntValueArray(const std::string &key, std::vector<int> &value)
742 {
743     std::lock_guard<std::mutex> mLock(mapLock_);
744     GET_PAC_MAP_ARRAY(Integer, dataList_, key, value)
745 }
746 
747 /**
748  * @brief Obtains some short values matching a specified key.
749  * @param key A specified key.
750  * @param value Save the returned short values.
751  */
GetShortValueArray(const std::string & key,std::vector<short> & value)752 void PacMap::GetShortValueArray(const std::string &key, std::vector<short> &value)
753 {
754     std::lock_guard<std::mutex> mLock(mapLock_);
755     GET_PAC_MAP_ARRAY(Short, dataList_, key, value)
756 }
757 /**
758  * @brief Obtains some boolean values matching a specified key.
759  * @param key A specified key.
760  * @param value Save the returned boolean values.
761  */
GetBooleanValueArray(const std::string & key,std::vector<bool> & value)762 void PacMap::GetBooleanValueArray(const std::string &key, std::vector<bool> &value)
763 {
764     std::lock_guard<std::mutex> mLock(mapLock_);
765     GET_PAC_MAP_ARRAY(Boolean, dataList_, key, value)
766 }
767 
768 /**
769  * @brief Obtains some long values matching a specified key.
770  * @param key A specified key.
771  * @param value Save the returned long values.
772  */
GetLongValueArray(const std::string & key,std::vector<long> & value)773 void PacMap::GetLongValueArray(const std::string &key, std::vector<long> &value)
774 {
775     std::lock_guard<std::mutex> mLock(mapLock_);
776     GET_PAC_MAP_ARRAY(Long, dataList_, key, value)
777 }
778 
779 /**
780  * @brief Obtains some char values matching a specified key.
781  * @param key A specified key.
782  * @param value Save the returned char values.
783  */
GetCharValueArray(const std::string & key,std::vector<char> & value)784 void PacMap::GetCharValueArray(const std::string &key, std::vector<char> &value)
785 {
786     std::lock_guard<std::mutex> mLock(mapLock_);
787     GET_PAC_MAP_ARRAY(Char, dataList_, key, value)
788 }
789 
790 /**
791  * @brief Obtains some byte values matching a specified key.
792  * @param key A specified key.
793  * @param value Save the returned byte values.
794  */
GetByteValueArray(const std::string & key,std::vector<AAFwk::byte> & value)795 void PacMap::GetByteValueArray(const std::string &key, std::vector<AAFwk::byte> &value)
796 {
797     std::lock_guard<std::mutex> mLock(mapLock_);
798     GET_PAC_MAP_ARRAY(Byte, dataList_, key, value)
799 }
800 
801 /**
802  * @brief Obtains some float values matching a specified key.
803  * @param key A specified key.
804  * @param value Save the returned float values.
805  */
GetFloatValueArray(const std::string & key,std::vector<float> & value)806 void PacMap::GetFloatValueArray(const std::string &key, std::vector<float> &value)
807 {
808     std::lock_guard<std::mutex> mLock(mapLock_);
809     GET_PAC_MAP_ARRAY(Float, dataList_, key, value)
810 }
811 
812 /**
813  * @brief Obtains some double values matching a specified key.
814  * @param key A specified key.
815  * @param value Save the returned double values.
816  */
GetDoubleValueArray(const std::string & key,std::vector<double> & value)817 void PacMap::GetDoubleValueArray(const std::string &key, std::vector<double> &value)
818 {
819     std::lock_guard<std::mutex> mLock(mapLock_);
820     GET_PAC_MAP_ARRAY(Double, dataList_, key, value)
821 }
822 
823 /**
824  * @brief Obtains some string {std::string} values matching a specified key.
825  * @param key A specified key.
826  * @param value Save the returned string {std::string} values.
827  */
GetStringValueArray(const std::string & key,std::vector<std::string> & value)828 void PacMap::GetStringValueArray(const std::string &key, std::vector<std::string> &value)
829 {
830     std::lock_guard<std::mutex> mLock(mapLock_);
831     GET_PAC_MAP_ARRAY(String, dataList_, key, value)
832 }
833 
834 /**
835  * @brief Obtains the object matching a specified key.
836  * @param key A specified key.
837  * @return Returns the smart pointer to object that matches the key.
838  */
GetObject(const std::string & key)839 std::shared_ptr<UserObjectBase> PacMap::GetObject(const std::string &key)
840 {
841     std::lock_guard<std::mutex> mLock(mapLock_);
842     auto it = dataList_.find(key);
843     if (it == dataList_.end()) {
844         return nullptr;
845     }
846 
847     if (it->second != nullptr) {
848         if (IUserObject::Query(it->second.GetRefPtr()) != nullptr) {
849             return UserObject::Unbox(static_cast<IUserObject *>(it->second.GetRefPtr()));
850         }
851     }
852 
853     return nullptr;
854 }
855 
856 /**
857  * @brief Obtains the PacMap matching a specified key.
858  * @param key A specified key.
859  * @return Returns PacMap that matches the key.
860  */
GetPacMap(const std::string & key)861 PacMap PacMap::GetPacMap(const std::string &key)
862 {
863     std::lock_guard<std::mutex> mLock(mapLock_);
864     PacMap pacmap;
865     auto it = dataList_.find(key);
866     if (it != dataList_.end()) {
867         if (IPacMap::Query(it->second.GetRefPtr()) != nullptr) {
868             pacmap.DeepCopy(*static_cast<PacMap *>(IPacMap::Query(it->second.GetRefPtr())));
869         }
870     }
871     return pacmap;
872 }
873 
874 /**
875  * @brief Obtains all the data that has been stored with shallow copy.
876  * @return Returns all data in current PacMap. There is no dependency between the returned data and
877  * the original data.
878  */
GetAll(void)879 std::map<std::string, PacMapObject::INTERFACE> PacMap::GetAll(void)
880 {
881     std::lock_guard<std::mutex> mLock(mapLock_);
882 
883     PacMapList tmpMapList;
884     StringToMapList(MapListToString(dataList_), tmpMapList);
885 
886     return tmpMapList;
887 }
888 
ShallowCopyData(PacMapList & desPacMap,const PacMapList & srcPacMap)889 void PacMap::ShallowCopyData(PacMapList &desPacMap, const PacMapList &srcPacMap)
890 {
891     desPacMap.clear();
892     for (auto it = srcPacMap.begin(); it != srcPacMap.end(); it++) {
893         desPacMap.emplace(it->first, it->second);
894     }
895 }
896 
RemoveData(PacMapList & pacMapList,const std::string & key)897 void PacMap::RemoveData(PacMapList &pacMapList, const std::string &key)
898 {
899     auto it = pacMapList.find(key);
900     if (it != pacMapList.end()) {
901         pacMapList.erase(it);
902     }
903 }
904 
EqualPacMapData(const PacMapList & leftPacMapList,const PacMapList & rightPacMapList)905 bool PacMap::EqualPacMapData(const PacMapList &leftPacMapList, const PacMapList &rightPacMapList)
906 {
907     if (leftPacMapList.size() != rightPacMapList.size()) {
908         return false;
909     }
910 
911     for (auto right = rightPacMapList.begin(); right != rightPacMapList.end(); right++) {
912         auto left = leftPacMapList.find(right->first);
913         if (left == leftPacMapList.end()) {
914             return false;
915         }
916         if (left->second.GetRefPtr() == right->second.GetRefPtr()) {
917             continue;
918         }
919 
920         // PacMap Object
921         if (IPacMap::Query(right->second.GetRefPtr()) != nullptr) {
922             auto leftMapIt = leftPacMapList.find(right->first);
923             if (leftMapIt == leftPacMapList.end()) {
924                 return false;
925             }
926             if (IPacMap::Query(leftMapIt->second.GetRefPtr()) == nullptr) {
927                 return false;
928             }
929 
930             PacMap *rightMap = static_cast<PacMap *>(IPacMap::Query(right->second.GetRefPtr()));
931             PacMap *leftMap = static_cast<PacMap *>(IPacMap::Query(leftMapIt->second.GetRefPtr()));
932             if (rightMap == nullptr || leftMap == nullptr ||
933                 !EqualPacMapData(leftMap->dataList_, rightMap->dataList_)) {
934                 return false;
935             }
936             continue;
937         }
938 
939         if (!Object::Equals(*(right->second.GetRefPtr()), *(left->second.GetRefPtr()))) {
940             return false;
941         }
942     }
943     return true;
944 }
945 
946 template<typename iid, typename id, typename value>
GetArrayData(AAFwk::IInterface * interface,std::vector<value> & array,std::function<bool (IArray *)> IsArrayfunc)947 static void GetArrayData(
948     AAFwk::IInterface *interface, std::vector<value> &array, std::function<bool(IArray *)> IsArrayfunc)
949 {
950     if (interface == nullptr) {
951         return;
952     }
953     if (IsArrayfunc(IArray::Query(interface))) {
954         auto func = [&array](IInterface *object) { array.push_back(id::Unbox(iid::Query(object))); };
955         Array::ForEach(IArray::Query(interface), func);
956     }
957 }
958 
959 template<typename iid, typename id, typename value>
CompareTwoArrayData(AAFwk::IInterface * one_interface,AAFwk::IInterface * two_interface,std::function<bool (IArray *)> IsArrayfunc)960 static bool CompareTwoArrayData(
961     AAFwk::IInterface *one_interface, AAFwk::IInterface *two_interface, std::function<bool(IArray *)> IsArrayfunc)
962 {
963     typename std::vector<value> array;
964     GetArrayData<iid, id, value>(IArray::Query(one_interface), array, IsArrayfunc);
965 
966     if (!IsArrayfunc(IArray::Query(two_interface))) {
967         return false;
968     }
969     typename std::vector<value> otherArray;
970     GetArrayData<iid, id, value>(IArray::Query(two_interface), otherArray, IsArrayfunc);
971     if (array.size() != 0 && otherArray.size() != 0 && array.size() != otherArray.size()) {
972         return false;
973     }
974     for (std::size_t i = 0; i < array.size(); i++) {
975         auto it = std::find(otherArray.begin(), otherArray.end(), array[i]);
976         if (it == array.end()) {
977             return false;
978         }
979     }
980     return true;
981 }
CompareArrayData(AAFwk::IInterface * one_interface,AAFwk::IInterface * two_interface)982 bool PacMap::CompareArrayData(AAFwk::IInterface *one_interface, AAFwk::IInterface *two_interface)
983 {
984     if (IArray::Query(one_interface) != nullptr && IArray::Query(two_interface) != nullptr) {
985         IArray *array_one = IArray::Query(one_interface);
986         IArray *array_two = IArray::Query(two_interface);
987         long size1 = 0;
988         array_one->GetLength(size1);
989         long size2 = 0;
990         array_two->GetLength(size2);
991 
992         if (size1 != 0 && size2 != 0 && size1 != size2) {
993             return false;
994         }
995         if (AAFwk::Array::IsBooleanArray(IArray::Query(one_interface))) {
996             if (!CompareTwoArrayData<AAFwk::IBoolean, AAFwk::Boolean, bool>(
997                 one_interface, two_interface, AAFwk::Array::IsBooleanArray)) {
998                 return false;
999             }
1000         } else if (AAFwk::Array::IsCharArray(AAFwk::IArray::Query(one_interface))) {
1001             return false;
1002         } else if (AAFwk::Array::IsByteArray(IArray::Query(one_interface))) {
1003             if (!CompareTwoArrayData<AAFwk::IByte, AAFwk::Byte, byte>(
1004                 one_interface, two_interface, AAFwk::Array::IsByteArray)) {
1005                 return false;
1006             }
1007         } else if (AAFwk::Array::IsShortArray(IArray::Query(one_interface))) {
1008             if (!CompareTwoArrayData<AAFwk::IShort, AAFwk::Short, short>(
1009                 one_interface, two_interface, AAFwk::Array::IsShortArray)) {
1010                 return false;
1011             }
1012         } else if (AAFwk::Array::IsIntegerArray(IArray::Query(one_interface))) {
1013             if (!CompareTwoArrayData<AAFwk::IInteger, AAFwk::Integer, int>(
1014                 one_interface, two_interface, AAFwk::Array::IsIntegerArray)) {
1015                 return false;
1016             }
1017         } else if (AAFwk::Array::IsLongArray(IArray::Query(one_interface))) {
1018             if (!CompareTwoArrayData<AAFwk::ILong, AAFwk::Long, long>(
1019                 one_interface, two_interface, AAFwk::Array::IsLongArray)) {
1020                 return false;
1021             }
1022         } else if (AAFwk::Array::IsFloatArray(IArray::Query(one_interface))) {
1023             if (!CompareTwoArrayData<AAFwk::IFloat, AAFwk::Float, float>(
1024                 one_interface, two_interface, AAFwk::Array::IsFloatArray)) {
1025                 return false;
1026             }
1027         } else if (AAFwk::Array::IsDoubleArray(IArray::Query(one_interface))) {
1028             if (!CompareTwoArrayData<AAFwk::IDouble, AAFwk::Double, double>(
1029                 one_interface, two_interface, AAFwk::Array::IsDoubleArray)) {
1030                 return false;
1031             }
1032         } else if (AAFwk::Array::IsStringArray(IArray::Query(one_interface))) {
1033             if (!CompareTwoArrayData<AAFwk::IString, AAFwk::String, std::string>(
1034                 one_interface, two_interface, AAFwk::Array::IsStringArray)) {
1035                 return false;
1036             }
1037         } else {
1038             return false;
1039         }
1040     }
1041     return true;
1042 }
1043 /**
1044  * @brief Indicates whether some other object is "equal to" this one.
1045  * @param pacMap The object with which to compare.
1046  * @return Returns true if this object is the same as the pacMap argument; false otherwise.
1047  */
Equals(const PacMap * pacMap)1048 bool PacMap::Equals(const PacMap *pacMap)
1049 {
1050     std::lock_guard<std::mutex> mLock(mapLock_);
1051     if (pacMap == nullptr) {
1052         return false;
1053     }
1054 
1055     if (this == pacMap) {
1056         return true;
1057     }
1058 
1059     if (dataList_.size() != pacMap->dataList_.size()) {
1060         return false;
1061     }
1062 
1063     if (!EqualPacMapData(dataList_, pacMap->dataList_)) {
1064         return false;
1065     }
1066 
1067     return true;
1068 }
1069 
Equals(const PacMap & pacMap)1070 bool PacMap::Equals(const PacMap &pacMap)
1071 {
1072     return Equals(&pacMap);
1073 }
1074 
1075 /**
1076  * @brief Checks whether the current object is empty.
1077  * @return If there is no data, return true, otherwise return false.
1078  */
IsEmpty(void) const1079 bool PacMap::IsEmpty(void) const
1080 {
1081     return dataList_.empty();
1082 }
1083 
1084 /**
1085  * @brief Obtains the number of key-value pairs stored in the current object.
1086  * @return Returns the number of key-value pairs.
1087  */
GetSize(void) const1088 int PacMap::GetSize(void) const
1089 {
1090     return dataList_.size();
1091 }
1092 
1093 /**
1094  * @brief Obtains all the keys of the current object.
1095  */
GetKeys(void)1096 const std::set<std::string> PacMap::GetKeys(void)
1097 {
1098     std::lock_guard<std::mutex> mLock(mapLock_);
1099     std::set<std::string> keys;
1100 
1101     for (auto it = dataList_.begin(); it != dataList_.end(); it++) {
1102         keys.emplace(it->first);
1103     }
1104     return keys;
1105 }
1106 
1107 /**
1108  * @brief Checks whether a specified key is contained.
1109  * @param key Indicates the key in String
1110  * @return Returns true if the key is contained; returns false otherwise.
1111  */
HasKey(const std::string & key)1112 bool PacMap::HasKey(const std::string &key)
1113 {
1114     std::lock_guard<std::mutex> mLock(mapLock_);
1115     return (dataList_.find(key) != dataList_.end());
1116 }
1117 
1118 /**
1119  * @brief Deletes a key-value pair with a specified key.
1120  * @param key Specifies the key of the deleted data.
1121  */
Remove(const std::string & key)1122 void PacMap::Remove(const std::string &key)
1123 {
1124     std::lock_guard<std::mutex> mLock(mapLock_);
1125     auto it = dataList_.find(key);
1126     if (it != dataList_.end()) {
1127         dataList_.erase(it);
1128     }
1129 }
1130 
ReadFromParcel(Parcel & parcel)1131 bool PacMap::ReadFromParcel(Parcel &parcel)
1132 {
1133     std::string value = parcel.ReadString();
1134     if (!value.empty()) {
1135         return StringToMapList(value, dataList_);
1136     } else {
1137         return true;
1138     }
1139 }
1140 
1141 /**
1142  * @brief Marshals this Sequenceable object to a Parcel.
1143  * @param parcel Indicates the Parcel object into which the Sequenceable object has been marshaled.
1144  * @return Marshals success returns true, otherwise returns false.
1145  */
Marshalling(Parcel & parcel) const1146 bool PacMap::Marshalling(Parcel &parcel) const
1147 {
1148     if (!parcel.WriteString("PACMAP")) {
1149         return false;
1150     }
1151     std::string str = MapListToString(dataList_);
1152     return parcel.WriteString(str);
1153 }
1154 
1155 /**
1156  * @brief Unmarshals this S`nceable object from a Parcel.
1157  * @param parcel Indicates the Parcel object into which the Sequenceable object has been marshaled.
1158  * @return Unmarshals success returns a smart pointer to PacMap, otherwise returns nullptr.
1159  */
Unmarshalling(Parcel & parcel)1160 PacMap *PacMap::Unmarshalling(Parcel &parcel)
1161 {
1162     std::string value = parcel.ReadString();
1163     if (value != "PACMAP") {
1164         return nullptr;
1165     }
1166     PacMap *pPacMap = new (std::nothrow) PacMap();
1167     if (pPacMap != nullptr && !pPacMap->ReadFromParcel(parcel)) {
1168         delete pPacMap;
1169         return nullptr;
1170     }
1171     return pPacMap;
1172 }
1173 
1174 /**
1175  * @brief Object serialization to string.
1176  * @return Returns the serialized string.
1177  */
ToString()1178 std::string PacMap::ToString()
1179 {
1180     std::lock_guard<std::mutex> mLock(mapLock_);
1181     return MapListToString(dataList_);
1182 }
1183 
MapListToString(const PacMapList & mapList) const1184 std::string PacMap::MapListToString(const PacMapList &mapList) const
1185 {
1186     Json::Value root;
1187     Json::Value dataObject;
1188 
1189     ToJson(mapList, dataObject);
1190     root["pacmap"] = dataObject;
1191 
1192     std::ostringstream os;
1193     Json::StreamWriterBuilder builder;
1194     builder.settings_["indentation"] = "";
1195     std::unique_ptr<Json::StreamWriter> jsonWriter(builder.newStreamWriter());
1196     if (jsonWriter != nullptr) {
1197         jsonWriter->write(root, &os);
1198         return os.str();
1199     } else {
1200         return std::string("");
1201     }
1202 }
1203 
ToJson(const PacMapList & mapList,Json::Value & dataObject) const1204 bool PacMap::ToJson(const PacMapList &mapList, Json::Value &dataObject) const
1205 {
1206     for (auto it = mapList.begin(); it != mapList.end(); it++) {
1207         Json::Value item;
1208         bool isOK = false;
1209         if (IPacMap::Query(it->second.GetRefPtr()) != nullptr) {
1210             PacMap *pacmap = static_cast<PacMap *>(IPacMap::Query(it->second.GetRefPtr()));
1211             if (pacmap == nullptr) {
1212                 continue;
1213             }
1214             Json::Value item2;
1215             isOK = pacmap->ToJson(pacmap->dataList_, item2);
1216             if (isOK) {
1217                 item["type"] = PACMAP_DATA_PACMAP;
1218                 item["data"] = item2;
1219             }
1220         } else {
1221             isOK = GetBaseJsonValue(it, item);
1222         }
1223         if (isOK) {
1224             dataObject[it->first] = item;
1225         } else {
1226             return false;
1227         }
1228     }
1229     return true;
1230 }
1231 
1232 template<typename RawType>
RawTypeToString(const RawType value,unsigned int precisionAfterPoint)1233 static std::string RawTypeToString(const RawType value, unsigned int precisionAfterPoint)
1234 {
1235     std::ostringstream out("RawTypeToString");
1236     out << std::setw(0) << std::setprecision(precisionAfterPoint) << value;
1237 
1238     std::string res = out.str();
1239     auto pos = res.find('.');
1240     if (pos == std::string::npos) {
1241         return res;
1242     }
1243 
1244     auto splitLen = pos + 1 + precisionAfterPoint;
1245     if (res.size() <= splitLen) {
1246         return res;
1247     }
1248 
1249     return res.substr(0, splitLen);
1250 }
1251 
GetBaseJsonValue(PacMapList::const_iterator & it,Json::Value & json) const1252 bool PacMap::GetBaseJsonValue(PacMapList::const_iterator &it, Json::Value &json) const
1253 {
1254     // base data  : short
1255     if (IShort::Query(it->second.GetRefPtr()) != nullptr) {
1256         GetBaseDataValue<IShort, short>(it->second.GetRefPtr(), json, PACMAP_DATA_SHORT);
1257     } else if (IInteger::Query(it->second.GetRefPtr()) != nullptr) {
1258         GetBaseDataValue<IInteger, int>(it->second.GetRefPtr(), json, PACMAP_DATA_INTEGER);
1259     } else if (ILong::Query(it->second.GetRefPtr()) != nullptr) {
1260         // long:string
1261         GET_BASE_LONG_DATA_VALUE(Long, it, long, json, PACMAP_DATA_LONG)
1262     } else if (IChar::Query(it->second.GetRefPtr()) != nullptr) {
1263         GetBaseDataValue<IChar, zchar>(it->second.GetRefPtr(), json, PACMAP_DATA_CHAR);
1264     } else if (IByte::Query(it->second.GetRefPtr()) != nullptr) {
1265         GetBaseDataValue<IByte, byte>(it->second.GetRefPtr(), json, PACMAP_DATA_BYTE);
1266     } else if (IBoolean::Query(it->second.GetRefPtr()) != nullptr) {
1267         GetBaseDataValue<IBoolean, bool>(it->second.GetRefPtr(), json, PACMAP_DATA_BOOLEAN);
1268     } else if (IFloat::Query(it->second.GetRefPtr()) != nullptr) {
1269         // base long:string
1270         GetBaseFloatDoubleDataValue<IFloat, Float, float>(
1271             it->second.GetRefPtr(), json, PACMAP_DATA_FLOAT, FLOAT_PRECISION);
1272     } else if (IDouble::Query(it->second.GetRefPtr()) != nullptr) {
1273         // base :double to string
1274         GetBaseFloatDoubleDataValue<IDouble, Double, double>(
1275             it->second.GetRefPtr(), json, PACMAP_DATA_DOUBLE, DOUBLE_PRECISION);
1276     } else if (IString::Query(it->second.GetRefPtr()) != nullptr) {
1277         GET_BASE_STRING_DATA_VALUE(String, it, std::string, json, PACMAP_DATA_STRING)
1278     } else if (IArray::Query(it->second.GetRefPtr()) != nullptr) {
1279         // array data
1280         return GetArrayJsonValue(it, json);
1281     } else if (IUserObject::Query(it->second.GetRefPtr()) != nullptr) {
1282         // Object data [UserObject--data:UserObjectBase]
1283         return GetUserObjectJsonValue(it, json);
1284     } else {
1285         return false;
1286     }
1287 
1288     return true;
1289 }
1290 
1291 // Base data: short
ToJsonArrayShort(std::vector<short> & array,Json::Value & item,int type) const1292 bool PacMap::ToJsonArrayShort(std::vector<short> &array, Json::Value &item, int type) const
1293 {
1294     ABILITYBASE_LOGD("start");
1295     if (array.size() > 0) {
1296         for (size_t i = 0; i < array.size(); i++) {
1297             item["data"].append(array[i]);
1298         }
1299         item["type"] = type;
1300         return true;
1301     }
1302     return false;
1303 }
1304 // Base data: Integer
ToJsonArrayInt(std::vector<int> & array,Json::Value & item,int type) const1305 bool PacMap::ToJsonArrayInt(std::vector<int> &array, Json::Value &item, int type) const
1306 {
1307     ABILITYBASE_LOGD("start");
1308     if (array.size() > 0) {
1309         for (size_t i = 0; i < array.size(); i++) {
1310             item["data"].append(array[i]);
1311         }
1312         item["type"] = type;
1313         return true;
1314     }
1315     return false;
1316 }
1317 // Base data: long:sting
ToJsonArrayLong(std::vector<long> & array,Json::Value & item,int type) const1318 bool PacMap::ToJsonArrayLong(std::vector<long> &array, Json::Value &item, int type) const
1319 {
1320     if (array.size() > 0) {
1321         for (size_t i = 0; i < array.size(); i++) {
1322             item["data"].append(std::to_string(array[i]));
1323         }
1324         item["type"] = type;
1325         return true;
1326     }
1327     return false;
1328 }
1329 
1330 // Base data: byte
ToJsonArrayByte(std::vector<byte> & array,Json::Value & item,int type) const1331 bool PacMap::ToJsonArrayByte(std::vector<byte> &array, Json::Value &item, int type) const
1332 {
1333     ABILITYBASE_LOGD("start");
1334     if (array.size() > 0) {
1335         for (size_t i = 0; i < array.size(); i++) {
1336             item["data"].append(array[i]);
1337         }
1338         item["type"] = type;
1339         return true;
1340     }
1341     return false;
1342 }
1343 // Base data: bool
ToJsonArrayBoolean(std::vector<bool> & array,Json::Value & item,int type) const1344 bool PacMap::ToJsonArrayBoolean(std::vector<bool> &array, Json::Value &item, int type) const
1345 {
1346     if (array.size() > 0) {
1347         for (size_t i = 0; i < array.size(); i++) {
1348             item["data"].append((int)array[i]);
1349         }
1350         item["type"] = type;
1351         return true;
1352     }
1353     return false;
1354 }
1355 // Base data: Float to string
ToJsonArrayFloat(std::vector<float> & array,Json::Value & item,int type) const1356 bool PacMap::ToJsonArrayFloat(std::vector<float> &array, Json::Value &item, int type) const
1357 {
1358     if (array.size() > 0) {
1359         for (size_t i = 0; i < array.size(); i++) {
1360             item["data"].append(RawTypeToString<float>(array[i], FLOAT_PRECISION));
1361         }
1362         item["type"] = type;
1363         return true;
1364     }
1365     return false;
1366 }
1367 // Base data: Double to string
ToJsonArrayDouble(std::vector<double> & array,Json::Value & item,int type) const1368 bool PacMap::ToJsonArrayDouble(std::vector<double> &array, Json::Value &item, int type) const
1369 {
1370     if (array.size() > 0) {
1371         for (size_t i = 0; i < array.size(); i++) {
1372             item["data"].append(RawTypeToString<double>(array[i], DOUBLE_PRECISION));
1373         }
1374         item["type"] = type;
1375         return true;
1376     }
1377     return false;
1378 }
1379 // Base data: string
ToJsonArrayString(std::vector<std::string> & array,Json::Value & item,int type) const1380 bool PacMap::ToJsonArrayString(std::vector<std::string> &array, Json::Value &item, int type) const
1381 {
1382     ABILITYBASE_LOGD("start");
1383     if (array.size() > 0) {
1384         for (size_t i = 0; i < array.size(); i++) {
1385             item["data"].append(array[i]);
1386         }
1387         item["type"] = type;
1388         return true;
1389     }
1390     return false;
1391 }
1392 
GetArrayJsonValue(PacMapList::const_iterator & it,Json::Value & json) const1393 bool PacMap::GetArrayJsonValue(PacMapList::const_iterator &it, Json::Value &json) const
1394 {
1395     if (IArray::Query(it->second.GetRefPtr()) == nullptr) {
1396         return false;
1397     }
1398     IArray *array = static_cast<IArray *>(it->second.GetRefPtr());
1399     if (array == nullptr) {
1400         return false;
1401     }
1402     if (Array::IsShortArray(array)) {
1403         std::vector<short> arrayData;
1404         PacmapGetArrayVal<AAFwk::IShort, AAFwk::Short, short>(it->second.GetRefPtr(), arrayData);
1405         return ToJsonArrayShort(arrayData, json, PACMAP_DATA_ARRAY_SHORT);
1406     } else if (Array::IsIntegerArray(array)) {
1407         std::vector<int> arrayData;
1408         PacmapGetArrayVal<AAFwk::IInteger, AAFwk::Integer, int>(it->second.GetRefPtr(), arrayData);
1409         return ToJsonArrayInt(arrayData, json, PACMAP_DATA_ARRAY_INTEGER);
1410     } else if (Array::IsLongArray(array)) {
1411         std::vector<long> arrayData;
1412         PacmapGetArrayVal<AAFwk::ILong, AAFwk::Long, long>(it->second.GetRefPtr(), arrayData);
1413         return ToJsonArrayLong(arrayData, json, PACMAP_DATA_ARRAY_LONG);
1414     } else if (Array::IsCharArray(array)) {
1415         return false;
1416     } else if (Array::IsByteArray(array)) {
1417         std::vector<byte> arrayData;
1418         PacmapGetArrayVal<AAFwk::IByte, AAFwk::Byte, byte>(it->second.GetRefPtr(), arrayData);
1419         return ToJsonArrayByte(arrayData, json, PACMAP_DATA_ARRAY_BYTE);
1420     } else if (Array::IsBooleanArray(array)) {
1421         std::vector<bool> arrayData;
1422         PacmapGetArrayVal<AAFwk::IBoolean, AAFwk::Boolean, bool>(it->second.GetRefPtr(), arrayData);
1423         return ToJsonArrayBoolean(arrayData, json, PACMAP_DATA_ARRAY_BOOLEAN);
1424     } else if (Array::IsFloatArray(array)) {
1425         std::vector<float> arrayData;
1426         PacmapGetArrayVal<AAFwk::IFloat, AAFwk::Float, float>(it->second.GetRefPtr(), arrayData);
1427         return ToJsonArrayFloat(arrayData, json, PACMAP_DATA_ARRAY_FLOAT);
1428     } else if (Array::IsDoubleArray(array)) {
1429         std::vector<double> arrayData;
1430         PacmapGetArrayVal<AAFwk::IDouble, AAFwk::Double, double>(it->second.GetRefPtr(), arrayData);
1431         return ToJsonArrayDouble(arrayData, json, PACMAP_DATA_ARRAY_DOUBLE);
1432     } else if (Array::IsStringArray(array)) {
1433         std::vector<std::string> arrayData;
1434         PacmapGetArrayVal<AAFwk::IString, AAFwk::String, std::string>(it->second.GetRefPtr(), arrayData);
1435         return ToJsonArrayString(arrayData, json, PACMAP_DATA_ARRAY_STRING);
1436     } else {
1437         return false;
1438     }
1439     return true;
1440 }
GetUserObjectJsonValue(PacMapList::const_iterator & it,Json::Value & json) const1441 bool PacMap::GetUserObjectJsonValue(PacMapList::const_iterator &it, Json::Value &json) const
1442 {
1443     std::shared_ptr<UserObjectBase> myObjectBase = UserObject::Unbox(IUserObject::Query(it->second.GetRefPtr()));
1444     if (myObjectBase == nullptr) {
1445         return false;
1446     }
1447 
1448     std::string userObjectString = myObjectBase->ToString();
1449     Json::Value objectData;
1450 
1451     json["type"] = PACMAP_DATA_USEROBJECT;
1452     json["class"] = myObjectBase->GetClassName();
1453     json["data"] = userObjectString;
1454     return true;
1455 }
1456 
1457 /**
1458  * @brief Restore pacmap from the string.
1459  * @return Return true if successful, otherwise false.
1460  */
FromString(const std::string & str)1461 bool PacMap::FromString(const std::string &str)
1462 {
1463     std::lock_guard<std::mutex> mLock(mapLock_);
1464     dataList_.clear();
1465     return StringToMapList(str, dataList_);
1466 }
1467 
StringToMapList(const std::string & str,PacMapList & mapList)1468 bool PacMap::StringToMapList(const std::string &str, PacMapList &mapList)
1469 {
1470     if (str.empty()) {
1471         return false;
1472     }
1473 
1474     JSONCPP_STRING err;
1475     Json::Value root;
1476 
1477     const int rawJsonLength = static_cast<int>(str.length());
1478     Json::CharReaderBuilder builder;
1479     std::unique_ptr<Json::CharReader> jsonReader(builder.newCharReader());
1480     if (!jsonReader->parse(str.c_str(), str.c_str() + rawJsonLength, &root, &err)) {
1481         jsonReader.reset();
1482         return false;
1483     }
1484 
1485     if (!root.isObject() && !root.isNull()) {
1486         return false;
1487     }
1488 
1489     if (!root.isMember("pacmap")) {
1490         return false;
1491     }
1492 
1493     Json::Value dataObject = root["pacmap"];
1494     if (dataObject.isNull()) {
1495         return true;
1496     }
1497     return ParseJson(dataObject, mapList);
1498 }
1499 
ParseJson(Json::Value & data,PacMapList & mapList)1500 bool PacMap::ParseJson(Json::Value &data, PacMapList &mapList)
1501 {
1502     if (data.isNull() || !data.isObject()) {
1503         return false;
1504     }
1505     Json::Value::Members keyList = data.getMemberNames();
1506     if (keyList.size() == 0) {
1507         return false;
1508     }
1509     Json::Value item;
1510     for (size_t i = 0; i < keyList.size(); i++) {
1511         item = data[keyList[i]];
1512         if (!item.isNull() && item.isObject() && JudgeType(item)) {
1513             ParseJsonItem(mapList, keyList[i], item);
1514         }
1515     }
1516     return true;
1517 }
1518 
JudgeType(Json::Value & item)1519 bool PacMap::JudgeType(Json::Value &item)
1520 {
1521     if (item["type"].isInt()) {
1522         switch (item["type"].asInt()) {
1523             case PACMAP_DATA_SHORT:
1524                 return item["data"].isInt();
1525             case PACMAP_DATA_INTEGER:
1526                 return item["data"].isInt();
1527             case PACMAP_DATA_LONG:
1528                 return item["data"].isString();
1529             case PACMAP_DATA_CHAR:
1530                 return item["data"].isInt();
1531             case PACMAP_DATA_BYTE:
1532                 return item["data"].isInt();
1533             case PACMAP_DATA_BOOLEAN:
1534                 return item["data"].isBool() || item["data"].isInt();
1535             case PACMAP_DATA_FLOAT:
1536                 return item["data"].isString();
1537             case PACMAP_DATA_DOUBLE:
1538                 return item["data"].isString();
1539             case PACMAP_DATA_STRING:
1540                 return item["data"].isString();
1541             case PACMAP_DATA_USEROBJECT:
1542                 return item["data"].isString() && item["class"].isString();
1543             case PACMAP_DATA_PACMAP:
1544                 return true;
1545             default:
1546                 return item["data"].isArray();
1547         }
1548     }
1549     return false;
1550 }
1551 
ParseJsonItem(PacMapList & mapList,const std::string & key,Json::Value & item)1552 bool PacMap::ParseJsonItem(PacMapList &mapList, const std::string &key, Json::Value &item)
1553 {
1554     // base data, object data, arry data
1555     switch (item["type"].asInt()) {
1556         case PACMAP_DATA_SHORT:
1557             InnerPutShortValue(mapList, key, item["data"].asInt());
1558             break;
1559         case PACMAP_DATA_INTEGER:
1560             InnerPutIntValue(mapList, key, item["data"].asInt());
1561             break;
1562         case PACMAP_DATA_LONG:
1563             InnerPutLongValue(mapList, key, std::atol(item["data"].asString().c_str()));
1564             break;
1565         case PACMAP_DATA_CHAR:
1566             InnerPutCharValue(mapList, key, item["data"].asInt());
1567             break;
1568         case PACMAP_DATA_BYTE:
1569             InnerPutByteValue(mapList, key, item["data"].asInt());
1570             break;
1571         case PACMAP_DATA_BOOLEAN:
1572             InnerPutBooleanValue(mapList, key, item["data"].asBool());
1573             break;
1574         case PACMAP_DATA_FLOAT:
1575             InnerPutFloatValue(mapList, key, std::atof(item["data"].asString().c_str()));
1576             break;
1577         case PACMAP_DATA_DOUBLE:
1578             InnerPutDoubleValue(mapList, key, std::atof(item["data"].asString().c_str()));
1579             break;
1580         case PACMAP_DATA_STRING:
1581             InnerPutStringValue(mapList, key, item["data"].asString());
1582             break;
1583         case PACMAP_DATA_USEROBJECT:
1584             InnerPutObjectValue(mapList, key, item);
1585             break;
1586         case PACMAP_DATA_PACMAP:
1587             InnerPutPacMapValue(mapList, key, item);
1588             break;
1589         default:
1590             return ParseJsonItemArray(mapList, key, item);
1591     }
1592     return true;
1593 }
1594 
ParseJsonItemArray(PacMapList & mapList,const std::string & key,Json::Value & item)1595 bool PacMap::ParseJsonItemArray(PacMapList &mapList, const std::string &key, Json::Value &item)
1596 {
1597     switch (item["type"].asInt()) {
1598         case PACMAP_DATA_ARRAY_SHORT:
1599             return ParseJsonItemArrayShort(mapList, key, item);
1600         case PACMAP_DATA_ARRAY_INTEGER:
1601             return ParseJsonItemArrayInteger(mapList, key, item);
1602         case PACMAP_DATA_ARRAY_LONG:
1603             return ParseJsonItemArrayLong(mapList, key, item);
1604         case PACMAP_DATA_ARRAY_CHAR:
1605             return ParseJsonItemArrayChar(mapList, key, item);
1606         case PACMAP_DATA_ARRAY_BYTE:
1607             return ParseJsonItemArrayByte(mapList, key, item);
1608         case PACMAP_DATA_ARRAY_BOOLEAN:
1609             return ParseJsonItemArrayBoolean(mapList, key, item);
1610         case PACMAP_DATA_ARRAY_FLOAT:
1611             return ParseJsonItemArrayFloat(mapList, key, item);
1612         case PACMAP_DATA_ARRAY_DOUBLE:
1613             return ParseJsonItemArrayDouble(mapList, key, item);
1614         case PACMAP_DATA_ARRAY_STRING:
1615             return ParseJsonItemArrayString(mapList, key, item);
1616         default:
1617             return false;
1618     }
1619 }
1620 
ParseJsonItemArrayShort(PacMapList & mapList,const std::string & key,Json::Value & item)1621 bool PacMap::ParseJsonItemArrayShort(PacMapList &mapList, const std::string &key, Json::Value &item)
1622 {
1623     Json::Value arrayValue = item["data"];
1624     if (arrayValue.isNull()) {
1625         return true;
1626     }
1627 
1628     if (arrayValue.size() < 0 || arrayValue.size() > MAX_ARRAY_ALLOW_SIZE) {
1629         return false;
1630     }
1631 
1632     std::vector<short> shortList;
1633     for (Json::ArrayIndex i = 0; i < arrayValue.size(); i++) {
1634         if (!arrayValue[i].isInt()) {
1635             return false;
1636         }
1637         shortList.push_back(arrayValue[i].asInt());
1638     }
1639     InnerPutShortValueArray(mapList, key, shortList);
1640     return true;
1641 }
1642 
ParseJsonItemArrayInteger(PacMapList & mapList,const std::string & key,Json::Value & item)1643 bool PacMap::ParseJsonItemArrayInteger(PacMapList &mapList, const std::string &key, Json::Value &item)
1644 {
1645     Json::Value arrayValue = item["data"];
1646     if (arrayValue.isNull()) {
1647         return true;
1648     }
1649 
1650     if (arrayValue.size() < 0 || arrayValue.size() > MAX_ARRAY_ALLOW_SIZE) {
1651         return false;
1652     }
1653 
1654     std::vector<int> intList;
1655     for (Json::ArrayIndex i = 0; i < arrayValue.size(); i++) {
1656         if (!arrayValue[i].isInt()) {
1657             return false;
1658         }
1659         intList.push_back(arrayValue[i].asInt());
1660     }
1661     InnerPutIntValueArray(mapList, key, intList);
1662     return true;
1663 }
1664 /**
1665  * @brief Determine whether the string content is a numeric string
1666  * @param str indicates stirng.
1667  * @return bool
1668  */
IsNumber(const std::string & str)1669 bool PacMap::IsNumber(const std::string &str)
1670 {
1671     return std::regex_match(str, NUMBER_REGEX);
1672 }
1673 
ParseJsonItemArrayLong(PacMapList & mapList,const std::string & key,Json::Value & item)1674 bool PacMap::ParseJsonItemArrayLong(PacMapList &mapList, const std::string &key, Json::Value &item)
1675 {
1676     Json::Value arrayValue = item["data"];
1677 
1678     if (arrayValue.isNull()) {
1679         return true;
1680     }
1681 
1682     if (arrayValue.size() < 0 || arrayValue.size() > MAX_ARRAY_ALLOW_SIZE) {
1683         return false;
1684     }
1685 
1686     std::vector<long> longList;
1687     for (Json::ArrayIndex i = 0; i < arrayValue.size(); i++) {
1688         if (!arrayValue[i].isString() || !IsNumber(arrayValue[i].asString())) {
1689             return false;
1690         }
1691         long longVal = std::atol(arrayValue[i].asString().c_str());
1692         longList.push_back(longVal);
1693     }
1694     InnerPutLongValueArray(mapList, key, longList);
1695     return true;
1696 }
1697 
ParseJsonItemArrayChar(PacMapList & mapList,const std::string & key,Json::Value & item)1698 bool PacMap::ParseJsonItemArrayChar(PacMapList &mapList, const std::string &key, Json::Value &item)
1699 {
1700     Json::Value arrayValue = item["data"];
1701     if (arrayValue.isNull()) {
1702         return true;
1703     }
1704 
1705     if (arrayValue.size() < 0 || arrayValue.size() > MAX_ARRAY_ALLOW_SIZE) {
1706         return false;
1707     }
1708 
1709     std::vector<char> charList;
1710     for (Json::ArrayIndex i = 0; i < arrayValue.size(); i++) {
1711         if (!arrayValue[i].isInt()) {
1712             return false;
1713         }
1714         charList.push_back(arrayValue[i].asInt());
1715     }
1716     InnerPutCharValueArray(mapList, key, charList);
1717     return true;
1718 }
1719 
ParseJsonItemArrayByte(PacMapList & mapList,const std::string & key,Json::Value & item)1720 bool PacMap::ParseJsonItemArrayByte(PacMapList &mapList, const std::string &key, Json::Value &item)
1721 {
1722     Json::Value arrayValue = item["data"];
1723     if (arrayValue.isNull()) {
1724         return true;
1725     }
1726 
1727     if (arrayValue.size() < 0 || arrayValue.size() > MAX_ARRAY_ALLOW_SIZE) {
1728         return false;
1729     }
1730 
1731     std::vector<AAFwk::byte> byteList;
1732     for (Json::ArrayIndex i = 0; i < arrayValue.size(); i++) {
1733         if (!arrayValue[i].isInt()) {
1734             return false;
1735         }
1736         byteList.push_back(arrayValue[i].asInt());
1737     }
1738     InnerPutByteValueArray(mapList, key, byteList);
1739     return true;
1740 }
1741 
ParseJsonItemArrayBoolean(PacMapList & mapList,const std::string & key,Json::Value & item)1742 bool PacMap::ParseJsonItemArrayBoolean(PacMapList &mapList, const std::string &key, Json::Value &item)
1743 {
1744     Json::Value arrayValue = item["data"];
1745     if (arrayValue.isNull()) {
1746         return true;
1747     }
1748 
1749     if (arrayValue.size() < 0 || arrayValue.size() > MAX_ARRAY_ALLOW_SIZE) {
1750         return false;
1751     }
1752 
1753     std::vector<bool> boolList;
1754     for (Json::ArrayIndex i = 0; i < arrayValue.size(); i++) {
1755         if (!arrayValue[i].isBool() && !arrayValue[i].isInt()) {
1756             return false;
1757         }
1758         boolList.push_back(arrayValue[i].asBool());
1759     }
1760     InnerPutBooleanValueArray(mapList, key, boolList);
1761     return true;
1762 }
1763 
ParseJsonItemArrayFloat(PacMapList & mapList,const std::string & key,Json::Value & item)1764 bool PacMap::ParseJsonItemArrayFloat(PacMapList &mapList, const std::string &key, Json::Value &item)
1765 {
1766     Json::Value arrayValue = item["data"];
1767     if (arrayValue.isNull()) {
1768         return true;
1769     }
1770 
1771     if (arrayValue.size() < 0 || arrayValue.size() > MAX_ARRAY_ALLOW_SIZE) {
1772         return false;
1773     }
1774 
1775     std::vector<float> floatList;
1776     for (Json::ArrayIndex i = 0; i < arrayValue.size(); i++) {
1777         if (!arrayValue[i].isString()) {
1778             return false;
1779         }
1780         floatList.push_back(std::atof(arrayValue[i].asString().c_str()));
1781     }
1782     InnerPutFloatValueArray(mapList, key, floatList);
1783     return true;
1784 }
1785 
ParseJsonItemArrayDouble(PacMapList & mapList,const std::string & key,Json::Value & item)1786 bool PacMap::ParseJsonItemArrayDouble(PacMapList &mapList, const std::string &key, Json::Value &item)
1787 {
1788     Json::Value arrayValue = item["data"];
1789     if (arrayValue.isNull()) {
1790         return true;
1791     }
1792 
1793     if (arrayValue.size() < 0 || arrayValue.size() > MAX_ARRAY_ALLOW_SIZE) {
1794         return false;
1795     }
1796 
1797     std::vector<double> doubleList;
1798     for (Json::ArrayIndex i = 0; i < arrayValue.size(); i++) {
1799         if (!arrayValue[i].isString()) {
1800             return false;
1801         }
1802         doubleList.push_back(std::atof(arrayValue[i].asString().c_str()));
1803     }
1804     InnerPutDoubleValueArray(mapList, key, doubleList);
1805     return true;
1806 }
1807 
ParseJsonItemArrayString(PacMapList & mapList,const std::string & key,Json::Value & item)1808 bool PacMap::ParseJsonItemArrayString(PacMapList &mapList, const std::string &key, Json::Value &item)
1809 {
1810     Json::Value arrayValue = item["data"];
1811     if (arrayValue.isNull()) {
1812         return true;
1813     }
1814 
1815     if (arrayValue.size() < 0 || arrayValue.size() > MAX_ARRAY_ALLOW_SIZE) {
1816         return false;
1817     }
1818 
1819     std::vector<std::string> stringList;
1820     for (Json::ArrayIndex i = 0; i < arrayValue.size(); i++) {
1821         if (!arrayValue[i].isString()) {
1822             return false;
1823         }
1824         stringList.push_back(arrayValue[i].asString());
1825     }
1826     InnerPutStringValueArray(mapList, key, stringList);
1827     return true;
1828 }
1829 
InnerPutObjectValue(PacMapList & mapList,const std::string & key,Json::Value & item)1830 bool PacMap::InnerPutObjectValue(PacMapList &mapList, const std::string &key, Json::Value &item)
1831 {
1832     std::string className = item["class"].asString();
1833     if (className.empty()) {
1834         return false;
1835     }
1836 
1837     UserObjectBase *userObjectIns = UserObjectBaseLoader::GetInstance().GetUserObjectByName(className);
1838     if (userObjectIns == nullptr) {
1839         return false;
1840     }
1841 
1842     std::string userObjectString = item["data"].asString();
1843     if (!userObjectString.empty()) {
1844         userObjectIns->Parse(userObjectString);
1845     }
1846 
1847     std::shared_ptr<UserObjectBase> userObject(userObjectIns);
1848     InnerPutObject(mapList, key, userObject);
1849     return true;
1850 }
1851 
InnerPutPacMapValue(PacMapList & mapList,const std::string & key,Json::Value & item)1852 bool PacMap::InnerPutPacMapValue(PacMapList &mapList, const std::string &key, Json::Value &item)
1853 {
1854     Json::Value value = item["data"];
1855 
1856     if (value.isNull()) {
1857         return false;
1858     }
1859     PacMap *p = new (std::nothrow) PacMap();
1860     if (p == nullptr) {
1861         return false;
1862     }
1863     sptr<IPacMap> sp = p;
1864     if (p->ParseJson(value, p->dataList_)) {
1865         mapList.emplace(key, sp);
1866         return true;
1867     }
1868 
1869     return false;
1870 }
1871 
Equals(IObject & other)1872 bool PacMap::Equals(IObject &other)
1873 {
1874     PacMap *otherObj = static_cast<PacMap *>(IPacMap::Query(&other));
1875     if (otherObj == nullptr) {
1876         return false;
1877     }
1878 
1879     return Equals(otherObj);
1880 }
1881 
Parse(const std::string & str)1882 sptr<IPacMap> PacMap::Parse(const std::string &str)
1883 {
1884     PacMap *pacmap = new (std::nothrow) PacMap();
1885     if (pacmap != nullptr) {
1886         pacmap->StringToMapList(str, pacmap->dataList_);
1887     }
1888     sptr<IPacMap> ret = pacmap;
1889 
1890     return ret;
1891 }
1892 }  // namespace AppExecFwk
1893 }  // namespace OHOS
1894