• 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 <cstdio>
20 #include "securec.h"
21 #include "error_code.h"
22 #include "unified_meta.h"
23 #include "unified_types.h"
24 #include "endian_converter.h"
25 
26 namespace OHOS {
27 namespace UDMF {
28 enum class TAG {
29     TAG_INT32 = 0x0000,
30     TAG_INT64,
31     TAG_UINT32,
32     TAG_UINT64,
33     TAG_BOOL,
34     TAG_DOUBLE,
35     TAG_STRING,
36     TAG_VECTOR,
37     TAG_MAP,
38     TAG_BUTT,
39 };
40 
41 #pragma pack(1)
42 struct TLVHead {
43     uint16_t tag;
44     uint32_t len;
45     std::uint8_t value[0];
46 };
47 #pragma pack()
48 
49 class TLVObject {
50 public:
51     TLVObject() = default;
52     ~TLVObject() = default;
53     explicit TLVObject(std::vector<std::uint8_t> &buffer);
54     void SetFile(std::FILE *file);
55     void UpdateSize();
56     std::vector<std::uint8_t> GetBuffer();
57     void Count(const uint32_t value);
58     void Count(const uint64_t value);
59     void Count(const int32_t value);
60     void Count(const int64_t value);
61     void Count(const float value);
62     void Count(const double value);
63     void Count(const std::string &value);
64     void Count(const std::vector<uint8_t> &value);
65     void Count(const UDVariant &value);
66     void Count(const UDDetails &value);
67     void Count(const UnifiedKey &value);
68     void Count(const Privilege &value);
69     template<typename T> bool WriteBasic(TAG type, const T &value);
70     template<typename T> bool ReadBasic(T &value);
71     bool WriteString(const std::string &value);
72     bool ReadString(std::string &value);
73     bool WriteVector(const std::vector<uint8_t> &value);
74     bool ReadVector(std::vector<uint8_t> &value);
75     bool WriteVariant(const UDVariant &value);
76     bool ReadVariant(UDVariant &value);
77     bool WriteMap(const UDDetails &value);
78     bool ReadMap(UDDetails &value);
79 
80 private:
81     bool WriteVariantInner(TAG &tag, const UDVariant &value);
82     bool ReadVariantInner(uint16_t tag, UDVariant &value);
83     bool ReadHead(TLVHead &head);
84     void WriteHead(uint16_t type, size_t tagCursor, uint32_t len);
85     bool HasExpectBuffer(const uint32_t expectLen) const;
86     void PrepareHeader(size_t size, size_t &tagCursor, size_t &valueCursor);
87     void PrepareBuffer(size_t size);
88     bool SaveBufferToFile();
89     bool LoadBufferFormFile(size_t size);
90 
91 private:
92     std::size_t total_ = 0;
93     std::size_t cursor_ = 0;
94     std::vector<std::uint8_t> *buffer_;
95     std::FILE *file_ = nullptr;
96 };
97 
98 template<typename T>
WriteBasic(TAG type,const T & value)99 bool TLVObject::WriteBasic(TAG type, const T &value)
100 {
101     PrepareBuffer(sizeof(TLVHead) + sizeof(value));
102     if (!HasExpectBuffer(sizeof(TLVHead) + sizeof(value))) {
103         return false;
104     }
105     auto *tlvHead = reinterpret_cast<TLVHead*>(buffer_->data() + cursor_);
106     tlvHead->tag = HostToNet(static_cast<uint16_t>(type));
107     tlvHead->len = HostToNet((uint32_t)sizeof(value));
108     auto valueBuff = HostToNet(value);
109     size_t maxSize = sizeof(value) + 1;
110     auto ret = memcpy_s(tlvHead->value, maxSize, &valueBuff, sizeof(value));
111     if (ret != EOK) {
112         return false;
113     }
114     if (!SaveBufferToFile()) {
115         return false;
116     }
117     cursor_ += sizeof(TLVHead) + sizeof(value);
118     return true;
119 }
120 
121 template<typename T>
ReadBasic(T & value)122 bool TLVObject::ReadBasic(T &value)
123 {
124     TLVHead head {};
125     if (!ReadHead(head)) {
126         return false;
127     }
128     if (head.len == 0 || head.len != sizeof(T)) {
129         return false;
130     }
131     if (!HasExpectBuffer(head.len)) {
132         return false;
133     }
134     if (!LoadBufferFormFile(head.len)) {
135         return false;
136     }
137     auto ret = memcpy_s(&value, sizeof(T), buffer_->data() + cursor_, sizeof(T));
138     if (ret != EOK) {
139         return false;
140     }
141     value = NetToHost(value);
142     cursor_ += sizeof(T);
143     if (file_ != nullptr) {
144         cursor_ += sizeof(TLVHead);
145     }
146     return true;
147 }
148 
149 } // namespace UDMF
150 } // namespace OHOS
151 #endif // UDMF_TLV_OBJECT_H