1 /*
2  * Copyright (c) 2024 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 "preferences_value_parcel.h"
17 
18 #include "log_print.h"
19 #include "preferences_errno.h"
20 #include "securec.h"
21 
22 namespace OHOS {
23 namespace NativePreferences {
24 
GetTypeIndex(const PreferencesValue & value)25 uint8_t PreferencesValueParcel::GetTypeIndex(const PreferencesValue &value)
26 {
27     if (value.IsInt()) {
28         return INT_TYPE;
29     } else if (value.IsLong()) {
30         return LONG_TYPE;
31     } else if (value.IsFloat()) {
32         return FLOAT_TYPE;
33     } else if (value.IsDouble()) {
34         return DOUBLE_TYPE;
35     } else if (value.IsBool()) {
36         return BOOL_TYPE;
37     } else if (value.IsString()) {
38         return STRING_TYPE;
39     } else if (value.IsStringArray()) {
40         return STRING_ARRAY_TYPE;
41     } else if (value.IsBoolArray()) {
42         return BOOL_ARRAY_TYPE;
43     } else if (value.IsDoubleArray()) {
44         return DOUBLE_ARRAY_TYPE;
45     } else if (value.IsUint8Array()) {
46         return UINT8_ARRAY_TYPE;
47     } else if (value.IsObject()) {
48         return OBJECT_TYPE;
49     } else if (value.IsBigInt()) {
50         return BIG_INT_TYPE;
51     } else {
52         return MONO_TYPE;
53     }
54 }
55 
CalSize(PreferencesValue value)56 uint32_t PreferencesValueParcel::CalSize(PreferencesValue value)
57 {
58     uint8_t type = GetTypeIndex(value);
59     switch (type) {
60         case INT_TYPE:
61             return sizeof(uint8_t) + sizeof(int);
62         case LONG_TYPE:
63             return sizeof(uint8_t) + sizeof(int64_t);
64         case FLOAT_TYPE:
65             return sizeof(uint8_t) + sizeof(float);
66         case DOUBLE_TYPE:
67             return sizeof(uint8_t) + sizeof(double);
68         case BOOL_TYPE:
69             return sizeof(uint8_t) + sizeof(bool);
70         case OBJECT_TYPE:
71         case STRING_TYPE: {
72             uint32_t strLen = sizeof(uint8_t) + sizeof(size_t);
73             strLen += (type == STRING_TYPE) ? std::get<std::string>(value.value_).size() :
74                 std::get<Object>(value.value_).valueStr.size();
75             return  strLen;
76         }
77         case BOOL_ARRAY_TYPE:
78             return sizeof(uint8_t) + sizeof(size_t) + std::get<std::vector<bool>>(value.value_).size() * sizeof(bool);
79         case DOUBLE_ARRAY_TYPE:
80             return sizeof(uint8_t) + sizeof(size_t) +
81                 std::get<std::vector<double>>(value.value_).size() * sizeof(double);
82         case UINT8_ARRAY_TYPE:
83             return sizeof(uint8_t) + sizeof(size_t) +
84                 ((std::get<std::vector<uint8_t>>(value.value_).size()) * sizeof(uint8_t));
85         case STRING_ARRAY_TYPE: {
86             uint32_t strArrBlobLen = sizeof(uint8_t) + sizeof(size_t);
87             std::vector<std::string> strVec = std::get<std::vector<std::string>>(value.value_);
88 
89             for (size_t i = 0; i < strVec.size(); i++) {
90                 strArrBlobLen += sizeof(size_t);
91                 strArrBlobLen += strVec[i].size();
92             }
93             return strArrBlobLen;
94         }
95         case BIG_INT_TYPE:
96             return sizeof(uint8_t) + sizeof(size_t) + sizeof(int64_t) +
97                 std::get<BigInt>(value.value_).words_.size() * sizeof(uint64_t);
98         default:
99             break;
100     }
101     return 0;
102 }
103 
MarshallingBasicValueInner(const PreferencesValue & value,const uint8_t type,std::vector<uint8_t> & data)104 int PreferencesValueParcel::MarshallingBasicValueInner(const PreferencesValue &value, const uint8_t type,
105     std::vector<uint8_t> &data)
106 {
107     uint8_t *startAddr = data.data();
108     size_t basicDataLen = 0;
109     if (data.size() <= sizeof(uint8_t)) {
110         LOG_ERROR("memcpy error when marshalling basic value, type: %{public}d", type);
111         return E_ERROR;
112     }
113     size_t memLen = data.size() - sizeof(uint8_t);
114     int errCode = E_OK;
115     switch (type) {
116         case INT_TYPE: {
117             int intValue = std::get<int>(value.value_);
118             basicDataLen = sizeof(int);
119             errCode = memcpy_s(startAddr + sizeof(uint8_t), memLen, &intValue, basicDataLen);
120             break;
121         }
122         case LONG_TYPE: {
123             int64_t longValue = std::get<int64_t>(value.value_);
124             basicDataLen = sizeof(int64_t);
125             errCode = memcpy_s(startAddr + sizeof(uint8_t), memLen, &longValue, basicDataLen);
126             break;
127         }
128         case FLOAT_TYPE: {
129             float floatValue = std::get<float>(value.value_);
130             basicDataLen = sizeof(float);
131             errCode = memcpy_s(startAddr + sizeof(uint8_t), memLen, &floatValue, basicDataLen);
132             break;
133         }
134         case DOUBLE_TYPE: {
135             double doubleValue = std::get<double>(value.value_);
136             basicDataLen = sizeof(double);
137             errCode = memcpy_s(startAddr + sizeof(uint8_t), memLen, &doubleValue, basicDataLen);
138             break;
139         }
140         case BOOL_TYPE: {
141             bool boolValue = std::get<bool>(value.value_);
142             basicDataLen = sizeof(bool);
143             errCode = memcpy_s(startAddr + sizeof(uint8_t), memLen, &boolValue, basicDataLen);
144             break;
145         }
146         default:
147             break;
148     }
149 
150     if (errCode != E_OK) {
151         LOG_ERROR("memcpy failed when marshalling basic value, %{public}d", errCode);
152         return E_ERROR;
153     }
154     return E_OK;
155 }
156 
157 /**
158  *     ------------------------
159  *     |  type  |   BasicData   |
160  *     ------------------------
161  * len:  uint8_t   sizeof(int) or size of(Bool) e.g.
162 */
MarshallingBasicValue(const PreferencesValue & value,const uint8_t type,std::vector<uint8_t> & data)163 int PreferencesValueParcel::MarshallingBasicValue(const PreferencesValue &value, const uint8_t type,
164     std::vector<uint8_t> &data)
165 {
166     uint8_t *startAddr = data.data();
167     int errCode = memcpy_s(startAddr, data.size(), &type, sizeof(uint8_t));
168     if (errCode != E_OK) {
169         LOG_ERROR("memcpy failed when marshalling basic value's type, %{public}d", errCode);
170         return E_NOT_SUPPORTED;
171     }
172     return MarshallingBasicValueInner(value, type, data);
173 }
174 
175 /**
176  *     -------------------------------------
177  *     |  type  |   strLen   |   strData   |
178  *     -------------------------------------
179  * len:  uint8_t   size_t        strLen
180 */
MarshallingStringValue(const PreferencesValue & value,const uint8_t type,std::vector<uint8_t> & data)181 int PreferencesValueParcel::MarshallingStringValue(const PreferencesValue &value, const uint8_t type,
182     std::vector<uint8_t> &data)
183 {
184     std::string stringValue;
185     if (type == OBJECT_TYPE) {
186         Object objValue = std::get<Object>(value.value_);
187         stringValue = objValue.valueStr;
188     } else {
189         // it's string type
190         stringValue = std::get<std::string>(value.value_);
191     }
192     uint8_t *startAddr = data.data();
193     int errCode = memcpy_s(startAddr, sizeof(uint8_t), &type, sizeof(uint8_t));
194     if (errCode != E_OK) {
195         LOG_ERROR("memcpy failed when marshalling string value's type, %{public}d", errCode);
196         return -E_ERROR;
197     }
198     size_t strLen = stringValue.size();
199     errCode = memcpy_s(startAddr + sizeof(uint8_t), sizeof(size_t), &strLen, sizeof(size_t));
200     if (errCode != E_OK) {
201         LOG_ERROR("memcpy failed when marshalling string value's str len, %{public}d", errCode);
202         return -E_ERROR;
203     }
204     if (strLen == 0) {
205         return E_OK;
206     }
207     errCode = memcpy_s(startAddr + sizeof(uint8_t) + sizeof(size_t), strLen,
208         stringValue.c_str(), strLen);
209     if (errCode != E_OK) {
210         LOG_ERROR("memcpy failed when marshalling string value's str data, %{public}d", errCode);
211         return -E_ERROR;
212     }
213     return E_OK;
214 }
215 
216 /**
217  *     --------------------------------------------------------------------
218  *     |  type  |   vec_num   |  len1  |  str1  |  len2  |  str2  |  ...  |
219  *     --------------------------------------------------------------------
220  * len:  uint8_t   size_t        sizet     len1    size_t   len2
221 */
MarshallingStringArrayValue(const PreferencesValue & value,const uint8_t type,std::vector<uint8_t> & data)222 int PreferencesValueParcel::MarshallingStringArrayValue(const PreferencesValue &value, const uint8_t type,
223     std::vector<uint8_t> &data)
224 {
225     std::vector<std::string> strVec = std::get<std::vector<std::string>>(value.value_);
226     uint8_t *startAddr = data.data();
227     // write type into data
228     int errCode = memcpy_s(startAddr, sizeof(uint8_t), &type, sizeof(uint8_t));
229     if (errCode != E_OK) {
230         LOG_ERROR("memcpy failed when marshalling string array value's type, %{public}d", errCode);
231         return -E_ERROR;
232     }
233     startAddr += sizeof(uint8_t);
234 
235     // write vector size into data
236     size_t vecNum = strVec.size();
237     errCode = memcpy_s(startAddr, sizeof(size_t), &vecNum, sizeof(size_t));
238     if (errCode != E_OK) {
239         LOG_ERROR("memcpy failed when marshalling string array value's vector num, %{public}d", errCode);
240         return -E_ERROR;
241     }
242     startAddr += sizeof(size_t);
243 
244     // write every single str into data
245     for (size_t i = 0; i < vecNum; i++) {
246         size_t strLen = strVec[i].size();
247         errCode = memcpy_s(startAddr, sizeof(size_t), &strLen, sizeof(size_t));
248         if (errCode != E_OK) {
249             LOG_ERROR("memcpy failed when marshalling string array value's str len, %{public}d", errCode);
250             return -E_ERROR;
251         }
252         startAddr += sizeof(size_t);
253         if (strLen == 0) {
254             continue;
255         }
256         errCode = memcpy_s(startAddr, strLen, strVec[i].c_str(), strLen);
257         if (errCode != E_OK) {
258             LOG_ERROR("memcpy failed when marshalling string array value's str data, %{public}d", errCode);
259             return -E_ERROR;
260         }
261         startAddr += strLen;
262     }
263     return E_OK;
264 }
265 
MarshallingVecUInt8AfterType(const PreferencesValue & value,uint8_t * startAddr)266 int PreferencesValueParcel::MarshallingVecUInt8AfterType(const PreferencesValue &value, uint8_t *startAddr)
267 {
268     std::vector<uint8_t> vec = std::get<std::vector<uint8_t>>(value.value_);
269     size_t vecNum = vec.size();
270     // write vec num
271     int errCode = memcpy_s(startAddr, sizeof(size_t), &vecNum, sizeof(size_t));
272     if (errCode != E_OK) {
273         LOG_ERROR("memcpy failed when marshalling uint8 array value's vector num, %{public}d", errCode);
274         return E_ERROR;
275     }
276     if (vecNum == 0) {
277         return E_OK;
278     }
279     startAddr += sizeof(size_t);
280     errCode = memcpy_s(startAddr, vecNum * sizeof(uint8_t), vec.data(), vecNum * sizeof(uint8_t));
281     if (errCode != E_OK) {
282         LOG_ERROR("memcpy failed when marshalling uint8 array value's data, %{public}d", errCode);
283         return E_ERROR;
284     }
285     return errCode;
286 }
287 
288 /**
289  *     --------------------------------------------------------------------------
290  *     |  type  |  vec_num  |    sign    |     data1     |     data2     | .... |
291  *     --------------------------------------------------------------------------
292  * len:  uint8_t   size_t   sizeof(int64_t)  sizeof(int64_t)    sizeof(int64_t)
293 */
MarshallingVecBigIntAfterType(const PreferencesValue & value,uint8_t * startAddr)294 int PreferencesValueParcel::MarshallingVecBigIntAfterType(const PreferencesValue &value, uint8_t *startAddr)
295 {
296     BigInt bigIntValue = std::get<BigInt>(value.value_);
297     int64_t sign = static_cast<int64_t>(bigIntValue.sign_);
298     std::vector<uint64_t> words = bigIntValue.words_;
299 
300     // write vec num
301     size_t vecNum = words.size();
302     int errCode = memcpy_s(startAddr, sizeof(size_t), &vecNum, sizeof(size_t));
303     if (errCode != E_OK) {
304         LOG_ERROR("memcpy failed when marshalling bigInt array value's vector num, %{public}d", errCode);
305         return E_ERROR;
306     }
307     startAddr += sizeof(size_t);
308 
309     // write sign
310     errCode = memcpy_s(startAddr, sizeof(int64_t), &sign, sizeof(int64_t));
311     if (errCode != E_OK) {
312         LOG_ERROR("memcpy failed when marshalling bigInt array value's sign, %{public}d", errCode);
313         return E_ERROR;
314     }
315     startAddr += sizeof(int64_t);
316 
317     // write vec element
318     for (size_t i = 0; i < vecNum; i++) {
319         uint64_t item = words[i];
320         errCode = memcpy_s(startAddr, sizeof(uint64_t), &item, sizeof(uint64_t));
321         if (errCode != E_OK) {
322             LOG_ERROR("memcpy failed when marshalling bigInt array value's words, %{public}d", errCode);
323             return E_ERROR;
324         }
325         startAddr += sizeof(uint64_t);
326     }
327     return errCode;
328 }
329 
MarshallingVecDoubleAfterType(const PreferencesValue & value,uint8_t * startAddr)330 int PreferencesValueParcel::MarshallingVecDoubleAfterType(const PreferencesValue &value, uint8_t *startAddr)
331 {
332     std::vector<double> vec = std::get<std::vector<double>>(value.value_);
333     size_t vecNum = vec.size();
334     // write vec num
335     int errCode = memcpy_s(startAddr, sizeof(size_t), &vecNum, sizeof(size_t));
336     if (errCode != E_OK) {
337         LOG_ERROR("memcpy failed when marshalling double array value's vector num, %{public}d", errCode);
338         return E_ERROR;
339     }
340     startAddr += sizeof(size_t);
341 
342     // write vec element
343     for (size_t i = 0; i < vecNum; i++) {
344         double item = vec[i];
345         errCode = memcpy_s(startAddr, sizeof(double), &item, sizeof(double));
346         if (errCode != E_OK) {
347             LOG_ERROR("memcpy failed when marshalling double array value's vector data, %{public}d", errCode);
348             return E_ERROR;
349         }
350         startAddr += sizeof(double);
351     }
352     return errCode;
353 }
354 
MarshallingVecBoolAfterType(const PreferencesValue & value,uint8_t * startAddr)355 int PreferencesValueParcel::MarshallingVecBoolAfterType(const PreferencesValue &value, uint8_t *startAddr)
356 {
357     const std::vector<bool> vec = std::get<std::vector<bool>>(value.value_);
358     size_t vecNum = vec.size();
359     // write vec num
360     int errCode = memcpy_s(startAddr, sizeof(size_t), &vecNum, sizeof(size_t));
361     if (errCode != E_OK) {
362         LOG_ERROR("memcpy failed when marshalling bool array value's vector num, %{public}d", errCode);
363         return E_ERROR;
364     }
365     startAddr += sizeof(size_t);
366 
367     // write vec element
368     for (size_t i = 0; i < vecNum; i++) {
369         bool item = vec[i];
370         errCode = memcpy_s(startAddr, sizeof(bool), &item, sizeof(bool));
371         if (errCode != E_OK) {
372             LOG_ERROR("memcpy failed when marshalling bool array value's vector data, %{public}d", errCode);
373             return E_ERROR;
374         }
375         startAddr += sizeof(bool);
376     }
377     return errCode;
378 }
379 
380 /**
381  *     -----------------------------------------------------------------------
382  *     |  type  |  vec_num  |    data1    |    data2    |    data3    | .... |
383  *     ----------------------------------------------------------------------
384  * len:  uint8_t   size_t     sizeof(typ)    sizeof(typ)
385 */
MarshallingBasicArrayValue(const PreferencesValue & value,const uint8_t type,std::vector<uint8_t> & data)386 int PreferencesValueParcel::MarshallingBasicArrayValue(const PreferencesValue &value, const uint8_t type,
387     std::vector<uint8_t> &data)
388 {
389     uint8_t *startAddr = data.data();
390     int errCode = memcpy_s(startAddr, sizeof(uint8_t), &type, sizeof(uint8_t));
391     if (errCode != E_OK) {
392         LOG_ERROR("memcpy failed when marshalling basic array value's type, %{public}d", errCode);
393         return E_ERROR;
394     }
395     // write type
396     startAddr += sizeof(uint8_t);
397 
398     switch (type) {
399         case UINT8_ARRAY_TYPE:
400             errCode = MarshallingVecUInt8AfterType(value, startAddr);
401             break;
402         case BIG_INT_TYPE:
403             errCode = MarshallingVecBigIntAfterType(value, startAddr);
404             break;
405         case DOUBLE_ARRAY_TYPE:
406             errCode = MarshallingVecDoubleAfterType(value, startAddr);
407             break;
408         case BOOL_ARRAY_TYPE:
409             errCode = MarshallingVecBoolAfterType(value, startAddr);
410             break;
411         default:
412             errCode = E_INVALID_ARGS;
413             break;
414     }
415     return errCode;
416 }
417 
MarshallingPreferenceValue(const PreferencesValue & value,std::vector<uint8_t> & data)418 int PreferencesValueParcel::MarshallingPreferenceValue(const PreferencesValue &value, std::vector<uint8_t> &data)
419 {
420     int errCode = E_OK;
421     uint8_t type = GetTypeIndex(value);
422     switch (type) {
423         case INT_TYPE:
424         case LONG_TYPE:
425         case FLOAT_TYPE:
426         case DOUBLE_TYPE:
427         case BOOL_TYPE:
428             errCode = MarshallingBasicValue(value, type, data);
429             break;
430         case STRING_TYPE:
431         case OBJECT_TYPE:
432             errCode = MarshallingStringValue(value, type, data);
433             break;
434         case STRING_ARRAY_TYPE:
435             errCode = MarshallingStringArrayValue(value, type, data);
436             break;
437         case UINT8_ARRAY_TYPE:
438         case BIG_INT_TYPE:
439         case DOUBLE_ARRAY_TYPE:
440         case BOOL_ARRAY_TYPE:
441             errCode = MarshallingBasicArrayValue(value, type, data);
442             break;
443         default:
444             errCode = E_INVALID_ARGS;
445             LOG_ERROR("MarshallingPreferenceValue failed, type invalid, %{public}d", errCode);
446             break;
447     }
448     return errCode;
449 }
450 
UnmarshallingBasicValue(const uint8_t type,const std::vector<uint8_t> & data)451 std::pair<int, PreferencesValue> PreferencesValueParcel::UnmarshallingBasicValue(const uint8_t type,
452     const std::vector<uint8_t> &data)
453 {
454     const uint8_t *startAddr = data.data();
455     switch (type) {
456         case INT_TYPE: {
457             const int intValue = *(reinterpret_cast<const int *>(startAddr + sizeof(uint8_t)));
458             return std::make_pair(E_OK, PreferencesValue(intValue));
459         }
460         case LONG_TYPE: {
461             const int64_t longValue = *(reinterpret_cast<const int64_t *>(startAddr + sizeof(uint8_t)));
462             return std::make_pair(E_OK, PreferencesValue(longValue));
463         }
464         case FLOAT_TYPE: {
465             const float floatValue = *(reinterpret_cast<const float *>(startAddr + sizeof(uint8_t)));
466             return std::make_pair(E_OK, PreferencesValue(floatValue));
467         }
468         case DOUBLE_TYPE: {
469             const double doubleValue = *(reinterpret_cast<const double *>(startAddr + sizeof(uint8_t)));
470             return std::make_pair(E_OK, PreferencesValue(doubleValue));
471         }
472         case BOOL_TYPE: {
473             const bool boolValue = *(reinterpret_cast<const bool *>(startAddr + sizeof(uint8_t)));
474             return std::make_pair(E_OK, PreferencesValue(boolValue));
475         }
476         default:
477             break;
478     }
479     return std::make_pair(E_INVALID_ARGS, PreferencesValue(0));
480 }
481 
UnmarshallingStringValue(const uint8_t type,const std::vector<uint8_t> & data)482 std::pair<int, PreferencesValue> PreferencesValueParcel::UnmarshallingStringValue(const uint8_t type,
483     const std::vector<uint8_t> &data)
484 {
485     const uint8_t *startAddr = data.data();
486     std::string strValue;
487     size_t strLen = *(reinterpret_cast<const size_t *>(startAddr + sizeof(uint8_t)));
488     if (strLen == 0) {
489         strValue = "";
490     } else {
491         strValue.resize(strLen);
492         strValue.assign(startAddr + sizeof(uint8_t) + sizeof(size_t), startAddr + sizeof(uint8_t) + sizeof(size_t) +
493             strLen);
494     }
495 
496     if (type == OBJECT_TYPE) {
497         Object obj;
498         obj.valueStr = strValue;
499         return std::make_pair(E_OK, PreferencesValue(obj));
500     } else if (type == STRING_TYPE) {
501         return std::make_pair(E_OK, PreferencesValue(strValue));
502     }
503     return std::make_pair(E_INVALID_ARGS, PreferencesValue(0));
504 }
505 
UnmarshallingStringArrayValue(const uint8_t type,const std::vector<uint8_t> & data)506 std::pair<int, PreferencesValue> PreferencesValueParcel::UnmarshallingStringArrayValue(const uint8_t type,
507     const std::vector<uint8_t> &data)
508 {
509     if (type != STRING_ARRAY_TYPE) {
510         return std::make_pair(E_INVALID_ARGS, PreferencesValue(0));
511     }
512 
513     const uint8_t *startAddr = data.data() + sizeof(uint8_t);
514     size_t vecNum = *(reinterpret_cast<const size_t *>(startAddr));
515     startAddr += sizeof(size_t);
516 
517     std::vector<std::string> strVec;
518     strVec.resize(vecNum);
519     for (size_t i = 0; i < vecNum; i++) {
520         size_t strLen = *(reinterpret_cast<const size_t *>(startAddr));
521         startAddr += sizeof(size_t);
522         std::string strValue;
523         if (strLen == 0) {
524             strValue = "";
525         } else {
526             strValue.resize(strLen);
527             strValue.assign(startAddr, startAddr + strLen);
528         }
529         strVec[i] = strValue;
530         startAddr += strLen;
531     }
532     return std::make_pair(E_OK, PreferencesValue(strVec));
533 }
534 
UnmarshallingVecUInt8(const std::vector<uint8_t> & data)535 std::pair<int, PreferencesValue> PreferencesValueParcel::UnmarshallingVecUInt8(const std::vector<uint8_t> &data)
536 {
537     const uint8_t *startAddr = data.data() + sizeof(uint8_t);
538     size_t vecNum = *(reinterpret_cast<const size_t *>(startAddr));
539     startAddr += sizeof(size_t);
540 
541     std::vector<uint8_t> vec;
542     vec.resize(vecNum);
543     for (size_t i = 0; i < vecNum; i++) {
544         uint8_t element = *(reinterpret_cast<const uint8_t *>(startAddr));
545         vec[i] = element;
546         startAddr += sizeof(uint8_t);
547     }
548     return std::make_pair(E_OK, PreferencesValue(vec));
549 }
550 
UnmarshallingVecDouble(const std::vector<uint8_t> & data)551 std::pair<int, PreferencesValue> PreferencesValueParcel::UnmarshallingVecDouble(const std::vector<uint8_t> &data)
552 {
553     const uint8_t *startAddr = data.data() + sizeof(uint8_t);
554     size_t vecNum = *(reinterpret_cast<const size_t *>(startAddr));
555     startAddr += sizeof(size_t);
556 
557     std::vector<double> vec;
558     vec.resize(vecNum);
559     for (size_t i = 0; i < vecNum; i++) {
560         double element = *(reinterpret_cast<const double *>(startAddr));
561         vec[i] = element;
562         startAddr += sizeof(double);
563     }
564     return std::make_pair(E_OK, PreferencesValue(vec));
565 }
566 
UnmarshallingVecBool(const std::vector<uint8_t> & data)567 std::pair<int, PreferencesValue> PreferencesValueParcel::UnmarshallingVecBool(const std::vector<uint8_t> &data)
568 {
569     const uint8_t *startAddr = data.data() + sizeof(uint8_t);
570     size_t vecNum = *(reinterpret_cast<const size_t *>(startAddr));
571     startAddr += sizeof(size_t);
572 
573     std::vector<bool> vec;
574     vec.resize(vecNum);
575     for (size_t i = 0; i < vecNum; i++) {
576         bool element = *(reinterpret_cast<const bool *>(startAddr));
577         vec[i] = element;
578         startAddr += sizeof(bool);
579     }
580     return std::make_pair(E_OK, PreferencesValue(vec));
581 }
582 
UnmarshallingVecBigInt(const std::vector<uint8_t> & data)583 std::pair<int, PreferencesValue> PreferencesValueParcel::UnmarshallingVecBigInt(const std::vector<uint8_t> &data)
584 {
585     const uint8_t *startAddr = data.data() + sizeof(uint8_t);
586     size_t vecNum = *(reinterpret_cast<const size_t *>(startAddr));
587     startAddr += sizeof(size_t);
588 
589     int64_t sign = *(reinterpret_cast<const int64_t *>(startAddr));
590     startAddr += sizeof(int64_t);
591 
592     std::vector<uint64_t> vec;
593     vec.resize(vecNum);
594     for (size_t i = 0; i < vecNum; i++) {
595         uint64_t element = *(reinterpret_cast<const uint64_t *>(startAddr));
596         vec[i] = element;
597         startAddr += sizeof(uint64_t);
598     }
599     BigInt bigIntValue = BigInt(vec, sign);
600     return std::make_pair(E_OK, PreferencesValue(bigIntValue));
601 }
602 
UnmarshallingBasicArrayValue(const uint8_t type,const std::vector<uint8_t> & data)603 std::pair<int, PreferencesValue> PreferencesValueParcel::UnmarshallingBasicArrayValue(const uint8_t type,
604     const std::vector<uint8_t> &data)
605 {
606     switch (type) {
607         case UINT8_ARRAY_TYPE:
608             return UnmarshallingVecUInt8(data);
609             break;
610         case BIG_INT_TYPE:
611             return UnmarshallingVecBigInt(data);
612             break;
613         case DOUBLE_ARRAY_TYPE:
614             return UnmarshallingVecDouble(data);
615             break;
616         case BOOL_ARRAY_TYPE:
617             return UnmarshallingVecBool(data);
618             break;
619         default:
620             break;
621     }
622     return std::make_pair(E_INVALID_ARGS, PreferencesValue(0));
623 }
624 
UnmarshallingPreferenceValue(const std::vector<uint8_t> & data)625 std::pair<int, PreferencesValue> PreferencesValueParcel::UnmarshallingPreferenceValue(const std::vector<uint8_t> &data)
626 {
627     PreferencesValue value(0);
628     if (data.empty()) {
629         LOG_ERROR("UnmarshallingPreferenceValue failed, data empty, %{public}d", E_INVALID_ARGS);
630         return std::make_pair(E_INVALID_ARGS, value);
631     }
632     uint8_t type = data[0];
633 
634     switch (type) {
635         case INT_TYPE:
636         case LONG_TYPE:
637         case FLOAT_TYPE:
638         case DOUBLE_TYPE:
639         case BOOL_TYPE:
640             return UnmarshallingBasicValue(type, data);
641         case OBJECT_TYPE:
642         case STRING_TYPE:
643             return UnmarshallingStringValue(type, data);
644         case STRING_ARRAY_TYPE:
645             return UnmarshallingStringArrayValue(type, data);
646         case UINT8_ARRAY_TYPE:
647         case BIG_INT_TYPE:
648         case DOUBLE_ARRAY_TYPE:
649         case BOOL_ARRAY_TYPE:
650             return UnmarshallingBasicArrayValue(type, data);
651         default:
652             break;
653     }
654 
655     return std::make_pair(E_INVALID_ARGS, value);
656 }
657 } // namespace NativePreferences
658 } // namespace OHOS