• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef UDMF_TLV_UTIL_H
17 #define UDMF_TLV_UTIL_H
18 
19 #include <utility>
20 #include <vector>
21 #include "unified_types.h"
22 #include "unified_data.h"
23 #include "unified_key.h"
24 #include "tlv_object.h"
25 #include "unified_record.h"
26 
27 
28 namespace OHOS {
29 namespace TLVUtil {
30 using namespace OHOS::UDMF;
31 
32 template <typename T> bool API_EXPORT ReadTlv(T &output, TLVObject &data, TAG tag);
33 
34 template <typename T> size_t API_EXPORT CountBufferSize(const T &input, TLVObject &data);
35 template <typename T> bool API_EXPORT Writing(const T &input, TLVObject &data, TAG tag);
36 template <typename T> bool API_EXPORT Reading(T &output, TLVObject &data, const TLVHead &head);
37 
38 template <typename... _Types> size_t API_EXPORT CountBufferSize(const std::variant<_Types...> &input, TLVObject &data);
39 template <typename... _Types> bool API_EXPORT Writing(const std::variant<_Types...> &input, TLVObject &data, TAG tag);
40 template <typename... _Types>
41 bool API_EXPORT Reading(std::variant<_Types...> &output, TLVObject &data, const TLVHead &head);
42 
43 template <typename T> size_t API_EXPORT CountBufferSize(const std::shared_ptr<T> &input, TLVObject &data);
44 template <typename T> bool API_EXPORT Writing(const std::shared_ptr<T> &input, TLVObject &data, TAG tag);
45 template <typename T> bool API_EXPORT Reading(std::shared_ptr<T> &output, TLVObject &data, const TLVHead &head);
46 
47 template <typename T> size_t API_EXPORT CountBufferSize(const std::vector<T> &input, TLVObject &data);
48 template <typename T> bool API_EXPORT Writing(const std::vector<T> &input, TLVObject &data, TAG tag);
49 template <typename T> bool API_EXPORT Reading(std::vector<T> &output, TLVObject &data, const TLVHead &head);
50 
51 template <typename T, typename R> size_t API_EXPORT CountBufferSize(const std::map<T, R> &input, TLVObject &data);
52 template <typename T, typename R> bool API_EXPORT Writing(const std::map<T, R> &input, TLVObject &data, TAG tag);
53 template <typename T, typename R> bool API_EXPORT Reading(std::map<T, R> &output, TLVObject &data, const TLVHead &head);
54 
55 template <typename T> size_t API_EXPORT CountBufferSize(const std::set<T> &input, TLVObject &data);
56 template <typename T> bool API_EXPORT Writing(const std::set<T> &input, TLVObject &data, TAG tag);
57 template <typename T> bool API_EXPORT Reading(std::set<T> &output, TLVObject &data, const TLVHead &head);
58 
59 template <> size_t API_EXPORT CountBufferSize(const std::nullptr_t &input, TLVObject &data);
60 template <> bool API_EXPORT Writing(const std::nullptr_t &input, TLVObject &data, TAG tag);
61 template <> bool API_EXPORT Reading(std::nullptr_t &output, TLVObject &data, const TLVHead &head);
62 
63 template <> size_t API_EXPORT CountBufferSize(const std::monostate &input, TLVObject &data);
64 template <> bool API_EXPORT Writing(const std::monostate &input, TLVObject &data, TAG tag);
65 template <> bool API_EXPORT Reading(std::monostate &output, TLVObject &data, const TLVHead &head);
66 
67 template <> size_t API_EXPORT CountBufferSize(const std::string &input, TLVObject &data);
68 template <> bool API_EXPORT Writing(const std::string &input, TLVObject &data, TAG tag);
69 template <> bool API_EXPORT Reading(std::string &output, TLVObject &data, const TLVHead &head);
70 
71 template <> size_t API_EXPORT CountBufferSize(const std::vector<uint8_t> &input, TLVObject &data);
72 template <> bool API_EXPORT Writing(const std::vector<uint8_t> &input, TLVObject &data, TAG tag);
73 template <> bool API_EXPORT Reading(std::vector<uint8_t> &output, TLVObject &data, const TLVHead &head);
74 
75 template <> size_t API_EXPORT CountBufferSize(const UDType &input, TLVObject &data);
76 template <> bool API_EXPORT Writing(const UDType &input, TLVObject &data, TAG tag);
77 template <> bool API_EXPORT Reading(UDType &output, TLVObject &data, const TLVHead &head);
78 
79 template <> size_t API_EXPORT CountBufferSize(const DataStatus &input, TLVObject &data);
80 template <> bool API_EXPORT Writing(const DataStatus &input, TLVObject &data, TAG tag);
81 template <> bool API_EXPORT Reading(DataStatus &output, TLVObject &data, const TLVHead &head);
82 
83 template <> size_t API_EXPORT CountBufferSize(const Object &input, TLVObject &data);
84 template <> bool API_EXPORT Writing(const Object &input, TLVObject &data, TAG tag);
85 template <> bool API_EXPORT Reading(Object &output, TLVObject &data, const TLVHead &head);
86 
87 template <> size_t API_EXPORT CountBufferSize(const UnifiedKey &input, TLVObject &data);
88 template <> bool API_EXPORT Writing(const UnifiedKey &input, TLVObject &data, TAG tag);
89 template <> bool API_EXPORT Reading(UnifiedKey &output, TLVObject &data, const TLVHead &head);
90 
91 template <> size_t API_EXPORT CountBufferSize(const UnifiedData &input, TLVObject &data);
92 template <> bool API_EXPORT Writing(const UnifiedData &input, TLVObject &data, TAG tag);
93 template <> bool API_EXPORT Reading(UnifiedData &output, TLVObject &data, const TLVHead &head);
94 
95 template <> size_t API_EXPORT CountBufferSize(const UnifiedRecord &input, TLVObject &data);
96 template <> bool API_EXPORT Writing(const UnifiedRecord &input, TLVObject &data, TAG tag);
97 template <> bool API_EXPORT Reading(UnifiedRecord &output, TLVObject &data, const TLVHead &head);
98 
99 template <> size_t API_EXPORT CountBufferSize(const Runtime &input, TLVObject &data);
100 template <> bool API_EXPORT Writing(const Runtime &input, TLVObject &data, TAG tag);
101 template <> bool API_EXPORT Reading(Runtime &output, TLVObject &data, const TLVHead &head);
102 
103 template <> size_t API_EXPORT CountBufferSize(const Privilege &input, TLVObject &data);
104 template <> bool API_EXPORT Writing(const Privilege &input, TLVObject &data, TAG tag);
105 template <> bool API_EXPORT Reading(Privilege &output, TLVObject &data, const TLVHead &head);
106 
107 template <> size_t API_EXPORT CountBufferSize(const UriInfo &input, TLVObject &data);
108 template <> bool API_EXPORT Writing(const UriInfo &input, TLVObject &data, TAG tag);
109 template <> bool API_EXPORT Reading(UriInfo &output, TLVObject &data, const TLVHead &head);
110 
111 template <> bool API_EXPORT Reading(ShareOptions &output, TLVObject &data, const TLVHead &head);
112 
113 template <> size_t API_EXPORT CountBufferSize(const UnifiedDataProperties &input, TLVObject &data);
114 template <> bool API_EXPORT Writing(const UnifiedDataProperties &input, TLVObject &data, TAG tag);
115 template <> bool API_EXPORT Reading(UnifiedDataProperties &output, TLVObject &data, const TLVHead &head);
116 
117 template <> size_t API_EXPORT CountBufferSize(const OHOS::AAFwk::WantParams &input, TLVObject &data);
118 template <> bool API_EXPORT Writing(const OHOS::AAFwk::WantParams &input, TLVObject &data, TAG tag);
119 template <> bool API_EXPORT Reading(OHOS::AAFwk::WantParams &output, TLVObject &data, const TLVHead &head);
120 
121 template <> size_t API_EXPORT CountBufferSize(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data);
122 template <> bool API_EXPORT Writing(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data, TAG tag);
123 template <>
124 bool API_EXPORT Reading(std::shared_ptr<OHOS::Media::PixelMap> &output, TLVObject &data, const TLVHead &head);
125 
126 template <> size_t API_EXPORT CountBufferSize(const std::shared_ptr<std::map<std::string, ValueType>> &input,
127     TLVObject &data);
128 template <> bool API_EXPORT Writing(const std::shared_ptr<std::map<std::string, ValueType>> &input,
129     TLVObject &data, TAG tag);
130 template <>
131 bool API_EXPORT Reading(std::shared_ptr<std::map<std::string, ValueType>> &output,
132     TLVObject &data, const TLVHead &head);
133 
134 template <> size_t API_EXPORT CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data);
135 template <> bool API_EXPORT Writing(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data, TAG tag);
136 template <> bool API_EXPORT Reading(std::shared_ptr<OHOS::AAFwk::Want> &output, TLVObject &data, const TLVHead &head);
137 
138 template <> size_t API_EXPORT CountBufferSize(const Summary &input, TLVObject &data);
139 template <> bool API_EXPORT Writing(const Summary &input, TLVObject &data, TAG tag);
140 template <> bool API_EXPORT Reading(Summary &output, TLVObject &data, const TLVHead &head);
141 
142 template <> size_t API_EXPORT CountBufferSize(const DataLoadInfo &input, TLVObject &data);
143 template <> bool API_EXPORT Writing(const DataLoadInfo &input, TLVObject &data, TAG tag);
144 template <> bool API_EXPORT Reading(DataLoadInfo &output, TLVObject &data, const TLVHead &head);
145 
ReadTlv(T & output,TLVObject & data,TAG tag)146 template <typename T> bool ReadTlv(T &output, TLVObject &data, TAG tag)
147 {
148     while (data.GetCursor() < data.GetTotal()) {
149         TLVHead head{};
150         if (!data.ReadHead(head)) {
151             return false;
152         }
153         if (head.tag != static_cast<uint16_t>(tag)) {
154             data.Skip(head);
155             continue;
156         }
157         if (!Reading(output, data, head)) {
158             return false;
159         }
160     }
161     return true;
162 }
163 
InitWhenFirst(const T & input,TLVObject & data)164 template <typename T> void InitWhenFirst(const T &input, TLVObject &data)
165 {
166     if (data.GetCursor() == data.GetTotal()) {
167         CountBufferSize(input, data);
168         data.UpdateSize();
169     }
170 }
171 
CountBufferSize(const T & input,TLVObject & data)172 template <typename T> size_t CountBufferSize(const T &input, TLVObject &data)
173 {
174     return data.CountBasic(input);
175 }
176 
Writing(const T & input,TLVObject & data,TAG tag)177 template <typename T> bool Writing(const T &input, TLVObject &data, TAG tag)
178 {
179     InitWhenFirst(input, data);
180     return data.WriteBasic(tag, input);
181 }
182 
Reading(T & output,TLVObject & data,const TLVHead & head)183 template <typename T> bool Reading(T &output, TLVObject &data, const TLVHead &head)
184 {
185     return data.ReadBasic(output, head);
186 }
187 
CountBufferSize(const std::shared_ptr<T> & input,TLVObject & data)188 template <typename T> size_t CountBufferSize(const std::shared_ptr<T> &input, TLVObject &data)
189 {
190     if (input == nullptr) {
191         return data.CountHead();
192     }
193     return CountBufferSize(*input, data);
194 }
195 
Writing(const std::shared_ptr<T> & input,TLVObject & data,TAG tag)196 template <typename T> bool Writing(const std::shared_ptr<T> &input, TLVObject &data, TAG tag)
197 {
198     if (input == nullptr) {
199         return false;
200     }
201     InitWhenFirst(input, data);
202     return Writing(*input, data, tag);
203 }
204 
Reading(std::shared_ptr<T> & output,TLVObject & data,const TLVHead & head)205 template <typename T> bool Reading(std::shared_ptr<T> &output, TLVObject &data, const TLVHead &head)
206 {
207     if (output == nullptr) {
208         output = std::make_shared<T>();
209     }
210     return Reading(*output, data, head);
211 }
212 
CountBufferSize(const std::vector<T> & input,TLVObject & data)213 template <typename T> size_t CountBufferSize(const std::vector<T> &input, TLVObject &data)
214 {
215     auto size = data.CountHead() + data.CountBasic(input.size());
216     for (auto item : input) {
217         size += CountBufferSize(item, data);
218     }
219     return size;
220 }
221 
Writing(const std::vector<T> & input,TLVObject & data,TAG tag)222 template <typename T> bool Writing(const std::vector<T> &input, TLVObject &data, TAG tag)
223 {
224     InitWhenFirst(input, data);
225     auto tagCursor = data.GetCursor();
226     data.OffsetHead();
227     if (!data.WriteBasic(TAG::TAG_VECTOR_SIZE, input.size())) {
228         return false;
229     }
230     if (!input.empty()) {
231         for (auto item : input) {
232             if (!Writing(item, data, TAG::TAG_VECTOR_ITEM)) {
233                 return false;
234             }
235         }
236     }
237     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
238 }
239 
Reading(std::vector<T> & output,TLVObject & data,const TLVHead & head)240 template <typename T> bool Reading(std::vector<T> &output, TLVObject &data, const TLVHead &head)
241 {
242     if (head.len > data.GetTotal() - data.GetCursor()) {
243         return false;
244     }
245     auto endCursor = data.GetCursor() + head.len;
246     while (data.GetCursor() < endCursor) {
247         TLVHead itemHead{};
248         if (!data.ReadHead(itemHead)) {
249             return false;
250         }
251         if (itemHead.tag == static_cast<uint16_t>(TAG::TAG_VECTOR_ITEM)) {
252             T item{};
253             if (!Reading(item, data, itemHead)) {
254                 return false;
255             }
256             output.push_back(std::move(item));
257             continue;
258         }
259         if (!data.Skip(itemHead)) {
260             return false;
261         }
262     }
263     return true;
264 }
265 
CountBufferSize(const std::map<T,R> & input,TLVObject & data)266 template <typename T, typename R> size_t CountBufferSize(const std::map<T, R> &input, TLVObject &data)
267 {
268     auto size = data.CountHead();
269     for (auto item : input) {
270         size += data.CountHead() + CountBufferSize(item.first, data) + CountBufferSize(item.second, data);
271     }
272     return size;
273 }
274 
Writing(const std::map<T,R> & input,TLVObject & data,TAG tag)275 template <typename T, typename R> bool Writing(const std::map<T, R> &input, TLVObject &data, TAG tag)
276 {
277     InitWhenFirst(input, data);
278     auto tagCursor = data.GetCursor();
279     data.OffsetHead();
280     if (!input.empty()) {
281         for (auto item : input) {
282             auto pairCursor = data.GetCursor();
283             data.OffsetHead();
284             if (!TLVUtil::Writing(item.first, data, TAG::TAG_MAP_KEY)) {
285                 return false;
286             }
287             if (!TLVUtil::Writing(item.second, data, TAG::TAG_MAP_VALUE)) {
288                 return false;
289             }
290             if (!data.WriteBackHead(static_cast<uint16_t>(TAG::TAG_MAP_PAIR), pairCursor,
291                 data.GetCursor() - pairCursor - sizeof(TLVHead))) {
292                 return false;
293             }
294         }
295     }
296     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
297 }
298 
Reading(std::map<T,R> & output,TLVObject & data,const TLVHead & head)299 template <typename T, typename R> bool Reading(std::map<T, R> &output, TLVObject &data, const TLVHead &head)
300 {
301     if (head.len > data.GetTotal() - data.GetCursor()) {
302         return false;
303     }
304     auto endCursor = data.GetCursor() + head.len;
305     while (data.GetCursor() < endCursor) {
306         TLVHead headPair{};
307         if (!data.ReadHead(headPair)) {
308             return false;
309         }
310         if (headPair.tag != static_cast<uint16_t>(TAG::TAG_MAP_PAIR)) {
311             return false;
312         }
313         TLVHead headKey{};
314         if (!data.ReadHead(headKey) || headKey.tag != static_cast<uint16_t>(TAG::TAG_MAP_KEY)) {
315             return false;
316         }
317         T itemKey{};
318         if (!Reading(itemKey, data, headKey)) {
319             return false;
320         }
321         TLVHead headValue{};
322         if (!data.ReadHead(headValue) || headValue.tag != static_cast<uint16_t>(TAG::TAG_MAP_VALUE)) {
323             return false;
324         }
325         R itemValue{};
326         if (!Reading(itemValue, data, headValue)) {
327             return false;
328         }
329         output.emplace(std::move(itemKey), std::move(itemValue));
330     }
331     return true;
332 }
333 
CountVariant(TLVObject & data,uint32_t step,const _InTp & input)334 template <typename _InTp> size_t CountVariant(TLVObject &data, uint32_t step, const _InTp &input)
335 {
336     return 0;
337 }
338 
339 template <typename _InTp, typename _First, typename... _Rest>
CountVariant(TLVObject & data,uint32_t step,const _InTp & input)340 size_t CountVariant(TLVObject &data, uint32_t step, const _InTp &input)
341 {
342     if (step == input.index()) {
343         return CountBufferSize(std::get<_First>(input), data);
344     }
345     return CountVariant<_InTp, _Rest...>(data, step + 1, input);
346 }
347 
CountBufferSize(const std::variant<_Types...> & input,TLVObject & data)348 template <typename... _Types> size_t CountBufferSize(const std::variant<_Types...> &input, TLVObject &data)
349 {
350     if (input.index() > size_t(std::numeric_limits<uint32_t>::max())) {
351         return 0;
352     }
353     uint32_t index = static_cast<uint32_t>(input.index());
354     return data.CountHead() + data.CountBasic(index) + CountVariant<decltype(input), _Types...>(data, 0, input);
355 }
356 
WriteVariant(TLVObject & data,uint32_t step,const _InTp & input,TAG tag)357 template <typename _InTp> bool WriteVariant(TLVObject &data, uint32_t step, const _InTp &input, TAG tag)
358 {
359     return true;
360 }
361 
362 template <typename _InTp, typename _First, typename... _Rest>
WriteVariant(TLVObject & data,uint32_t step,const _InTp & input,TAG tag)363 bool WriteVariant(TLVObject &data, uint32_t step, const _InTp &input, TAG tag)
364 {
365     if (step == input.index()) {
366         auto val = std::get<_First>(input);
367         return Writing(val, data, tag);
368     }
369     return WriteVariant<_InTp, _Rest...>(data, step + 1, input, tag);
370 }
371 
Writing(const std::variant<_Types...> & input,TLVObject & data,TAG tag)372 template <typename... _Types> bool Writing(const std::variant<_Types...> &input, TLVObject &data, TAG tag)
373 {
374     InitWhenFirst(input, data);
375     auto tagCursor = data.GetCursor();
376     data.OffsetHead();
377     uint32_t index = input.index();
378     if (!data.WriteBasic(TAG::TAG_VARIANT_INDEX, index)) {
379         return false;
380     }
381     if (!WriteVariant<decltype(input), _Types...>(data, 0, input, TAG::TAG_VARIANT_ITEM)) {
382         return false;
383     }
384     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
385 }
386 
ReadVariant(TLVObject & data,uint32_t step,uint32_t index,_OutTp & value,TLVHead head)387 template <typename _OutTp> bool ReadVariant(TLVObject &data, uint32_t step, uint32_t index, _OutTp &value, TLVHead head)
388 {
389     return true;
390 }
391 
392 template <typename _OutTp, typename _First, typename... _Rest>
ReadVariant(TLVObject & data,uint32_t step,uint32_t index,_OutTp & value,TLVHead head)393 bool ReadVariant(TLVObject &data, uint32_t step, uint32_t index, _OutTp &value, TLVHead head)
394 {
395     if (step == index) {
396         _First output{};
397         auto success = Reading(output, data, head);
398         value = output;
399         return success;
400     }
401     return ReadVariant<_OutTp, _Rest...>(data, step + 1, index, value, head);
402 }
403 
Reading(std::variant<_Types...> & output,TLVObject & data,const TLVHead & head)404 template <typename... _Types> bool Reading(std::variant<_Types...> &output, TLVObject &data, const TLVHead &head)
405 {
406     if (head.len > data.GetTotal() - data.GetCursor()) {
407         return false;
408     }
409     uint32_t index = 0;
410     auto endCursor = data.GetCursor() + head.len;
411     while (data.GetCursor() < endCursor) {
412         TLVHead headItem{};
413         if (!data.ReadHead(headItem)) {
414             return false;
415         }
416         if (headItem.tag == static_cast<uint16_t>(TAG::TAG_VARIANT_INDEX)) {
417             if (!Reading(index, data, headItem)) {
418                 return false;
419             }
420         } else {
421             return ReadVariant<decltype(output), _Types...>(data, 0, index, output, headItem);
422         }
423     }
424     return true;
425 }
426 
CountBufferSize(const std::set<T> & input,TLVObject & data)427 template <typename T> size_t CountBufferSize(const std::set<T> &input, TLVObject &data)
428 {
429     auto size = data.CountHead() + data.CountBasic(input.size());
430     for (const auto &item : input) {
431         size += CountBufferSize(item, data);
432     }
433     return size;
434 }
435 
Writing(const std::set<T> & input,TLVObject & data,TAG tag)436 template <typename T> bool Writing(const std::set<T> &input, TLVObject &data, TAG tag)
437 {
438     InitWhenFirst(input, data);
439     auto tagCursor = data.GetCursor();
440     data.OffsetHead();
441     if (!data.WriteBasic(TAG::TAG_SET_SIZE, input.size())) {
442         return false;
443     }
444     for (const auto &item : input) {
445         if (!Writing(item, data, TAG::TAG_SET_ITEM)) {
446             return false;
447         }
448     }
449     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
450 }
451 
Reading(std::set<T> & output,TLVObject & data,const TLVHead & head)452 template <typename T> bool Reading(std::set<T> &output, TLVObject &data, const TLVHead &head)
453 {
454     if (head.len > data.GetTotal() - data.GetCursor()) {
455         return false;
456     }
457     auto endCursor = data.GetCursor() + head.len;
458     while (data.GetCursor() < endCursor) {
459         TLVHead itemHead{};
460         if (!data.ReadHead(itemHead)) {
461             return false;
462         }
463         if (itemHead.tag == static_cast<uint16_t>(TAG::TAG_SET_ITEM)) {
464             T item{};
465             if (!Reading(item, data, itemHead)) {
466                 return false;
467             }
468             output.insert(std::move(item));
469             continue;
470         }
471         if (!data.Skip(itemHead)) {
472             return false;
473         }
474     }
475     return true;
476 }
477 } // namespace TLVUtil
478 } // namespace OHOS
479 #endif // UDMF_TLV_UTIL_H
480