blob: 1e5d781dfc571ee12e16ab9eb23c5aef78485454 [file] [log] [blame]
Austin Schuh64fab802020-09-09 22:47:47 -07001#ifndef AOS_EVENTS_LOGGING_UUID_H_
2#define AOS_EVENTS_LOGGING_UUID_H_
3
4#include <array>
Austin Schuh5e2bfb82021-03-13 22:46:55 -08005#include <ostream>
James Kuszmaula791b762023-07-13 14:56:21 -07006#include <random>
Austin Schuh5e2bfb82021-03-13 22:46:55 -08007#include <string>
8
Austin Schuh99f7c6a2024-06-25 22:07:44 -07009#include "absl/log/check.h"
10#include "absl/log/log.h"
Austin Schuh5e2bfb82021-03-13 22:46:55 -080011#include "absl/types/span.h"
12#include "flatbuffers/flatbuffers.h"
Austin Schuh64fab802020-09-09 22:47:47 -070013
14namespace aos {
15
16// Class to generate and hold a UUID.
17class UUID {
18 public:
Austin Schuh5e2bfb82021-03-13 22:46:55 -080019 // Size of a UUID both as a string and the raw data.
20 static constexpr size_t kStringSize = 36;
21 static constexpr size_t kDataSize = 16;
22
Austin Schuh64fab802020-09-09 22:47:47 -070023 // Returns a randomly generated UUID. This is known as a UUID4.
James Kuszmaula791b762023-07-13 14:56:21 -070024 // The first Random() call in a thread will tend to be slightly slower than
25 // the rest so that it can seed the pseudo-random number generator used
26 // internally.
Austin Schuh64fab802020-09-09 22:47:47 -070027 static UUID Random();
28
Austin Schuh5e2bfb82021-03-13 22:46:55 -080029 // Returns a uuid with all '0's.
Austin Schuh81d0fe42022-08-17 16:29:23 -070030 static constexpr UUID Zero() {
31 UUID result;
32 std::memset(result.data_.data(), 0, result.data_.size());
33 return result;
34 }
Brian Silverman1f345222020-09-24 21:14:48 -070035
Austin Schuh5e2bfb82021-03-13 22:46:55 -080036 // Converts a string UUID of the form 00000000-0000-0000-0000-000000000000 to
37 // a UUID.
38 static UUID FromString(std::string_view string);
39 static UUID FromString(const flatbuffers::String *string);
Austin Schuh20ac95d2020-12-05 17:24:19 -080040
Austin Schuh5e2bfb82021-03-13 22:46:55 -080041 // Converts a 16 byte vector (128 bits) to a UUID. This requires no
42 // transformation.
43 static UUID FromVector(const flatbuffers::Vector<uint8_t> *data);
44
Alexei Strots72060d62022-10-10 19:23:53 -070045 // Initializes new UUID from data.
46 static UUID FromSpan(absl::Span<const uint8_t> data);
47
Austin Schuh5e2bfb82021-03-13 22:46:55 -080048 // Returns the boot UUID for the current linux computer.
Austin Schuh20ac95d2020-12-05 17:24:19 -080049 static UUID BootUUID();
50
Austin Schuh5e2bfb82021-03-13 22:46:55 -080051 // Default constructor which builds an uninitialized UUID. Use one of the
52 // static methods if you want something more useful.
Austin Schuh81d0fe42022-08-17 16:29:23 -070053 constexpr UUID() : data_() {}
Brian Silverman25969762022-08-24 19:54:00 -070054 constexpr UUID(const UUID &uuid) = default;
Austin Schuh81d0fe42022-08-17 16:29:23 -070055
Brian Silverman25969762022-08-24 19:54:00 -070056 constexpr UUID &operator=(const UUID &other) = default;
Austin Schuh20ac95d2020-12-05 17:24:19 -080057
Austin Schuh5e2bfb82021-03-13 22:46:55 -080058 // Packs this UUID into a flatbuffer as a string.
59 flatbuffers::Offset<flatbuffers::String> PackString(
60 flatbuffers::FlatBufferBuilder *fbb) const;
61 // Copies this UUID as a string into the memory pointed by result. Result
62 // must be at least kStringSize long.
63 void CopyTo(char *result) const;
64 // Returns this UUID as a string.
65 std::string ToString() const;
66
67 // Packs the UUID bytes directly into a vector.
68 flatbuffers::Offset<flatbuffers::Vector<uint8_t>> PackVector(
69 flatbuffers::FlatBufferBuilder *fbb) const;
70
James Kuszmaul55844a72023-12-20 11:57:01 -080071 template <typename T>
72 void PackStaticVector(T *static_vector) const {
73 CHECK(static_vector->FromData(data_.data(), data_.size()));
74 }
75
Austin Schuh81d0fe42022-08-17 16:29:23 -070076 // Returns a human-readable string representing this UUID.
77 //
78 // This is done without any memory allocation, which means it's returned in a
79 // thread-local buffer.
80 //
81 // Be careful using this. It's mostly useful for low-level tracing of UUIDs
82 // through the system.
83 const char *thread_local_string() const {
Austin Schuhf7bfb652023-08-25 14:22:50 -070084 thread_local char buffer[kStringSize + 1];
Austin Schuh81d0fe42022-08-17 16:29:23 -070085 CopyTo(buffer);
86 return buffer;
87 }
88
Austin Schuh5e2bfb82021-03-13 22:46:55 -080089 // Returns the underlying UUID data.
90 absl::Span<const uint8_t> span() const {
91 return absl::Span<const uint8_t>(data_.data(), data_.size());
Austin Schuh64fab802020-09-09 22:47:47 -070092 }
93
Austin Schuh4385b142021-03-14 21:31:13 -070094 bool operator==(const UUID &other) const { return other.span() == span(); }
Austin Schuh58646e22021-08-23 23:51:46 -070095 bool operator<(const UUID &other) const { return other.span() < span(); }
Austin Schuh4385b142021-03-14 21:31:13 -070096 bool operator!=(const UUID &other) const { return other.span() != span(); }
Austin Schuh64fab802020-09-09 22:47:47 -070097
98 private:
Austin Schuh5e2bfb82021-03-13 22:46:55 -080099 friend std::ostream &operator<<(std::ostream &os, const UUID &uuid);
Austin Schuh64fab802020-09-09 22:47:47 -0700100
Austin Schuh5e2bfb82021-03-13 22:46:55 -0800101 // Encoded storage for the data.
102 std::array<uint8_t, kDataSize> data_;
Austin Schuh64fab802020-09-09 22:47:47 -0700103};
104
Austin Schuh5e2bfb82021-03-13 22:46:55 -0800105std::ostream &operator<<(std::ostream &os, const UUID &uuid);
106
James Kuszmaula791b762023-07-13 14:56:21 -0700107namespace internal {
108// Initializes a mt19937 with as much entropy as it can take (rather than just a
109// 32-bit value from std::random_device).
110// Exposed for testing purposes.
111std::mt19937 FullySeededRandomGenerator();
112} // namespace internal
113
Austin Schuh64fab802020-09-09 22:47:47 -0700114} // namespace aos
115
116#endif // AOS_EVENTS_LOGGING_UUID_H_