• 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 
20 #include <utility>
21 #include <vector>
22 #include "unified_types.h"
23 #include "unified_data.h"
24 #include "unified_key.h"
25 #include "tlv_object.h"
26 #include "unified_record.h"
27 
28 
29 namespace OHOS {
30 namespace TLVUtil {
31 using namespace OHOS::UDMF;
32 
33 template <typename T> bool API_EXPORT ReadTlv(T &output, TLVObject &data, TAG tag);
34 
35 template <typename T> size_t API_EXPORT CountBufferSize(const T &input, TLVObject &data);
36 template <typename T> bool API_EXPORT Writing(const T &input, TLVObject &data, TAG tag);
37 template <typename T> bool API_EXPORT Reading(T &output, TLVObject &data, const TLVHead &head);
38 
39 template <typename... _Types> size_t API_EXPORT CountBufferSize(const std::variant<_Types...> &input, TLVObject &data);
40 template <typename... _Types> bool API_EXPORT Writing(const std::variant<_Types...> &input, TLVObject &data, TAG tag);
41 template <typename... _Types>
42 bool API_EXPORT Reading(std::variant<_Types...> &output, TLVObject &data, const TLVHead &head);
43 
44 template <typename T> size_t API_EXPORT CountBufferSize(const std::shared_ptr<T> &input, TLVObject &data);
45 template <typename T> bool API_EXPORT Writing(const std::shared_ptr<T> &input, TLVObject &data, TAG tag);
46 template <typename T> bool API_EXPORT Reading(std::shared_ptr<T> &output, TLVObject &data, const TLVHead &head);
47 
48 template <typename T> size_t API_EXPORT CountBufferSize(const std::vector<T> &input, TLVObject &data);
49 template <typename T> bool API_EXPORT Writing(const std::vector<T> &input, TLVObject &data, TAG tag);
50 template <typename T> bool API_EXPORT Reading(std::vector<T> &output, TLVObject &data, const TLVHead &head);
51 
52 template <typename T, typename R> size_t API_EXPORT CountBufferSize(const std::map<T, R> &input, TLVObject &data);
53 template <typename T, typename R> bool API_EXPORT Writing(const std::map<T, R> &input, TLVObject &data, TAG tag);
54 template <typename T, typename R> bool API_EXPORT Reading(std::map<T, R> &output, TLVObject &data, const TLVHead &head);
55 
56 template <> size_t API_EXPORT CountBufferSize(const std::nullptr_t &input, TLVObject &data);
57 template <> bool API_EXPORT Writing(const std::nullptr_t &input, TLVObject &data, TAG tag);
58 template <> bool API_EXPORT Reading(std::nullptr_t &output, TLVObject &data, const TLVHead &head);
59 
60 template <> size_t API_EXPORT CountBufferSize(const std::monostate &input, TLVObject &data);
61 template <> bool API_EXPORT Writing(const std::monostate &input, TLVObject &data, TAG tag);
62 template <> bool API_EXPORT Reading(std::monostate &output, TLVObject &data, const TLVHead &head);
63 
64 template <> size_t API_EXPORT CountBufferSize(const std::string &input, TLVObject &data);
65 template <> bool API_EXPORT Writing(const std::string &input, TLVObject &data, TAG tag);
66 template <> bool API_EXPORT Reading(std::string &output, TLVObject &data, const TLVHead &head);
67 
68 template <> size_t API_EXPORT CountBufferSize(const std::vector<uint8_t> &input, TLVObject &data);
69 template <> bool API_EXPORT Writing(const std::vector<uint8_t> &input, TLVObject &data, TAG tag);
70 template <> bool API_EXPORT Reading(std::vector<uint8_t> &output, TLVObject &data, const TLVHead &head);
71 
72 template <> size_t API_EXPORT CountBufferSize(const UDType &input, TLVObject &data);
73 template <> bool API_EXPORT Writing(const UDType &input, TLVObject &data, TAG tag);
74 template <> bool API_EXPORT Reading(UDType &output, TLVObject &data, const TLVHead &head);
75 
76 template <> size_t API_EXPORT CountBufferSize(const DataStatus &input, TLVObject &data);
77 template <> bool API_EXPORT Writing(const DataStatus &input, TLVObject &data, TAG tag);
78 template <> bool API_EXPORT Reading(DataStatus &output, TLVObject &data, const TLVHead &head);
79 
80 template <> size_t API_EXPORT CountBufferSize(const Object &input, TLVObject &data);
81 template <> bool API_EXPORT Writing(const Object &input, TLVObject &data, TAG tag);
82 template <> bool API_EXPORT Reading(Object &output, TLVObject &data, const TLVHead &head);
83 
84 template <> size_t API_EXPORT CountBufferSize(const UnifiedKey &input, TLVObject &data);
85 template <> bool API_EXPORT Writing(const UnifiedKey &input, TLVObject &data, TAG tag);
86 template <> bool API_EXPORT Reading(UnifiedKey &output, TLVObject &data, const TLVHead &head);
87 
88 template <> size_t API_EXPORT CountBufferSize(const UnifiedData &input, TLVObject &data);
89 template <> bool API_EXPORT Writing(const UnifiedData &input, TLVObject &data, TAG tag);
90 template <> bool API_EXPORT Reading(UnifiedData &output, TLVObject &data, const TLVHead &head);
91 
92 template <> size_t API_EXPORT CountBufferSize(const UnifiedRecord &input, TLVObject &data);
93 template <> bool API_EXPORT Writing(const UnifiedRecord &input, TLVObject &data, TAG tag);
94 template <> bool API_EXPORT Reading(UnifiedRecord &output, TLVObject &data, const TLVHead &head);
95 
96 template <> size_t API_EXPORT CountBufferSize(const Runtime &input, TLVObject &data);
97 template <> bool API_EXPORT Writing(const Runtime &input, TLVObject &data, TAG tag);
98 template <> bool API_EXPORT Reading(Runtime &output, TLVObject &data, const TLVHead &head);
99 
100 template <> size_t API_EXPORT CountBufferSize(const Privilege &input, TLVObject &data);
101 template <> bool API_EXPORT Writing(const Privilege &input, TLVObject &data, TAG tag);
102 template <> bool API_EXPORT Reading(Privilege &output, TLVObject &data, const TLVHead &head);
103 
104 template <> size_t API_EXPORT CountBufferSize(const UriInfo &input, TLVObject &data);
105 template <> bool API_EXPORT Writing(const UriInfo &input, TLVObject &data, TAG tag);
106 template <> bool API_EXPORT Reading(UriInfo &output, TLVObject &data, const TLVHead &head);
107 
108 template <> bool API_EXPORT Reading(ShareOptions &output, TLVObject &data, const TLVHead &head);
109 
110 template <> size_t API_EXPORT CountBufferSize(const UnifiedDataProperties &input, TLVObject &data);
111 template <> bool API_EXPORT Writing(const UnifiedDataProperties &input, TLVObject &data, TAG tag);
112 template <> bool API_EXPORT Reading(UnifiedDataProperties &output, TLVObject &data, const TLVHead &head);
113 
114 template <> size_t API_EXPORT CountBufferSize(const OHOS::AAFwk::WantParams &input, TLVObject &data);
115 template <> bool API_EXPORT Writing(const OHOS::AAFwk::WantParams &input, TLVObject &data, TAG tag);
116 template <> bool API_EXPORT Reading(OHOS::AAFwk::WantParams &output, TLVObject &data, const TLVHead &head);
117 
118 template <> size_t API_EXPORT CountBufferSize(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data);
119 template <> bool API_EXPORT Writing(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data, TAG tag);
120 template <>
121 bool API_EXPORT Reading(std::shared_ptr<OHOS::Media::PixelMap> &output, TLVObject &data, const TLVHead &head);
122 
123 template <> size_t API_EXPORT CountBufferSize(const std::shared_ptr<std::map<std::string, ValueType>> &input,
124     TLVObject &data);
125 template <> bool API_EXPORT Writing(const std::shared_ptr<std::map<std::string, ValueType>> &input,
126     TLVObject &data, TAG tag);
127 template <>
128 bool API_EXPORT Reading(std::shared_ptr<std::map<std::string, ValueType>> &output,
129     TLVObject &data, const TLVHead &head);
130 
131 template <> size_t API_EXPORT CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data);
132 template <> bool API_EXPORT Writing(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data, TAG tag);
133 template <> bool API_EXPORT Reading(std::shared_ptr<OHOS::AAFwk::Want> &output, TLVObject &data, const TLVHead &head);
134 
135 template <> size_t API_EXPORT CountBufferSize(const Summary &input, TLVObject &data);
136 template <> bool API_EXPORT Writing(const Summary &input, TLVObject &data, TAG tag);
137 template <> bool API_EXPORT Reading(Summary &output, TLVObject &data, const TLVHead &head);
138 
ReadTlv(T & output,TLVObject & data,TAG tag)139 template <typename T> bool ReadTlv(T &output, TLVObject &data, TAG tag)
140 {
141     while (data.GetCursor() < data.GetTotal()) {
142         TLVHead head{};
143         if (!data.ReadHead(head)) {
144             return false;
145         }
146         if (head.tag != static_cast<uint16_t>(tag)) {
147             data.Skip(head);
148             continue;
149         }
150         if (!Reading(output, data, head)) {
151             return false;
152         }
153     }
154     return true;
155 }
156 
InitWhenFirst(T & input,TLVObject & data)157 template <typename T> void InitWhenFirst(T &input, TLVObject &data)
158 {
159     if (data.GetCursor() == data.GetTotal()) {
160         CountBufferSize(input, data);
161         data.UpdateSize();
162     }
163 }
164 
CountBufferSize(const T & input,TLVObject & data)165 template <typename T> size_t CountBufferSize(const T &input, TLVObject &data)
166 {
167     return data.CountBasic(input);
168 }
169 
Writing(const T & input,TLVObject & data,TAG tag)170 template <typename T> bool Writing(const T &input, TLVObject &data, TAG tag)
171 {
172     InitWhenFirst(input, data);
173     return data.WriteBasic(tag, input);
174 }
175 
Reading(T & output,TLVObject & data,const TLVHead & head)176 template <typename T> bool Reading(T &output, TLVObject &data, const TLVHead &head)
177 {
178     return data.ReadBasic(output, head);
179 }
180 
CountBufferSize(const std::shared_ptr<T> & input,TLVObject & data)181 template <typename T> size_t CountBufferSize(const std::shared_ptr<T> &input, TLVObject &data)
182 {
183     if (input == nullptr) {
184         return data.CountHead();
185     }
186     return CountBufferSize(*input, data);
187 }
188 
Writing(const std::shared_ptr<T> & input,TLVObject & data,TAG tag)189 template <typename T> bool Writing(const std::shared_ptr<T> &input, TLVObject &data, TAG tag)
190 {
191     if (input == nullptr) {
192         return false;
193     }
194     InitWhenFirst(input, data);
195     return Writing(*input, data, tag);
196 }
197 
Reading(std::shared_ptr<T> & output,TLVObject & data,const TLVHead & head)198 template <typename T> bool Reading(std::shared_ptr<T> &output, TLVObject &data, const TLVHead &head)
199 {
200     if (output == nullptr) {
201         output = std::make_shared<T>();
202     }
203     return Reading(*output, data, head);
204 }
205 
CountBufferSize(const std::vector<T> & input,TLVObject & data)206 template <typename T> size_t CountBufferSize(const std::vector<T> &input, TLVObject &data)
207 {
208     auto size = data.CountHead() + data.CountBasic(input.size());
209     for (auto item : input) {
210         size += CountBufferSize(item, data);
211     }
212     return size;
213 }
214 
Writing(const std::vector<T> & input,TLVObject & data,TAG tag)215 template <typename T> bool Writing(const std::vector<T> &input, TLVObject &data, TAG tag)
216 {
217     InitWhenFirst(input, data);
218     auto tagCursor = data.GetCursor();
219     data.OffsetHead();
220     if (!data.WriteBasic(TAG::TAG_VECTOR_SIZE, input.size())) {
221         return false;
222     }
223     if (!input.empty()) {
224         for (auto item : input) {
225             if (!Writing(item, data, TAG::TAG_VECTOR_ITEM)) {
226                 return false;
227             }
228         }
229     }
230     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
231 }
232 
Reading(std::vector<T> & output,TLVObject & data,const TLVHead & head)233 template <typename T> bool Reading(std::vector<T> &output, TLVObject &data, const TLVHead &head)
234 {
235     auto endCursor = data.GetCursor() + head.len;
236     while (data.GetCursor() < endCursor) {
237         TLVHead itemHead{};
238         if (!data.ReadHead(itemHead)) {
239             return false;
240         }
241         if (itemHead.tag == static_cast<uint16_t>(TAG::TAG_VECTOR_ITEM)) {
242             T item{};
243             if (!Reading(item, data, itemHead)) {
244                 return false;
245             }
246             output.push_back(std::move(item));
247             continue;
248         }
249         if (!data.Skip(itemHead)) {
250             return false;
251         }
252     }
253     return true;
254 }
255 
CountBufferSize(const std::map<T,R> & input,TLVObject & data)256 template <typename T, typename R> size_t CountBufferSize(const std::map<T, R> &input, TLVObject &data)
257 {
258     auto size = data.CountHead();
259     for (auto item : input) {
260         size += data.CountHead() + CountBufferSize(item.first, data) + CountBufferSize(item.second, data);
261     }
262     return size;
263 }
264 
Writing(const std::map<T,R> & input,TLVObject & data,TAG tag)265 template <typename T, typename R> bool Writing(const std::map<T, R> &input, TLVObject &data, TAG tag)
266 {
267     InitWhenFirst(input, data);
268     auto tagCursor = data.GetCursor();
269     data.OffsetHead();
270     if (!input.empty()) {
271         for (auto item : input) {
272             auto pairCursor = data.GetCursor();
273             data.OffsetHead();
274             if (!TLVUtil::Writing(item.first, data, TAG::TAG_MAP_KEY)) {
275                 return false;
276             }
277             if (!TLVUtil::Writing(item.second, data, TAG::TAG_MAP_VALUE)) {
278                 return false;
279             }
280             if (!data.WriteBackHead(static_cast<uint16_t>(TAG::TAG_MAP_PAIR), pairCursor,
281                 data.GetCursor() - pairCursor - sizeof(TLVHead))) {
282                 return false;
283             }
284         }
285     }
286     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
287 }
288 
Reading(std::map<T,R> & output,TLVObject & data,const TLVHead & head)289 template <typename T, typename R> bool Reading(std::map<T, R> &output, TLVObject &data, const TLVHead &head)
290 {
291     auto endCursor = data.GetCursor() + head.len;
292     while (data.GetCursor() < endCursor) {
293         TLVHead headPair{};
294         if (!data.ReadHead(headPair)) {
295             return false;
296         }
297         if (headPair.tag != static_cast<uint16_t>(TAG::TAG_MAP_PAIR)) {
298             return false;
299         }
300         TLVHead headKey{};
301         if (!data.ReadHead(headKey) || headKey.tag != static_cast<uint16_t>(TAG::TAG_MAP_KEY)) {
302             return false;
303         }
304         T itemKey{};
305         if (!Reading(itemKey, data, headKey)) {
306             return false;
307         }
308         TLVHead headValue{};
309         if (!data.ReadHead(headValue) || headValue.tag != static_cast<uint16_t>(TAG::TAG_MAP_VALUE)) {
310             return false;
311         }
312         R itemValue{};
313         if (!Reading(itemValue, data, headValue)) {
314             return false;
315         }
316         output.emplace(std::move(itemKey), std::move(itemValue));
317     }
318     return true;
319 }
320 
CountVariant(TLVObject & data,uint32_t step,const _InTp & input)321 template <typename _InTp> size_t CountVariant(TLVObject &data, uint32_t step, const _InTp &input)
322 {
323     return 0;
324 }
325 
326 template <typename _InTp, typename _First, typename... _Rest>
CountVariant(TLVObject & data,uint32_t step,const _InTp & input)327 size_t CountVariant(TLVObject &data, uint32_t step, const _InTp &input)
328 {
329     if (step == input.index()) {
330         return CountBufferSize(std::get<_First>(input), data);
331     }
332     return CountVariant<_InTp, _Rest...>(data, step + 1, input);
333 }
334 
CountBufferSize(const std::variant<_Types...> & input,TLVObject & data)335 template <typename... _Types> size_t CountBufferSize(const std::variant<_Types...> &input, TLVObject &data)
336 {
337     if (input.index() > size_t(std::numeric_limits<uint32_t>::max())) {
338         return 0;
339     }
340     uint32_t index = static_cast<uint32_t>(input.index());
341     return data.CountHead() + data.CountBasic(index) + CountVariant<decltype(input), _Types...>(data, 0, input);
342 }
343 
WriteVariant(TLVObject & data,uint32_t step,const _InTp & input,TAG tag)344 template <typename _InTp> bool WriteVariant(TLVObject &data, uint32_t step, const _InTp &input, TAG tag)
345 {
346     return true;
347 }
348 
349 template <typename _InTp, typename _First, typename... _Rest>
WriteVariant(TLVObject & data,uint32_t step,const _InTp & input,TAG tag)350 bool WriteVariant(TLVObject &data, uint32_t step, const _InTp &input, TAG tag)
351 {
352     if (step == input.index()) {
353         auto val = std::get<_First>(input);
354         return Writing(val, data, tag);
355     }
356     return WriteVariant<_InTp, _Rest...>(data, step + 1, input, tag);
357 }
358 
Writing(const std::variant<_Types...> & input,TLVObject & data,TAG tag)359 template <typename... _Types> bool Writing(const std::variant<_Types...> &input, TLVObject &data, TAG tag)
360 {
361     InitWhenFirst(input, data);
362     auto tagCursor = data.GetCursor();
363     data.OffsetHead();
364     uint32_t index = input.index();
365     if (!data.WriteBasic(TAG::TAG_VARIANT_INDEX, index)) {
366         return false;
367     }
368     if (!WriteVariant<decltype(input), _Types...>(data, 0, input, TAG::TAG_VARIANT_ITEM)) {
369         return false;
370     }
371     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
372 }
373 
ReadVariant(TLVObject & data,uint32_t step,uint32_t index,_OutTp & value,TLVHead head)374 template <typename _OutTp> bool ReadVariant(TLVObject &data, uint32_t step, uint32_t index, _OutTp &value, TLVHead head)
375 {
376     return true;
377 }
378 
379 template <typename _OutTp, typename _First, typename... _Rest>
ReadVariant(TLVObject & data,uint32_t step,uint32_t index,_OutTp & value,TLVHead head)380 bool ReadVariant(TLVObject &data, uint32_t step, uint32_t index, _OutTp &value, TLVHead head)
381 {
382     if (step == index) {
383         _First output{};
384         auto success = Reading(output, data, head);
385         value = output;
386         return success;
387     }
388     return ReadVariant<_OutTp, _Rest...>(data, step + 1, index, value, head);
389 }
390 
Reading(std::variant<_Types...> & output,TLVObject & data,const TLVHead & head)391 template <typename... _Types> bool Reading(std::variant<_Types...> &output, TLVObject &data, const TLVHead &head)
392 {
393     uint32_t index = 0;
394     auto endCursor = data.GetCursor() + head.len;
395     while (data.GetCursor() < endCursor) {
396         TLVHead headItem{};
397         if (!data.ReadHead(headItem)) {
398             return false;
399         }
400         if (headItem.tag == static_cast<uint16_t>(TAG::TAG_VARIANT_INDEX)) {
401             if (!Reading(index, data, headItem)) {
402                 return false;
403             }
404         } else {
405             return ReadVariant<decltype(output), _Types...>(data, 0, index, output, headItem);
406         }
407     }
408     return true;
409 }
410 } // namespace TLVUtil
411 } // namespace OHOS
412 #endif // UDMF_TLV_UTIL_H
413