LLDB mainline
UUID.cpp
Go to the documentation of this file.
1//===-- UUID.cpp ----------------------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Utility/UUID.h"
10
11#include "lldb/Utility/Stream.h"
12#include "llvm/ADT/StringRef.h"
13#include "llvm/Support/Format.h"
14#include "llvm/Support/RandomNumberGenerator.h"
15
16#include <cctype>
17#include <chrono>
18#include <climits>
19#include <cstdint>
20#include <cstdio>
21#include <cstring>
22#include <random>
23
24using namespace lldb_private;
25
26// Whether to put a separator after count uuid bytes.
27// For the first 16 bytes we follow the traditional UUID format. After that, we
28// simply put a dash after every 6 bytes.
29static inline bool separate(size_t count) {
30 if (count >= 10)
31 return (count - 10) % 6 == 0;
32
33 switch (count) {
34 case 4:
35 case 6:
36 case 8:
37 return true;
38 default:
39 return false;
40 }
41}
42
44 llvm::sys::swapByteOrder(debug_info.Uuid.Data1);
45 llvm::sys::swapByteOrder(debug_info.Uuid.Data2);
46 llvm::sys::swapByteOrder(debug_info.Uuid.Data3);
47 llvm::sys::swapByteOrder(debug_info.Age);
48 if (debug_info.Age)
49 *this = UUID(&debug_info, sizeof(debug_info));
50 else
51 *this = UUID(&debug_info.Uuid, sizeof(debug_info.Uuid));
52}
53
54std::string UUID::GetAsString(llvm::StringRef separator) const {
55 std::string result;
56 llvm::raw_string_ostream os(result);
57
58 for (auto B : llvm::enumerate(GetBytes())) {
59 if (separate(B.index()))
60 os << separator;
61
62 os << llvm::format_hex_no_prefix(B.value(), 2, true);
63 }
64
65 return result;
66}
67
68void UUID::Dump(Stream &s) const { s.PutCString(GetAsString()); }
69
70static inline int xdigit_to_int(char ch) {
71 ch = tolower(ch);
72 if (ch >= 'a' && ch <= 'f')
73 return 10 + ch - 'a';
74 return ch - '0';
75}
76
77llvm::StringRef
80 uuid_bytes.clear();
81 while (p.size() >= 2) {
82 if (isxdigit(p[0]) && isxdigit(p[1])) {
83 int hi_nibble = xdigit_to_int(p[0]);
84 int lo_nibble = xdigit_to_int(p[1]);
85 // Translate the two hex nibble characters into a byte
86 uuid_bytes.push_back((hi_nibble << 4) + lo_nibble);
87
88 // Skip both hex digits
89 p = p.drop_front(2);
90 } else if (p.front() == '-') {
91 // Skip dashes
92 p = p.drop_front();
93 } else {
94 // UUID values can only consist of hex characters and '-' chars
95 break;
96 }
97 }
98 return p;
99}
100
101bool UUID::SetFromStringRef(llvm::StringRef str) {
102 llvm::StringRef p = str;
103
104 // Skip leading whitespace characters
105 p = p.ltrim();
106
107 llvm::SmallVector<uint8_t, 20> bytes;
108 llvm::StringRef rest = UUID::DecodeUUIDBytesFromString(p, bytes);
109
110 // Return false if we could not consume the entire string or if the parsed
111 // UUID is empty.
112 if (!rest.empty() || bytes.empty())
113 return false;
114
115 *this = UUID(bytes);
116 return true;
117}
118
119UUID UUID::Generate(uint32_t num_bytes) {
120 llvm::SmallVector<uint8_t, 20> bytes(num_bytes);
121 auto ec = llvm::getRandomBytes(bytes.data(), bytes.size());
122
123 // If getRandomBytes failed, fall back to a lower entropy source.
124 if (ec) {
125 auto seed = std::chrono::steady_clock::now().time_since_epoch().count();
126 std::independent_bits_engine<std::default_random_engine, CHAR_BIT,
127 unsigned short>
128 engine(seed);
129 std::generate(bytes.begin(), bytes.end(), std::ref(engine));
130 }
131
132 return UUID(bytes);
133}
static bool separate(size_t count)
Definition UUID.cpp:29
static int xdigit_to_int(char ch)
Definition UUID.cpp:70
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:65
bool SetFromStringRef(llvm::StringRef str)
Definition UUID.cpp:101
void Dump(Stream &s) const
Definition UUID.cpp:68
llvm::ArrayRef< uint8_t > GetBytes() const
Definition UUID.h:66
static UUID Generate(uint32_t num_bytes=16)
Create a random UUID.
Definition UUID.cpp:119
std::string GetAsString(llvm::StringRef separator="-") const
Definition UUID.cpp:54
static llvm::StringRef DecodeUUIDBytesFromString(llvm::StringRef str, llvm::SmallVectorImpl< uint8_t > &uuid_bytes)
Decode as many UUID bytes as possible from the C string cstr.
Definition UUID.cpp:78
A class that represents a running process on the host machine.
llvm::support::ulittle16_t Data2
Definition UUID.h:43
llvm::support::ulittle32_t Data1
Definition UUID.h:42
llvm::support::ulittle16_t Data3
Definition UUID.h:44
struct lldb_private::UUID::CvRecordPdb70::@031031370151201011001273071037042037235035311007 Uuid
llvm::support::ulittle32_t Age
Definition UUID.h:47