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