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