EtcPal  0.3.0
ETC Platform Abstraction Layer (EtcPal)
View other versions:
uuid.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2020 ETC Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *******************************************************************************
16  * This file is a part of EtcPal. For more information, go to:
17  * https://github.com/ETCLabs/EtcPal
18  ******************************************************************************/
19 
22 
23 #ifndef ETCPAL_CPP_UUID_H_
24 #define ETCPAL_CPP_UUID_H_
25 
26 #include <cstdint>
27 #include <cstring>
28 #include <array>
29 #include <string>
30 #include "etcpal/pack.h"
31 #include "etcpal/uuid.h"
32 
33 namespace etcpal
34 {
35 // clang-format off
68 // clang-format on
69 
71 enum class UuidVersion
72 {
73  V1 = 1,
74  V2 = 2,
75  V3 = 3,
76  V4 = 4,
77  V5 = 5,
78  Unknown
79 };
80 
86 class Uuid
87 {
88 public:
90  Uuid() = default;
91 
92  Uuid(const uint8_t* data) noexcept;
93  Uuid(uint32_t time_low, uint16_t time_mid, uint16_t time_hi_and_version, const uint8_t clock_seq_and_node[8]);
94  Uuid(uint32_t time_low,
95  uint16_t time_mid,
96  uint16_t time_hi_and_version,
97  const std::array<uint8_t, 8>& clock_seq_and_node);
98 
99  // Note: this constructor is not explicit by design, to allow implicit conversions e.g.
100  // etcpal::Uuid uuid = etcpal_c_function_that_returns_uuid();
101  constexpr Uuid(const EtcPalUuid& c_uuid) noexcept;
102  Uuid& operator=(const EtcPalUuid& c_uuid) noexcept;
103 
104  constexpr const EtcPalUuid& get() const noexcept;
105  const uint8_t* data() const noexcept;
106  std::string ToString() const;
107  bool IsNull() const noexcept;
108  UuidVersion version() const noexcept;
109 
112  uint32_t time_low() const noexcept;
113  uint16_t time_mid() const noexcept;
114  uint16_t time_hi_and_version() const noexcept;
115  std::array<uint8_t, 8> clock_seq_and_node() const noexcept;
117 
118  static Uuid FromString(const char* uuid_str) noexcept;
119  static Uuid FromString(const std::string& uuid_str) noexcept;
120  static Uuid V1() noexcept;
121  static Uuid V3(const Uuid& ns, const void* name, size_t name_len) noexcept;
122  static Uuid V3(const Uuid& ns, const char* name) noexcept;
123  static Uuid V3(const Uuid& ns, const std::string& name) noexcept;
124  static Uuid V4() noexcept;
125  static Uuid V5(const Uuid& ns, const void* name, size_t name_len) noexcept;
126  static Uuid V5(const Uuid& ns, const char* name) noexcept;
127  static Uuid V5(const Uuid& ns, const std::string& name) noexcept;
128  static Uuid OsPreferred() noexcept;
129  static Uuid Device(const std::string& device_str, const uint8_t* mac_addr, uint32_t uuid_num) noexcept;
130  static Uuid Device(const std::string& device_str, const std::array<uint8_t, 6>& mac_addr, uint32_t uuid_num) noexcept;
131 
132 private:
134 };
135 
137 constexpr Uuid::Uuid(const EtcPalUuid& c_uuid) noexcept : uuid_(c_uuid)
138 {
139 }
140 
143 inline Uuid::Uuid(const uint8_t* data) noexcept
144 {
145  std::memcpy(uuid_.data, data, ETCPAL_UUID_BYTES);
146 }
147 
153 inline Uuid::Uuid(uint32_t time_low,
154  uint16_t time_mid,
155  uint16_t time_hi_and_version,
156  const uint8_t clock_seq_and_node[8])
157 {
158  etcpal_pack_u32b(&uuid_.data[0], time_low);
159  etcpal_pack_u16b(&uuid_.data[4], time_mid);
161  std::memcpy(&uuid_.data[8], clock_seq_and_node, 8);
162 }
163 
169 inline Uuid::Uuid(uint32_t time_low,
170  uint16_t time_mid,
171  uint16_t time_hi_and_version,
172  const std::array<uint8_t, 8>& clock_seq_and_node)
173  : Uuid(time_low, time_mid, time_hi_and_version, clock_seq_and_node.data())
174 {
175 }
176 
178 inline Uuid& Uuid::operator=(const EtcPalUuid& c_uuid) noexcept
179 {
180  uuid_ = c_uuid;
181  return *this;
182 }
183 
185 constexpr const EtcPalUuid& Uuid::get() const noexcept
186 {
187  return uuid_;
188 }
189 
192 inline const uint8_t* Uuid::data() const noexcept
193 {
194  return uuid_.data;
195 }
196 
198 inline std::string Uuid::ToString() const
199 {
200  char str_buf[ETCPAL_UUID_STRING_BYTES];
201  if (etcpal_uuid_to_string(&uuid_, str_buf))
202  return str_buf;
203  else
204  return std::string();
205 }
206 
208 inline bool Uuid::IsNull() const noexcept
209 {
210  return ETCPAL_UUID_IS_NULL(&uuid_);
211 }
212 
215 inline UuidVersion Uuid::version() const noexcept
216 {
217  uint8_t vers_val = uuid_.data[6] >> 4;
218  return (vers_val >= 1 && vers_val <= 5) ? static_cast<UuidVersion>(vers_val) : UuidVersion::Unknown;
219 }
220 
222 inline uint32_t Uuid::time_low() const noexcept
223 {
224  return etcpal_unpack_u32b(&uuid_.data[0]);
225 }
226 
228 inline uint16_t Uuid::time_mid() const noexcept
229 {
230  return etcpal_unpack_u16b(&uuid_.data[4]);
231 }
232 
234 inline uint16_t Uuid::time_hi_and_version() const noexcept
235 {
236  return etcpal_unpack_u16b(&uuid_.data[6]);
237 }
238 
241 inline std::array<uint8_t, 8> Uuid::clock_seq_and_node() const noexcept
242 {
243  std::array<uint8_t, 8> res;
244  std::memcpy(res.data(), &uuid_.data[8], 8);
245  return res;
246 }
247 
250 inline Uuid Uuid::FromString(const char* uuid_str) noexcept
251 {
252  Uuid uuid;
253  etcpal_string_to_uuid(uuid_str, &uuid.uuid_);
254  return uuid;
255 }
256 
259 inline Uuid Uuid::FromString(const std::string& uuid_str) noexcept
260 {
261  return FromString(uuid_str.c_str());
262 }
263 
267 inline Uuid Uuid::V1() noexcept
268 {
269  Uuid uuid;
270  etcpal_generate_v1_uuid(&uuid.uuid_);
271  return uuid;
272 }
273 
277 inline Uuid Uuid::V3(const Uuid& ns, const void* name, size_t name_len) noexcept
278 {
279  Uuid uuid;
280  etcpal_generate_v3_uuid(&ns.get(), name, name_len, &uuid.uuid_);
281  return uuid;
282 }
283 
289 inline Uuid Uuid::V3(const Uuid& ns, const char* name) noexcept
290 {
291  return V3(ns, name, std::strlen(name));
292 }
293 
299 inline Uuid Uuid::V3(const Uuid& ns, const std::string& name) noexcept
300 {
301  return V3(ns, name.c_str(), name.length());
302 }
303 
307 inline Uuid Uuid::V4() noexcept
308 {
309  Uuid uuid;
310  etcpal_generate_v4_uuid(&uuid.uuid_);
311  return uuid;
312 }
313 
317 inline Uuid Uuid::V5(const Uuid& ns, const void* name, size_t name_len) noexcept
318 {
319  Uuid uuid;
320  etcpal_generate_v5_uuid(&ns.get(), name, name_len, &uuid.uuid_);
321  return uuid;
322 }
323 
329 inline Uuid Uuid::V5(const Uuid& ns, const char* name) noexcept
330 {
331  return V5(ns, name, std::strlen(name));
332 }
333 
339 inline Uuid Uuid::V5(const Uuid& ns, const std::string& name) noexcept
340 {
341  return V5(ns, name.c_str(), name.length());
342 }
343 
348 inline Uuid Uuid::OsPreferred() noexcept
349 {
350  Uuid uuid;
352  return uuid;
353 }
354 
358 inline Uuid Uuid::Device(const std::string& device_str, const uint8_t* mac_addr, uint32_t uuid_num) noexcept
359 {
360  Uuid uuid;
361  etcpal_generate_device_uuid(device_str.c_str(), mac_addr, uuid_num, &uuid.uuid_);
362  return uuid;
363 }
364 
368 inline Uuid Uuid::Device(const std::string& device_str,
369  const std::array<uint8_t, 6>& mac_addr,
370  uint32_t uuid_num) noexcept
371 {
372  Uuid uuid;
373  etcpal_generate_device_uuid(device_str.c_str(), mac_addr.data(), uuid_num, &uuid.uuid_);
374  return uuid;
375 }
376 
379 
382 
383 // Special operators for comparing with EtcPalUuids
384 
385 inline bool operator==(const EtcPalUuid& c_uuid, const Uuid& uuid) noexcept
386 {
387  return c_uuid == uuid.get();
388 }
389 
390 inline bool operator!=(const EtcPalUuid& c_uuid, const Uuid& uuid) noexcept
391 {
392  return !(c_uuid == uuid);
393 }
394 
395 inline bool operator==(const Uuid& uuid, const EtcPalUuid& c_uuid) noexcept
396 {
397  return uuid.get() == c_uuid;
398 }
399 
400 inline bool operator!=(const Uuid& uuid, const EtcPalUuid& c_uuid) noexcept
401 {
402  return !(uuid == c_uuid);
403 }
404 
405 // Standard operators
406 
407 inline bool operator==(const Uuid& a, const Uuid& b) noexcept
408 {
409  return a.get() == b.get();
410 }
411 
412 inline bool operator!=(const Uuid& a, const Uuid& b) noexcept
413 {
414  return !(a == b);
415 }
416 
417 inline bool operator<(const Uuid& a, const Uuid& b) noexcept
418 {
419  return a.get() < b.get();
420 }
421 
422 inline bool operator>(const Uuid& a, const Uuid& b) noexcept
423 {
424  return b < a;
425 }
426 
427 inline bool operator<=(const Uuid& a, const Uuid& b) noexcept
428 {
429  return !(b < a);
430 }
431 
432 inline bool operator>=(const Uuid& a, const Uuid& b) noexcept
433 {
434  return !(a < b);
435 }
436 
439 
440 }; // namespace etcpal
441 
442 #endif // ETCPAL_CPP_UUID_H_
A wrapper class for the EtcPal UUID type.
Definition: uuid.h:87
static Uuid V1() noexcept
Generate and return a Version 1 UUID.
Definition: uuid.h:267
uint16_t time_hi_and_version() const noexcept
Get the time_hi_and_version portion of a UUID.
Definition: uuid.h:234
uint32_t time_low() const noexcept
Get the time_low portion of a UUID.
Definition: uuid.h:222
std::string ToString() const
Convert the UUID to a string representation formatted per RFC 4122.
Definition: uuid.h:198
const uint8_t * data() const noexcept
Get the raw data of a UUID.
Definition: uuid.h:192
bool IsNull() const noexcept
Check if a UUID is null (all 0's).
Definition: uuid.h:208
static Uuid Device(const std::string &device_str, const uint8_t *mac_addr, uint32_t uuid_num) noexcept
Generate and return a Device UUID.
Definition: uuid.h:358
static Uuid V4() noexcept
Generate and return a Version 4 UUID.
Definition: uuid.h:307
uint16_t time_mid() const noexcept
Get the time_mid portion of a UUID.
Definition: uuid.h:228
constexpr const EtcPalUuid & get() const noexcept
Get a reference to the underlying C type.
Definition: uuid.h:185
static Uuid FromString(const char *uuid_str) noexcept
Create a UUID from a string representation.
Definition: uuid.h:250
Uuid()=default
Constructs a null UUID by default.
static Uuid V3(const Uuid &ns, const void *name, size_t name_len) noexcept
Generate and return a Version 3 UUID.
Definition: uuid.h:277
std::array< uint8_t, 8 > clock_seq_and_node() const noexcept
Get the remaining portion of a UUID, including clock_seq_hi_and_res, clock_seq_low,...
Definition: uuid.h:241
UuidVersion version() const noexcept
Get the version type of a UUID.
Definition: uuid.h:215
Uuid & operator=(const EtcPalUuid &c_uuid) noexcept
Assign an instance of the C EtcPalUuid type to an instance of this class.
Definition: uuid.h:178
static Uuid OsPreferred() noexcept
Generate and return a UUID of the version preferred by the underlying OS.
Definition: uuid.h:348
static Uuid V5(const Uuid &ns, const void *name, size_t name_len) noexcept
Generate and return a Version 5 UUID.
Definition: uuid.h:317
UuidVersion
Represents a UUID version as defined in RFC 4122.
Definition: uuid.h:72
@ Unknown
Unknown UUID version.
@ V5
Version 5 UUID: Namespace-based, SHA-1.
@ V1
Version 1 UUID: Date-time and MAC address.
@ V3
Version 3 UUID: Namespace-based, MD5.
@ V2
Version 2 UUID: DCE Security version (rarely used)
uint32_t etcpal_unpack_u32b(const uint8_t *buf)
Unpack a uint32_t from a known big-endian buffer.
Definition: pack.c:174
void etcpal_pack_u32b(uint8_t *buf, uint32_t val)
Pack a uint32_t to a known big-endian buffer.
Definition: pack.c:192
void etcpal_pack_u16b(uint8_t *buf, uint16_t val)
Pack a uint16_t to a known big-endian buffer.
Definition: pack.c:90
uint16_t etcpal_unpack_u16b(const uint8_t *buf)
Unpack a uint16_t from a known big-endian buffer.
Definition: pack.c:74
etcpal_error_t etcpal_generate_device_uuid(const char *dev_str, const uint8_t *mac_addr, uint32_t uuid_num, EtcPalUuid *uuid)
Generate a UUID from a combination of a custom string and MAC address.
Definition: uuid.c:309
etcpal_error_t etcpal_generate_v4_uuid(EtcPalUuid *uuid)
Generate a Version 4 UUID.
Definition: uuid.c:216
#define ETCPAL_UUID_IS_NULL(uuidptr)
Determine if a UUID is null.
Definition: uuid.h:118
bool etcpal_uuid_to_string(const EtcPalUuid *uuid, char *buf)
Create a string representation of a UUID.
Definition: uuid.c:61
etcpal_error_t etcpal_generate_v1_uuid(EtcPalUuid *uuid)
Generate a Version 1 UUID.
Definition: uuid.c:152
bool etcpal_string_to_uuid(const char *str, EtcPalUuid *uuid)
Create a UUID from a string representation.
Definition: uuid.c:85
#define ETCPAL_UUID_STRING_BYTES
The maximum number of bytes required to hold an ASCII string representation of a UUID.
Definition: uuid.h:121
etcpal_error_t etcpal_generate_os_preferred_uuid(EtcPalUuid *uuid)
Generate the preferred UUID version of the underlying OS.
Definition: uuid.c:282
etcpal_error_t etcpal_generate_v5_uuid(const EtcPalUuid *ns, const void *name, size_t name_len, EtcPalUuid *uuid)
Generate a Version 5 UUID.
Definition: uuid.c:243
etcpal_error_t etcpal_generate_v3_uuid(const EtcPalUuid *ns, const void *name, size_t name_len, EtcPalUuid *uuid)
Generate a Version 3 UUID.
Definition: uuid.c:178
#define ETCPAL_UUID_BYTES
The number of bytes that make up a UUID.
Definition: uuid.h:89
const EtcPalUuid kEtcPalNullUuid
A null (all 0's) UUID, used by ETCPAL_UUID_IS_NULL() for comparison.
Definition: uuid.c:46
The UUID type.
Definition: uuid.h:93
uint8_t data[ETCPAL_UUID_BYTES]
The 16-byte UUID data.
Definition: uuid.h:94