• 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 std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data);
105 template <> bool API_EXPORT Writing(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data, TAG tag);
106 template <>
107 bool API_EXPORT Reading(std::shared_ptr<OHOS::Media::PixelMap> &output, TLVObject &data, const TLVHead &head);
108 
109 template <> size_t API_EXPORT CountBufferSize(const std::shared_ptr<std::map<std::string, ValueType>> &input,
110     TLVObject &data);
111 template <> bool API_EXPORT Writing(const std::shared_ptr<std::map<std::string, ValueType>> &input,
112     TLVObject &data, TAG tag);
113 template <>
114 bool API_EXPORT Reading(std::shared_ptr<std::map<std::string, ValueType>> &output,
115     TLVObject &data, const TLVHead &head);
116 
117 template <> size_t API_EXPORT CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data);
118 template <> bool API_EXPORT Writing(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data, TAG tag);
119 template <> bool API_EXPORT Reading(std::shared_ptr<OHOS::AAFwk::Want> &output, TLVObject &data, const TLVHead &head);
120 
ReadTlv(T & output,TLVObject & data,TAG tag)121 template <typename T> bool ReadTlv(T &output, TLVObject &data, TAG tag)
122 {
123     while (data.GetCursor() < data.GetTotal()) {
124         TLVHead head{};
125         if (!data.ReadHead(head)) {
126             return false;
127         }
128         if (head.tag != static_cast<uint16_t>(tag)) {
129             data.Skip(head);
130             continue;
131         }
132         if (!Reading(output, data, head)) {
133             return false;
134         }
135     }
136     return true;
137 }
138 
InitWhenFirst(T & input,TLVObject & data)139 template <typename T> void InitWhenFirst(T &input, TLVObject &data)
140 {
141     if (data.GetCursor() == data.GetTotal()) {
142         CountBufferSize(input, data);
143         data.UpdateSize();
144     }
145 }
146 
CountBufferSize(const T & input,TLVObject & data)147 template <typename T> size_t CountBufferSize(const T &input, TLVObject &data)
148 {
149     return data.CountBasic(input);
150 }
151 
Writing(const T & input,TLVObject & data,TAG tag)152 template <typename T> bool Writing(const T &input, TLVObject &data, TAG tag)
153 {
154     InitWhenFirst(input, data);
155     return data.WriteBasic(tag, input);
156 }
157 
Reading(T & output,TLVObject & data,const TLVHead & head)158 template <typename T> bool Reading(T &output, TLVObject &data, const TLVHead &head)
159 {
160     return data.ReadBasic(output, head);
161 }
162 
CountBufferSize(const std::shared_ptr<T> & input,TLVObject & data)163 template <typename T> size_t CountBufferSize(const std::shared_ptr<T> &input, TLVObject &data)
164 {
165     if (input == nullptr) {
166         return data.CountHead();
167     }
168     return CountBufferSize(*input, data);
169 }
170 
Writing(const std::shared_ptr<T> & input,TLVObject & data,TAG tag)171 template <typename T> bool Writing(const std::shared_ptr<T> &input, TLVObject &data, TAG tag)
172 {
173     if (input == nullptr) {
174         return false;
175     }
176     InitWhenFirst(input, data);
177     return Writing(*input, data, tag);
178 }
179 
Reading(std::shared_ptr<T> & output,TLVObject & data,const TLVHead & head)180 template <typename T> bool Reading(std::shared_ptr<T> &output, TLVObject &data, const TLVHead &head)
181 {
182     if (output == nullptr) {
183         output = std::make_shared<T>();
184     }
185     return Reading(*output, data, head);
186 }
187 
CountBufferSize(const std::vector<T> & input,TLVObject & data)188 template <typename T> size_t CountBufferSize(const std::vector<T> &input, TLVObject &data)
189 {
190     auto size = data.CountHead() + data.CountBasic(input.size());
191     for (auto item : input) {
192         size += CountBufferSize(item, data);
193     }
194     return size;
195 }
196 
Writing(const std::vector<T> & input,TLVObject & data,TAG tag)197 template <typename T> bool Writing(const std::vector<T> &input, TLVObject &data, TAG tag)
198 {
199     InitWhenFirst(input, data);
200     auto tagCursor = data.GetCursor();
201     data.OffsetHead();
202     if (!data.WriteBasic(TAG::TAG_VECTOR_SIZE, input.size())) {
203         return false;
204     }
205     if (!input.empty()) {
206         for (auto item : input) {
207             if (!Writing(item, data, TAG::TAG_VECTOR_ITEM)) {
208                 return false;
209             }
210         }
211     }
212     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
213 }
214 
Reading(std::vector<T> & output,TLVObject & data,const TLVHead & head)215 template <typename T> bool Reading(std::vector<T> &output, TLVObject &data, const TLVHead &head)
216 {
217     auto endCursor = data.GetCursor() + head.len;
218     while (data.GetCursor() < endCursor) {
219         TLVHead itemHead{};
220         if (!data.ReadHead(itemHead)) {
221             return false;
222         }
223         if (itemHead.tag == static_cast<uint16_t>(TAG::TAG_VECTOR_ITEM)) {
224             T item{};
225             if (!Reading(item, data, itemHead)) {
226                 return false;
227             }
228             output.push_back(std::move(item));
229             continue;
230         }
231         if (!data.Skip(itemHead)) {
232             return false;
233         }
234     }
235     return true;
236 }
237 
CountBufferSize(const std::map<T,R> & input,TLVObject & data)238 template <typename T, typename R> size_t CountBufferSize(const std::map<T, R> &input, TLVObject &data)
239 {
240     auto size = data.CountHead();
241     for (auto item : input) {
242         size += data.CountHead() + CountBufferSize(item.first, data) + CountBufferSize(item.second, data);
243     }
244     return size;
245 }
246 
Writing(const std::map<T,R> & input,TLVObject & data,TAG tag)247 template <typename T, typename R> bool Writing(const std::map<T, R> &input, TLVObject &data, TAG tag)
248 {
249     InitWhenFirst(input, data);
250     auto tagCursor = data.GetCursor();
251     data.OffsetHead();
252     if (!input.empty()) {
253         for (auto item : input) {
254             auto pairCursor = data.GetCursor();
255             data.OffsetHead();
256             if (!TLVUtil::Writing(item.first, data, TAG::TAG_MAP_KEY)) {
257                 return false;
258             }
259             if (!TLVUtil::Writing(item.second, data, TAG::TAG_MAP_VALUE)) {
260                 return false;
261             }
262             if (!data.WriteBackHead(static_cast<uint16_t>(TAG::TAG_MAP_PAIR), pairCursor,
263                 data.GetCursor() - pairCursor - sizeof(TLVHead))) {
264                 return false;
265             }
266         }
267     }
268     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
269 }
270 
Reading(std::map<T,R> & output,TLVObject & data,const TLVHead & head)271 template <typename T, typename R> bool Reading(std::map<T, R> &output, TLVObject &data, const TLVHead &head)
272 {
273     auto endCursor = data.GetCursor() + head.len;
274     while (data.GetCursor() < endCursor) {
275         TLVHead headPair{};
276         if (!data.ReadHead(headPair)) {
277             return false;
278         }
279         if (headPair.tag != static_cast<uint16_t>(TAG::TAG_MAP_PAIR)) {
280             return false;
281         }
282         TLVHead headKey{};
283         if (!data.ReadHead(headKey) || headKey.tag != static_cast<uint16_t>(TAG::TAG_MAP_KEY)) {
284             return false;
285         }
286         T itemKey{};
287         if (!Reading(itemKey, data, headKey)) {
288             return false;
289         }
290         TLVHead headValue{};
291         if (!data.ReadHead(headValue) || headValue.tag != static_cast<uint16_t>(TAG::TAG_MAP_VALUE)) {
292             return false;
293         }
294         R itemValue{};
295         if (!Reading(itemValue, data, headValue)) {
296             return false;
297         }
298         output.emplace(std::move(itemKey), std::move(itemValue));
299     }
300     return true;
301 }
302 
CountVariant(TLVObject & data,uint32_t step,const _InTp & input)303 template <typename _InTp> size_t CountVariant(TLVObject &data, uint32_t step, const _InTp &input)
304 {
305     return 0;
306 }
307 
308 template <typename _InTp, typename _First, typename... _Rest>
CountVariant(TLVObject & data,uint32_t step,const _InTp & input)309 size_t CountVariant(TLVObject &data, uint32_t step, const _InTp &input)
310 {
311     if (step == input.index()) {
312         return CountBufferSize(std::get<_First>(input), data);
313     }
314     return CountVariant<_InTp, _Rest...>(data, step + 1, input);
315 }
316 
CountBufferSize(const std::variant<_Types...> & input,TLVObject & data)317 template <typename... _Types> size_t CountBufferSize(const std::variant<_Types...> &input, TLVObject &data)
318 {
319     if (input.index() > size_t(std::numeric_limits<uint32_t>::max())) {
320         return 0;
321     }
322     uint32_t index = static_cast<uint32_t>(input.index());
323     return data.CountHead() + data.CountBasic(index) + CountVariant<decltype(input), _Types...>(data, 0, input);
324 }
325 
WriteVariant(TLVObject & data,uint32_t step,const _InTp & input,TAG tag)326 template <typename _InTp> bool WriteVariant(TLVObject &data, uint32_t step, const _InTp &input, TAG tag)
327 {
328     return true;
329 }
330 
331 template <typename _InTp, typename _First, typename... _Rest>
WriteVariant(TLVObject & data,uint32_t step,const _InTp & input,TAG tag)332 bool WriteVariant(TLVObject &data, uint32_t step, const _InTp &input, TAG tag)
333 {
334     if (step == input.index()) {
335         auto val = std::get<_First>(input);
336         return Writing(val, data, tag);
337     }
338     return WriteVariant<_InTp, _Rest...>(data, step + 1, input, tag);
339 }
340 
Writing(const std::variant<_Types...> & input,TLVObject & data,TAG tag)341 template <typename... _Types> bool Writing(const std::variant<_Types...> &input, TLVObject &data, TAG tag)
342 {
343     InitWhenFirst(input, data);
344     auto tagCursor = data.GetCursor();
345     data.OffsetHead();
346     uint32_t index = input.index();
347     if (!data.WriteBasic(TAG::TAG_VARIANT_INDEX, index)) {
348         return false;
349     }
350     if (!WriteVariant<decltype(input), _Types...>(data, 0, input, TAG::TAG_VARIANT_ITEM)) {
351         return false;
352     }
353     return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
354 }
355 
ReadVariant(TLVObject & data,uint32_t step,uint32_t index,_OutTp & value,TLVHead head)356 template <typename _OutTp> bool ReadVariant(TLVObject &data, uint32_t step, uint32_t index, _OutTp &value, TLVHead head)
357 {
358     return true;
359 }
360 
361 template <typename _OutTp, typename _First, typename... _Rest>
ReadVariant(TLVObject & data,uint32_t step,uint32_t index,_OutTp & value,TLVHead head)362 bool ReadVariant(TLVObject &data, uint32_t step, uint32_t index, _OutTp &value, TLVHead head)
363 {
364     if (step == index) {
365         _First output{};
366         auto success = Reading(output, data, head);
367         value = output;
368         return success;
369     }
370     return ReadVariant<_OutTp, _Rest...>(data, step + 1, index, value, head);
371 }
372 
Reading(std::variant<_Types...> & output,TLVObject & data,const TLVHead & head)373 template <typename... _Types> bool Reading(std::variant<_Types...> &output, TLVObject &data, const TLVHead &head)
374 {
375     uint32_t index = 0;
376     auto endCursor = data.GetCursor() + head.len;
377     while (data.GetCursor() < endCursor) {
378         TLVHead headItem{};
379         if (!data.ReadHead(headItem)) {
380             return false;
381         }
382         if (headItem.tag == static_cast<uint16_t>(TAG::TAG_VARIANT_INDEX)) {
383             if (!Reading(index, data, headItem)) {
384                 return false;
385             }
386         } else {
387             return ReadVariant<decltype(output), _Types...>(data, 0, index, output, headItem);
388         }
389     }
390     return true;
391 }
392 } // namespace TLVUtil
393 } // namespace OHOS
394 #endif // UDMF_TLV_UTIL_H
395