• 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     return data.CountHead() + data.Count(input.GetSdkVersion()) + TLVUtil::CountBufferSize(input.GetRecords(), data) +
235         TLVUtil::CountBufferSize(input.GetProperties(), 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     if (!data.Write(TAG::TAG_VERSION, input.GetSdkVersion())) {
244         return false;
245     }
246     if (!TLVUtil::Writing(input.GetRecords(), data, TAG::TAG_UNIFIED_RECORD)) {
247         return false;
248     }
249     if (!TLVUtil::Writing(input.GetProperties(), data, TAG::TAG_UNIFIED_PROPERTIES)) {
250         return false;
251     }
252     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
253 }
254 
Reading(UnifiedData & output,TLVObject & data,const TLVHead & head)255 template <> bool Reading(UnifiedData &output, TLVObject &data, const TLVHead &head)
256 {
257     auto endCursor = data.GetCursor() + head.len;
258     while (data.GetCursor() < endCursor) {
259         TLVHead headItem{};
260         if (!data.ReadHead(headItem)) {
261             return false;
262         }
263         if (headItem.tag == static_cast<uint16_t>(TAG::TAG_VERSION)) {
264             std::string version;
265             if (!Reading(version, data, headItem)) {
266                 return false;
267             }
268             output.SetSdkVersion(version);
269             continue;
270         }
271         if (headItem.tag == static_cast<uint16_t>(TAG::TAG_UNIFIED_RECORD)) {
272             auto records = output.GetRecords();
273             if (!Reading(records, data, headItem)) {
274                 return false;
275             }
276             output.SetRecords(records);
277             continue;
278         }
279         if (headItem.tag == static_cast<uint16_t>(TAG::TAG_UNIFIED_PROPERTIES)) {
280             auto properties = output.GetProperties();
281             if (!Reading(properties, data, headItem)) {
282                 return false;
283             }
284             output.SetProperties(std::move(properties));
285             continue;
286         }
287         data.Skip(headItem);
288     }
289     return true;
290 }
291 
CountBufferSize(const UnifiedDataProperties & input,TLVObject & data)292 template <> size_t CountBufferSize(const UnifiedDataProperties &input, TLVObject &data)
293 {
294     return data.CountHead() + data.Count(input.tag) + data.CountBasic(input.timestamp) +
295         data.CountBasic(static_cast<int32_t>(input.shareOptions))  + TLVUtil::CountBufferSize(input.extras, data);
296 }
297 
Writing(const UnifiedDataProperties & input,TLVObject & data,TAG tag)298 template <> bool Writing(const UnifiedDataProperties &input, TLVObject &data, TAG tag)
299 {
300     InitWhenFirst(input, data);
301     auto tagCursor = data.GetCursor();
302     data.OffsetHead();
303     if (!data.Write(TAG::TAG_PROPERTIES_TAG, input.tag)) {
304         return false;
305     }
306     if (!data.WriteBasic(TAG::TAG_PROPERTIES_TIMESTAMP, input.timestamp)) {
307         return false;
308     }
309     if (!data.WriteBasic(TAG::TAG_PROPERTIES_SHARE_OPTIONS, static_cast<int32_t>(input.shareOptions))) {
310         return false;
311     }
312     if (!TLVUtil::Writing(input.extras, data, TAG::TAG_PROPERTIES_EXTRAS)) {
313         return false;
314     }
315     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
316 }
317 
Reading(UnifiedDataProperties & output,TLVObject & data,const TLVHead & head)318 template <> bool Reading(UnifiedDataProperties &output, TLVObject &data, const TLVHead &head)
319 {
320     auto endCursor = data.GetCursor() + head.len;
321     while (data.GetCursor() < endCursor) {
322         TLVHead headItem{};
323         if (!data.ReadHead(headItem)) {
324             return false;
325         }
326         bool result = true;
327         switch (headItem.tag) {
328             case static_cast<uint16_t>(TAG::TAG_PROPERTIES_TAG):
329                 result = data.Read(output.tag, headItem);
330                 break;
331             case static_cast<uint16_t>(TAG::TAG_PROPERTIES_TIMESTAMP):
332                 result = data.ReadBasic(output.timestamp, headItem);
333                 break;
334             case static_cast<uint16_t>(TAG::TAG_PROPERTIES_SHARE_OPTIONS):
335                 result = TLVUtil::Reading(output.shareOptions, data, headItem);
336                 break;
337             case static_cast<uint16_t>(TAG::TAG_PROPERTIES_EXTRAS):
338                 result = TLVUtil::Reading(output.extras, data, headItem);
339                 break;
340             default:
341                 result = data.Skip(headItem);
342         }
343         if (!result) {
344             return false;
345         }
346     }
347     return true;
348 }
349 
Reading(ShareOptions & output,TLVObject & data,const TLVHead & head)350 template <> bool Reading(ShareOptions &output, TLVObject &data, const TLVHead &head)
351 {
352     int32_t shareOptions;
353     if (!Reading(shareOptions, data, head)) {
354         return false;
355     }
356     if (shareOptions < ShareOptions::IN_APP || shareOptions >= ShareOptions::SHARE_OPTIONS_BUTT) {
357         return false;
358     }
359     output = static_cast<ShareOptions>(shareOptions);
360     return true;
361 }
362 
CountBufferSize(const OHOS::AAFwk::WantParams & input,TLVObject & data)363 template <> size_t CountBufferSize(const OHOS::AAFwk::WantParams &input, TLVObject &data)
364 {
365     Parcel parcel;
366     if (!input.Marshalling(parcel)) {
367         LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error when Count");
368         return 0;
369     }
370     auto size = parcel.GetDataSize();
371     std::vector<std::uint8_t> val(size);
372     return CountBufferSize(val, data);
373 }
374 
Writing(const OHOS::AAFwk::WantParams & input,TLVObject & data,TAG tag)375 template <> bool Writing(const OHOS::AAFwk::WantParams &input, TLVObject &data, TAG tag)
376 {
377     InitWhenFirst(input, data);
378     Parcel parcel;
379     if (!input.Marshalling(parcel)) {
380         LOG_ERROR(UDMF_FRAMEWORK, "Marshalling wantParams error in tlv write. tag=%{public}hu", tag);
381         return false;
382     }
383     auto size = parcel.GetDataSize();
384     auto buffer = parcel.GetData();
385     std::vector<std::uint8_t> val(size);
386     if (size != 0) {
387         auto err = memcpy_s(val.data(), size, reinterpret_cast<const void *>(buffer), size);
388         if (err != EOK) {
389             LOG_ERROR(UDMF_FRAMEWORK, "memcpy error in tlv write wantParams. tag=%{public}hu", tag);
390             return false;
391         }
392     }
393     return data.Write(tag, val);
394 }
395 
Reading(OHOS::AAFwk::WantParams & output,TLVObject & data,const TLVHead & head)396 template <> bool Reading(OHOS::AAFwk::WantParams &output, TLVObject &data, const TLVHead &head)
397 {
398     std::vector<std::uint8_t> val;
399     if (!data.Read(val, head)) {
400         LOG_ERROR(UDMF_FRAMEWORK, "Reading u8 vector error.");
401         return false;
402     }
403 
404     std::shared_ptr<Parcel> parcel = std::make_shared<Parcel>();
405     auto buffer = malloc(val.size());
406     if (buffer == nullptr) {
407         LOG_ERROR(UDMF_FRAMEWORK, "malloc error in tlv read. tag=%{public}hu", head.tag);
408         return false;
409     }
410     auto err = memcpy_s(buffer, val.size(), val.data(), val.size());
411     if (err != EOK) {
412         LOG_ERROR(UDMF_FRAMEWORK, "memcpy_s error in tlv read wantParams. tag=%{public}hu", head.tag);
413         free(buffer);
414         return false;
415     }
416     if (!parcel->ParseFrom((uintptr_t)buffer, head.len)) {
417         LOG_ERROR(UDMF_FRAMEWORK, "ParseFrom error in tlv read wantParams. tag=%{public}hu", head.tag);
418         free(buffer);
419         return false;
420     }
421     // The pointer returned by Unmarshalling needs to be manually deleted.
422     auto wantParams = AAFwk::WantParams::Unmarshalling(*parcel);
423     if (wantParams == nullptr) {
424         LOG_ERROR(UDMF_FRAMEWORK, "Unmarshalling wantParams error in tlv read. tag=%{public}hu", head.tag);
425         return false;
426     }
427     output = *wantParams;
428     delete wantParams;
429     return true;
430 }
431 
CountBufferSize(const UnifiedRecord & input,TLVObject & data)432 template <> size_t CountBufferSize(const UnifiedRecord &input, TLVObject &data)
433 {
434     return data.CountHead() + data.CountBasic(static_cast<int32_t>(input.GetType())) +
435         data.Count(input.GetUid()) + CountBufferSize(input.GetOriginValue(), data) + data.Count(input.GetUtdId()) +
436         data.Count(input.GetUtdId2()) + CountBufferSize(input.GetInnerEntries(), data) +
437         CountBufferSize(input.GetUris(), data);
438 }
439 
Writing(const UnifiedRecord & input,TLVObject & data,TAG tag)440 template <> bool Writing(const UnifiedRecord &input, TLVObject &data, TAG tag)
441 {
442     InitWhenFirst(input, data);
443     auto tagCursor = data.GetCursor();
444     data.OffsetHead();
445     if (!data.WriteBasic(TAG::TAG_UD_TYPE, static_cast<int32_t>(input.GetType()))) {
446         return false;
447     }
448     if (!data.Write(TAG::TAG_UID, input.GetUid())) {
449         return false;
450     }
451     if (!TLVUtil::Writing(input.GetOriginValue(), data, TAG::TAG_RECORD_VALUE)) {
452         return false;
453     }
454     if (!data.Write(TAG::TAG_RECORD_UTD_ID, input.GetUtdId())) {
455         return false;
456     }
457     if (!data.Write(TAG::TAG_RECORD_UTD_ID2, input.GetUtdId2())) {
458         return false;
459     }
460     if (!TLVUtil::Writing(input.GetInnerEntries(), data, TAG::TAG_RECORD_ENTRIES)) {
461         return false;
462     }
463     if (!TLVUtil::Writing(input.GetUris(), data, TAG::TAG_RECORD_URIS)) {
464         return false;
465     }
466     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
467 }
468 
Reading(UnifiedRecord & output,TLVObject & data,const TLVHead & head)469 template <> bool Reading(UnifiedRecord &output, TLVObject &data, const TLVHead &head)
470 {
471     auto endCursor = data.GetCursor() + head.len;
472     UDType dataType;
473     std::string uid;
474     ValueType value;
475     while (data.GetCursor() < endCursor) {
476         TLVHead headItem{};
477         if (!data.ReadHead(headItem)) {
478             return false;
479         }
480         std::string utdId;
481         std::string utdId2;
482         std::shared_ptr<std::map<std::string, ValueType>> entries;
483         std::vector<UriInfo> uriInfos;
484         switch (headItem.tag) {
485             case static_cast<uint16_t>(TAG::TAG_UD_TYPE):
486                 if (!TLVUtil::Reading(dataType, data, headItem)) {
487                     return false;
488                 }
489                 output.SetType(dataType);
490                 break;
491             case static_cast<uint16_t>(TAG::TAG_UID):
492                 if (!data.Read(uid, headItem)) {
493                     return false;
494                 }
495                 output.SetUid(uid);
496                 break;
497             case static_cast<uint16_t>(TAG::TAG_RECORD_VALUE):
498                 if (!TLVUtil::Reading(value, data, headItem)) {
499                     return false;
500                 }
501                 output.SetValue(value);
502                 break;
503             case static_cast<uint16_t>(TAG::TAG_RECORD_UTD_ID):
504                 if (!data.Read(utdId, headItem)) {
505                     return false;
506                 }
507                 output.SetUtdId(std::move(utdId));
508                 break;
509             case static_cast<uint16_t>(TAG::TAG_RECORD_UTD_ID2):
510                 if (!data.Read(utdId2, headItem)) {
511                     return false;
512                 }
513                 output.SetUtdId2(std::move(utdId2));
514                 break;
515             case static_cast<uint16_t>(TAG::TAG_RECORD_ENTRIES):
516                 if (!TLVUtil::Reading(entries, data, headItem)) {
517                     return false;
518                 }
519                 output.SetInnerEntries(entries);
520                 break;
521             case static_cast<uint16_t>(TAG::TAG_RECORD_URIS):
522                 if (!TLVUtil::Reading(uriInfos, data, headItem)) {
523                     return false;
524                 }
525                 output.SetUris(std::move(uriInfos));
526                 break;
527             default:
528                 data.Skip(headItem);
529         }
530     }
531     return true;
532 }
533 
CountBufferSize(const Runtime & input,TLVObject & data)534 template <> size_t CountBufferSize(const Runtime &input, TLVObject &data)
535 {
536     return data.CountHead() + data.CountBasic(input.isPrivate) + data.CountBasic(input.dataVersion) +
537         data.CountBasic(input.recordTotalNum) + data.CountBasic(input.tokenId) +
538         data.CountBasic(static_cast<int64_t>(input.createTime)) +
539         data.CountBasic(static_cast<int64_t>(input.lastModifiedTime)) +
540         data.CountBasic(static_cast<int32_t>(input.dataStatus)) + data.Count(input.sourcePackage) +
541         data.Count(input.createPackage) + data.Count(input.deviceId) + TLVUtil::CountBufferSize(input.key, data) +
542         data.Count(input.sdkVersion) + TLVUtil::CountBufferSize(input.privileges, data);
543 }
544 
Writing(const Runtime & input,TLVObject & data,TAG tag)545 template <> bool Writing(const Runtime &input, TLVObject &data, TAG tag)
546 {
547     InitWhenFirst(input, data);
548     auto tagCursor = data.GetCursor();
549     data.OffsetHead();
550     if (!TLVUtil::Writing(input.key, data, TAG::TAG_KEY)) {
551         return false;
552     }
553     if (!data.WriteBasic(TAG::TAG_IS_PRIVATE, input.isPrivate)) {
554         return false;
555     }
556     if (!TLVUtil::Writing(input.privileges, data, TAG::TAG_PRIVILEGE)) {
557         return false;
558     }
559     if (!data.WriteBasic(TAG::TAG_CREATE_TIME, static_cast<int64_t>(input.createTime))) {
560         return false;
561     }
562     if (!data.Write(TAG::TAG_SOURCE_PACKAGE, input.sourcePackage)) {
563         return false;
564     }
565     if (!data.WriteBasic(TAG::TAG_DATA_STATUS, static_cast<int32_t>(input.dataStatus))) {
566         return false;
567     }
568     if (!data.WriteBasic(TAG::TAG_DATA_VERSION, input.dataVersion)) {
569         return false;
570     }
571     if (!data.WriteBasic(TAG::TAG_LAST_MODIFIED_TIME, static_cast<int64_t>(input.lastModifiedTime))) {
572         return false;
573     }
574     if (!data.Write(TAG::TAG_CREATE_PACKAGE, input.createPackage)) {
575         return false;
576     }
577     if (!data.Write(TAG::TAG_DEVICE_ID, input.deviceId)) {
578         return false;
579     }
580     if (!data.WriteBasic(TAG::TAG_RECORD_TOTAL_NUM, input.recordTotalNum)) {
581         return false;
582     }
583     if (!data.WriteBasic(TAG::TAG_TOKEN_ID, input.tokenId)) {
584         return false;
585     }
586     if (!TLVUtil::Writing(input.sdkVersion, data, TAG::TAG_VERSION)) {
587         return false;
588     }
589     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
590 }
591 
Reading(Runtime & output,TLVObject & data,const TLVHead & head)592 template <> bool Reading(Runtime &output, TLVObject &data, const TLVHead &head)
593 {
594     auto endCursor = data.GetCursor() + head.len;
595     while (data.GetCursor() < endCursor) {
596         TLVHead headItem{};
597         if (!data.ReadHead(headItem)) {
598             return false;
599         }
600         bool result = true;
601         int64_t createTime = 0;
602         int64_t lastModifiedTime = 0;
603         switch (headItem.tag) {
604             case static_cast<uint16_t>(TAG::TAG_KEY):
605                 result = TLVUtil::Reading(output.key, data, headItem);
606                 break;
607             case static_cast<uint16_t>(TAG::TAG_IS_PRIVATE):
608                 result = data.ReadBasic(output.isPrivate, headItem);
609                 break;
610             case static_cast<uint16_t>(TAG::TAG_PRIVILEGE):
611                 result = TLVUtil::Reading(output.privileges, data, headItem);
612                 break;
613             case static_cast<uint16_t>(TAG::TAG_CREATE_TIME):
614                 result = data.ReadBasic(createTime, headItem);
615                 output.createTime = static_cast<time_t>(createTime);
616                 break;
617             case static_cast<uint16_t>(TAG::TAG_SOURCE_PACKAGE):
618                 result = data.Read(output.sourcePackage, headItem);
619                 break;
620             case static_cast<uint16_t>(TAG::TAG_DATA_STATUS):
621                 result = TLVUtil::Reading(output.dataStatus, data, headItem);
622                 break;
623             case static_cast<uint16_t>(TAG::TAG_DATA_VERSION):
624                 result = data.ReadBasic(output.dataVersion, headItem);
625                 break;
626             case static_cast<uint16_t>(TAG::TAG_LAST_MODIFIED_TIME):
627                 result = data.ReadBasic(lastModifiedTime, headItem);
628                 output.lastModifiedTime = static_cast<time_t>(lastModifiedTime);
629                 break;
630             case static_cast<uint16_t>(TAG::TAG_CREATE_PACKAGE):
631                 result = data.Read(output.createPackage, headItem);
632                 break;
633             case static_cast<uint16_t>(TAG::TAG_DEVICE_ID):
634                 result = data.Read(output.deviceId, headItem);
635                 break;
636             case static_cast<uint16_t>(TAG::TAG_RECORD_TOTAL_NUM):
637                 result = data.ReadBasic(output.recordTotalNum, headItem);
638                 break;
639             case static_cast<uint16_t>(TAG::TAG_TOKEN_ID):
640                 result = data.ReadBasic(output.tokenId, headItem);
641                 break;
642             case static_cast<uint16_t>(TAG::TAG_VERSION):
643                 result = data.Read(output.sdkVersion, headItem);
644                 break;
645             default:
646                 result = data.Skip(headItem);
647         }
648         if (!result) {
649             return false;
650         }
651     }
652     return true;
653 }
654 
CountBufferSize(const Privilege & input,TLVObject & data)655 template <> size_t CountBufferSize(const Privilege &input, TLVObject &data)
656 {
657     return data.CountHead() + data.CountBasic(input.tokenId) + data.Count(input.readPermission) +
658         data.Count(input.writePermission);
659 }
660 
Writing(const Privilege & input,TLVObject & data,TAG tag)661 template <> bool Writing(const Privilege &input, TLVObject &data, TAG tag)
662 {
663     InitWhenFirst(input, data);
664     auto tagCursor = data.GetCursor();
665     data.OffsetHead();
666     if (!data.WriteBasic(TAG::TAG_TOKEN_ID, input.tokenId)) {
667         return false;
668     }
669     if (!data.Write(TAG::TAG_READPERMISSION, input.readPermission)) {
670         return false;
671     }
672     if (!data.Write(TAG::TAG_WRITEPERMISSION, input.writePermission)) {
673         return false;
674     }
675     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
676 }
677 
Reading(Privilege & output,TLVObject & data,const TLVHead & head)678 template <> bool Reading(Privilege &output, TLVObject &data, const TLVHead &head)
679 {
680     auto endCursor = data.GetCursor() + head.len;
681     while (data.GetCursor() < endCursor) {
682         TLVHead headItem{};
683         if (!data.ReadHead(headItem)) {
684             return false;
685         }
686         switch (headItem.tag) {
687             case static_cast<uint16_t>(TAG::TAG_TOKEN_ID):
688                 if (!data.ReadBasic(output.tokenId, headItem)) {
689                     return false;
690                 }
691                 break;
692             case static_cast<uint16_t>(TAG::TAG_READPERMISSION):
693                 if (!data.Read(output.readPermission, headItem)) {
694                     return false;
695                 }
696                 break;
697             case static_cast<uint16_t>(TAG::TAG_WRITEPERMISSION):
698                 if (!data.Read(output.writePermission, headItem)) {
699                     return false;
700                 }
701                 break;
702             default:
703                 data.Skip(headItem);
704         }
705     }
706     return true;
707 }
708 
CountBufferSize(const UriInfo & input,TLVObject & data)709 template <> size_t CountBufferSize(const UriInfo &input, TLVObject &data)
710 {
711     return data.CountHead() + data.CountBasic(input.position) + data.Count(input.oriUri) +
712         data.Count(input.dfsUri) + data.Count(input.authUri);
713 }
714 
Writing(const UriInfo & input,TLVObject & data,TAG tag)715 template <> bool Writing(const UriInfo &input, TLVObject &data, TAG tag)
716 {
717     InitWhenFirst(input, data);
718     auto tagCursor = data.GetCursor();
719     data.OffsetHead();
720     if (!TLVUtil::Writing(input.oriUri, data, TAG::TAG_URI_ORI)) {
721         return false;
722     }
723     if (!TLVUtil::Writing(input.dfsUri, data, TAG::TAG_URI_DFS)) {
724         return false;
725     }
726     if (!TLVUtil::Writing(input.authUri, data, TAG::TAG_URI_AUTH)) {
727         return false;
728     }
729     if (!data.WriteBasic(TAG::TAG_URI_POS, input.position)) {
730         return false;
731     }
732     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
733 }
734 
Reading(UriInfo & output,TLVObject & data,const TLVHead & head)735 template <> bool Reading(UriInfo &output, TLVObject &data, const TLVHead &head)
736 {
737     auto endCursor = data.GetCursor() + head.len;
738     while (data.GetCursor() < endCursor) {
739         TLVHead headItem{};
740         if (!data.ReadHead(headItem)) {
741             return false;
742         }
743         bool result = true;
744         switch (headItem.tag) {
745             case static_cast<uint16_t>(TAG::TAG_URI_ORI):
746                 result = TLVUtil::Reading(output.oriUri, data, headItem);
747                 break;
748             case static_cast<uint16_t>(TAG::TAG_URI_DFS):
749                 result = TLVUtil::Reading(output.dfsUri, data, headItem);
750                 break;
751             case static_cast<uint16_t>(TAG::TAG_URI_AUTH):
752                 result = TLVUtil::Reading(output.authUri, data, headItem);
753                 break;
754             case static_cast<uint16_t>(TAG::TAG_URI_POS):
755                 result = data.ReadBasic(output.position, headItem);
756                 break;
757             default:
758                 result = data.Skip(headItem);
759         }
760         if (!result) {
761             return false;
762         }
763     }
764     return true;
765 }
766 
CountBufferSize(const std::shared_ptr<OHOS::Media::PixelMap> & input,TLVObject & data)767 template <> size_t CountBufferSize(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data)
768 {
769     std::vector<std::uint8_t> val;
770     if (!input->EncodeTlv(val)) {
771         LOG_ERROR(UDMF_FRAMEWORK, "Encode pixelMap error when CountBufferSize");
772         return 0;
773     }
774     return CountBufferSize(val, data);
775 }
776 
Writing(const std::shared_ptr<OHOS::Media::PixelMap> & input,TLVObject & data,TAG tag)777 template <> bool Writing(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data, TAG tag)
778 {
779     InitWhenFirst(input, data);
780     std::vector<std::uint8_t> val;
781     if (!input->EncodeTlv(val)) {
782         LOG_ERROR(UDMF_FRAMEWORK, "Encode pixelMap error when Writing");
783         return false;
784     }
785     return data.Write(tag, val);
786 }
787 
Reading(std::shared_ptr<OHOS::Media::PixelMap> & output,TLVObject & data,const TLVHead & head)788 template <> bool Reading(std::shared_ptr<OHOS::Media::PixelMap> &output, TLVObject &data, const TLVHead &head)
789 {
790     std::vector<std::uint8_t> val;
791     if (!data.Read(val, head)) {
792         LOG_ERROR(UDMF_FRAMEWORK, "Reading u8 vector error.");
793         return false;
794     }
795     output = std::shared_ptr<OHOS::Media::PixelMap>(OHOS::Media::PixelMap::DecodeTlv(val));
796     if (output == nullptr) {
797         LOG_ERROR(UDMF_FRAMEWORK, "DecodeTlv pixelMap error when Reading.");
798         return false;
799     }
800     return true;
801 }
802 
CountBufferSize(const std::shared_ptr<std::map<std::string,ValueType>> & input,TLVObject & data)803 template <> size_t CountBufferSize(const std::shared_ptr<std::map<std::string, ValueType>> &input, TLVObject &data)
804 {
805     if (input == nullptr) {
806         return data.CountHead();
807     }
808     return CountBufferSize(*input, data);
809 }
810 
Writing(const std::shared_ptr<std::map<std::string,ValueType>> & input,TLVObject & data,TAG tag)811 template <> bool Writing(const std::shared_ptr<std::map<std::string, ValueType>> &input, TLVObject &data, TAG tag)
812 {
813     if (input == nullptr) {
814         return false;
815     }
816     InitWhenFirst(input, data);
817     return Writing(*input, data, tag);
818 }
819 
Reading(std::shared_ptr<std::map<std::string,ValueType>> & output,TLVObject & data,const TLVHead & head)820 template <> bool Reading(std::shared_ptr<std::map<std::string, ValueType>> &output,
821     TLVObject &data, const TLVHead &head)
822 {
823     if (output == nullptr) {
824         output = std::make_shared<std::map<std::string, ValueType>>();
825     }
826     return Reading(*output, data, head);
827 }
828 
CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> & input,TLVObject & data)829 template <> size_t CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data)
830 {
831     Parcel parcel;
832     if (!input->Marshalling(parcel)) {
833         LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error when Count");
834         return 0;
835     }
836     auto size = parcel.GetDataSize();
837     std::vector<std::uint8_t> val(size);
838     return CountBufferSize(val, data);
839 }
840 
Writing(const std::shared_ptr<OHOS::AAFwk::Want> & input,TLVObject & data,TAG tag)841 template <> bool Writing(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data, TAG tag)
842 {
843     InitWhenFirst(input, data);
844     Parcel parcel;
845     if (!input->Marshalling(parcel)) {
846         LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error in tlv write. tag=%{public}hu", tag);
847         return false;
848     }
849     auto size = parcel.GetDataSize();
850     auto buffer = parcel.GetData();
851     std::vector<std::uint8_t> val(size);
852     if (size != 0) {
853         auto err = memcpy_s(val.data(), size, reinterpret_cast<const void *>(buffer), size);
854         if (err != EOK) {
855             LOG_ERROR(UDMF_FRAMEWORK, "memcpy error in tlv write want. tag=%{public}hu", tag);
856             return false;
857         }
858     }
859     return data.Write(tag, val);
860 }
861 
Reading(std::shared_ptr<OHOS::AAFwk::Want> & output,TLVObject & data,const TLVHead & head)862 template <> bool Reading(std::shared_ptr<OHOS::AAFwk::Want> &output, TLVObject &data, const TLVHead &head)
863 {
864     std::vector<std::uint8_t> val;
865     if (!data.Read(val, head)) {
866         LOG_ERROR(UDMF_FRAMEWORK, "Reading u8 vector error.");
867         return false;
868     }
869 
870     std::shared_ptr<Parcel> parcel = std::make_shared<Parcel>();
871     auto buffer = malloc(val.size());
872     if (buffer == nullptr) {
873         LOG_ERROR(UDMF_FRAMEWORK, "malloc error in tlv read. tag=%{public}hu", head.tag);
874         return false;
875     }
876     auto err = memcpy_s(buffer, val.size(), val.data(), val.size());
877     if (err != EOK) {
878         LOG_ERROR(UDMF_FRAMEWORK, "memcpy_s error in tlv read want. tag=%{public}hu", head.tag);
879         free(buffer);
880         return false;
881     }
882     if (!parcel->ParseFrom((uintptr_t)buffer, head.len)) {
883         LOG_ERROR(UDMF_FRAMEWORK, "ParseFrom error in tlv read want. tag=%{public}hu", head.tag);
884         free(buffer);
885         return false;
886     }
887     auto want = AAFwk::Want::Unmarshalling(*parcel);
888     if (want == nullptr) {
889         LOG_ERROR(UDMF_FRAMEWORK, "Unmarshalling want error in tlv read. tag=%{public}hu", head.tag);
890         return false;
891     }
892     output = std::shared_ptr<OHOS::AAFwk::Want>(want);
893     return true;
894 }
895 
CountBufferSize(const Summary & input,TLVObject & data)896 template <> size_t CountBufferSize(const Summary &input, TLVObject &data)
897 {
898     return data.CountHead() + CountBufferSize(input.summary, data) + data.CountBasic(input.totalSize);
899 }
900 
Writing(const Summary & input,TLVObject & data,TAG tag)901 template <> bool Writing(const Summary &input, TLVObject &data, TAG tag)
902 {
903     InitWhenFirst(input, data);
904     auto tagCursor = data.GetCursor();
905     data.OffsetHead();
906     if (!TLVUtil::Writing(input.summary, data, TAG::TAG_SUMMARY_MAP)) {
907         return false;
908     }
909     if (!data.WriteBasic(TAG::TAG_SUMMARY_SIZE, input.totalSize)) {
910         return false;
911     }
912     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
913 }
914 
Reading(Summary & output,TLVObject & data,const TLVHead & head)915 template <> bool Reading(Summary &output, TLVObject &data, const TLVHead &head)
916 {
917     auto endCursor = data.GetCursor() + head.len;
918     while (data.GetCursor() < endCursor) {
919         TLVHead headItem{};
920         if (!data.ReadHead(headItem)) {
921             return false;
922         }
923         switch (headItem.tag) {
924             case static_cast<uint16_t>(TAG::TAG_SUMMARY_MAP):
925                 if (!TLVUtil::Reading(output.summary, data, headItem)) {
926                     return false;
927                 }
928                 break;
929             case static_cast<uint16_t>(TAG::TAG_SUMMARY_SIZE):
930                 if (!data.ReadBasic(output.totalSize, headItem)) {
931                     return false;
932                 }
933                 break;
934             default:
935                 data.Skip(headItem);
936         }
937     }
938     return true;
939 }
940 } // namespace TLVUtil
941 } // namespace OHOS
942