• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #define LOG_TAG "TlvUtil"
17 
18 #include "tlv_util.h"
19 #include "udmf_utils.h"
20 #include "logger.h"
21 #include "tlv_object.h"
22 
23 namespace OHOS {
24 namespace TLVUtil {
CountBufferSize(const std::nullptr_t & input,TLVObject & data)25 template <> size_t CountBufferSize(const std::nullptr_t &input, TLVObject &data)
26 {
27     return data.CountHead();
28 }
29 
Writing(const std::nullptr_t & input,TLVObject & data,TAG tag)30 template <> bool Writing(const std::nullptr_t &input, TLVObject &data, TAG tag)
31 {
32     InitWhenFirst(input, data);
33     return data.WriteHead(static_cast<uint16_t>(tag), 0);
34 }
35 
Reading(std::nullptr_t & output,TLVObject & data,const TLVHead & head)36 template <> bool Reading(std::nullptr_t &output, TLVObject &data, const TLVHead &head)
37 {
38     return data.Read(output, head);
39 }
40 
CountBufferSize(const std::monostate & input,TLVObject & data)41 template <> size_t CountBufferSize(const std::monostate &input, TLVObject &data)
42 {
43     return data.Count(input);
44 }
45 
Writing(const std::monostate & input,TLVObject & data,TAG tag)46 template <> bool Writing(const std::monostate &input, TLVObject &data, TAG tag)
47 {
48     InitWhenFirst(input, data);
49     return data.Write(tag, input);
50 }
51 
Reading(std::monostate & output,TLVObject & data,const TLVHead & head)52 template <> bool Reading(std::monostate &output, TLVObject &data, const TLVHead &head)
53 {
54     return data.Read(output, head);
55 }
56 
CountBufferSize(const std::string & input,TLVObject & data)57 template <> size_t CountBufferSize(const std::string &input, TLVObject &data)
58 {
59     return data.Count(input);
60 }
61 
Writing(const std::string & input,TLVObject & data,TAG tag)62 template <> bool Writing(const std::string &input, TLVObject &data, TAG tag)
63 {
64     InitWhenFirst(input, data);
65     return data.Write(tag, input);
66 }
67 
Reading(std::string & output,TLVObject & data,const TLVHead & head)68 template <> bool Reading(std::string &output, TLVObject &data, const TLVHead &head)
69 {
70     return data.Read(output, head);
71 }
72 
CountBufferSize(const std::vector<uint8_t> & input,TLVObject & data)73 template <> size_t CountBufferSize(const std::vector<uint8_t> &input, TLVObject &data)
74 {
75     return data.Count(input);
76 }
77 
Writing(const std::vector<uint8_t> & input,TLVObject & data,TAG tag)78 template <> bool Writing(const std::vector<uint8_t> &input, TLVObject &data, TAG tag)
79 {
80     InitWhenFirst(input, data);
81     return data.Write(tag, input);
82 }
83 
Reading(std::vector<uint8_t> & output,TLVObject & data,const TLVHead & head)84 template <> bool Reading(std::vector<uint8_t> &output, TLVObject &data, const TLVHead &head)
85 {
86     return data.Read(output, head);
87 }
88 
CountBufferSize(const UDType & input,TLVObject & data)89 template <> size_t CountBufferSize(const UDType &input, TLVObject &data)
90 {
91     int32_t type = input;
92     return data.CountBasic(type);
93 }
94 
Writing(const UDType & input,TLVObject & data,TAG tag)95 template <> bool Writing(const UDType &input, TLVObject &data, TAG tag)
96 {
97     InitWhenFirst(input, data);
98     int32_t type = input;
99     return data.WriteBasic(tag, type);
100 }
101 
Reading(UDType & output,TLVObject & data,const TLVHead & head)102 template <> bool Reading(UDType &output, TLVObject &data, const TLVHead &head)
103 {
104     int32_t type;
105     if (!Reading(type, data, head)) {
106         return false;
107     }
108     if (type < UDType::ENTITY || type >= UDType::UD_BUTT) {
109         return false;
110     }
111     output = static_cast<UDType>(type);
112     return true;
113 }
114 
CountBufferSize(const DataStatus & input,TLVObject & data)115 template <> size_t CountBufferSize(const DataStatus &input, TLVObject &data)
116 {
117     int32_t status = input;
118     return data.CountBasic(status);
119 }
120 
Writing(const DataStatus & input,TLVObject & data,TAG tag)121 template <> bool Writing(const DataStatus &input, TLVObject &data, TAG tag)
122 {
123     InitWhenFirst(input, data);
124     int32_t status = input;
125     return data.WriteBasic(tag, status);
126 }
127 
Reading(DataStatus & output,TLVObject & data,const TLVHead & head)128 template <> bool Reading(DataStatus &output, TLVObject &data, const TLVHead &head)
129 {
130     int32_t status;
131     if (!data.ReadBasic(status, head)) {
132         return false;
133     }
134     if (status < DataStatus::WORKING || status >= DataStatus::FADE) {
135         return false;
136     }
137     output = static_cast<DataStatus>(status);
138     return true;
139 }
140 
CountBufferSize(const Object & input,TLVObject & data)141 template <> size_t CountBufferSize(const Object &input, TLVObject &data)
142 {
143     return data.CountHead() + CountBufferSize(input.value_, data);
144 }
145 
Writing(const Object & input,TLVObject & data,TAG tag)146 template <> bool Writing(const Object &input, TLVObject &data, TAG tag)
147 {
148     InitWhenFirst(input, data);
149     auto tagCursor = data.GetCursor();
150     data.OffsetHead();
151     if (!Writing(input.value_, data, TAG::TAG_OBJECT_VALUE)) {
152         return false;
153     }
154     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
155 }
Reading(Object & output,TLVObject & data,const TLVHead & head)156 template <> bool Reading(Object &output, TLVObject &data, const TLVHead &head)
157 {
158     TLVHead headValue{};
159     if (!data.ReadHead(headValue)) {
160         return false;
161     }
162     if (headValue.tag != static_cast<uint16_t>(TAG::TAG_OBJECT_VALUE)) {
163         return false;
164     }
165     if (!Reading(output.value_, data, headValue)) {
166         return false;
167     }
168     return true;
169 }
170 
CountBufferSize(const UnifiedKey & input,TLVObject & data)171 template <> size_t CountBufferSize(const UnifiedKey &input, TLVObject &data)
172 {
173     return data.CountHead() + data.Count(input.key) + data.Count(input.intention) + data.Count(input.bundleName) +
174         data.Count(input.groupId);
175 }
Writing(const UnifiedKey & input,TLVObject & data,TAG tag)176 template <> bool Writing(const UnifiedKey &input, TLVObject &data, TAG tag)
177 {
178     InitWhenFirst(input, data);
179     auto tagCursor = data.GetCursor();
180     data.OffsetHead();
181     if (!data.Write(TAG::TAG_KEY, input.key)) {
182         return false;
183     }
184     if (!data.Write(TAG::TAG_INTENTION, input.intention)) {
185         return false;
186     }
187     if (!data.Write(TAG::TAG_BUNDLE_NAME, input.bundleName)) {
188         return false;
189     }
190     if (!data.Write(TAG::TAG_GROUP_ID, input.groupId)) {
191         return false;
192     }
193     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
194 }
195 
Reading(UnifiedKey & output,TLVObject & data,const TLVHead & head)196 template <> bool Reading(UnifiedKey &output, TLVObject &data, const TLVHead &head)
197 {
198     auto endCursor = data.GetCursor() + head.len;
199     while (data.GetCursor() < endCursor) {
200         TLVHead headItem{};
201         if (!data.ReadHead(headItem)) {
202             return false;
203         }
204         switch (headItem.tag) {
205             case static_cast<uint16_t>(TAG::TAG_KEY):
206                 if (!data.Read(output.key, headItem)) {
207                     return false;
208                 }
209                 break;
210             case static_cast<uint16_t>(TAG::TAG_INTENTION):
211                 if (!data.Read(output.intention, headItem)) {
212                     return false;
213                 }
214                 break;
215             case static_cast<uint16_t>(TAG::TAG_BUNDLE_NAME):
216                 if (!data.Read(output.bundleName, headItem)) {
217                     return false;
218                 }
219                 break;
220             case static_cast<uint16_t>(TAG::TAG_GROUP_ID):
221                 if (!data.Read(output.groupId, headItem)) {
222                     return false;
223                 }
224                 break;
225             default:
226                 data.Skip(headItem);
227         }
228     }
229     return true;
230 }
231 
CountBufferSize(const UnifiedData & input,TLVObject & data)232 template <> size_t CountBufferSize(const UnifiedData &input, TLVObject &data)
233 {
234     std::string version = UTILS::GetCurrentSdkVersion();
235     return data.CountHead() + data.Count(version) + TLVUtil::CountBufferSize(input.GetRecords(), data);
236 }
237 
Writing(const UnifiedData & input,TLVObject & data,TAG tag)238 template <> bool Writing(const UnifiedData &input, TLVObject &data, TAG tag)
239 {
240     InitWhenFirst(input, data);
241     auto tagCursor = data.GetCursor();
242     data.OffsetHead();
243     std::string version = UTILS::GetCurrentSdkVersion();
244     if (!data.Write(TAG::TAG_VERSION, version)) {
245         return false;
246     }
247     if (!TLVUtil::Writing(input.GetRecords(), data, TAG::TAG_UNIFIED_RECORD)) {
248         return false;
249     }
250     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
251 }
252 
Reading(UnifiedData & output,TLVObject & data,const TLVHead & head)253 template <> bool Reading(UnifiedData &output, TLVObject &data, const TLVHead &head)
254 {
255     auto endCursor = data.GetCursor() + head.len;
256     while (data.GetCursor() < endCursor) {
257         TLVHead headItem{};
258         if (!data.ReadHead(headItem)) {
259             return false;
260         }
261         if (headItem.tag == static_cast<uint16_t>(TAG::TAG_VERSION)) {
262             data.Skip(headItem);
263             continue;
264         }
265         if (headItem.tag == static_cast<uint16_t>(TAG::TAG_UNIFIED_RECORD)) {
266             auto records = output.GetRecords();
267             if (!Reading(records, data, headItem)) {
268                 return false;
269             }
270             output.SetRecords(records);
271             continue;
272         }
273         data.Skip(headItem);
274     }
275     return true;
276 }
277 
CountBufferSize(const UnifiedRecord & input,TLVObject & data)278 template <> size_t CountBufferSize(const UnifiedRecord &input, TLVObject &data)
279 {
280     std::string version = UTILS::GetCurrentSdkVersion();
281     return data.CountHead() + data.Count(version) + data.CountBasic(static_cast<int32_t>(input.GetType())) +
282         data.Count(input.GetUid()) + CountBufferSize(input.GetOriginValue(), data) + data.Count(input.GetUtdId()) +
283         CountBufferSize(input.GetInnerEntries(), data);
284 }
285 
Writing(const UnifiedRecord & input,TLVObject & data,TAG tag)286 template <> bool Writing(const UnifiedRecord &input, TLVObject &data, TAG tag)
287 {
288     InitWhenFirst(input, data);
289     auto tagCursor = data.GetCursor();
290     data.OffsetHead();
291     std::string version = UTILS::GetCurrentSdkVersion();
292     if (!data.Write(TAG::TAG_VERSION, version)) {
293         return false;
294     }
295     if (!data.WriteBasic(TAG::TAG_UD_TYPE, static_cast<int32_t>(input.GetType()))) {
296         return false;
297     }
298     if (!data.Write(TAG::TAG_UID, input.GetUid())) {
299         return false;
300     }
301     if (!TLVUtil::Writing(input.GetOriginValue(), data, TAG::TAG_RECORD_VALUE)) {
302         return false;
303     }
304     if (!data.Write(TAG::TAG_RECORD_UTD_ID, input.GetUtdId())) {
305         return false;
306     }
307     if (!TLVUtil::Writing(input.GetInnerEntries(), data, TAG::TAG_RECORD_ENTRIES)) {
308         return false;
309     }
310     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
311 }
312 
Reading(UnifiedRecord & output,TLVObject & data,const TLVHead & head)313 template <> bool Reading(UnifiedRecord &output, TLVObject &data, const TLVHead &head)
314 {
315     auto endCursor = data.GetCursor() + head.len;
316     UDType dataType;
317     std::string uid;
318     ValueType value;
319     while (data.GetCursor() < endCursor) {
320         TLVHead headItem{};
321         if (!data.ReadHead(headItem)) {
322             return false;
323         }
324         std::string utdId;
325         std::shared_ptr<std::map<std::string, ValueType>> entries;
326         switch (headItem.tag) {
327             case static_cast<uint16_t>(TAG::TAG_VERSION):
328                 data.Skip(headItem);
329                 break;
330             case static_cast<uint16_t>(TAG::TAG_UD_TYPE):
331                 if (!TLVUtil::Reading(dataType, data, headItem)) {
332                     return false;
333                 }
334                 output.SetType(dataType);
335                 break;
336             case static_cast<uint16_t>(TAG::TAG_UID):
337                 if (!data.Read(uid, headItem)) {
338                     return false;
339                 }
340                 output.SetUid(uid);
341                 break;
342             case static_cast<uint16_t>(TAG::TAG_RECORD_VALUE):
343                 if (!TLVUtil::Reading(value, data, headItem)) {
344                     return false;
345                 }
346                 output.SetValue(value);
347                 break;
348             case static_cast<uint16_t>(TAG::TAG_RECORD_UTD_ID):
349                 if (!data.Read(utdId, headItem)) {
350                     return false;
351                 }
352                 output.SetUtdId(std::move(utdId));
353                 break;
354             case static_cast<uint16_t>(TAG::TAG_RECORD_ENTRIES):
355                 if (!TLVUtil::Reading(entries, data, headItem)) {
356                     return false;
357                 }
358                 output.SetInnerEntries(entries);
359                 break;
360             default:
361                 data.Skip(headItem);
362         }
363     }
364     return true;
365 }
366 
CountBufferSize(const Runtime & input,TLVObject & data)367 template <> size_t CountBufferSize(const Runtime &input, TLVObject &data)
368 {
369     std::string version = UTILS::GetCurrentSdkVersion();
370     return data.CountHead() + data.CountBasic(input.isPrivate) + data.CountBasic(input.dataVersion) +
371         data.CountBasic(input.recordTotalNum) + data.CountBasic(input.tokenId) +
372         data.CountBasic(static_cast<int64_t>(input.createTime)) +
373         data.CountBasic(static_cast<int64_t>(input.lastModifiedTime)) +
374         data.CountBasic(static_cast<int32_t>(input.dataStatus)) + data.Count(input.sourcePackage) +
375         data.Count(input.createPackage) + data.Count(input.deviceId) + TLVUtil::CountBufferSize(input.key, data) +
376         data.Count(version) + TLVUtil::CountBufferSize(input.privileges, data);
377 }
378 
Writing(const Runtime & input,TLVObject & data,TAG tag)379 template <> bool Writing(const Runtime &input, TLVObject &data, TAG tag)
380 {
381     InitWhenFirst(input, data);
382     auto tagCursor = data.GetCursor();
383     data.OffsetHead();
384     std::string version = UTILS::GetCurrentSdkVersion();
385     if (!TLVUtil::Writing(version, data, TAG::TAG_VERSION)) {
386         return false;
387     }
388     if (!TLVUtil::Writing(input.key, data, TAG::TAG_KEY)) {
389         return false;
390     }
391     if (!data.WriteBasic(TAG::TAG_IS_PRIVATE, input.isPrivate)) {
392         return false;
393     }
394     if (!TLVUtil::Writing(input.privileges, data, TAG::TAG_PRIVILEGE)) {
395         return false;
396     }
397     if (!data.WriteBasic(TAG::TAG_CREATE_TIME, static_cast<int64_t>(input.createTime))) {
398         return false;
399     }
400     if (!data.Write(TAG::TAG_SOURCE_PACKAGE, input.sourcePackage)) {
401         return false;
402     }
403     if (!data.WriteBasic(TAG::TAG_DATA_STATUS, static_cast<int32_t>(input.dataStatus))) {
404         return false;
405     }
406     if (!data.WriteBasic(TAG::TAG_DATA_VERSION, input.dataVersion)) {
407         return false;
408     }
409     if (!data.WriteBasic(TAG::TAG_LAST_MODIFIED_TIME, static_cast<int64_t>(input.lastModifiedTime))) {
410         return false;
411     }
412     if (!data.Write(TAG::TAG_CREATE_PACKAGE, input.createPackage)) {
413         return false;
414     }
415     if (!data.Write(TAG::TAG_DEVICE_ID, input.deviceId)) {
416         return false;
417     }
418     if (!data.WriteBasic(TAG::TAG_RECORD_TOTAL_NUM, input.recordTotalNum)) {
419         return false;
420     }
421     if (!data.WriteBasic(TAG::TAG_TOKEN_ID, input.tokenId)) {
422         return false;
423     }
424     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
425 }
426 
Reading(Runtime & output,TLVObject & data,const TLVHead & head)427 template <> bool Reading(Runtime &output, TLVObject &data, const TLVHead &head)
428 {
429     auto endCursor = data.GetCursor() + head.len;
430     while (data.GetCursor() < endCursor) {
431         TLVHead headItem{};
432         if (!data.ReadHead(headItem)) {
433             return false;
434         }
435         bool result = true;
436         int64_t createTime = 0;
437         int64_t lastModifiedTime = 0;
438         switch (headItem.tag) {
439             case static_cast<uint16_t>(TAG::TAG_KEY):
440                 result = TLVUtil::Reading(output.key, data, headItem);
441                 break;
442             case static_cast<uint16_t>(TAG::TAG_IS_PRIVATE):
443                 result = data.ReadBasic(output.isPrivate, headItem);
444                 break;
445             case static_cast<uint16_t>(TAG::TAG_PRIVILEGE):
446                 result = TLVUtil::Reading(output.privileges, data, headItem);
447                 break;
448             case static_cast<uint16_t>(TAG::TAG_CREATE_TIME):
449                 result = data.ReadBasic(createTime, headItem);
450                 output.createTime = static_cast<time_t>(createTime);
451                 break;
452             case static_cast<uint16_t>(TAG::TAG_SOURCE_PACKAGE):
453                 result = data.Read(output.sourcePackage, headItem);
454                 break;
455             case static_cast<uint16_t>(TAG::TAG_DATA_STATUS):
456                 result = TLVUtil::Reading(output.dataStatus, data, headItem);
457                 break;
458             case static_cast<uint16_t>(TAG::TAG_DATA_VERSION):
459                 result = data.ReadBasic(output.dataVersion, headItem);
460                 break;
461             case static_cast<uint16_t>(TAG::TAG_LAST_MODIFIED_TIME):
462                 result = data.ReadBasic(lastModifiedTime, headItem);
463                 output.lastModifiedTime = static_cast<time_t>(lastModifiedTime);
464                 break;
465             case static_cast<uint16_t>(TAG::TAG_CREATE_PACKAGE):
466                 result = data.Read(output.createPackage, headItem);
467                 break;
468             case static_cast<uint16_t>(TAG::TAG_DEVICE_ID):
469                 result = data.Read(output.deviceId, headItem);
470                 break;
471             case static_cast<uint16_t>(TAG::TAG_RECORD_TOTAL_NUM):
472                 result = data.ReadBasic(output.recordTotalNum, headItem);
473                 break;
474             case static_cast<uint16_t>(TAG::TAG_TOKEN_ID):
475                 result = data.ReadBasic(output.tokenId, headItem);
476                 break;
477             default:
478                 result = data.Skip(headItem);
479         }
480         if (!result) {
481             return false;
482         }
483     }
484     return true;
485 }
486 
CountBufferSize(const Privilege & input,TLVObject & data)487 template <> size_t CountBufferSize(const Privilege &input, TLVObject &data)
488 {
489     return data.CountHead() + data.CountBasic(input.tokenId) + data.Count(input.readPermission) +
490         data.Count(input.writePermission);
491 }
492 
Writing(const Privilege & input,TLVObject & data,TAG tag)493 template <> bool Writing(const Privilege &input, TLVObject &data, TAG tag)
494 {
495     InitWhenFirst(input, data);
496     auto tagCursor = data.GetCursor();
497     data.OffsetHead();
498     if (!data.WriteBasic(TAG::TAG_TOKEN_ID, input.tokenId)) {
499         return false;
500     }
501     if (!data.Write(TAG::TAG_READPERMISSION, input.readPermission)) {
502         return false;
503     }
504     if (!data.Write(TAG::TAG_WRITEPERMISSION, input.writePermission)) {
505         return false;
506     }
507     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
508 }
509 
Reading(Privilege & output,TLVObject & data,const TLVHead & head)510 template <> bool Reading(Privilege &output, TLVObject &data, const TLVHead &head)
511 {
512     auto endCursor = data.GetCursor() + head.len;
513     while (data.GetCursor() < endCursor) {
514         TLVHead headItem{};
515         if (!data.ReadHead(headItem)) {
516             return false;
517         }
518         switch (headItem.tag) {
519             case static_cast<uint16_t>(TAG::TAG_TOKEN_ID):
520                 if (!data.ReadBasic(output.tokenId, headItem)) {
521                     return false;
522                 }
523                 break;
524             case static_cast<uint16_t>(TAG::TAG_READPERMISSION):
525                 if (!data.Read(output.readPermission, headItem)) {
526                     return false;
527                 }
528                 break;
529             case static_cast<uint16_t>(TAG::TAG_WRITEPERMISSION):
530                 if (!data.Read(output.writePermission, headItem)) {
531                     return false;
532                 }
533                 break;
534             default:
535                 data.Skip(headItem);
536         }
537     }
538     return true;
539 }
540 
CountBufferSize(const std::shared_ptr<OHOS::Media::PixelMap> & input,TLVObject & data)541 template <> size_t CountBufferSize(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data)
542 {
543     std::vector<std::uint8_t> val;
544     if (!input->EncodeTlv(val)) {
545         LOG_ERROR(UDMF_FRAMEWORK, "Encode pixelMap error when CountBufferSize");
546         return 0;
547     }
548     return CountBufferSize(val, data);
549 }
550 
Writing(const std::shared_ptr<OHOS::Media::PixelMap> & input,TLVObject & data,TAG tag)551 template <> bool Writing(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data, TAG tag)
552 {
553     InitWhenFirst(input, data);
554     std::vector<std::uint8_t> val;
555     if (!input->EncodeTlv(val)) {
556         LOG_ERROR(UDMF_FRAMEWORK, "Encode pixelMap error when Writing");
557         return false;
558     }
559     return data.Write(tag, val);
560 }
561 
Reading(std::shared_ptr<OHOS::Media::PixelMap> & output,TLVObject & data,const TLVHead & head)562 template <> bool Reading(std::shared_ptr<OHOS::Media::PixelMap> &output, TLVObject &data, const TLVHead &head)
563 {
564     std::vector<std::uint8_t> val;
565     if (!data.Read(val, head)) {
566         LOG_ERROR(UDMF_FRAMEWORK, "Reading u8 vector error.");
567         return false;
568     }
569     output = std::shared_ptr<OHOS::Media::PixelMap>(OHOS::Media::PixelMap::DecodeTlv(val));
570     if (output == nullptr) {
571         LOG_ERROR(UDMF_FRAMEWORK, "DecodeTlv pixelMap error when Reading.");
572         return false;
573     }
574     return true;
575 }
576 
CountBufferSize(const std::shared_ptr<std::map<std::string,ValueType>> & input,TLVObject & data)577 template <> size_t CountBufferSize(const std::shared_ptr<std::map<std::string, ValueType>> &input, TLVObject &data)
578 {
579     if (input == nullptr) {
580         return data.CountHead();
581     }
582     return CountBufferSize(*input, data);
583 }
584 
Writing(const std::shared_ptr<std::map<std::string,ValueType>> & input,TLVObject & data,TAG tag)585 template <> bool Writing(const std::shared_ptr<std::map<std::string, ValueType>> &input, TLVObject &data, TAG tag)
586 {
587     if (input == nullptr) {
588         return false;
589     }
590     InitWhenFirst(input, data);
591     return Writing(*input, data, tag);
592 }
593 
Reading(std::shared_ptr<std::map<std::string,ValueType>> & output,TLVObject & data,const TLVHead & head)594 template <> bool Reading(std::shared_ptr<std::map<std::string, ValueType>> &output,
595     TLVObject &data, const TLVHead &head)
596 {
597     if (output == nullptr) {
598         output = std::make_shared<std::map<std::string, ValueType>>();
599     }
600     return Reading(*output, data, head);
601 }
602 
CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> & input,TLVObject & data)603 template <> size_t CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data)
604 {
605     Parcel parcel;
606     if (!input->Marshalling(parcel)) {
607         LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error when Count");
608         return 0;
609     }
610     auto size = parcel.GetDataSize();
611     std::vector<std::uint8_t> val(size);
612     return CountBufferSize(val, data);
613 }
614 
Writing(const std::shared_ptr<OHOS::AAFwk::Want> & input,TLVObject & data,TAG tag)615 template <> bool Writing(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data, TAG tag)
616 {
617     InitWhenFirst(input, data);
618     Parcel parcel;
619     if (!input->Marshalling(parcel)) {
620         LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error in tlv write. tag=%{public}hu", tag);
621         return false;
622     }
623     auto size = parcel.GetDataSize();
624     auto buffer = parcel.GetData();
625     std::vector<std::uint8_t> val(size);
626     if (size != 0) {
627         auto err = memcpy_s(val.data(), size, reinterpret_cast<const void *>(buffer), size);
628         if (err != EOK) {
629             LOG_ERROR(UDMF_FRAMEWORK, "memcpy error in tlv write want. tag=%{public}hu", tag);
630             return false;
631         }
632     }
633     return data.Write(tag, val);
634 }
635 
Reading(std::shared_ptr<OHOS::AAFwk::Want> & output,TLVObject & data,const TLVHead & head)636 template <> bool Reading(std::shared_ptr<OHOS::AAFwk::Want> &output, TLVObject &data, const TLVHead &head)
637 {
638     std::vector<std::uint8_t> val;
639     if (!data.Read(val, head)) {
640         LOG_ERROR(UDMF_FRAMEWORK, "Reading u8 vector error.");
641         return false;
642     }
643 
644     std::shared_ptr<Parcel> parcel = std::make_shared<Parcel>();
645     auto buffer = malloc(val.size());
646     if (buffer == nullptr) {
647         LOG_ERROR(UDMF_FRAMEWORK, "malloc error in tlv read. tag=%{public}hu", head.tag);
648         return false;
649     }
650     auto err = memcpy_s(buffer, val.size(), val.data(), val.size());
651     if (err != EOK) {
652         LOG_ERROR(UDMF_FRAMEWORK, "memcpy_s error in tlv read want. tag=%{public}hu", head.tag);
653         free(buffer);
654         return false;
655     }
656     if (!parcel->ParseFrom((uintptr_t)buffer, head.len)) {
657         LOG_ERROR(UDMF_FRAMEWORK, "ParseFrom error in tlv read want. tag=%{public}hu", head.tag);
658         return false;
659     }
660     auto want = AAFwk::Want::Unmarshalling(*parcel);
661     if (want == nullptr) {
662         LOG_ERROR(UDMF_FRAMEWORK, "Unmarshalling want error in tlv read. tag=%{public}hu", head.tag);
663         return false;
664     }
665     output = std::shared_ptr<OHOS::AAFwk::Want>(want);
666     return true;
667 }
668 } // namespace TLVUtil
669 } // namespace OHOS
670