1/*
2 * Copyright (C) 2024 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#include "uuid.h"
17
18#define CONSTANT_ZERO 0
19#define CONSTANT_FOUR 4
20#define CONSTANT_EIGHT 8
21#define CONSTANT_TWELVE 12
22#define CONSTANT_SIXTEEN 16
23#define CONSTANT_TWENTY 20
24
25namespace OHOS {
26namespace Bluetooth {
27const std::regex uuidRegex("^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$");
28
29UUID::UUID(const long mostSigBits, const long leastSigBits)
30{
31    this->uuid_[15] = static_cast<uint8_t>(leastSigBits & 0x00000000000000FF); // 15是uuid的数组下标
32    this->uuid_[14] = static_cast<uint8_t>((leastSigBits & 0x000000000000FF00) >> 8); // 14是uuid的数组下标,右移8位
33    // 13是uuid的数组下标,右移16位
34    this->uuid_[13] = static_cast<uint8_t>((leastSigBits & 0x0000000000FF0000) >> 16);
35    // 12是uuid的数组下标,右移24位
36    this->uuid_[12] = static_cast<uint8_t>((leastSigBits & 0x00000000FF000000) >> 24);
37    // 11是uuid的数组下标,右移32位
38    this->uuid_[11] = static_cast<uint8_t>((leastSigBits & 0x000000FF00000000) >> 32);
39    // 10是uuid的数组下标,右移40位
40    this->uuid_[10] = static_cast<uint8_t>((leastSigBits & 0x0000FF0000000000) >> 40);
41    this->uuid_[9] = static_cast<uint8_t>((leastSigBits & 0x00FF000000000000) >> 48); // 9是uuid的数组下标,右移48位
42    this->uuid_[8] = static_cast<uint8_t>((leastSigBits & 0xFF00000000000000) >> 56); // 8是uuid的数组下标,右移56位
43    this->uuid_[7] = static_cast<uint8_t>(mostSigBits & 0x00000000000000FF); // 7是uuid的数组下标,右移8位
44    this->uuid_[6] = static_cast<uint8_t>((mostSigBits & 0x000000000000FF00) >> 8); // 6是uuid的数组下标,右移8位
45    this->uuid_[5] = static_cast<uint8_t>((mostSigBits & 0x0000000000FF0000) >> 16); // 5是uuid的数组下标,右移16位
46    this->uuid_[4] = static_cast<uint8_t>((mostSigBits & 0x00000000FF000000) >> 24); // 4是uuid的数组下标,右移24位
47    this->uuid_[3] = static_cast<uint8_t>((mostSigBits & 0x000000FF00000000) >> 32); // 3是uuid的数组下标,右移32位
48    this->uuid_[2] = static_cast<uint8_t>((mostSigBits & 0x0000FF0000000000) >> 40); // 2是uuid的数组下标,右移40位
49    this->uuid_[1] = static_cast<uint8_t>((mostSigBits & 0x00FF000000000000) >> 48); // 1是uuid的数组下标,右移48位
50    this->uuid_[0] = static_cast<uint8_t>((mostSigBits & 0xFF00000000000000) >> 56); // 0是uuid的数组下标,右移56位
51}
52
53UUID UUID::FromString(const std::string &name)
54{
55    UUID ret;
56    std::string tmp = name;
57    std::size_t pos = tmp.find("-");
58
59    while (pos != std::string::npos) {
60        tmp.replace(pos, 1, "");
61        pos = tmp.find("-");
62    }
63
64    for (std::size_t i = 0; (i + 1) < tmp.length();) {
65        ret.uuid_[i / 2] = std::stoi(tmp.substr(i, 2), nullptr, 16); // uuid的长度为16,i / 2作为uuid的数组下标
66        i += 2; // for 循环中,每轮增加2
67    }
68
69    return ret;
70}
71
72UUID UUID::RandomUUID()
73{
74    UUID random;
75
76    struct timeval tv;
77    struct timezone tz;
78    struct tm randomTime;
79    unsigned int randNum = 0;
80
81    rand_r(&randNum);
82    gettimeofday(&tv, &tz);
83    localtime_r(&tv.tv_sec, &randomTime);
84    random.uuid_[15] = static_cast<uint8_t>(tv.tv_usec & 0x00000000000000FF); // 15是uuid的数组下标
85    random.uuid_[14] = static_cast<uint8_t>((tv.tv_usec & 0x000000000000FF00) >> 8); // 14是uuid的数组下标,右移8位
86    random.uuid_[13] = static_cast<uint8_t>((tv.tv_usec & 0x0000000000FF0000) >> 16); // 13是uuid的数组下标,右移16位
87    random.uuid_[12] = static_cast<uint8_t>((tv.tv_usec & 0x00000000FF000000) >> 24); // 12是uuid的数组下标,右移24位
88    random.uuid_[10] = static_cast<uint8_t>((tv.tv_usec & 0x000000FF00000000) >> 32); // 10是uuid的数组下标,右移32位
89    random.uuid_[9] = static_cast<uint8_t>((tv.tv_usec & 0x0000FF0000000000) >> 40); // 9是uuid的数组下标,右移40位
90    random.uuid_[8] = static_cast<uint8_t>((tv.tv_usec & 0x00FF000000000000) >> 48); // 8是uuid的数组下标,右移48位
91    random.uuid_[7] = static_cast<uint8_t>((tv.tv_usec & 0xFF00000000000000) >> 56); // 7是uuid的数组下标,右移56位
92    // 6是uuid的数组下标
93    random.uuid_[6] = static_cast<uint8_t>((randomTime.tm_sec + static_cast<int>(randNum)) & 0xFF);
94    // 5是uuid的数组下标,右移8位
95    random.uuid_[5] = static_cast<uint8_t>((randomTime.tm_min + (randNum >> 8)) & 0xFF);
96    // 4是uuid的数组下标,右移16位
97    random.uuid_[4] = static_cast<uint8_t>((randomTime.tm_hour + (randNum >> 16)) & 0xFF);
98    // 3是uuid的数组下标,右移24位
99    random.uuid_[3] = static_cast<uint8_t>((randomTime.tm_mday + (randNum >> 24)) & 0xFF);
100    random.uuid_[2] = static_cast<uint8_t>(randomTime.tm_mon & 0xFF); // 2是uuid的数组下标
101    random.uuid_[1] = static_cast<uint8_t>(randomTime.tm_year & 0xFF); // 1是uuid的数组下标
102    random.uuid_[0] = static_cast<uint8_t>((randomTime.tm_year & 0xFF00) >> 8); // 0是uuid的数组下标,右移8位
103    return random;
104}
105
106std::string UUID::ToString() const
107{
108    std::string tmp = "";
109    std::string ret = "";
110    static const char *hex = "0123456789ABCDEF";
111
112    for (auto it = this->uuid_.begin(); it != this->uuid_.end(); it++) {
113        tmp.push_back(hex[(((*it) >> 4) & 0xF)]); // 右移4位
114        tmp.push_back(hex[(*it) & 0xF]);
115    }
116    // ToString操作,8, 4, 12, 16,20 作为截取字符的开始位置或截取长度
117    ret = tmp.substr(CONSTANT_ZERO, CONSTANT_EIGHT) + "-" +
118            tmp.substr(CONSTANT_EIGHT, CONSTANT_FOUR) + "-" +
119            tmp.substr(CONSTANT_TWELVE, CONSTANT_FOUR) + "-" +
120            tmp.substr(CONSTANT_SIXTEEN, CONSTANT_FOUR) + "-" +
121            tmp.substr(CONSTANT_TWENTY);
122
123    return ret;
124}
125
126int UUID::CompareTo(const UUID &val) const
127{
128    UUID tmp = val;
129    return this->ToString().compare(tmp.ToString());
130}
131
132bool UUID::Equals(const UUID &val) const
133{
134    for (int i = 0; i < UUID::UUID128_BYTES_LEN; i++) {
135        if (this->uuid_[i] != val.uuid_[i]) {
136            return false;
137        }
138    }
139    return true;
140}
141
142uint64_t UUID::GetLeastSignificantBits() const
143{
144    uint64_t leastSigBits = 0;
145    for (int i = UUID::UUID128_BYTES_LEN / 2; i < UUID::UUID128_BYTES_LEN; i++) { // uuid长度/2作为i初始值
146        leastSigBits = (leastSigBits << 8) | (uuid_[i] & 0xFF); // 左移8位
147    }
148    return leastSigBits;
149}
150
151uint64_t UUID::GetMostSignificantBits() const
152{
153    uint64_t mostSigBits = 0;
154    for (int i = 0 / 2; i < UUID::UUID128_BYTES_LEN / 2; i++) { // uuid长度/2作为i最大值
155        mostSigBits = (mostSigBits << 8) | (uuid_[i] & 0xFF); // 左移8位
156    }
157    return mostSigBits;
158}
159
160UUID UUID::ConvertFrom128Bits(const std::array<uint8_t, UUID::UUID128_BYTES_LEN> &name)
161{
162    UUID tmp;
163    for (int i = 0; i < UUID::UUID128_BYTES_LEN; i++) {
164        tmp.uuid_[i] = name[i];
165    }
166    return tmp;
167}
168
169std::array<uint8_t, UUID::UUID128_BYTES_LEN> UUID::ConvertTo128Bits() const
170{
171    std::array<uint8_t, UUID::UUID128_BYTES_LEN> uuid;
172
173    for (int i = 0; i < UUID::UUID128_BYTES_LEN; i++) {
174        uuid[i] = uuid_[i];
175    }
176
177    return uuid;
178}
179
180bool UUID::operator==(const UUID &rhs) const
181{
182    return uuid_ == rhs.uuid_;
183}
184
185bool UUID::operator<(const UUID &uuid) const
186{
187    return !Equals(uuid);
188}
189
190bool IsValidUuid(std::string uuid)
191{
192    return regex_match(uuid, uuidRegex);
193}
194}
195}