blob: 1e5d781dfc571ee12e16ab9eb23c5aef78485454 [file] [log] [blame]
#ifndef AOS_EVENTS_LOGGING_UUID_H_
#define AOS_EVENTS_LOGGING_UUID_H_
#include <array>
#include <ostream>
#include <random>
#include <string>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/types/span.h"
#include "flatbuffers/flatbuffers.h"
namespace aos {
// Class to generate and hold a UUID.
class UUID {
public:
// Size of a UUID both as a string and the raw data.
static constexpr size_t kStringSize = 36;
static constexpr size_t kDataSize = 16;
// Returns a randomly generated UUID. This is known as a UUID4.
// The first Random() call in a thread will tend to be slightly slower than
// the rest so that it can seed the pseudo-random number generator used
// internally.
static UUID Random();
// Returns a uuid with all '0's.
static constexpr UUID Zero() {
UUID result;
std::memset(result.data_.data(), 0, result.data_.size());
return result;
}
// Converts a string UUID of the form 00000000-0000-0000-0000-000000000000 to
// a UUID.
static UUID FromString(std::string_view string);
static UUID FromString(const flatbuffers::String *string);
// Converts a 16 byte vector (128 bits) to a UUID. This requires no
// transformation.
static UUID FromVector(const flatbuffers::Vector<uint8_t> *data);
// Initializes new UUID from data.
static UUID FromSpan(absl::Span<const uint8_t> data);
// Returns the boot UUID for the current linux computer.
static UUID BootUUID();
// Default constructor which builds an uninitialized UUID. Use one of the
// static methods if you want something more useful.
constexpr UUID() : data_() {}
constexpr UUID(const UUID &uuid) = default;
constexpr UUID &operator=(const UUID &other) = default;
// Packs this UUID into a flatbuffer as a string.
flatbuffers::Offset<flatbuffers::String> PackString(
flatbuffers::FlatBufferBuilder *fbb) const;
// Copies this UUID as a string into the memory pointed by result. Result
// must be at least kStringSize long.
void CopyTo(char *result) const;
// Returns this UUID as a string.
std::string ToString() const;
// Packs the UUID bytes directly into a vector.
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> PackVector(
flatbuffers::FlatBufferBuilder *fbb) const;
template <typename T>
void PackStaticVector(T *static_vector) const {
CHECK(static_vector->FromData(data_.data(), data_.size()));
}
// Returns a human-readable string representing this UUID.
//
// This is done without any memory allocation, which means it's returned in a
// thread-local buffer.
//
// Be careful using this. It's mostly useful for low-level tracing of UUIDs
// through the system.
const char *thread_local_string() const {
thread_local char buffer[kStringSize + 1];
CopyTo(buffer);
return buffer;
}
// Returns the underlying UUID data.
absl::Span<const uint8_t> span() const {
return absl::Span<const uint8_t>(data_.data(), data_.size());
}
bool operator==(const UUID &other) const { return other.span() == span(); }
bool operator<(const UUID &other) const { return other.span() < span(); }
bool operator!=(const UUID &other) const { return other.span() != span(); }
private:
friend std::ostream &operator<<(std::ostream &os, const UUID &uuid);
// Encoded storage for the data.
std::array<uint8_t, kDataSize> data_;
};
std::ostream &operator<<(std::ostream &os, const UUID &uuid);
namespace internal {
// Initializes a mt19937 with as much entropy as it can take (rather than just a
// 32-bit value from std::random_device).
// Exposed for testing purposes.
std::mt19937 FullySeededRandomGenerator();
} // namespace internal
} // namespace aos
#endif // AOS_EVENTS_LOGGING_UUID_H_