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