18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#ifndef API_BASE_UTIL_UID_H 178bf80f4bSopenharmony_ci#define API_BASE_UTIL_UID_H 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ci#include <cstddef> 208bf80f4bSopenharmony_ci#include <cstdint> 218bf80f4bSopenharmony_ci 228bf80f4bSopenharmony_ci#include <base/containers/string_view.h> 238bf80f4bSopenharmony_ci#include <base/namespace.h> 248bf80f4bSopenharmony_ci#include <base/util/hash.h> 258bf80f4bSopenharmony_ci#include <base/util/log.h> 268bf80f4bSopenharmony_ci 278bf80f4bSopenharmony_ciBASE_BEGIN_NAMESPACE() 288bf80f4bSopenharmony_ciconstexpr uint8_t HexToDec(char c) noexcept 298bf80f4bSopenharmony_ci{ 308bf80f4bSopenharmony_ci if (c <= '9' && c >= '0') { 318bf80f4bSopenharmony_ci return static_cast<uint8_t>(c - '0'); 328bf80f4bSopenharmony_ci } 338bf80f4bSopenharmony_ci if (c <= 'F' && c >= 'A') { 348bf80f4bSopenharmony_ci return static_cast<uint8_t>(c - 'A' + 10); 358bf80f4bSopenharmony_ci } 368bf80f4bSopenharmony_ci if (c <= 'f' && c >= 'a') { 378bf80f4bSopenharmony_ci return static_cast<uint8_t>(c - 'a' + 10); 388bf80f4bSopenharmony_ci } 398bf80f4bSopenharmony_ci return 0; 408bf80f4bSopenharmony_ci} 418bf80f4bSopenharmony_ci 428bf80f4bSopenharmony_ciconstexpr uint8_t HexToUint8(const char* c) noexcept 438bf80f4bSopenharmony_ci{ 448bf80f4bSopenharmony_ci return static_cast<uint8_t>((HexToDec(c[0]) << 4U) + HexToDec(c[1])); 458bf80f4bSopenharmony_ci} 468bf80f4bSopenharmony_ci 478bf80f4bSopenharmony_ciconstexpr bool IsUidString(string_view str) noexcept 488bf80f4bSopenharmony_ci{ 498bf80f4bSopenharmony_ci // UID string in the form 8-4-4-4-12. A total of 36 characters (32 hexadecimal characters and 4 hyphens). 508bf80f4bSopenharmony_ci if (str.size() != 36U) { 518bf80f4bSopenharmony_ci return false; 528bf80f4bSopenharmony_ci } 538bf80f4bSopenharmony_ci 548bf80f4bSopenharmony_ci auto hexChars = [](string_view str) { 558bf80f4bSopenharmony_ci for (const auto& c : str) { 568bf80f4bSopenharmony_ci if (!((c <= '9' && c >= '0') || (c <= 'F' && c >= 'A') || (c <= 'f' && c >= 'a'))) { 578bf80f4bSopenharmony_ci return false; 588bf80f4bSopenharmony_ci } 598bf80f4bSopenharmony_ci } 608bf80f4bSopenharmony_ci return true; 618bf80f4bSopenharmony_ci }; 628bf80f4bSopenharmony_ci return hexChars(str.substr(0U, 8U)) && (str[8U] == '-') && hexChars(str.substr(9U, 4U)) && (str[13U] == '-') && 638bf80f4bSopenharmony_ci hexChars(str.substr(14U, 4U)) && (str[18U] == '-') && hexChars(str.substr(19U, 4U)) && (str[23U] == '-') && 648bf80f4bSopenharmony_ci hexChars(str.substr(24U, 12U)); 658bf80f4bSopenharmony_ci} 668bf80f4bSopenharmony_ci 678bf80f4bSopenharmony_cistruct Uid { 688bf80f4bSopenharmony_ci constexpr Uid() noexcept = default; 698bf80f4bSopenharmony_ci 708bf80f4bSopenharmony_ci explicit constexpr Uid(const uint8_t (&values)[16]) noexcept 718bf80f4bSopenharmony_ci { 728bf80f4bSopenharmony_ci uint64_t value = 0U; 738bf80f4bSopenharmony_ci for (auto first = values, last = values + 8; first != last; ++first) { 748bf80f4bSopenharmony_ci value = (value << 8) | *first; // 8: Multiply by 256 758bf80f4bSopenharmony_ci } 768bf80f4bSopenharmony_ci data[0] = value; 778bf80f4bSopenharmony_ci 788bf80f4bSopenharmony_ci value = 0U; 798bf80f4bSopenharmony_ci for (auto first = values + 8, last = values + 16; first != last; ++first) { 808bf80f4bSopenharmony_ci value = (value << 8) | *first; // 8: Multiply by 256 818bf80f4bSopenharmony_ci } 828bf80f4bSopenharmony_ci data[1] = value; 838bf80f4bSopenharmony_ci } 848bf80f4bSopenharmony_ci 858bf80f4bSopenharmony_ci explicit constexpr Uid(const char (&str)[37]) 868bf80f4bSopenharmony_ci { 878bf80f4bSopenharmony_ci if (IsUidString(str)) { 888bf80f4bSopenharmony_ci auto src = str; 898bf80f4bSopenharmony_ci 908bf80f4bSopenharmony_ci uint64_t value = 0U; 918bf80f4bSopenharmony_ci for (size_t i = 0; i < sizeof(uint32_t); ++i) { 928bf80f4bSopenharmony_ci value = (value << 8) | HexToUint8(src); // 8: Multiply by 256 938bf80f4bSopenharmony_ci src += 2; 948bf80f4bSopenharmony_ci } 958bf80f4bSopenharmony_ci ++src; 968bf80f4bSopenharmony_ci for (size_t i = 0; i < sizeof(uint16_t); ++i) { 978bf80f4bSopenharmony_ci value = (value << 8) | HexToUint8(src); // 8: Multiply by 256 988bf80f4bSopenharmony_ci src += 2; 998bf80f4bSopenharmony_ci } 1008bf80f4bSopenharmony_ci ++src; 1018bf80f4bSopenharmony_ci for (size_t i = 0; i < sizeof(uint16_t); ++i) { 1028bf80f4bSopenharmony_ci value = (value << 8) | HexToUint8(src); // 8: Multiply by 256 1038bf80f4bSopenharmony_ci src += 2; 1048bf80f4bSopenharmony_ci } 1058bf80f4bSopenharmony_ci ++src; 1068bf80f4bSopenharmony_ci data[0U] = value; 1078bf80f4bSopenharmony_ci 1088bf80f4bSopenharmony_ci value = 0U; 1098bf80f4bSopenharmony_ci for (size_t i = 0; i < sizeof(uint16_t); ++i) { 1108bf80f4bSopenharmony_ci value = (value << 8) | HexToUint8(src); // 8: Multiply by 256 1118bf80f4bSopenharmony_ci src += 2; 1128bf80f4bSopenharmony_ci } 1138bf80f4bSopenharmony_ci ++src; 1148bf80f4bSopenharmony_ci for (size_t i = 0; i < (sizeof(uint16_t) * 3); ++i) { 1158bf80f4bSopenharmony_ci value = (value << 8) | HexToUint8(src); // 8: Multiply by 256 1168bf80f4bSopenharmony_ci src += 2; 1178bf80f4bSopenharmony_ci } 1188bf80f4bSopenharmony_ci data[1U] = value; 1198bf80f4bSopenharmony_ci } 1208bf80f4bSopenharmony_ci } 1218bf80f4bSopenharmony_ci 1228bf80f4bSopenharmony_ci constexpr int compare(const Uid& rhs) const 1238bf80f4bSopenharmony_ci { 1248bf80f4bSopenharmony_ci if (data[0] < rhs.data[0]) { 1258bf80f4bSopenharmony_ci return -1; 1268bf80f4bSopenharmony_ci } 1278bf80f4bSopenharmony_ci if (data[0] > rhs.data[0]) { 1288bf80f4bSopenharmony_ci return 1; 1298bf80f4bSopenharmony_ci } 1308bf80f4bSopenharmony_ci if (data[1] < rhs.data[1]) { 1318bf80f4bSopenharmony_ci return -1; 1328bf80f4bSopenharmony_ci } 1338bf80f4bSopenharmony_ci if (data[1] > rhs.data[1]) { 1348bf80f4bSopenharmony_ci return 1; 1358bf80f4bSopenharmony_ci } 1368bf80f4bSopenharmony_ci return 0; 1378bf80f4bSopenharmony_ci } 1388bf80f4bSopenharmony_ci uint64_t data[2u] {}; 1398bf80f4bSopenharmony_ci}; 1408bf80f4bSopenharmony_ci 1418bf80f4bSopenharmony_ciinline constexpr bool operator<(const Uid& lhs, const Uid& rhs) 1428bf80f4bSopenharmony_ci{ 1438bf80f4bSopenharmony_ci if (lhs.data[0] > rhs.data[0]) { 1448bf80f4bSopenharmony_ci return false; 1458bf80f4bSopenharmony_ci } 1468bf80f4bSopenharmony_ci if (lhs.data[0] < rhs.data[0]) { 1478bf80f4bSopenharmony_ci return true; 1488bf80f4bSopenharmony_ci } 1498bf80f4bSopenharmony_ci if (lhs.data[1] < rhs.data[1]) { 1508bf80f4bSopenharmony_ci return true; 1518bf80f4bSopenharmony_ci } 1528bf80f4bSopenharmony_ci return false; 1538bf80f4bSopenharmony_ci} 1548bf80f4bSopenharmony_ci 1558bf80f4bSopenharmony_ciinline constexpr bool operator==(const Uid& lhs, const Uid& rhs) 1568bf80f4bSopenharmony_ci{ 1578bf80f4bSopenharmony_ci return (lhs.data[0U] == rhs.data[0U]) && (lhs.data[1U] == rhs.data[1U]); 1588bf80f4bSopenharmony_ci} 1598bf80f4bSopenharmony_ci 1608bf80f4bSopenharmony_ciinline constexpr bool operator!=(const Uid& lhs, const Uid& rhs) 1618bf80f4bSopenharmony_ci{ 1628bf80f4bSopenharmony_ci return !(lhs == rhs); 1638bf80f4bSopenharmony_ci} 1648bf80f4bSopenharmony_ci 1658bf80f4bSopenharmony_citemplate<> 1668bf80f4bSopenharmony_ciinline uint64_t hash(const Uid& value) 1678bf80f4bSopenharmony_ci{ 1688bf80f4bSopenharmony_ci return Hash(value.data[0], value.data[1]); 1698bf80f4bSopenharmony_ci} 1708bf80f4bSopenharmony_ciBASE_END_NAMESPACE() 1718bf80f4bSopenharmony_ci 1728bf80f4bSopenharmony_ci#endif // API_BASE_UTIL_UID_H 173