1 /*
2  * Copyright (c) 2022-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 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 <variant>
23 #include <vector>
24 
25 #include "api/visibility.h"
26 #include "endian_converter.h"
27 #include "parcel.h"
28 #include "securec.h"
29 #include "unified_meta.h"
30 #include "parcel_util.h"
31 namespace OHOS::MiscServices {
32 #pragma pack(1)
33 struct TLVHead {
34     uint16_t tag;
35     uint32_t len;
36     std::uint8_t value[0];
37 };
38 #pragma pack()
39 
40 /*
41  * Common tag definitions.
42  * Product should use after TAG_BUFF
43  **/
44 enum COMMON_TAG : uint16_t {
45     TAG_VECTOR_ITEM = 0x0000,
46     TAG_MAP_KEY,
47     TAG_MAP_VALUE, // std::vector<uint8_t>
48     TAG_MAP_VALUE_TYPE,
49     TAG_VARIANT_INDEX,
50     TAG_VARIANT_VALUE,
51     TAG_BUFF = 0x0100,
52 };
53 
54 using ValueType = std::variant<int32_t, int64_t, bool, double, std::string, std::vector<uint8_t>>;
55 using Details = std::map<std::string, ValueType>;
56 
57 using EntryValue = UDMF::ValueType;
58 using Object = UDMF::Object;
59 
60 struct API_EXPORT TLVObject {
61 public:
TLVObjectTLVObject62     TLVObject() : total_(0), cursor_(0)
63     {
64     }
65     virtual bool Encode(std::vector<std::uint8_t> &buffer) = 0;
66     virtual bool Decode(const std::vector<std::uint8_t> &buffer) = 0;
67     virtual size_t Count() = 0;
InitTLVObject68     inline void Init(std::vector<std::uint8_t> &buffer)
69     {
70         buffer.resize(Count());
71         total_ = buffer.size();
72         cursor_ = 0;
73     }
74 
CountTLVObject75     static inline size_t Count(bool value)
76     {
77         return sizeof(value) + sizeof(TLVHead);
78     }
CountTLVObject79     static inline size_t Count(int8_t value)
80     {
81         return sizeof(value) + sizeof(TLVHead);
82     }
CountTLVObject83     static inline size_t Count(int16_t value)
84     {
85         return sizeof(value) + sizeof(TLVHead);
86     }
CountTLVObject87     static inline size_t Count(int32_t value)
88     {
89         return sizeof(value) + sizeof(TLVHead);
90     }
CountTLVObject91     static inline size_t Count(double value)
92     {
93         return sizeof(value) + sizeof(TLVHead);
94     }
CountTLVObject95     static inline size_t Count(int64_t value)
96     {
97         return sizeof(value) + sizeof(TLVHead);
98     }
CountTLVObject99     static inline size_t Count(uint32_t value)
100     {
101         return sizeof(value) + sizeof(TLVHead);
102     }
CountTLVObject103     static inline size_t Count(const std::string &value)
104     {
105         return value.size() + sizeof(TLVHead);
106     }
CountTLVObject107     static inline size_t Count(const RawMem &value)
108     {
109         return value.bufferLen + sizeof(TLVHead);
110     }
CountTLVObject111     static inline size_t Count(TLVObject &value)
112     {
113         return value.Count() + sizeof(TLVHead);
114     }
115     template<typename T>
CountTLVObject116     inline size_t Count(const std::shared_ptr<T> value)
117     {
118         if (value == nullptr) {
119             return 0;
120         }
121         return Count(*value);
122     }
123     template<typename T>
CountTLVObject124     inline size_t Count(const std::vector<T> &value)
125     {
126         size_t expectSize = sizeof(TLVHead);
127         for (auto &item : value) {
128             expectSize += Count(item);
129         }
130         return expectSize;
131     }
CountTLVObject132     static inline size_t Count(const std::vector<uint8_t> &value)
133     {
134         size_t expectSize = sizeof(TLVHead);
135         expectSize += value.size();
136         return expectSize;
137     }
CountTLVObject138     static inline size_t Count(const std::map<std::string, std::vector<uint8_t>> &value)
139     {
140         size_t expectSize = sizeof(TLVHead);
141         for (auto &item : value) {
142             expectSize += Count(item.first);
143             expectSize += Count(item.second);
144         }
145         return expectSize;
146     }
147 
CountTLVObject148     static inline size_t Count(const Details& value)
149     {
150         size_t expectSize = sizeof(TLVHead);
151         for (auto& item : value) {
152             expectSize += Count(item.first);
153             expectSize += Count(item.second);
154         }
155         return expectSize;
156     }
157 
CountTLVObject158     static inline size_t Count(const std::shared_ptr<AAFwk::Want>& value)
159     {
160         size_t expectSize = sizeof(TLVHead);
161         if (value == nullptr) {
162             return 0;
163         }
164         return expectSize + Count(ParcelUtil::Parcelable2Raw(value.get()));
165     }
166 
CountTLVObject167     static inline size_t Count(std::shared_ptr<Media::PixelMap> value)
168     {
169         size_t expectSize = sizeof(TLVHead);
170         if (value == nullptr) {
171             return 0;
172         }
173         return expectSize + Count(PixelMap2Vector(value));
174     }
175 
CountTLVObject176     static inline size_t Count(const std::shared_ptr<Object>& value)
177     {
178         size_t expectSize = sizeof(TLVHead);
179         if (value == nullptr) {
180             return 0;
181         }
182         for (auto& item : value->value_) {
183             expectSize += Count(item.first);
184             expectSize += Count(item.second);
185         }
186         return expectSize;
187     }
188 
CountTLVObject189     static inline size_t Count(const std::monostate &value)
190     {
191         return sizeof(TLVHead);
192     }
193 
CountTLVObject194     static inline size_t Count(const void *value)
195     {
196         return sizeof(TLVHead);
197     }
198 
199     static std::shared_ptr<Media::PixelMap> Vector2PixelMap(std::vector<std::uint8_t> &value);
200     static std::vector<std::uint8_t> PixelMap2Vector(std::shared_ptr<Media::PixelMap> pixelMap);
201 
202     template<typename _InTp>
CountVariantTLVObject203     static inline size_t CountVariant(uint32_t step, const _InTp& input)
204     {
205         return 0;
206     }
207 
208     template<typename _InTp, typename _First, typename... _Rest>
CountVariantTLVObject209     static inline size_t CountVariant(uint32_t step, const _InTp& input)
210     {
211         if (step == input.index()) {
212             return Count(step) + Count(std::get<_First>(input));
213         }
214         return CountVariant<_InTp, _Rest...>(step + 1, input);
215     }
216 
217     template<typename... _Types>
CountTLVObject218     static inline size_t Count(const std::variant<_Types...>& input)
219     {
220         size_t expectSize = sizeof(TLVHead);
221         return expectSize + CountVariant<decltype(input), _Types...>(0, input);
222     }
223 
224     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, std::monostate value);
225     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, void* value);
226     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, bool value);
227     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, double value);
228     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, int8_t value);
229     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, int16_t value);
230     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, int32_t value);
231     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, int64_t value);
232     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, uint32_t value);
233     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, const std::string &value);
234     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, const Object &value);
235     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, const AAFwk::Want &value);
236     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, const Media::PixelMap &value);
237     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, const RawMem &value);
238     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, TLVObject &value);
239     template<typename T>
WriteTLVObject240     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, std::vector<T> &value)
241     {
242         if (!HasExpectBuffer(buffer, sizeof(TLVHead))) {
243             return false;
244         }
245         auto tagCursor = cursor_;
246         cursor_ += sizeof(TLVHead);
247         auto valueCursor = cursor_;
248         bool ret = WriteValue(buffer, value);
249         WriteHead(buffer, type, tagCursor, cursor_ - valueCursor);
250         return ret;
251     }
252     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, std::vector<uint8_t> &value);
253     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, std::map<std::string, std::vector<uint8_t>> &value);
254     template<typename T>
WriteTLVObject255     bool Write(std::vector<std::uint8_t> &buffer, uint16_t type, std::shared_ptr<T> &value)
256     {
257         if (value == nullptr) {
258             return true;
259         }
260         return Write(buffer, type, *value);
261     }
262 
263     template<typename _InTp>
264     bool WriteVariant(std::vector<std::uint8_t>& buffer, uint16_t type, uint32_t step, const _InTp& input);
265 
266     template<typename _InTp, typename _First, typename... _Rest>
267     bool WriteVariant(std::vector<std::uint8_t>& buffer, uint16_t type, uint32_t step, const _InTp& input);
268 
269     template<typename... _Types>
270     bool Write(std::vector<std::uint8_t>& buffer, uint16_t type, const std::variant<_Types...>& input);
271 
272     template<>
273     bool Write(std::vector<std::uint8_t>& buffer, uint16_t type, const EntryValue& input);
274 
275     bool Write(std::vector<std::uint8_t>& buffer, uint16_t type, const Details& value);
276 
277     bool ReadHead(const std::vector<std::uint8_t> &buffer, TLVHead &head);
278     bool ReadValue(const std::vector<std::uint8_t> &buffer, bool &value, const TLVHead &head);
279     bool ReadValue(const std::vector<std::uint8_t> &buffer, std::monostate &value, const TLVHead &head);
280     bool ReadValue(const std::vector<std::uint8_t> &buffer, void *value, const TLVHead &head);
281     bool ReadValue(const std::vector<std::uint8_t> &buffer, int8_t &value, const TLVHead &head);
282     bool ReadValue(const std::vector<std::uint8_t> &buffer, int16_t &value, const TLVHead &head);
283     bool ReadValue(const std::vector<std::uint8_t> &buffer, int32_t &value, const TLVHead &head);
284     bool ReadValue(const std::vector<std::uint8_t> &buffer, int64_t &value, const TLVHead &head);
285     bool ReadValue(const std::vector<std::uint8_t> &buffer, double &value, const TLVHead &head);
286     bool ReadValue(const std::vector<std::uint8_t> &buffer, uint32_t &value, const TLVHead &head);
287     bool ReadValue(const std::vector<std::uint8_t> &buffer, std::string &value, const TLVHead &head);
288     bool ReadValue(const std::vector<std::uint8_t> &buffer, RawMem &rawMem, const TLVHead &head);
289     bool ReadValue(const std::vector<std::uint8_t> &buffer, Object &value, const TLVHead &head);
290     bool ReadValue(const std::vector<std::uint8_t> &buffer, AAFwk::Want &value, const TLVHead &head);
291     bool ReadValue(const std::vector<std::uint8_t> &buffer, std::shared_ptr<Media::PixelMap> &value,
292         const TLVHead &head);
293     bool ReadValue(const std::vector<std::uint8_t> &buffer, TLVObject &value, const TLVHead &head);
294     template<typename T>
ReadValueTLVObject295     bool ReadValue(const std::vector<std::uint8_t> &buffer, std::vector<T> &value, const TLVHead &head)
296     {
297         auto vectorEnd = cursor_ + head.len;
298         for (; cursor_ < vectorEnd;) {
299             // V: item value
300             TLVHead valueHead{};
301             bool ret = ReadHead(buffer, valueHead);
302             T item{};
303             ret = ret && ReadValue(buffer, item, valueHead);
304             if (!ret) {
305                 return false;
306             }
307             value.push_back(item);
308         }
309         return true;
310     }
311 
312     bool ReadValue(const std::vector<std::uint8_t>& buffer, std::vector<uint8_t>& value, const TLVHead& head);
313 
314     template<typename _InTp>
315     bool ReadVariant(const std::vector<std::uint8_t>& buffer, uint32_t step, uint32_t index, _InTp& input,
316         const TLVHead& head);
317 
318     template<typename _InTp, typename _First, typename... _Rest>
319     bool ReadVariant(const std::vector<std::uint8_t>& buffer, uint32_t step, uint32_t index, _InTp& input,
320         const TLVHead& head);
321 
322     template<typename... _Types>
323     bool ReadValue(const std::vector<std::uint8_t>& buffer, std::variant<_Types...>& value, const TLVHead& head);
324 
325     template<>
326     bool ReadValue(const std::vector<std::uint8_t>& buffer, EntryValue& value, const TLVHead& head);
327 
328     bool ReadValue(const std::vector<std::uint8_t>& buffer, Details& value, const TLVHead& head);
329     bool ReadValue(const std::vector<std::uint8_t> &buffer, std::map<std::string, std::vector<uint8_t>> &value,
330         const TLVHead &head);
331 
332     template<typename T>
ReadValueTLVObject333     bool ReadValue(const std::vector<std::uint8_t> &buffer, std::shared_ptr<T> &value, const TLVHead &head)
334     {
335         value = std::make_shared<T>();
336         if (value == nullptr) {
337             return false;
338         }
339         return ReadValue(buffer, *value, head);
340     }
341 
342 protected:
343     virtual ~TLVObject() = default;
SkipTLVObject344     inline bool Skip(size_t len, size_t total)
345     {
346         if (total < len || total - len < cursor_) {
347             return false;
348         }
349         cursor_ += len;
350         return true;
351     }
IsEnoughTLVObject352     inline bool IsEnough() const
353     {
354         return cursor_ < total_;
355     }
356 
357     size_t total_ = 0;
358 
359 private:
360     bool Encode(std::vector<std::uint8_t> &buffer, size_t &cursor, size_t total);
361     bool Decode(const std::vector<std::uint8_t> &buffer, size_t &cursor, size_t total);
WriteHeadTLVObject362     static inline void WriteHead(std::vector<std::uint8_t> &buffer, uint16_t type, size_t tagCursor, uint32_t len)
363     {
364         auto *tlvHead = reinterpret_cast<TLVHead *>(buffer.data() + tagCursor);
365         tlvHead->tag = HostToNet(type);
366         tlvHead->len = HostToNet(len);
367     }
368     template<typename T>
WriteBasicTLVObject369     bool WriteBasic(std::vector<std::uint8_t> &buffer, uint16_t type, T value)
370     {
371         if (!HasExpectBuffer(buffer, sizeof(TLVHead) + sizeof(value))) {
372             return false;
373         }
374         auto *tlvHead = reinterpret_cast<TLVHead *>(buffer.data() + cursor_);
375         tlvHead->tag = HostToNet(type);
376         tlvHead->len = HostToNet((uint32_t)sizeof(value));
377         auto valueBuff = HostToNet(value);
378         auto ret = memcpy_s(tlvHead->value, sizeof(value), &valueBuff, sizeof(value));
379         if (ret != EOK) {
380             return false;
381         }
382         cursor_ += sizeof(TLVHead) + sizeof(value);
383         return true;
384     }
385 
386     template<typename T>
WriteValueTLVObject387     bool WriteValue(std::vector<std::uint8_t> &buffer, std::vector<T> &value)
388     {
389         // items iterator
390         bool ret = true;
391         for (T &item : value) {
392             // V:item value
393             ret = ret && Write(buffer, TAG_VECTOR_ITEM, item);
394         }
395         return ret;
396     }
397 
ReadBasicValueTLVObject398     bool ReadBasicValue(const std::vector<std::uint8_t> &buffer, bool &value, const TLVHead &head)
399     {
400         if (head.len != sizeof(bool) || head.len == 0) {
401             return false;
402         }
403         if (!HasExpectBuffer(buffer, head.len)) {
404             return false;
405         }
406         uint8_t rawValue = 0;
407         auto ret = memcpy_s(&rawValue, sizeof(bool), buffer.data() + cursor_, sizeof(bool));
408         if (ret != EOK) {
409             return false;
410         }
411         if (rawValue > 1) {
412             return false;
413         }
414         value = NetToHost(rawValue);
415         cursor_ += sizeof(bool);
416         return true;
417     }
418 
419     template<typename T>
ReadBasicValueTLVObject420     bool ReadBasicValue(const std::vector<std::uint8_t> &buffer, T &value, const TLVHead &head)
421     {
422         if (head.len != sizeof(T) || head.len == 0) {
423             return false;
424         }
425         if (!HasExpectBuffer(buffer, head.len)) {
426             return false;
427         }
428         auto ret = memcpy_s(&value, sizeof(T), buffer.data() + cursor_, sizeof(T));
429         if (ret != EOK) {
430             return false;
431         }
432         value = NetToHost(value);
433         cursor_ += sizeof(T);
434         return true;
435     }
436 
HasExpectBufferTLVObject437     inline bool HasExpectBuffer(const std::vector<std::uint8_t> &buffer, uint32_t expectLen) const
438     {
439         return buffer.size() >= cursor_ && buffer.size() - cursor_ >= expectLen;
440     }
441 
442     size_t cursor_ = 0;
443 };
444 } // namespace OHOS::MiscServices
445 #endif // DISTRIBUTEDDATAMGR_PASTEBOARD_TLV_OBJECT_H
446