C/C++ API Reference
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
30namespace pw::uuid {
31
33
35class Uuid {
36 public:
38 static constexpr size_t kSizeBytes = 16;
40 static constexpr size_t kStringSize =
41 std::string_view{"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}.size();
42
47 Status status = ValidateSpan(span);
48 if (!status.ok()) {
49 return status;
50 }
51 return Uuid(span);
52 }
53
58 return FromSpan(
59 {reinterpret_cast<const uint8_t*>(span.data()), span.size()});
60 }
61
65 static constexpr Result<Uuid> FromString(std::string_view string) {
66 Status status = ValidateString(string);
67 if (!status.ok()) {
68 return status;
69 }
70 return Uuid(string);
71 }
72
75 return uuid_;
76 }
77
78 constexpr bool operator==(const Uuid& other) const {
79 for (size_t i = 0; i < kSizeBytes; i++) {
80 if (uuid_[i] != other.uuid_[i]) {
81 return false;
82 }
83 }
84 return true;
85 }
86
87 constexpr bool operator!=(const Uuid& other) const {
88 return !(*this == other);
89 }
90
94
95 for (size_t i = uuid_.size(); i-- != 0;) {
96 out += string::NibbleToHex(uuid_[i] >> 4);
97 out += string::NibbleToHex(uuid_[i] & 0xf);
98 if ((i == 12) || (i == 10) || (i == 8) || (i == 6)) {
99 out += '-';
100 }
101 }
102 return out;
103 }
104
105 // Default constructor initializes the uuid to the Nil UUID
106 constexpr explicit Uuid() : uuid_() {}
107
108 private:
112 constexpr explicit Uuid(span<const uint8_t> span) : uuid_() {
113 PW_ASSERT(span.size() == uuid_.size());
114 for (size_t i = 0; i < uuid_.size(); i++) {
115 uuid_[i] = span[i];
116 }
117 }
118
122 constexpr explicit Uuid(std::string_view uuid_str) : uuid_() {
123 size_t out_hex_index = 2 * uuid_.size(); // UUID is stored little-endian.
124 for (size_t i = 0; i < kStringSize; i++) {
125 // Indices at which we expect to find a hyphen ('-') in a UUID string.
126 if (i == 8 || i == 13 || i == 18 || i == 23) {
127 PW_ASSERT(uuid_str[i] == '-');
128 continue;
129 }
130 PW_ASSERT(uuid_str[i] != '\0');
131
132 out_hex_index--;
133 uint16_t value = string::HexToNibble(uuid_str[i]);
134 PW_ASSERT(value <= 0xf);
135 if (out_hex_index % 2 == 0) {
136 uuid_[out_hex_index / 2] |= static_cast<uint8_t>(value);
137 } else {
138 uuid_[out_hex_index / 2] = static_cast<uint8_t>(value << 4);
139 }
140 }
141 }
142
152 static constexpr Status ValidateString(std::string_view uuid_str) {
153 if (kStringSize != uuid_str.size()) {
155 }
156 for (size_t i = 0; i < uuid_str.size(); i++) {
157 if (i == 8 || i == 13 || i == 18 || i == 23) {
158 if (uuid_str[i] != '-') {
160 }
161 continue;
162 }
163 if (string::IsHexDigit(uuid_str[i]) == 0) {
165 }
166 }
167 return OkStatus();
168 }
169
178 static constexpr Status ValidateSpan(span<const uint8_t> span) {
179 if (span.size() != kSizeBytes) {
181 }
182 return OkStatus();
183 }
184
185 std::array<uint8_t, kSizeBytes> uuid_;
186};
187
188} // namespace pw::uuid
pw::InlineBasicString is a fixed-capacity version of std::basic_string. In brief:
Definition: string.h:68
Definition: poll.h:25
Definition: status.h:109
static constexpr Status InvalidArgument()
Argument was malformed; e.g. invalid characters when parsing integer.
Definition: status.h:131
constexpr bool ok() const
Definition: status.h:214
static constexpr Status FailedPrecondition()
System isn’t in the required state; e.g. deleting a non-empty directory.
Definition: status.h:162
Definition: span_impl.h:235
Represents a 128-bit universally unique identifier (UUID).
Definition: uuid.h:35
constexpr Status OkStatus()
Definition: status.h:297
static constexpr size_t kSizeBytes
Size of the UUID in bytes.
Definition: uuid.h:38
static Result< Uuid > FromSpan(ConstByteSpan span)
Definition: uuid.h:57
constexpr pw::span< const uint8_t, kSizeBytes > GetSpan() const
Return the backing span holding the uuid.
Definition: uuid.h:74
static constexpr Result< Uuid > FromString(std::string_view string)
Definition: uuid.h:65
static constexpr Result< Uuid > FromSpan(span< const uint8_t > span)
Definition: uuid.h:46
constexpr InlineString< kStringSize > ToString() const
Convert the Uuid to a human readable string.
Definition: uuid.h:92
static constexpr size_t kStringSize
Length of the UUID's string representation.
Definition: uuid.h:40
128-bit universally unique identifier library
Definition: uuid.h:30
pw::InlineBasicString and pw::InlineString are safer alternatives to std::basic_string and std::strin...