/src/mysql-server/libs/mysql/gtid/uuid.h
Line | Count | Source |
1 | | /* Copyright (c) 2017, 2025, Oracle and/or its affiliates. |
2 | | |
3 | | This program is free software; you can redistribute it and/or modify |
4 | | it under the terms of the GNU General Public License, version 2.0, |
5 | | as published by the Free Software Foundation. |
6 | | |
7 | | This program is designed to work with certain software (including |
8 | | but not limited to OpenSSL) that is licensed under separate terms, |
9 | | as designated in a particular file or component or in included license |
10 | | documentation. The authors of MySQL hereby grant you an additional |
11 | | permission to link the program and your derivative works with the |
12 | | separately licensed software that they have either included with |
13 | | the program or referenced in the documentation. |
14 | | |
15 | | This program is distributed in the hope that it will be useful, |
16 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | | GNU General Public License, version 2.0, for more details. |
19 | | |
20 | | You should have received a copy of the GNU General Public License |
21 | | along with this program; if not, write to the Free Software |
22 | | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
23 | | |
24 | | #ifndef MYSQL_GTID_UUID_H |
25 | | #define MYSQL_GTID_UUID_H |
26 | | |
27 | | #include <stddef.h> |
28 | | #include <stdio.h> |
29 | | #include <string.h> |
30 | | |
31 | | #include <array> |
32 | | #include <string> |
33 | | #include <utility> |
34 | | |
35 | | #include "template_utils.h" |
36 | | |
37 | | /// @addtogroup GroupLibsMysqlGtid |
38 | | /// @{ |
39 | | |
40 | | namespace mysql::gtid { |
41 | | |
42 | | /** |
43 | | @struct Uuid |
44 | | |
45 | | Uuid is a trivial and of standard layout |
46 | | The structure contains the following components. |
47 | | <table> |
48 | | <caption>Structure gtid_info</caption> |
49 | | |
50 | | <tr> |
51 | | <th>Name</th> |
52 | | <th>Format</th> |
53 | | <th>Description</th> |
54 | | </tr> |
55 | | <tr> |
56 | | <td>byte</td> |
57 | | <td>unsigned char array</td> |
58 | | <td>This stores the Uuid of the server on which transaction |
59 | | is originated</td> |
60 | | </tr> |
61 | | </table> |
62 | | */ |
63 | | |
64 | | struct Uuid { |
65 | | /// Set to all zeros. |
66 | 0 | void clear() { memset(bytes.data(), 0, BYTE_LENGTH); } |
67 | | /// Copies the given 16-byte data to this UUID. |
68 | 0 | void copy_from(const unsigned char *data) { |
69 | 0 | memcpy(bytes.data(), data, BYTE_LENGTH); |
70 | 0 | } |
71 | | |
72 | | /// Copies the given UUID object to this UUID. |
73 | 0 | void copy_to(unsigned char *data) const { |
74 | 0 | memcpy(data, bytes.data(), BYTE_LENGTH); |
75 | 0 | } |
76 | | /// Returns true if this UUID is equal the given UUID. |
77 | 0 | bool equals(const Uuid &other) const { |
78 | 0 | return memcmp(bytes.data(), other.bytes.data(), BYTE_LENGTH) == 0; |
79 | 0 | } |
80 | | |
81 | 0 | bool operator<(const Uuid &other) const { |
82 | 0 | return memcmp(this->bytes.data(), other.bytes.data(), BYTE_LENGTH) < 0; |
83 | 0 | } |
84 | | /** |
85 | | Returns true if parse() would succeed, but doesn't store the result. |
86 | | |
87 | | @param string String that needs to be checked. |
88 | | @param len Length of that string. |
89 | | |
90 | | @retval true valid string. |
91 | | @retval false invalid string. |
92 | | */ |
93 | | static bool is_valid(const char *string, size_t len); |
94 | | |
95 | | /** |
96 | | Stores the UUID represented by a string of the form |
97 | | XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX or |
98 | | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX or |
99 | | {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} |
100 | | in this object. |
101 | | |
102 | | @param string String to be parsed and stored. |
103 | | @param len Length of that string. |
104 | | |
105 | | @retval 0 success. |
106 | | @retval >0 failure. |
107 | | */ |
108 | | int parse(const char *string, size_t len); |
109 | | |
110 | | /** |
111 | | Parses the UUID passed as argument in in_string and functions and writes |
112 | | the binary representation in out_binary_string. |
113 | | Depends on UUID's read_section method and the constants for text length. |
114 | | |
115 | | @param[in] in_string String to be parsed. |
116 | | @param[in] len Length of that string. |
117 | | @param[out] out_binary_string String where the binary UUID will be stored |
118 | | |
119 | | @retval 0 success. |
120 | | @retval >0 failure. |
121 | | */ |
122 | | static int parse(const char *in_string, size_t len, |
123 | | const unsigned char *out_binary_string); |
124 | | /** |
125 | | Helper method used to validate and parse one section of a uuid. |
126 | | If the last parameter, out_binary_str, is NULL then the function will |
127 | | just validate the section. |
128 | | |
129 | | @param[in] section_len Length of the section to be parsed. |
130 | | @param[in,out] section_str Pointer to a string containing the |
131 | | section. It will be updated during the |
132 | | execution as the string is parsed. |
133 | | @param[out] out_binary_str String where the section will be stored |
134 | | in binary format. If null, the function |
135 | | will just validate the input string. |
136 | | |
137 | | @retval false success. |
138 | | @retval true failure. |
139 | | */ |
140 | | static bool read_section(int section_len, const char **section_str, |
141 | | const unsigned char **out_binary_str); |
142 | | /** The number of bytes in the data of a Uuid. */ |
143 | | static constexpr std::size_t BYTE_LENGTH = 16; |
144 | | |
145 | | /** The data for this Uuid. */ |
146 | | std::array<unsigned char, BYTE_LENGTH> bytes; |
147 | | |
148 | | /** |
149 | | Generates a 36+1 character long representation of this UUID object |
150 | | in the given string buffer. |
151 | | |
152 | | @retval 36 - the length of the resulting string. |
153 | | */ |
154 | | size_t to_string(char *buf) const; |
155 | | /// Convert the given binary buffer to a UUID |
156 | | static size_t to_string(const unsigned char *bytes_arg, char *buf); |
157 | 0 | std::string to_string() const { |
158 | 0 | char buf[TEXT_LENGTH + 1]; |
159 | 0 | to_string(buf); |
160 | 0 | return buf; |
161 | 0 | } |
162 | 0 | void print() const { |
163 | 0 | char buf[TEXT_LENGTH + 1]; |
164 | 0 | to_string(buf); |
165 | 0 | printf("%s\n", buf); |
166 | 0 | } |
167 | | /// The number of bytes in the textual representation of a Uuid. |
168 | | static const size_t TEXT_LENGTH = 36; |
169 | | /// The number of bits in the data of a Uuid. |
170 | | static const size_t BIT_LENGTH = 128; |
171 | | static const int NUMBER_OF_SECTIONS = 5; |
172 | | static constexpr int bytes_per_section[NUMBER_OF_SECTIONS] = {4, 2, 2, 2, 6}; |
173 | | static constexpr int hex_to_byte[256] = { |
174 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
175 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
176 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, |
177 | | 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, |
178 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
179 | | -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, |
180 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
181 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
182 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
183 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
184 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
185 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
186 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
187 | | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
188 | | -1, -1, -1, -1, |
189 | | }; |
190 | | }; |
191 | | |
192 | | static_assert(std::is_trivial_v<Uuid>); |
193 | | static_assert(std::is_standard_layout_v<Uuid>); |
194 | | |
195 | | struct Uuid_hash { |
196 | 0 | size_t operator()(const Uuid &uuid) const { |
197 | 0 | return std::hash<std::string>()(std::string( |
198 | 0 | pointer_cast<const char *>(uuid.bytes.data()), Uuid::BYTE_LENGTH)); |
199 | 0 | } |
200 | | }; |
201 | | |
202 | 0 | inline bool operator==(const Uuid &a, const Uuid &b) { return a.equals(b); } |
203 | 0 | inline bool operator!=(const Uuid &a, const Uuid &b) { return !a.equals(b); } |
204 | | |
205 | | } // namespace mysql::gtid |
206 | | |
207 | | namespace [[deprecated]] binary_log { |
208 | | namespace [[deprecated]] gtids { |
209 | | using namespace mysql::gtid; |
210 | | } // namespace gtids |
211 | | } // namespace binary_log |
212 | | |
213 | | /// @} |
214 | | |
215 | | #endif // MYSQL_GTID_UUID_H |