Pigweed
C/C++ API Reference
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
uuid.h
1// Copyright 2025 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://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, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15#pragma once
16
17#include <algorithm>
18#include <array>
19#include <cstdint>
20#include <string_view>
21
22#include "pw_assert/assert.h"
23#include "pw_bytes/span.h"
24#include "pw_result/result.h"
25#include "pw_status/status.h"
26#include "pw_string/hex.h"
27#include "pw_string/string.h"
28
29namespace pw::uuid {
30
32class Uuid {
33 public:
35 static constexpr size_t kSizeBytes = 16;
37 static constexpr size_t kStringSize =
38 std::string_view{"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}.size();
39
43 static constexpr Result<Uuid> FromSpan(span<const uint8_t> span) {
44 Status status = ValidateSpan(span);
45 if (!status.ok()) {
46 return status;
47 }
48 return Uuid(span);
49 }
50
54 static Result<Uuid> FromSpan(ConstByteSpan span) {
55 return FromSpan(
56 {reinterpret_cast<const uint8_t*>(span.data()), span.size()});
57 }
58
62 static constexpr Result<Uuid> FromString(std::string_view string) {
63 Status status = ValidateString(string);
64 if (!status.ok()) {
65 return status;
66 }
67 return Uuid(string);
68 }
69
71 constexpr pw::span<const uint8_t, kSizeBytes> GetSpan() const {
72 return uuid_;
73 }
74
75 constexpr bool operator==(const Uuid& other) const {
76 for (size_t i = 0; i < kSizeBytes; i++) {
77 if (uuid_[i] != other.uuid_[i]) {
78 return false;
79 }
80 }
81 return true;
82 }
83
84 constexpr bool operator!=(const Uuid& other) const {
85 return !(*this == other);
86 }
87
91
92 for (size_t i = uuid_.size(); i-- != 0;) {
93 out += string::NibbleToHex(uuid_[i] >> 4);
94 out += string::NibbleToHex(uuid_[i] & 0xf);
95 if ((i == 12) || (i == 10) || (i == 8) || (i == 6)) {
96 out += '-';
97 }
98 }
99 return out;
100 }
101
102 // Default constructor initializes the uuid to the Nil UUID
103 constexpr explicit Uuid() : uuid_() {}
104
105 private:
109 constexpr explicit Uuid(span<const uint8_t> span) : uuid_() {
110 PW_ASSERT(span.size() == uuid_.size());
111 for (size_t i = 0; i < uuid_.size(); i++) {
112 uuid_[i] = span[i];
113 }
114 }
115
119 constexpr explicit Uuid(std::string_view uuid_str) : uuid_() {
120 size_t out_hex_index = 2 * uuid_.size(); // UUID is stored little-endian.
121 for (size_t i = 0; i < kStringSize; i++) {
122 // Indices at which we expect to find a hyphen ('-') in a UUID string.
123 if (i == 8 || i == 13 || i == 18 || i == 23) {
124 PW_ASSERT(uuid_str[i] == '-');
125 continue;
126 }
127 PW_ASSERT(uuid_str[i] != '\0');
128
129 out_hex_index--;
130 uint16_t value = string::HexToNibble(uuid_str[i]);
131 PW_ASSERT(value <= 0xf);
132 if (out_hex_index % 2 == 0) {
133 uuid_[out_hex_index / 2] |= static_cast<uint8_t>(value);
134 } else {
135 uuid_[out_hex_index / 2] = static_cast<uint8_t>(value << 4);
136 }
137 }
138 }
139
149 static constexpr Status ValidateString(std::string_view uuid_str) {
150 if (kStringSize != uuid_str.size()) {
151 return Status::FailedPrecondition();
152 }
153 for (size_t i = 0; i < uuid_str.size(); i++) {
154 if (i == 8 || i == 13 || i == 18 || i == 23) {
155 if (uuid_str[i] != '-') {
156 return Status::InvalidArgument();
157 }
158 continue;
159 }
160 if (string::IsHexDigit(uuid_str[i]) == 0) {
161 return Status::InvalidArgument();
162 }
163 }
164 return OkStatus();
165 }
166
175 static constexpr Status ValidateSpan(span<const uint8_t> span) {
176 if (span.size() != kSizeBytes) {
177 return Status::FailedPrecondition();
178 }
179 return OkStatus();
180 }
181
182 std::array<uint8_t, kSizeBytes> uuid_;
183};
184
185} // namespace pw::uuid
pw::InlineBasicString is a fixed-capacity version of std::basic_string. In brief:
Definition: string.h:66
Definition: status.h:85
constexpr bool ok() const
Definition: status.h:157
Represents a 128-bit universally unique identifier (UUID).
Definition: uuid.h:32
static constexpr size_t kSizeBytes
Size of the UUID in bytes.
Definition: uuid.h:35
static Result< Uuid > FromSpan(ConstByteSpan span)
Definition: uuid.h:54
constexpr pw::span< const uint8_t, kSizeBytes > GetSpan() const
Return the backing span holding the uuid.
Definition: uuid.h:71
static constexpr Result< Uuid > FromString(std::string_view string)
Definition: uuid.h:62
static constexpr Result< Uuid > FromSpan(span< const uint8_t > span)
Definition: uuid.h:43
constexpr InlineString< kStringSize > ToString() const
Convert the Uuid to a human readable string.
Definition: uuid.h:89
static constexpr size_t kStringSize
Length of the UUID's string representation.
Definition: uuid.h:37
constexpr Status OkStatus()
Definition: status.h:234
pw::InlineBasicString and pw::InlineString are safer alternatives to std::basic_string and std::strin...