• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 DISTRIBUTEDDATAMGR_PASTEBOARD_TLV_OBJECT_H
17 #define DISTRIBUTEDDATAMGR_PASTEBOARD_TLV_OBJECT_H
18 #include <cstdint>
19 #include <map>
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 #include "api/visibility.h"
25 #include "endian_converter.h"
26 #include "parcel.h"
27 #include "securec.h"
28 
29 namespace OHOS::MiscServices {
30 #pragma pack(1)
31 struct TLVHead {
32     uint16_t tag;
33     uint32_t len;
34     std::uint8_t value[0];
35 };
36 #pragma pack()
37 struct RawMem {
38     uintptr_t buffer;
39     size_t bufferLen;
40     // notice:Keep the parcel reference to prevent the memory in the parcel from being destructed
41     std::shared_ptr<OHOS::Parcel> parcel;
42 };
43 
44 /*
45  * Common tag definitions.
46  * Product should use after TAG_BUFF
47  **/
48 enum COMMON_TAG : uint16_t {
49     TAG_VECTOR_ITEM = 0x0000,
50     TAG_MAP_KEY,
51     TAG_MAP_VALUE,
52 
53     TAG_BUFF = 0x0100,
54 };
55 struct API_EXPORT TLVObject {
56 public:
TLVObjectTLVObject57     TLVObject() : total_(0), cursor_(0)
58     {
59     }
60     virtual bool Encode(std::vector<std::uint8_t> &buffer) = 0;
61     virtual bool Decode(const std::vector<std::uint8_t> &buffer) = 0;
62     virtual size_t Count() = 0;
63 
InitTLVObject64     inline void Init(std::vector<std::uint8_t> &buffer)
65     {
66         buffer.resize(Count());
67         total_ = buffer.size();
68         cursor_ = 0;
69     }
70 
CountTLVObject71     static inline size_t Count(bool value)
72     {
73         return sizeof(value) + sizeof(TLVHead);
74     }
CountTLVObject75     static inline size_t Count(int8_t value)
76     {
77         return sizeof(value) + sizeof(TLVHead);
78     }
CountTLVObject79     static inline size_t Count(int16_t value)
80     {
81         return sizeof(value) + sizeof(TLVHead);
82     }
CountTLVObject83     static inline size_t Count(int32_t value)
84     {
85         return sizeof(value) + sizeof(TLVHead);
86     }
CountTLVObject87     static inline size_t Count(int64_t value)
88     {
89         return sizeof(value) + sizeof(TLVHead);
90     }
CountTLVObject91     static inline size_t Count(uint32_t value)
92     {
93         return sizeof(value) + sizeof(TLVHead);
94     }
CountTLVObject95     static inline size_t Count(const std::string &value)
96     {
97         return value.size() + sizeof(TLVHead);
98     }
CountTLVObject99     static inline size_t Count(const RawMem &value)
100     {
101         return value.bufferLen + sizeof(TLVHead);
102     }
CountTLVObject103     static inline size_t Count(TLVObject &value)
104     {
105         return value.Count() + sizeof(TLVHead);
106     }
CountTLVObject107     template<typename T> inline size_t Count(std::shared_ptr<T> &value)
108     {
109         if (value == nullptr) {
110             return 0;
111         }
112         return Count(*value);
113     }
CountTLVObject114     template<typename T> inline size_t Count(std::vector<T> &value)
115     {
116         size_t expectSize = sizeof(TLVHead);
117         for (auto &item : value) {
118             expectSize += Count(item);
119         }
120         return expectSize;
121     }
CountTLVObject122     static inline size_t Count(std::vector<uint8_t> &value)
123     {
124         size_t expectSize = sizeof(TLVHead);
125         expectSize += value.size();
126         return expectSize;
127     }
CountTLVObject128     static inline size_t Count(std::map<std::string, std::vector<uint8_t>> &value)
129     {
130         size_t expectSize = sizeof(TLVHead);
131         for (auto &item : value) {
132             expectSize += Count(item.first);
133             expectSize += Count(item.second);
134         }
135         return expectSize;
136     }
137 
138     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, bool value);
139     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, int8_t value);
140     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, int16_t value);
141     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, int32_t value);
142     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, int64_t value);
143     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, uint32_t value);
144     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, const std::string &value);
145     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, const RawMem &value);
146     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, TLVObject &value);
WriteTLVObject147     template<typename T> bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, std::vector<T> &value)
148     {
149         if (!HasExpectBuffer(buffer, sizeof(TLVHead))) {
150             return false;
151         }
152         auto tagCursor = cursor_;
153         cursor_ += sizeof(TLVHead);
154         auto valueCursor = cursor_;
155         bool ret = WriteValue(buffer, value);
156         WriteHead(buffer, type, tagCursor, cursor_ - valueCursor);
157         return ret;
158     }
159     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, std::vector<uint8_t> &value);
160     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, std::map<std::string, std::vector<uint8_t>> &value);
WriteTLVObject161     template<typename T> bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, std::shared_ptr<T> &value)
162     {
163         if (value == nullptr) {
164             return true;
165         }
166         return Write(buffer, type, *value);
167     }
168     bool ReadHead(const std::vector<std::uint8_t> &buffer, TLVHead &head);
169     bool ReadValue(const std::vector<std::uint8_t> &buffer, bool &value, const TLVHead &head);
170     bool ReadValue(const std::vector<std::uint8_t> &buffer, int8_t &value, const TLVHead &head);
171     bool ReadValue(const std::vector<std::uint8_t> &buffer, int16_t &value, const TLVHead &head);
172     bool ReadValue(const std::vector<std::uint8_t> &buffer, int32_t &value, const TLVHead &head);
173     bool ReadValue(const std::vector<std::uint8_t> &buffer, int64_t &value, const TLVHead &head);
174     bool ReadValue(const std::vector<std::uint8_t> &buffer, uint32_t &value, const TLVHead &head);
175     bool ReadValue(const std::vector<std::uint8_t> &buffer, std::string &value, const TLVHead &head);
176     bool ReadValue(const std::vector<std::uint8_t> &buffer, RawMem &rawMem, const TLVHead &head);
177     bool ReadValue(const std::vector<std::uint8_t> &buffer, TLVObject &value, const TLVHead &head);
178     template<typename T>
ReadValueTLVObject179     bool ReadValue(const std::vector<std::uint8_t> &buffer, std::vector<T> &value, const TLVHead &head)
180     {
181         auto vectorEnd = cursor_ + head.len;
182         for (; cursor_ < vectorEnd;) {
183             // V: item value
184             TLVHead valueHead{};
185             bool ret = ReadHead(buffer, valueHead);
186             T item{};
187             ret = ret && ReadValue(buffer, item, valueHead);
188             if (!ret) {
189                 return false;
190             }
191             value.push_back(item);
192         }
193         return true;
194     }
195     bool ReadValue(const std::vector<std::uint8_t> &buffer, std::vector<uint8_t> &value, const TLVHead &head);
196     bool ReadValue(const std::vector<std::uint8_t> &buffer, std::map<std::string, std::vector<uint8_t>> &value,
197         const TLVHead &head);
198 
199     template<typename T>
ReadValueTLVObject200     bool ReadValue(const std::vector<std::uint8_t> &buffer, std::shared_ptr<T> &value, const TLVHead &head)
201     {
202         value = std::make_shared<T>();
203         if (value == nullptr) {
204             return false;
205         }
206         return ReadValue(buffer, *value, head);
207     }
208 
209 protected:
210     virtual ~TLVObject() = default;
SkipTLVObject211     inline bool Skip(size_t len, size_t total)
212     {
213         if (total < len || total - len < cursor_) {
214             return false;
215         }
216         cursor_ += len;
217         return true;
218     }
IsEnoughTLVObject219     inline bool IsEnough() const
220     {
221         return cursor_ < total_;
222     }
223 
224     size_t total_ = 0;
225 
226 private:
227     bool Encode(std::vector<std::uint8_t> &buffer, size_t &cursor, size_t total);
228     bool Decode(const std::vector<std::uint8_t> &buffer, size_t &cursor, size_t total);
WriteHeadTLVObject229     static inline void WriteHead(std::vector<std::uint8_t> &buffer, uint16_t type, size_t tagCursor, uint32_t len)
230     {
231         auto *tlvHead = reinterpret_cast<TLVHead *>(buffer.data() + tagCursor);
232         tlvHead->tag = HostToNet(type);
233         tlvHead->len = HostToNet(len);
234     }
WriteBasicTLVObject235     template<typename T> bool WriteBasic(std::vector<std::uint8_t> &buffer, uint16_t type, T value)
236     {
237         if (!HasExpectBuffer(buffer, sizeof(TLVHead) + sizeof(value))) {
238             return false;
239         }
240         auto *tlvHead = reinterpret_cast<TLVHead *>(buffer.data() + cursor_);
241         tlvHead->tag = HostToNet(type);
242         tlvHead->len = HostToNet((uint32_t)sizeof(value));
243         auto valueBuff = HostToNet(value);
244         auto ret = memcpy_s(tlvHead->value, sizeof(value), &valueBuff, sizeof(value));
245         if (ret != EOK) {
246             return false;
247         }
248         cursor_ += sizeof(TLVHead) + sizeof(value);
249         return true;
250     }
251 
WriteValueTLVObject252     template<typename T> bool WriteValue(std::vector<std::uint8_t> &buffer, std::vector<T> &value)
253     {
254         // items iterator
255         bool ret = true;
256         for (T &item : value) {
257             // V:item value
258             ret = ret && Write(buffer, TAG_VECTOR_ITEM, item);
259         }
260         return ret;
261     }
262 
ReadBasicValueTLVObject263     template<typename T> bool ReadBasicValue(const std::vector<std::uint8_t> &buffer, T &value, const TLVHead &head)
264     {
265         if (head.len == 0) {
266             return false;
267         }
268         if (!HasExpectBuffer(buffer, head.len)) {
269             return false;
270         }
271         auto ret = memcpy_s(&value, sizeof(T), buffer.data() + cursor_, sizeof(T));
272         if (ret != EOK) {
273             return false;
274         }
275         value = NetToHost(value);
276         cursor_ += sizeof(T);
277         return true;
278     }
279 
HasExpectBufferTLVObject280     inline bool HasExpectBuffer(const std::vector<std::uint8_t> &buffer, uint32_t expectLen) const
281     {
282         return buffer.size() >= cursor_ && buffer.size() - cursor_ >= expectLen;
283     }
284 
285     size_t cursor_ = 0;
286 };
287 } // namespace OHOS::MiscServices
288 #endif // DISTRIBUTEDDATAMGR_PASTEBOARD_TLV_OBJECT_H
289