• 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_OBJECT_H
17 #define UDMF_TLV_OBJECT_H
18 
19 #include "securec.h"
20 #include "error_code.h"
21 #include "unified_meta.h"
22 #include "unified_types.h"
23 #include "endian_converter.h"
24 
25 namespace OHOS {
26 namespace UDMF {
27 enum TAG : uint16_t {
28     TAG_INT32 = 0x0000,
29     TAG_INT64,
30     TAG_UINT32,
31     TAG_UINT64,
32     TAG_BOOL,
33     TAG_DOUBLE,
34     TAG_STRING,
35     TAG_VECTOR,
36     TAG_MAP,
37     TAG_BUTT,
38 };
39 
40 #pragma pack(1)
41 struct TLVHead {
42     uint16_t tag;
43     uint32_t len;
44     std::uint8_t value[0];
45 };
46 #pragma pack()
47 
48 class TLVObject {
49 public:
50     TLVObject() = default;
51     ~TLVObject() = default;
TLVObject(std::vector<std::uint8_t> & buffer)52     explicit TLVObject(std::vector<std::uint8_t> &buffer)
53     {
54         total_ += buffer.size();
55         buffer_ = &buffer;
56         cursor_ = 0;
57     }
58 
UpdateSize()59     void UpdateSize()
60     {
61         buffer_->resize(total_);
62     }
63 
GetBuffer()64     std::vector<std::uint8_t> GetBuffer()
65     {
66         return *buffer_;
67     }
68 
Count(const uint32_t value)69     void Count(const uint32_t value)
70     {
71         total_ += sizeof(value) + sizeof(TLVHead);
72     }
73 
Count(const uint64_t value)74     void Count(const uint64_t value)
75     {
76         total_ += sizeof(value) + sizeof(TLVHead);
77     }
78 
Count(const int32_t value)79     void Count(const int32_t value)
80     {
81         total_ += sizeof(value) + sizeof(TLVHead);
82     }
83 
Count(const int64_t value)84     void Count(const int64_t value)
85     {
86         total_ += sizeof(value) + sizeof(TLVHead);
87     }
88 
Count(const float value)89     void Count(const float value)
90     {
91         total_ += sizeof(value) + sizeof(TLVHead);
92     }
93 
Count(const double value)94     void Count(const double value)
95     {
96         total_ += sizeof(value) + sizeof(TLVHead);
97     }
98 
Count(const std::string & value)99     void Count(const std::string &value)
100     {
101         total_ += value.size() + sizeof(TLVHead);
102     }
103 
Count(const std::vector<uint8_t> & value)104     void Count(const std::vector<uint8_t> &value)
105     {
106         std::size_t expectSize = sizeof(TLVHead);
107         expectSize += value.size();
108         total_ += expectSize;
109     }
110 
Count(const UDVariant & value)111     void Count(const UDVariant &value)
112     {
113         total_ += sizeof(TLVHead);
114         auto int32Value = std::get_if<int32_t>(&value);
115         if (int32Value != nullptr) {
116             Count(std::get<int32_t>(value));
117             return;
118         }
119         auto int64Value = std::get_if<int64_t>(&value);
120         if (int64Value != nullptr) {
121             Count(std::get<int64_t>(value));
122             return;
123         }
124         auto boolValue = std::get_if<bool>(&value);
125         if (boolValue != nullptr) {
126             Count(std::get<bool>(value));
127             return;
128         }
129         auto doubleValue = std::get_if<double>(&value);
130         if (doubleValue != nullptr) {
131             Count(std::get<double>(value));
132             return;
133         }
134         auto strValue = std::get_if<std::string>(&value);
135         if (strValue != nullptr) {
136             Count(std::get<std::string>(value));
137             return;
138         }
139         auto vecValue = std::get_if<std::vector<uint8_t>>(&value);
140         if (vecValue != nullptr) {
141             Count(std::get<std::vector<uint8_t>>(value));
142             return;
143         }
144         total_ += sizeof(TLVHead);
145     }
146 
Count(const UDDetails & value)147     void Count(const UDDetails &value)
148     {
149         for (auto &item : value) {
150             Count(item.first);
151             Count(item.second);
152         }
153         total_ += sizeof(TLVHead);
154     }
155 
Count(const UnifiedKey & value)156     void Count(const UnifiedKey &value)
157     {
158         Count(value.key);
159         Count(value.intention);
160         Count(value.bundleName);
161         Count(value.groupId);
162     }
163 
Count(const Privilege & value)164     void Count(const Privilege &value)
165     {
166         Count(value.tokenId);
167         Count(value.readPermission);
168         Count(value.writePermission);
169     }
170 
171     template<typename T>
WriteBasic(uint16_t type,const T & value)172     bool WriteBasic(uint16_t type, const T &value)
173     {
174         if (!HasExpectBuffer(sizeof(TLVHead) + sizeof(value))) {
175             return false;
176         }
177         auto *tlvHead = reinterpret_cast<TLVHead*>(buffer_->data() + cursor_);
178         tlvHead->tag = HostToNet(type);
179         tlvHead->len = HostToNet((uint32_t)sizeof(value));
180         auto valueBuff = HostToNet(value);
181         auto ret = memcpy_s(tlvHead->value, sizeof(value), &valueBuff, sizeof(value));
182         if (ret != EOK) {
183             return false;
184         }
185         cursor_ += sizeof(TLVHead) + sizeof(value);
186         return true;
187     }
188 
189     template<typename T>
ReadBasic(T & value)190     bool ReadBasic(T &value)
191     {
192         TLVHead head {};
193         if (!ReadHead(head)) {
194             return false;
195         }
196         if (head.len == 0 || head.len != sizeof(T)) {
197             return false;
198         }
199         if (!HasExpectBuffer(head.len)) {
200             return false;
201         }
202         auto ret = memcpy_s(&value, sizeof(T), buffer_->data() + cursor_, sizeof(T));
203         if (ret != EOK) {
204             return false;
205         }
206         value = NetToHost(value);
207         cursor_ += sizeof(T);
208         return true;
209     }
210 
WriteString(const std::string & value)211     bool WriteString(const std::string &value)
212     {
213         if (!HasExpectBuffer(sizeof(TLVHead) + value.size())) {
214             return false;
215         }
216         auto *tlvHead = reinterpret_cast<TLVHead *>(buffer_->data() + cursor_);
217         tlvHead->tag = HostToNet(TAG_STRING);
218         tlvHead->len = HostToNet((uint32_t)value.size());
219         if (!value.empty()) {
220             auto err = memcpy_s(tlvHead->value, value.size(), value.c_str(), value.size());
221             if (err != EOK) {
222                 return false;
223             }
224         }
225         cursor_ += sizeof(TLVHead) + value.size();
226         return true;
227     }
228 
ReadString(std::string & value)229     bool ReadString(std::string &value)
230     {
231         TLVHead head {};
232         if (!ReadHead(head)) {
233             return false;
234         }
235         if (!HasExpectBuffer(head.len)) {
236             return false;
237         }
238         value.append(reinterpret_cast<const char *>(buffer_->data() + cursor_), head.len);
239         cursor_ += head.len;
240         return true;
241     }
242 
WriteVector(const std::vector<uint8_t> & value)243     bool WriteVector(const std::vector<uint8_t> &value)
244     {
245         if (!HasExpectBuffer(sizeof(TLVHead) + value.size())) {
246             return false;
247         }
248         WriteHead(TAG_VECTOR, cursor_, value.size());
249         cursor_ += sizeof(TLVHead);
250 
251         if (!value.empty()) {
252             auto err = memcpy_s(buffer_->data() + cursor_, buffer_->size() - cursor_, value.data(), value.size());
253             if (err != EOK) {
254                 return false;
255             }
256         }
257         cursor_ += value.size();
258         return true;
259     }
260 
ReadVector(std::vector<uint8_t> & value)261     bool ReadVector(std::vector<uint8_t> &value)
262     {
263         TLVHead head {};
264         if (!ReadHead(head)) {
265             return false;
266         }
267         if (!HasExpectBuffer(head.len)) {
268             return false;
269         }
270         std::vector<uint8_t> buff(buffer_->data() + cursor_, buffer_->data() + cursor_ + head.len);
271         value = std::move(buff);
272         cursor_ += head.len;
273         return true;
274     }
275 
WriteVariant(const UDVariant & value)276     bool WriteVariant(const UDVariant &value)
277     {
278         if (!HasExpectBuffer(sizeof(TLVHead))) {
279             return false;
280         }
281         auto tagCursor = cursor_;
282         cursor_ += sizeof(TLVHead);
283         auto valueCursor = cursor_;
284         TAG tag = TAG::TAG_BUTT;
285         auto int32Value = std::get_if<int32_t>(&value);
286         if (int32Value != nullptr) {
287             if (!WriteBasic(TAG_INT32, std::get<int32_t>(value))) {
288                 return false;
289             }
290             tag = TAG::TAG_INT32;
291         }
292         auto int64Value = std::get_if<int64_t>(&value);
293         if (int64Value != nullptr) {
294             if (!WriteBasic(TAG_INT64, std::get<int64_t>(value))) {
295                 return false;
296             }
297             tag = TAG::TAG_INT64;
298         }
299         auto boolValue = std::get_if<bool>(&value);
300         if (boolValue != nullptr) {
301             if (!WriteBasic(TAG_BOOL, std::get<bool>(value))) {
302                 return false;
303             }
304             tag = TAG::TAG_BOOL;
305         }
306         auto doubleValue = std::get_if<double>(&value);
307         if (doubleValue != nullptr) {
308             if (!WriteBasic(TAG_DOUBLE, std::get<double>(value))) {
309                 return false;
310             }
311             tag = TAG::TAG_DOUBLE;
312         }
313         auto stringValue = std::get_if<std::string>(&value);
314         if (stringValue != nullptr) {
315             if (!WriteString(std::get<std::string>(value))) {
316                 return false;
317             }
318             tag = TAG::TAG_STRING;
319         }
320         auto vectorValue = std::get_if<std::vector<uint8_t>>(&value);
321         if (vectorValue != nullptr) {
322             if (!WriteVector(std::get<std::vector<uint8_t>>(value))) {
323                 return false;
324             }
325             tag = TAG::TAG_VECTOR;
326         }
327         WriteHead(tag, tagCursor, cursor_ - valueCursor);
328         return true;
329     }
330 
ReadVariant(UDVariant & value)331     bool ReadVariant(UDVariant &value)
332     {
333         TLVHead head {};
334         if (!ReadHead(head)) {
335             return false;
336         }
337         if (!HasExpectBuffer(head.len)) {
338             return false;
339         }
340         switch (head.tag) {
341             case static_cast<uint16_t>(TAG::TAG_INT32): {
342                 int32_t int32Value;
343                 if (!ReadBasic(int32Value)) {
344                     return false;
345                 }
346                 value.emplace<int32_t>(int32Value);
347                 break;
348             }
349             case static_cast<uint16_t>(TAG::TAG_INT64): {
350                 int64_t int64Value;
351                 if (!ReadBasic(int64Value)) {
352                     return false;
353                 }
354                 value.emplace<int64_t>(int64Value);
355                 break;
356             }
357             case static_cast<uint16_t>(TAG::TAG_BOOL): {
358                 bool boolValue;
359                 if (!ReadBasic(boolValue)) {
360                     return false;
361                 }
362                 value.emplace<bool>(boolValue);
363                 break;
364             }
365             case static_cast<uint16_t>(TAG::TAG_DOUBLE): {
366                 double doubleValue;
367                 if (!ReadBasic(doubleValue)) {
368                     return false;
369                 }
370                 value.emplace<double>(doubleValue);
371                 break;
372             }
373             case static_cast<uint16_t>(TAG::TAG_STRING): {
374                 std::string stringValue;
375                 if (!ReadString(stringValue)) {
376                     return false;
377                 }
378                 value.emplace<std::string>(stringValue);
379                 break;
380             }
381             case static_cast<uint16_t>(TAG::TAG_VECTOR): {
382                 std::vector<uint8_t> vectorValue;
383                 if (!ReadVector(vectorValue)) {
384                     return false;
385                 }
386                 value.emplace<std::vector<uint8_t>>(vectorValue);
387                 break;
388             }
389             default: {
390                 return false;
391             }
392         }
393         return true;
394     }
395 
WriteMap(const UDDetails & value)396     bool WriteMap(const UDDetails &value)
397     {
398         if (!HasExpectBuffer(sizeof(TLVHead))) {
399             return false;
400         }
401 
402         auto tagCursor = cursor_;
403         cursor_ += sizeof(TLVHead);
404         auto valueCursor = cursor_;
405 
406         for (const auto &item : value) {
407             if (!WriteString(item.first)) {
408                 return false;
409             }
410             if (!WriteVariant(item.second)) {
411                 return false;
412             }
413         }
414 
415         WriteHead(TAG_MAP, tagCursor, cursor_ - valueCursor);
416         return true;
417     }
418 
ReadMap(UDDetails & value)419     bool ReadMap(UDDetails &value)
420     {
421         TLVHead head {};
422         if (!ReadHead(head)) {
423             return false;
424         }
425         if (!HasExpectBuffer(head.len)) {
426             return false;
427         }
428         auto mapEnd = cursor_ + head.len;
429         while (cursor_ < mapEnd) {
430             std::string itemKey;
431             if (!ReadString(itemKey)) {
432                 return false;
433             }
434             UDVariant itemValue;
435             if (!ReadVariant(itemValue)) {
436                 return false;
437             }
438             value.emplace(itemKey, itemValue);
439         }
440         return true;
441     }
442 
443 private:
ReadHead(TLVHead & head)444     inline bool ReadHead(TLVHead &head)
445     {
446         if (!HasExpectBuffer(sizeof(TLVHead))) {
447             return false;
448         }
449         const auto *pHead = reinterpret_cast<const TLVHead *>(buffer_->data() + cursor_);
450         if (!HasExpectBuffer(NetToHost(pHead->len)) &&
451             !HasExpectBuffer(NetToHost(pHead->len) + sizeof(TLVHead))) {
452             return false;
453         }
454         head.tag = NetToHost(pHead->tag);
455         head.len = NetToHost(pHead->len);
456         cursor_ += sizeof(TLVHead);
457         return true;
458     }
459 
WriteHead(uint16_t type,size_t tagCursor,uint32_t len)460     inline void WriteHead(uint16_t type, size_t tagCursor, uint32_t len)
461     {
462         auto *tlvHead = reinterpret_cast<TLVHead *>(buffer_->data() + tagCursor);
463         tlvHead->tag = HostToNet(type);
464         tlvHead->len = HostToNet(len);
465     }
466 
HasExpectBuffer(const uint32_t expectLen)467     inline bool HasExpectBuffer(const uint32_t expectLen) const
468     {
469         if (buffer_== nullptr) {
470             return false;
471         }
472         return buffer_->size() >= cursor_ && buffer_->size() - cursor_ >= expectLen;
473     }
474 
475     std::size_t total_ = 0;
476     std::size_t cursor_ = 0;
477     std::vector<std::uint8_t> *buffer_;
478 };
479 } // namespace UDMF
480 } // namespace OHOS
481 #endif // UDMF_TLV_OBJECT_H