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