1 //===-- UUID.cpp ------------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Utility/UUID.h"
12 // Other libraries and framework includes
14 #include "lldb/Utility/Stream.h"
15 #include "llvm/ADT/StringRef.h"
22 namespace lldb_private {
24 UUID::UUID() : m_num_uuid_bytes(16) { ::memset(m_uuid, 0, sizeof(m_uuid)); }
26 UUID::UUID(const UUID &rhs) {
27 m_num_uuid_bytes = rhs.m_num_uuid_bytes;
28 ::memcpy(m_uuid, rhs.m_uuid, sizeof(m_uuid));
31 UUID::UUID(const void *uuid_bytes, uint32_t num_uuid_bytes) {
32 SetBytes(uuid_bytes, num_uuid_bytes);
35 const UUID &UUID::operator=(const UUID &rhs) {
37 m_num_uuid_bytes = rhs.m_num_uuid_bytes;
38 ::memcpy(m_uuid, rhs.m_uuid, sizeof(m_uuid));
46 m_num_uuid_bytes = 16;
47 ::memset(m_uuid, 0, sizeof(m_uuid));
50 const void *UUID::GetBytes() const { return m_uuid; }
52 std::string UUID::GetAsString(const char *separator) const {
57 const uint8_t *u = (const uint8_t *)GetBytes();
59 (size_t)snprintf(buf, sizeof(buf), "%2.2X%2.2X%2.2X%2.2X%s%2.2X%2.2X%s%2."
60 "2X%2.2X%s%2.2X%2.2X%s%2.2X%2.2X%2.2X%"
62 u[0], u[1], u[2], u[3], separator, u[4], u[5], separator,
63 u[6], u[7], separator, u[8], u[9], separator, u[10],
64 u[11], u[12], u[13], u[14], u[15])) {
66 if (m_num_uuid_bytes == 20) {
67 if (sizeof(buf) > (size_t)snprintf(buf, sizeof(buf),
68 "%s%2.2X%2.2X%2.2X%2.2X", separator,
69 u[16], u[17], u[18], u[19]))
76 void UUID::Dump(Stream *s) const {
77 const uint8_t *u = (const uint8_t *)GetBytes();
78 s->Printf("%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%"
79 "2.2X%2.2X%2.2X%2.2X",
80 u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], u[9], u[10],
81 u[11], u[12], u[13], u[14], u[15]);
82 if (m_num_uuid_bytes == 20) {
83 s->Printf("-%2.2X%2.2X%2.2X%2.2X", u[16], u[17], u[18], u[19]);
87 bool UUID::SetBytes(const void *uuid_bytes, uint32_t num_uuid_bytes) {
89 switch (num_uuid_bytes) {
91 m_num_uuid_bytes = 20;
94 m_num_uuid_bytes = 16;
95 m_uuid[16] = m_uuid[17] = m_uuid[18] = m_uuid[19] = 0;
98 // Unsupported UUID byte size
103 if (m_num_uuid_bytes > 0) {
104 ::memcpy(m_uuid, uuid_bytes, m_num_uuid_bytes);
108 ::memset(m_uuid, 0, sizeof(m_uuid));
112 size_t UUID::GetByteSize() { return m_num_uuid_bytes; }
114 bool UUID::IsValid() const {
115 return m_uuid[0] || m_uuid[1] || m_uuid[2] || m_uuid[3] || m_uuid[4] ||
116 m_uuid[5] || m_uuid[6] || m_uuid[7] || m_uuid[8] || m_uuid[9] ||
117 m_uuid[10] || m_uuid[11] || m_uuid[12] || m_uuid[13] || m_uuid[14] ||
118 m_uuid[15] || m_uuid[16] || m_uuid[17] || m_uuid[18] || m_uuid[19];
121 static inline int xdigit_to_int(char ch) {
123 if (ch >= 'a' && ch <= 'f')
124 return 10 + ch - 'a';
128 llvm::StringRef UUID::DecodeUUIDBytesFromString(llvm::StringRef p,
129 ValueType &uuid_bytes,
130 uint32_t &bytes_decoded,
131 uint32_t num_uuid_bytes) {
132 ::memset(uuid_bytes, 0, sizeof(uuid_bytes));
133 size_t uuid_byte_idx = 0;
135 if (isxdigit(p[0]) && isxdigit(p[1])) {
136 int hi_nibble = xdigit_to_int(p[0]);
137 int lo_nibble = xdigit_to_int(p[1]);
138 // Translate the two hex nibble characters into a byte
139 uuid_bytes[uuid_byte_idx] = (hi_nibble << 4) + lo_nibble;
141 // Skip both hex digits
144 // Increment the byte that we are decoding within the UUID value
145 // and break out if we are done
146 if (++uuid_byte_idx == num_uuid_bytes)
148 } else if (p.front() == '-') {
152 // UUID values can only consist of hex characters and '-' chars
157 // Clear trailing bytes to 0.
158 for (uint32_t i = uuid_byte_idx; i < sizeof(ValueType); i++)
160 bytes_decoded = uuid_byte_idx;
164 size_t UUID::SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes) {
165 llvm::StringRef p = str;
167 // Skip leading whitespace characters
170 uint32_t bytes_decoded = 0;
171 llvm::StringRef rest =
172 UUID::DecodeUUIDBytesFromString(p, m_uuid, bytes_decoded, num_uuid_bytes);
174 // If we successfully decoded a UUID, return the amount of characters that
176 if (bytes_decoded == num_uuid_bytes) {
177 m_num_uuid_bytes = num_uuid_bytes;
178 return str.size() - rest.size();
181 // Else return zero to indicate we were not able to parse a UUID value
185 size_t UUID::SetFromCString(const char *cstr, uint32_t num_uuid_bytes) {
189 return SetFromStringRef(cstr, num_uuid_bytes);
193 bool lldb_private::operator==(const lldb_private::UUID &lhs,
194 const lldb_private::UUID &rhs) {
195 return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
196 sizeof(lldb_private::UUID::ValueType)) == 0;
199 bool lldb_private::operator!=(const lldb_private::UUID &lhs,
200 const lldb_private::UUID &rhs) {
201 return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
202 sizeof(lldb_private::UUID::ValueType)) != 0;
205 bool lldb_private::operator<(const lldb_private::UUID &lhs,
206 const lldb_private::UUID &rhs) {
207 return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
208 sizeof(lldb_private::UUID::ValueType)) < 0;
211 bool lldb_private::operator<=(const lldb_private::UUID &lhs,
212 const lldb_private::UUID &rhs) {
213 return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
214 sizeof(lldb_private::UUID::ValueType)) <= 0;
217 bool lldb_private::operator>(const lldb_private::UUID &lhs,
218 const lldb_private::UUID &rhs) {
219 return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
220 sizeof(lldb_private::UUID::ValueType)) > 0;
223 bool lldb_private::operator>=(const lldb_private::UUID &lhs,
224 const lldb_private::UUID &rhs) {
225 return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
226 sizeof(lldb_private::UUID::ValueType)) >= 0;