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 
15 #include <ctype.h>
16 #include <stdio.h>
17 #include <string.h>
18 
19 using namespace lldb_private;
20 
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) {
25  if (count >= 10)
26  return (count - 10) % 6 == 0;
27 
28  switch (count) {
29  case 4:
30  case 6:
31  case 8:
32  return true;
33  default:
34  return false;
35  }
36 }
37 
39  llvm::sys::swapByteOrder(debug_info.Uuid.Data1);
40  llvm::sys::swapByteOrder(debug_info.Uuid.Data2);
41  llvm::sys::swapByteOrder(debug_info.Uuid.Data3);
42  llvm::sys::swapByteOrder(debug_info.Age);
43  if (debug_info.Age)
44  return UUID::fromOptionalData(&debug_info, sizeof(debug_info));
45  return UUID::fromOptionalData(&debug_info.Uuid, sizeof(debug_info.Uuid));
46 }
47 
48 std::string UUID::GetAsString(llvm::StringRef separator) const {
49  std::string result;
50  llvm::raw_string_ostream os(result);
51 
52  for (auto B : llvm::enumerate(GetBytes())) {
53  if (separate(B.index()))
54  os << separator;
55 
56  os << llvm::format_hex_no_prefix(B.value(), 2, true);
57  }
58  os.flush();
59 
60  return result;
61 }
62 
63 void UUID::Dump(Stream *s) const { s->PutCString(GetAsString()); }
64 
65 static inline int xdigit_to_int(char ch) {
66  ch = tolower(ch);
67  if (ch >= 'a' && ch <= 'f')
68  return 10 + ch - 'a';
69  return ch - '0';
70 }
71 
72 llvm::StringRef
74  llvm::SmallVectorImpl<uint8_t> &uuid_bytes) {
75  uuid_bytes.clear();
76  while (p.size() >= 2) {
77  if (isxdigit(p[0]) && isxdigit(p[1])) {
78  int hi_nibble = xdigit_to_int(p[0]);
79  int lo_nibble = xdigit_to_int(p[1]);
80  // Translate the two hex nibble characters into a byte
81  uuid_bytes.push_back((hi_nibble << 4) + lo_nibble);
82 
83  // Skip both hex digits
84  p = p.drop_front(2);
85  } else if (p.front() == '-') {
86  // Skip dashes
87  p = p.drop_front();
88  } else {
89  // UUID values can only consist of hex characters and '-' chars
90  break;
91  }
92  }
93  return p;
94 }
95 
96 bool UUID::SetFromStringRef(llvm::StringRef str) {
97  llvm::StringRef p = str;
98 
99  // Skip leading whitespace characters
100  p = p.ltrim();
101 
102  llvm::SmallVector<uint8_t, 20> bytes;
103  llvm::StringRef rest = UUID::DecodeUUIDBytesFromString(p, bytes);
104 
105  // Return false if we could not consume the entire string or if the parsed
106  // UUID is empty.
107  if (!rest.empty() || bytes.empty())
108  return false;
109 
110  *this = fromData(bytes);
111  return true;
112 }
113 
114 bool UUID::SetFromOptionalStringRef(llvm::StringRef str) {
115  bool result = SetFromStringRef(str);
116  if (result) {
117  if (llvm::all_of(m_bytes, [](uint8_t b) { return b == 0; }))
118  Clear();
119  }
120 
121  return result;
122 }
lldb_private::UUID::CvRecordPdb70::Age
llvm::support::ulittle32_t Age
Definition: UUID.h:36
lldb_private::UUID::fromData
static UUID fromData(const void *bytes, uint32_t num_bytes)
Creates a UUID from the data pointed to by the bytes argument.
Definition: UUID.h:45
lldb_private::UUID
Definition: UUID.h:23
separate
static bool separate(size_t count)
Definition: UUID.cpp:24
lldb_private::UUID::CvRecordPdb70::Data3
llvm::support::ulittle16_t Data3
Definition: UUID.h:33
lldb_private::UUID::CvRecordPdb70::Uuid
struct lldb_private::UUID::CvRecordPdb70::@43 Uuid
UUID.h
lldb_private::Stream
Definition: Stream.h:28
lldb_private::UUID::CvRecordPdb70::Data2
llvm::support::ulittle16_t Data2
Definition: UUID.h:32
lldb_private::UUID::GetAsString
std::string GetAsString(llvm::StringRef separator="-") const
Definition: UUID.cpp:48
lldb_private::UUID::CvRecordPdb70::Data1
llvm::support::ulittle32_t Data1
Definition: UUID.h:31
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:38
lldb_private::UUID::Clear
void Clear()
Definition: UUID.h:72
lldb_private::UUID::Dump
void Dump(Stream *s) const
Definition: UUID.cpp:63
lldb_private::UUID::CvRecordPdb70
Definition: UUID.h:29
lldb_private::UUID::SetFromStringRef
bool SetFromStringRef(llvm::StringRef str)
Definition: UUID.cpp:96
lldb_private::UUID::DecodeUUIDBytesFromString
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:73
xdigit_to_int
static int xdigit_to_int(char ch)
Definition: UUID.cpp:65
lldb_private::UUID::fromCvRecord
static UUID fromCvRecord(CvRecordPdb70 debug_info)
Create a UUID from CvRecordPdb70.
Definition: UUID.cpp:38
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::UUID::m_bytes
llvm::SmallVector< uint8_t, 20 > m_bytes
Definition: UUID.h:110
Stream.h
lldb_private::Stream::PutCString
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
llvm::SmallVectorImpl
Definition: Disassembler.h:42
lldb_private::UUID::fromOptionalData
static UUID fromOptionalData(const void *bytes, uint32_t num_bytes)
Creates a UUID from the data pointed to by the bytes argument.
Definition: UUID.h:57
lldb_private::UUID::SetFromOptionalStringRef
bool SetFromOptionalStringRef(llvm::StringRef str)
Definition: UUID.cpp:114
lldb_private::UUID::GetBytes
llvm::ArrayRef< uint8_t > GetBytes() const
Definition: UUID.h:76