1 //===-- UUID.cpp ------------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Utility/UUID.h"
11 #include "lldb/Utility/Stream.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/Support/Format.h"
19 using namespace lldb_private;
21 // Whether to put a separator after count uuid bytes.
22 // For the first 16 bytes we follow the traditional UUID format. After that, we
23 // simply put a dash after every 6 bytes.
24 static inline bool separate(size_t count) {
26 return (count - 10) % 6 == 0;
38 std::string UUID::GetAsString(llvm::StringRef separator) const {
40 llvm::raw_string_ostream os(result);
42 for (auto B : llvm::enumerate(GetBytes())) {
43 if (separate(B.index()))
46 os << llvm::format_hex_no_prefix(B.value(), 2, true);
53 void UUID::Dump(Stream *s) const { s->PutCString(GetAsString()); }
55 static inline int xdigit_to_int(char ch) {
57 if (ch >= 'a' && ch <= 'f')
63 UUID::DecodeUUIDBytesFromString(llvm::StringRef p,
64 llvm::SmallVectorImpl<uint8_t> &uuid_bytes,
65 uint32_t num_uuid_bytes) {
68 if (isxdigit(p[0]) && isxdigit(p[1])) {
69 int hi_nibble = xdigit_to_int(p[0]);
70 int lo_nibble = xdigit_to_int(p[1]);
71 // Translate the two hex nibble characters into a byte
72 uuid_bytes.push_back((hi_nibble << 4) + lo_nibble);
74 // Skip both hex digits
77 // Increment the byte that we are decoding within the UUID value and
78 // break out if we are done
79 if (uuid_bytes.size() == num_uuid_bytes)
81 } else if (p.front() == '-') {
85 // UUID values can only consist of hex characters and '-' chars
92 size_t UUID::SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes) {
93 llvm::StringRef p = str;
95 // Skip leading whitespace characters
98 llvm::SmallVector<uint8_t, 20> bytes;
99 llvm::StringRef rest =
100 UUID::DecodeUUIDBytesFromString(p, bytes, num_uuid_bytes);
102 // If we successfully decoded a UUID, return the amount of characters that
104 if (bytes.size() == num_uuid_bytes) {
105 *this = fromData(bytes);
106 return str.size() - rest.size();
109 // Else return zero to indicate we were not able to parse a UUID value
113 size_t UUID::SetFromOptionalStringRef(llvm::StringRef str,
114 uint32_t num_uuid_bytes) {
115 size_t num_chars_consumed = SetFromStringRef(str, num_uuid_bytes);
116 if (num_chars_consumed) {
117 if (llvm::all_of(m_bytes, [](uint8_t b) { return b == 0; }))
121 return num_chars_consumed;