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