• 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 "pixelmap_loader.h"
22 #include "tlv_object.h"
23 
24 namespace OHOS {
25 namespace TLVUtil {
CountBufferSize(const std::nullptr_t & input,TLVObject & data)26 template <> size_t CountBufferSize(const std::nullptr_t &input, TLVObject &data)
27 {
28     return data.CountHead();
29 }
30 
Writing(const std::nullptr_t & input,TLVObject & data,TAG tag)31 template <> bool Writing(const std::nullptr_t &input, TLVObject &data, TAG tag)
32 {
33     InitWhenFirst(input, data);
34     return data.WriteHead(static_cast<uint16_t>(tag), 0);
35 }
36 
Reading(std::nullptr_t & output,TLVObject & data,const TLVHead & head)37 template <> bool Reading(std::nullptr_t &output, TLVObject &data, const TLVHead &head)
38 {
39     return data.Read(output, head);
40 }
41 
CountBufferSize(const std::monostate & input,TLVObject & data)42 template <> size_t CountBufferSize(const std::monostate &input, TLVObject &data)
43 {
44     return data.Count(input);
45 }
46 
Writing(const std::monostate & input,TLVObject & data,TAG tag)47 template <> bool Writing(const std::monostate &input, TLVObject &data, TAG tag)
48 {
49     InitWhenFirst(input, data);
50     return data.Write(tag, input);
51 }
52 
Reading(std::monostate & output,TLVObject & data,const TLVHead & head)53 template <> bool Reading(std::monostate &output, TLVObject &data, const TLVHead &head)
54 {
55     return data.Read(output, head);
56 }
57 
CountBufferSize(const std::string & input,TLVObject & data)58 template <> size_t CountBufferSize(const std::string &input, TLVObject &data)
59 {
60     return data.Count(input);
61 }
62 
Writing(const std::string & input,TLVObject & data,TAG tag)63 template <> bool Writing(const std::string &input, TLVObject &data, TAG tag)
64 {
65     InitWhenFirst(input, data);
66     return data.Write(tag, input);
67 }
68 
Reading(std::string & output,TLVObject & data,const TLVHead & head)69 template <> bool Reading(std::string &output, TLVObject &data, const TLVHead &head)
70 {
71     return data.Read(output, head);
72 }
73 
CountBufferSize(const std::vector<uint8_t> & input,TLVObject & data)74 template <> size_t CountBufferSize(const std::vector<uint8_t> &input, TLVObject &data)
75 {
76     return data.Count(input);
77 }
78 
Writing(const std::vector<uint8_t> & input,TLVObject & data,TAG tag)79 template <> bool Writing(const std::vector<uint8_t> &input, TLVObject &data, TAG tag)
80 {
81     InitWhenFirst(input, data);
82     return data.Write(tag, input);
83 }
84 
Reading(std::vector<uint8_t> & output,TLVObject & data,const TLVHead & head)85 template <> bool Reading(std::vector<uint8_t> &output, TLVObject &data, const TLVHead &head)
86 {
87     return data.Read(output, head);
88 }
89 
CountBufferSize(const UDType & input,TLVObject & data)90 template <> size_t CountBufferSize(const UDType &input, TLVObject &data)
91 {
92     int32_t type = input;
93     return data.CountBasic(type);
94 }
95 
Writing(const UDType & input,TLVObject & data,TAG tag)96 template <> bool Writing(const UDType &input, TLVObject &data, TAG tag)
97 {
98     InitWhenFirst(input, data);
99     int32_t type = input;
100     return data.WriteBasic(tag, type);
101 }
102 
Reading(UDType & output,TLVObject & data,const TLVHead & head)103 template <> bool Reading(UDType &output, TLVObject &data, const TLVHead &head)
104 {
105     int32_t type;
106     if (!Reading(type, data, head)) {
107         return false;
108     }
109     if (type < UDType::ENTITY || type >= UDType::UD_BUTT) {
110         return false;
111     }
112     output = static_cast<UDType>(type);
113     return true;
114 }
115 
CountBufferSize(const DataStatus & input,TLVObject & data)116 template <> size_t CountBufferSize(const DataStatus &input, TLVObject &data)
117 {
118     int32_t status = input;
119     return data.CountBasic(status);
120 }
121 
Writing(const DataStatus & input,TLVObject & data,TAG tag)122 template <> bool Writing(const DataStatus &input, TLVObject &data, TAG tag)
123 {
124     InitWhenFirst(input, data);
125     int32_t status = input;
126     return data.WriteBasic(tag, status);
127 }
128 
Reading(DataStatus & output,TLVObject & data,const TLVHead & head)129 template <> bool Reading(DataStatus &output, TLVObject &data, const TLVHead &head)
130 {
131     int32_t status;
132     if (!data.ReadBasic(status, head)) {
133         return false;
134     }
135     if (status < DataStatus::WORKING || status >= DataStatus::FADE) {
136         return false;
137     }
138     output = static_cast<DataStatus>(status);
139     return true;
140 }
141 
CountBufferSize(const Object & input,TLVObject & data)142 template <> size_t CountBufferSize(const Object &input, TLVObject &data)
143 {
144     return data.CountHead() + CountBufferSize(input.value_, data);
145 }
146 
Writing(const Object & input,TLVObject & data,TAG tag)147 template <> bool Writing(const Object &input, TLVObject &data, TAG tag)
148 {
149     InitWhenFirst(input, data);
150     auto tagCursor = data.GetCursor();
151     data.OffsetHead();
152     if (!Writing(input.value_, data, TAG::TAG_OBJECT_VALUE)) {
153         return false;
154     }
155     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
156 }
Reading(Object & output,TLVObject & data,const TLVHead & head)157 template <> bool Reading(Object &output, TLVObject &data, const TLVHead &head)
158 {
159     TLVHead headValue{};
160     if (!data.ReadHead(headValue)) {
161         return false;
162     }
163     if (headValue.tag != static_cast<uint16_t>(TAG::TAG_OBJECT_VALUE)) {
164         return false;
165     }
166     if (!Reading(output.value_, data, headValue)) {
167         return false;
168     }
169     return true;
170 }
171 
CountBufferSize(const UnifiedKey & input,TLVObject & data)172 template <> size_t CountBufferSize(const UnifiedKey &input, TLVObject &data)
173 {
174     return data.CountHead() + data.Count(input.key) + data.Count(input.intention) + data.Count(input.bundleName) +
175         data.Count(input.groupId);
176 }
Writing(const UnifiedKey & input,TLVObject & data,TAG tag)177 template <> bool Writing(const UnifiedKey &input, TLVObject &data, TAG tag)
178 {
179     InitWhenFirst(input, data);
180     auto tagCursor = data.GetCursor();
181     data.OffsetHead();
182     if (!data.Write(TAG::TAG_KEY, input.key)) {
183         return false;
184     }
185     if (!data.Write(TAG::TAG_INTENTION, input.intention)) {
186         return false;
187     }
188     if (!data.Write(TAG::TAG_BUNDLE_NAME, input.bundleName)) {
189         return false;
190     }
191     if (!data.Write(TAG::TAG_GROUP_ID, input.groupId)) {
192         return false;
193     }
194     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
195 }
196 
Reading(UnifiedKey & output,TLVObject & data,const TLVHead & head)197 template <> bool Reading(UnifiedKey &output, TLVObject &data, const TLVHead &head)
198 {
199     if (head.len > data.GetTotal() - data.GetCursor()) {
200         LOG_ERROR(UDMF_FRAMEWORK, "Invalid length, would read out of bounds.");
201         return false;
202     }
203     auto endCursor = data.GetCursor() + head.len;
204     while (data.GetCursor() < endCursor) {
205         TLVHead headItem{};
206         if (!data.ReadHead(headItem)) {
207             return false;
208         }
209         switch (headItem.tag) {
210             case static_cast<uint16_t>(TAG::TAG_KEY):
211                 if (!data.Read(output.key, headItem)) {
212                     return false;
213                 }
214                 break;
215             case static_cast<uint16_t>(TAG::TAG_INTENTION):
216                 if (!data.Read(output.intention, headItem)) {
217                     return false;
218                 }
219                 break;
220             case static_cast<uint16_t>(TAG::TAG_BUNDLE_NAME):
221                 if (!data.Read(output.bundleName, headItem)) {
222                     return false;
223                 }
224                 break;
225             case static_cast<uint16_t>(TAG::TAG_GROUP_ID):
226                 if (!data.Read(output.groupId, headItem)) {
227                     return false;
228                 }
229                 break;
230             default:
231                 data.Skip(headItem);
232         }
233     }
234     return true;
235 }
236 
CountBufferSize(const UnifiedData & input,TLVObject & data)237 template <> size_t CountBufferSize(const UnifiedData &input, TLVObject &data)
238 {
239     return data.CountHead() + data.Count(input.GetSdkVersion()) + TLVUtil::CountBufferSize(input.GetRecords(), data) +
240         TLVUtil::CountBufferSize(input.GetProperties(), data);
241 }
242 
Writing(const UnifiedData & input,TLVObject & data,TAG tag)243 template <> bool Writing(const UnifiedData &input, TLVObject &data, TAG tag)
244 {
245     InitWhenFirst(input, data);
246     auto tagCursor = data.GetCursor();
247     data.OffsetHead();
248     if (!data.Write(TAG::TAG_VERSION, input.GetSdkVersion())) {
249         return false;
250     }
251     if (!TLVUtil::Writing(input.GetRecords(), data, TAG::TAG_UNIFIED_RECORD)) {
252         return false;
253     }
254     if (!TLVUtil::Writing(input.GetProperties(), data, TAG::TAG_UNIFIED_PROPERTIES)) {
255         return false;
256     }
257     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
258 }
259 
Reading(UnifiedData & output,TLVObject & data,const TLVHead & head)260 template <> bool Reading(UnifiedData &output, TLVObject &data, const TLVHead &head)
261 {
262     if (head.len > data.GetTotal() - data.GetCursor()) {
263         LOG_ERROR(UDMF_FRAMEWORK, "Invalid length, would read out of bounds.");
264         return false;
265     }
266     auto endCursor = data.GetCursor() + head.len;
267     while (data.GetCursor() < endCursor) {
268         TLVHead headItem{};
269         if (!data.ReadHead(headItem)) {
270             return false;
271         }
272         if (headItem.tag == static_cast<uint16_t>(TAG::TAG_VERSION)) {
273             std::string version;
274             if (!Reading(version, data, headItem)) {
275                 return false;
276             }
277             output.SetSdkVersion(version);
278             continue;
279         }
280         if (headItem.tag == static_cast<uint16_t>(TAG::TAG_UNIFIED_RECORD)) {
281             auto records = output.GetRecords();
282             if (!Reading(records, data, headItem)) {
283                 return false;
284             }
285             output.SetRecords(records);
286             continue;
287         }
288         if (headItem.tag == static_cast<uint16_t>(TAG::TAG_UNIFIED_PROPERTIES)) {
289             auto properties = output.GetProperties();
290             if (!Reading(properties, data, headItem)) {
291                 return false;
292             }
293             output.SetProperties(std::move(properties));
294             continue;
295         }
296         data.Skip(headItem);
297     }
298     return true;
299 }
300 
CountBufferSize(const UnifiedDataProperties & input,TLVObject & data)301 template <> size_t CountBufferSize(const UnifiedDataProperties &input, TLVObject &data)
302 {
303     return data.CountHead() + data.Count(input.tag) + data.CountBasic(input.timestamp) +
304         data.CountBasic(static_cast<int32_t>(input.shareOptions))  + TLVUtil::CountBufferSize(input.extras, data);
305 }
306 
Writing(const UnifiedDataProperties & input,TLVObject & data,TAG tag)307 template <> bool Writing(const UnifiedDataProperties &input, TLVObject &data, TAG tag)
308 {
309     InitWhenFirst(input, data);
310     auto tagCursor = data.GetCursor();
311     data.OffsetHead();
312     if (!data.Write(TAG::TAG_PROPERTIES_TAG, input.tag)) {
313         return false;
314     }
315     if (!data.WriteBasic(TAG::TAG_PROPERTIES_TIMESTAMP, input.timestamp)) {
316         return false;
317     }
318     if (!data.WriteBasic(TAG::TAG_PROPERTIES_SHARE_OPTIONS, static_cast<int32_t>(input.shareOptions))) {
319         return false;
320     }
321     if (!TLVUtil::Writing(input.extras, data, TAG::TAG_PROPERTIES_EXTRAS)) {
322         return false;
323     }
324     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
325 }
326 
Reading(UnifiedDataProperties & output,TLVObject & data,const TLVHead & head)327 template <> bool Reading(UnifiedDataProperties &output, TLVObject &data, const TLVHead &head)
328 {
329     if (head.len > data.GetTotal() - data.GetCursor()) {
330         LOG_ERROR(UDMF_FRAMEWORK, "Invalid length, would read out of bounds.");
331         return false;
332     }
333     auto endCursor = data.GetCursor() + head.len;
334     while (data.GetCursor() < endCursor) {
335         TLVHead headItem{};
336         if (!data.ReadHead(headItem)) {
337             return false;
338         }
339         bool result = true;
340         switch (headItem.tag) {
341             case static_cast<uint16_t>(TAG::TAG_PROPERTIES_TAG):
342                 result = data.Read(output.tag, headItem);
343                 break;
344             case static_cast<uint16_t>(TAG::TAG_PROPERTIES_TIMESTAMP):
345                 result = data.ReadBasic(output.timestamp, headItem);
346                 break;
347             case static_cast<uint16_t>(TAG::TAG_PROPERTIES_SHARE_OPTIONS):
348                 result = TLVUtil::Reading(output.shareOptions, data, headItem);
349                 break;
350             case static_cast<uint16_t>(TAG::TAG_PROPERTIES_EXTRAS):
351                 result = TLVUtil::Reading(output.extras, data, headItem);
352                 break;
353             default:
354                 result = data.Skip(headItem);
355         }
356         if (!result) {
357             return false;
358         }
359     }
360     return true;
361 }
362 
Reading(ShareOptions & output,TLVObject & data,const TLVHead & head)363 template <> bool Reading(ShareOptions &output, TLVObject &data, const TLVHead &head)
364 {
365     int32_t shareOptions;
366     if (!Reading(shareOptions, data, head)) {
367         return false;
368     }
369     if (shareOptions < ShareOptions::IN_APP || shareOptions >= ShareOptions::SHARE_OPTIONS_BUTT) {
370         return false;
371     }
372     output = static_cast<ShareOptions>(shareOptions);
373     return true;
374 }
375 
CountBufferSize(const OHOS::AAFwk::WantParams & input,TLVObject & data)376 template <> size_t CountBufferSize(const OHOS::AAFwk::WantParams &input, TLVObject &data)
377 {
378     Parcel parcel;
379     if (!input.Marshalling(parcel)) {
380         LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error when Count");
381         return 0;
382     }
383     auto size = parcel.GetDataSize();
384     std::vector<std::uint8_t> val(size);
385     return CountBufferSize(val, data);
386 }
387 
Writing(const OHOS::AAFwk::WantParams & input,TLVObject & data,TAG tag)388 template <> bool Writing(const OHOS::AAFwk::WantParams &input, TLVObject &data, TAG tag)
389 {
390     InitWhenFirst(input, data);
391     Parcel parcel;
392     if (!input.Marshalling(parcel)) {
393         LOG_ERROR(UDMF_FRAMEWORK, "Marshalling wantParams error in tlv write. tag=%{public}hu", tag);
394         return false;
395     }
396     auto size = parcel.GetDataSize();
397     auto buffer = parcel.GetData();
398     std::vector<std::uint8_t> val(size);
399     if (size != 0) {
400         auto err = memcpy_s(val.data(), size, reinterpret_cast<const void *>(buffer), size);
401         if (err != EOK) {
402             LOG_ERROR(UDMF_FRAMEWORK, "memcpy error in tlv write wantParams. tag=%{public}hu", tag);
403             return false;
404         }
405     }
406     return data.Write(tag, val);
407 }
408 
Reading(OHOS::AAFwk::WantParams & output,TLVObject & data,const TLVHead & head)409 template <> bool Reading(OHOS::AAFwk::WantParams &output, TLVObject &data, const TLVHead &head)
410 {
411     std::vector<std::uint8_t> val;
412     if (!data.Read(val, head)) {
413         LOG_ERROR(UDMF_FRAMEWORK, "Reading u8 vector error.");
414         return false;
415     }
416 
417     std::shared_ptr<Parcel> parcel = std::make_shared<Parcel>();
418     auto buffer = malloc(val.size());
419     if (buffer == nullptr) {
420         LOG_ERROR(UDMF_FRAMEWORK, "malloc error in tlv read. tag=%{public}hu", head.tag);
421         return false;
422     }
423     auto err = memcpy_s(buffer, val.size(), val.data(), val.size());
424     if (err != EOK) {
425         LOG_ERROR(UDMF_FRAMEWORK, "memcpy_s error in tlv read wantParams. tag=%{public}hu", head.tag);
426         free(buffer);
427         return false;
428     }
429     if (!parcel->ParseFrom((uintptr_t)buffer, head.len)) {
430         LOG_ERROR(UDMF_FRAMEWORK, "ParseFrom error in tlv read wantParams. tag=%{public}hu", head.tag);
431         free(buffer);
432         return false;
433     }
434     // The pointer returned by Unmarshalling needs to be manually deleted.
435     auto wantParams = AAFwk::WantParams::Unmarshalling(*parcel);
436     if (wantParams == nullptr) {
437         LOG_ERROR(UDMF_FRAMEWORK, "Unmarshalling wantParams error in tlv read. tag=%{public}hu", head.tag);
438         return false;
439     }
440     output = *wantParams;
441     delete wantParams;
442     return true;
443 }
444 
CountBufferSize(const UnifiedRecord & input,TLVObject & data)445 template <> size_t CountBufferSize(const UnifiedRecord &input, TLVObject &data)
446 {
447     return data.CountHead() + data.CountBasic(static_cast<int32_t>(input.GetType())) +
448         data.Count(input.GetUid()) + CountBufferSize(input.GetOriginValue(), data) + data.Count(input.GetUtdId()) +
449         data.Count(input.GetUtdId2()) + CountBufferSize(input.GetInnerEntries(), data) +
450         CountBufferSize(input.GetUris(), data);
451 }
452 
Writing(const UnifiedRecord & input,TLVObject & data,TAG tag)453 template <> bool Writing(const UnifiedRecord &input, TLVObject &data, TAG tag)
454 {
455     InitWhenFirst(input, data);
456     auto tagCursor = data.GetCursor();
457     data.OffsetHead();
458     if (!data.WriteBasic(TAG::TAG_UD_TYPE, static_cast<int32_t>(input.GetType()))) {
459         return false;
460     }
461     if (!data.Write(TAG::TAG_UID, input.GetUid())) {
462         return false;
463     }
464     if (!TLVUtil::Writing(input.GetOriginValue(), data, TAG::TAG_RECORD_VALUE)) {
465         return false;
466     }
467     if (!data.Write(TAG::TAG_RECORD_UTD_ID, input.GetUtdId())) {
468         return false;
469     }
470     if (!data.Write(TAG::TAG_RECORD_UTD_ID2, input.GetUtdId2())) {
471         return false;
472     }
473     if (!TLVUtil::Writing(input.GetInnerEntries(), data, TAG::TAG_RECORD_ENTRIES)) {
474         return false;
475     }
476     if (!TLVUtil::Writing(input.GetUris(), data, TAG::TAG_RECORD_URIS)) {
477         return false;
478     }
479     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
480 }
481 
Reading(UnifiedRecord & output,TLVObject & data,const TLVHead & head)482 template <> bool Reading(UnifiedRecord &output, TLVObject &data, const TLVHead &head)
483 {
484     if (head.len > data.GetTotal() - data.GetCursor()) {
485         LOG_ERROR(UDMF_FRAMEWORK, "Invalid length, would read out of bounds.");
486         return false;
487     }
488     auto endCursor = data.GetCursor() + head.len;
489     UDType dataType;
490     std::string uid;
491     ValueType value;
492     while (data.GetCursor() < endCursor) {
493         TLVHead headItem{};
494         if (!data.ReadHead(headItem)) {
495             return false;
496         }
497         std::string utdId;
498         std::string utdId2;
499         std::shared_ptr<std::map<std::string, ValueType>> entries;
500         std::vector<UriInfo> uriInfos;
501         switch (headItem.tag) {
502             case static_cast<uint16_t>(TAG::TAG_UD_TYPE):
503                 if (!TLVUtil::Reading(dataType, data, headItem)) {
504                     return false;
505                 }
506                 output.SetType(dataType);
507                 break;
508             case static_cast<uint16_t>(TAG::TAG_UID):
509                 if (!data.Read(uid, headItem)) {
510                     return false;
511                 }
512                 output.SetUid(uid);
513                 break;
514             case static_cast<uint16_t>(TAG::TAG_RECORD_VALUE):
515                 if (!TLVUtil::Reading(value, data, headItem)) {
516                     return false;
517                 }
518                 output.SetValue(value);
519                 break;
520             case static_cast<uint16_t>(TAG::TAG_RECORD_UTD_ID):
521                 if (!data.Read(utdId, headItem)) {
522                     return false;
523                 }
524                 output.SetUtdId(std::move(utdId));
525                 break;
526             case static_cast<uint16_t>(TAG::TAG_RECORD_UTD_ID2):
527                 if (!data.Read(utdId2, headItem)) {
528                     return false;
529                 }
530                 output.SetUtdId2(std::move(utdId2));
531                 break;
532             case static_cast<uint16_t>(TAG::TAG_RECORD_ENTRIES):
533                 if (!TLVUtil::Reading(entries, data, headItem)) {
534                     return false;
535                 }
536                 output.SetInnerEntries(entries);
537                 break;
538             case static_cast<uint16_t>(TAG::TAG_RECORD_URIS):
539                 if (!TLVUtil::Reading(uriInfos, data, headItem)) {
540                     return false;
541                 }
542                 output.SetUris(std::move(uriInfos));
543                 break;
544             default:
545                 data.Skip(headItem);
546         }
547     }
548     return true;
549 }
550 
CountBufferSize(const Runtime & input,TLVObject & data)551 template <> size_t CountBufferSize(const Runtime &input, TLVObject &data)
552 {
553     return data.CountHead() + data.CountBasic(input.isPrivate) + data.CountBasic(input.dataVersion) +
554         data.CountBasic(input.recordTotalNum) + data.CountBasic(input.tokenId) +
555         data.CountBasic(static_cast<int64_t>(input.createTime)) +
556         data.CountBasic(static_cast<int64_t>(input.lastModifiedTime)) +
557         data.CountBasic(static_cast<int32_t>(input.dataStatus)) + data.Count(input.sourcePackage) +
558         data.Count(input.createPackage) + data.Count(input.deviceId) + TLVUtil::CountBufferSize(input.key, data) +
559         data.Count(input.sdkVersion) + TLVUtil::CountBufferSize(input.privileges, data) +
560         data.CountBasic(static_cast<int32_t>(input.visibility)) + data.Count(input.appId);
561 }
562 
Writing(const Runtime & input,TLVObject & data,TAG tag)563 template <> bool Writing(const Runtime &input, TLVObject &data, TAG tag)
564 {
565     InitWhenFirst(input, data);
566     auto tagCursor = data.GetCursor();
567     data.OffsetHead();
568     if (!TLVUtil::Writing(input.key, data, TAG::TAG_KEY)) {
569         return false;
570     }
571     if (!data.WriteBasic(TAG::TAG_IS_PRIVATE, input.isPrivate)) {
572         return false;
573     }
574     if (!TLVUtil::Writing(input.privileges, data, TAG::TAG_PRIVILEGE)) {
575         return false;
576     }
577     if (!data.WriteBasic(TAG::TAG_CREATE_TIME, static_cast<int64_t>(input.createTime))) {
578         return false;
579     }
580     if (!data.Write(TAG::TAG_SOURCE_PACKAGE, input.sourcePackage)) {
581         return false;
582     }
583     if (!data.WriteBasic(TAG::TAG_DATA_STATUS, static_cast<int32_t>(input.dataStatus))) {
584         return false;
585     }
586     if (!data.WriteBasic(TAG::TAG_DATA_VERSION, input.dataVersion)) {
587         return false;
588     }
589     if (!data.WriteBasic(TAG::TAG_LAST_MODIFIED_TIME, static_cast<int64_t>(input.lastModifiedTime))) {
590         return false;
591     }
592     if (!data.Write(TAG::TAG_CREATE_PACKAGE, input.createPackage)) {
593         return false;
594     }
595     if (!data.Write(TAG::TAG_DEVICE_ID, input.deviceId)) {
596         return false;
597     }
598     if (!data.WriteBasic(TAG::TAG_RECORD_TOTAL_NUM, input.recordTotalNum)) {
599         return false;
600     }
601     if (!data.WriteBasic(TAG::TAG_TOKEN_ID, input.tokenId)) {
602         return false;
603     }
604     if (!TLVUtil::Writing(input.sdkVersion, data, TAG::TAG_VERSION)) {
605         return false;
606     }
607     if (!data.WriteBasic(TAG::TAG_VISIBILITY, static_cast<int32_t>(input.visibility))) {
608         return false;
609     }
610     if (!TLVUtil::Writing(input.appId, data, TAG::TAG_APP_ID)) {
611         return false;
612     }
613     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
614 }
615 
Reading(Runtime & output,TLVObject & data,const TLVHead & head)616 template <> bool Reading(Runtime &output, TLVObject &data, const TLVHead &head)
617 {
618     if (head.len > data.GetTotal() - data.GetCursor()) {
619         LOG_ERROR(UDMF_FRAMEWORK, "Invalid length, would read out of bounds.");
620         return false;
621     }
622     auto endCursor = data.GetCursor() + head.len;
623     while (data.GetCursor() < endCursor) {
624         TLVHead headItem{};
625         if (!data.ReadHead(headItem)) {
626             return false;
627         }
628         bool result = true;
629         int64_t createTime = 0;
630         int64_t lastModifiedTime = 0;
631         int32_t visibility = 0;
632         switch (headItem.tag) {
633             case static_cast<uint16_t>(TAG::TAG_KEY):
634                 result = TLVUtil::Reading(output.key, data, headItem);
635                 break;
636             case static_cast<uint16_t>(TAG::TAG_IS_PRIVATE):
637                 result = data.ReadBasic(output.isPrivate, headItem);
638                 break;
639             case static_cast<uint16_t>(TAG::TAG_PRIVILEGE):
640                 result = TLVUtil::Reading(output.privileges, data, headItem);
641                 break;
642             case static_cast<uint16_t>(TAG::TAG_CREATE_TIME):
643                 result = data.ReadBasic(createTime, headItem);
644                 output.createTime = static_cast<time_t>(createTime);
645                 break;
646             case static_cast<uint16_t>(TAG::TAG_SOURCE_PACKAGE):
647                 result = data.Read(output.sourcePackage, headItem);
648                 break;
649             case static_cast<uint16_t>(TAG::TAG_DATA_STATUS):
650                 result = TLVUtil::Reading(output.dataStatus, data, headItem);
651                 break;
652             case static_cast<uint16_t>(TAG::TAG_DATA_VERSION):
653                 result = data.ReadBasic(output.dataVersion, headItem);
654                 break;
655             case static_cast<uint16_t>(TAG::TAG_LAST_MODIFIED_TIME):
656                 result = data.ReadBasic(lastModifiedTime, headItem);
657                 output.lastModifiedTime = static_cast<time_t>(lastModifiedTime);
658                 break;
659             case static_cast<uint16_t>(TAG::TAG_CREATE_PACKAGE):
660                 result = data.Read(output.createPackage, headItem);
661                 break;
662             case static_cast<uint16_t>(TAG::TAG_DEVICE_ID):
663                 result = data.Read(output.deviceId, headItem);
664                 break;
665             case static_cast<uint16_t>(TAG::TAG_RECORD_TOTAL_NUM):
666                 result = data.ReadBasic(output.recordTotalNum, headItem);
667                 break;
668             case static_cast<uint16_t>(TAG::TAG_TOKEN_ID):
669                 result = data.ReadBasic(output.tokenId, headItem);
670                 break;
671             case static_cast<uint16_t>(TAG::TAG_VERSION):
672                 result = data.Read(output.sdkVersion, headItem);
673                 break;
674             case static_cast<uint16_t>(TAG::TAG_VISIBILITY):
675                 result = data.ReadBasic(visibility, headItem);
676                 output.visibility = static_cast<UDMF::Visibility>(visibility);
677                 break;
678             case static_cast<uint16_t>(TAG::TAG_APP_ID):
679                 result = data.Read(output.appId, headItem);
680                 break;
681             default:
682                 result = data.Skip(headItem);
683         }
684         if (!result) {
685             return false;
686         }
687     }
688     return true;
689 }
690 
CountBufferSize(const Privilege & input,TLVObject & data)691 template <> size_t CountBufferSize(const Privilege &input, TLVObject &data)
692 {
693     return data.CountHead() + data.CountBasic(input.tokenId) + data.Count(input.readPermission) +
694         data.Count(input.writePermission);
695 }
696 
Writing(const Privilege & input,TLVObject & data,TAG tag)697 template <> bool Writing(const Privilege &input, TLVObject &data, TAG tag)
698 {
699     InitWhenFirst(input, data);
700     auto tagCursor = data.GetCursor();
701     data.OffsetHead();
702     if (!data.WriteBasic(TAG::TAG_TOKEN_ID, input.tokenId)) {
703         return false;
704     }
705     if (!data.Write(TAG::TAG_READPERMISSION, input.readPermission)) {
706         return false;
707     }
708     if (!data.Write(TAG::TAG_WRITEPERMISSION, input.writePermission)) {
709         return false;
710     }
711     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
712 }
713 
Reading(Privilege & output,TLVObject & data,const TLVHead & head)714 template <> bool Reading(Privilege &output, TLVObject &data, const TLVHead &head)
715 {
716     if (head.len > data.GetTotal() - data.GetCursor()) {
717         LOG_ERROR(UDMF_FRAMEWORK, "Invalid length, would read out of bounds.");
718         return false;
719     }
720     auto endCursor = data.GetCursor() + head.len;
721     while (data.GetCursor() < endCursor) {
722         TLVHead headItem{};
723         if (!data.ReadHead(headItem)) {
724             return false;
725         }
726         switch (headItem.tag) {
727             case static_cast<uint16_t>(TAG::TAG_TOKEN_ID):
728                 if (!data.ReadBasic(output.tokenId, headItem)) {
729                     return false;
730                 }
731                 break;
732             case static_cast<uint16_t>(TAG::TAG_READPERMISSION):
733                 if (!data.Read(output.readPermission, headItem)) {
734                     return false;
735                 }
736                 break;
737             case static_cast<uint16_t>(TAG::TAG_WRITEPERMISSION):
738                 if (!data.Read(output.writePermission, headItem)) {
739                     return false;
740                 }
741                 break;
742             default:
743                 data.Skip(headItem);
744         }
745     }
746     return true;
747 }
748 
CountBufferSize(const UriInfo & input,TLVObject & data)749 template <> size_t CountBufferSize(const UriInfo &input, TLVObject &data)
750 {
751     return data.CountHead() + data.CountBasic(input.position) + data.Count(input.oriUri) +
752         data.Count(input.dfsUri) + data.Count(input.authUri);
753 }
754 
Writing(const UriInfo & input,TLVObject & data,TAG tag)755 template <> bool Writing(const UriInfo &input, TLVObject &data, TAG tag)
756 {
757     InitWhenFirst(input, data);
758     auto tagCursor = data.GetCursor();
759     data.OffsetHead();
760     if (!TLVUtil::Writing(input.oriUri, data, TAG::TAG_URI_ORI)) {
761         return false;
762     }
763     if (!TLVUtil::Writing(input.dfsUri, data, TAG::TAG_URI_DFS)) {
764         return false;
765     }
766     if (!TLVUtil::Writing(input.authUri, data, TAG::TAG_URI_AUTH)) {
767         return false;
768     }
769     if (!data.WriteBasic(TAG::TAG_URI_POS, input.position)) {
770         return false;
771     }
772     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
773 }
774 
Reading(UriInfo & output,TLVObject & data,const TLVHead & head)775 template <> bool Reading(UriInfo &output, TLVObject &data, const TLVHead &head)
776 {
777     if (head.len > data.GetTotal() - data.GetCursor()) {
778         LOG_ERROR(UDMF_FRAMEWORK, "Invalid length, would read out of bounds.");
779         return false;
780     }
781     auto endCursor = data.GetCursor() + head.len;
782     while (data.GetCursor() < endCursor) {
783         TLVHead headItem{};
784         if (!data.ReadHead(headItem)) {
785             return false;
786         }
787         bool result = true;
788         switch (headItem.tag) {
789             case static_cast<uint16_t>(TAG::TAG_URI_ORI):
790                 result = TLVUtil::Reading(output.oriUri, data, headItem);
791                 break;
792             case static_cast<uint16_t>(TAG::TAG_URI_DFS):
793                 result = TLVUtil::Reading(output.dfsUri, data, headItem);
794                 break;
795             case static_cast<uint16_t>(TAG::TAG_URI_AUTH):
796                 result = TLVUtil::Reading(output.authUri, data, headItem);
797                 break;
798             case static_cast<uint16_t>(TAG::TAG_URI_POS):
799                 result = data.ReadBasic(output.position, headItem);
800                 break;
801             default:
802                 result = data.Skip(headItem);
803         }
804         if (!result) {
805             return false;
806         }
807     }
808     return true;
809 }
810 
CountBufferSize(const std::shared_ptr<OHOS::Media::PixelMap> & input,TLVObject & data)811 template <> size_t CountBufferSize(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data)
812 {
813     std::vector<std::uint8_t> val;
814     PixelMapLoader loader;
815     if (!loader.EncodeTlv(input, val)) {
816         LOG_ERROR(UDMF_FRAMEWORK, "Encode pixelMap error when CountBufferSize");
817         return 0;
818     }
819     return CountBufferSize(val, data);
820 }
821 
Writing(const std::shared_ptr<OHOS::Media::PixelMap> & input,TLVObject & data,TAG tag)822 template <> bool Writing(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data, TAG tag)
823 {
824     InitWhenFirst(input, data);
825     std::vector<std::uint8_t> val;
826     PixelMapLoader loader;
827     if (!loader.EncodeTlv(input, val)) {
828         LOG_ERROR(UDMF_FRAMEWORK, "Encode pixelMap error when Writing");
829         return false;
830     }
831     return data.Write(tag, val);
832 }
833 
Reading(std::shared_ptr<OHOS::Media::PixelMap> & output,TLVObject & data,const TLVHead & head)834 template <> bool Reading(std::shared_ptr<OHOS::Media::PixelMap> &output, TLVObject &data, const TLVHead &head)
835 {
836     std::vector<std::uint8_t> val;
837     if (!data.Read(val, head)) {
838         LOG_ERROR(UDMF_FRAMEWORK, "Reading u8 vector error.");
839         return false;
840     }
841     PixelMapLoader loader;
842     output = loader.DecodeTlv(val);
843     if (output == nullptr) {
844         LOG_ERROR(UDMF_FRAMEWORK, "DecodeTlv pixelMap error when Reading.");
845         return false;
846     }
847     return true;
848 }
849 
CountBufferSize(const std::shared_ptr<std::map<std::string,ValueType>> & input,TLVObject & data)850 template <> size_t CountBufferSize(const std::shared_ptr<std::map<std::string, ValueType>> &input, TLVObject &data)
851 {
852     if (input == nullptr) {
853         return data.CountHead();
854     }
855     return CountBufferSize(*input, data);
856 }
857 
Writing(const std::shared_ptr<std::map<std::string,ValueType>> & input,TLVObject & data,TAG tag)858 template <> bool Writing(const std::shared_ptr<std::map<std::string, ValueType>> &input, TLVObject &data, TAG tag)
859 {
860     if (input == nullptr) {
861         return false;
862     }
863     InitWhenFirst(input, data);
864     return Writing(*input, data, tag);
865 }
866 
Reading(std::shared_ptr<std::map<std::string,ValueType>> & output,TLVObject & data,const TLVHead & head)867 template <> bool Reading(std::shared_ptr<std::map<std::string, ValueType>> &output,
868     TLVObject &data, const TLVHead &head)
869 {
870     if (output == nullptr) {
871         output = std::make_shared<std::map<std::string, ValueType>>();
872     }
873     return Reading(*output, data, head);
874 }
875 
CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> & input,TLVObject & data)876 template <> size_t CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data)
877 {
878     Parcel parcel;
879     if (!input->Marshalling(parcel)) {
880         LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error when Count");
881         return 0;
882     }
883     auto size = parcel.GetDataSize();
884     std::vector<std::uint8_t> val(size);
885     return CountBufferSize(val, data);
886 }
887 
Writing(const std::shared_ptr<OHOS::AAFwk::Want> & input,TLVObject & data,TAG tag)888 template <> bool Writing(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data, TAG tag)
889 {
890     InitWhenFirst(input, data);
891     Parcel parcel;
892     if (!input->Marshalling(parcel)) {
893         LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error in tlv write. tag=%{public}hu", tag);
894         return false;
895     }
896     auto size = parcel.GetDataSize();
897     auto buffer = parcel.GetData();
898     std::vector<std::uint8_t> val(size);
899     if (size != 0) {
900         auto err = memcpy_s(val.data(), size, reinterpret_cast<const void *>(buffer), size);
901         if (err != EOK) {
902             LOG_ERROR(UDMF_FRAMEWORK, "memcpy error in tlv write want. tag=%{public}hu", tag);
903             return false;
904         }
905     }
906     return data.Write(tag, val);
907 }
908 
Reading(std::shared_ptr<OHOS::AAFwk::Want> & output,TLVObject & data,const TLVHead & head)909 template <> bool Reading(std::shared_ptr<OHOS::AAFwk::Want> &output, TLVObject &data, const TLVHead &head)
910 {
911     std::vector<std::uint8_t> val;
912     if (!data.Read(val, head)) {
913         LOG_ERROR(UDMF_FRAMEWORK, "Reading u8 vector error.");
914         return false;
915     }
916 
917     std::shared_ptr<Parcel> parcel = std::make_shared<Parcel>();
918     auto buffer = malloc(val.size());
919     if (buffer == nullptr) {
920         LOG_ERROR(UDMF_FRAMEWORK, "malloc error in tlv read. tag=%{public}hu", head.tag);
921         return false;
922     }
923     auto err = memcpy_s(buffer, val.size(), val.data(), val.size());
924     if (err != EOK) {
925         LOG_ERROR(UDMF_FRAMEWORK, "memcpy_s error in tlv read want. tag=%{public}hu", head.tag);
926         free(buffer);
927         return false;
928     }
929     if (!parcel->ParseFrom((uintptr_t)buffer, head.len)) {
930         LOG_ERROR(UDMF_FRAMEWORK, "ParseFrom error in tlv read want. tag=%{public}hu", head.tag);
931         free(buffer);
932         return false;
933     }
934     auto want = AAFwk::Want::Unmarshalling(*parcel);
935     if (want == nullptr) {
936         LOG_ERROR(UDMF_FRAMEWORK, "Unmarshalling want error in tlv read. tag=%{public}hu", head.tag);
937         return false;
938     }
939     output = std::shared_ptr<OHOS::AAFwk::Want>(want);
940     return true;
941 }
942 
CountBufferSize(const Summary & input,TLVObject & data)943 template <> size_t CountBufferSize(const Summary &input, TLVObject &data)
944 {
945     return data.CountHead() + CountBufferSize(input.summary, data) + data.CountBasic(input.totalSize) +
946         CountBufferSize(input.specificSummary, data) + CountBufferSize(input.summaryFormat, data) +
947         data.CountBasic(input.version);
948 }
949 
Writing(const Summary & input,TLVObject & data,TAG tag)950 template <> bool Writing(const Summary &input, TLVObject &data, TAG tag)
951 {
952     InitWhenFirst(input, data);
953     auto tagCursor = data.GetCursor();
954     data.OffsetHead();
955     if (!TLVUtil::Writing(input.summary, data, TAG::TAG_SUMMARY_MAP)) {
956         return false;
957     }
958     if (!data.WriteBasic(TAG::TAG_SUMMARY_SIZE, input.totalSize)) {
959         return false;
960     }
961     if (!TLVUtil::Writing(input.specificSummary, data, TAG::TAG_SUMMARY_SPECIFIC_SUMMARY)) {
962         return false;
963     }
964     if (!TLVUtil::Writing(input.summaryFormat, data, TAG::TAG_SUMMARY_SUMMARY_FORMAT)) {
965         return false;
966     }
967     if (!data.WriteBasic(TAG::TAG_SUMMARY_VERSION, input.version)) {
968         return false;
969     }
970     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
971 }
972 
Reading(Summary & output,TLVObject & data,const TLVHead & head)973 template <> bool Reading(Summary &output, TLVObject &data, const TLVHead &head)
974 {
975     if (head.len > data.GetTotal() - data.GetCursor()) {
976         LOG_ERROR(UDMF_FRAMEWORK, "Invalid length, would read out of bounds.");
977         return false;
978     }
979     auto endCursor = data.GetCursor() + head.len;
980     while (data.GetCursor() < endCursor) {
981         TLVHead headItem{};
982         if (!data.ReadHead(headItem)) {
983             return false;
984         }
985         switch (headItem.tag) {
986             case static_cast<uint16_t>(TAG::TAG_SUMMARY_MAP):
987                 if (!TLVUtil::Reading(output.summary, data, headItem)) {
988                     return false;
989                 }
990                 break;
991             case static_cast<uint16_t>(TAG::TAG_SUMMARY_SIZE):
992                 if (!data.ReadBasic(output.totalSize, headItem)) {
993                     return false;
994                 }
995                 break;
996             case static_cast<uint16_t>(TAG::TAG_SUMMARY_SPECIFIC_SUMMARY):
997                 if (!TLVUtil::Reading(output.specificSummary, data, headItem)) {
998                     return false;
999                 }
1000                 break;
1001             case static_cast<uint16_t>(TAG::TAG_SUMMARY_SUMMARY_FORMAT):
1002                 if (!TLVUtil::Reading(output.summaryFormat, data, headItem)) {
1003                     return false;
1004                 }
1005                 break;
1006             case static_cast<uint16_t>(TAG::TAG_SUMMARY_VERSION):
1007                 if (!data.ReadBasic(output.version, headItem)) {
1008                     return false;
1009                 }
1010                 break;
1011             default:
1012                 data.Skip(headItem);
1013         }
1014     }
1015     return true;
1016 }
1017 
CountBufferSize(const DataLoadInfo & input,TLVObject & data)1018 template <> size_t API_EXPORT CountBufferSize(const DataLoadInfo &input, TLVObject &data)
1019 {
1020     return data.CountHead() + data.Count(input.sequenceKey) + CountBufferSize(input.types, data) +
1021         data.CountBasic(input.recordCount);
1022 }
1023 
Writing(const DataLoadInfo & input,TLVObject & data,TAG tag)1024 template <> bool API_EXPORT Writing(const DataLoadInfo &input, TLVObject &data, TAG tag)
1025 {
1026     InitWhenFirst(input, data);
1027     auto tagCursor = data.GetCursor();
1028     data.OffsetHead();
1029     if (!TLVUtil::Writing(input.sequenceKey, data, TAG::TAG_DATA_LOAD_KEY)) {
1030         return false;
1031     }
1032     if (!TLVUtil::Writing(input.types, data, TAG::TAG_SET_TYPES)) {
1033         return false;
1034     }
1035     if (!data.WriteBasic(TAG::TAG_RECORD_COUNT, input.recordCount)) {
1036         return false;
1037     }
1038     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
1039 }
1040 
Reading(DataLoadInfo & output,TLVObject & data,const TLVHead & head)1041 template <> bool API_EXPORT Reading(DataLoadInfo &output, TLVObject &data, const TLVHead &head)
1042 {
1043     if (head.len > data.GetTotal() - data.GetCursor()) {
1044         LOG_ERROR(UDMF_FRAMEWORK, "Invalid length, would read out of bounds.");
1045         return false;
1046     }
1047     auto endCursor = data.GetCursor() + head.len;
1048     while (data.GetCursor() < endCursor) {
1049         TLVHead headItem{};
1050         if (!data.ReadHead(headItem)) {
1051             return false;
1052         }
1053         switch (headItem.tag) {
1054             case static_cast<uint16_t>(TAG::TAG_DATA_LOAD_KEY):
1055                 if (!TLVUtil::Reading(output.sequenceKey, data, headItem)) {
1056                     return false;
1057                 }
1058                 break;
1059             case static_cast<uint16_t>(TAG::TAG_SET_TYPES):
1060                 if (!TLVUtil::Reading(output.types, data, headItem)) {
1061                     return false;
1062                 }
1063                 break;
1064             case static_cast<uint16_t>(TAG::TAG_RECORD_COUNT):
1065                 if (!data.ReadBasic(output.recordCount, headItem)) {
1066                     return false;
1067                 }
1068                 break;
1069             default:
1070                 data.Skip(headItem);
1071         }
1072     }
1073     return true;
1074 }
1075 } // namespace TLVUtil
1076 } // namespace OHOS
1077