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