]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Utility/UUID.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Utility / UUID.cpp
1 //===-- UUID.cpp ------------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Utility/UUID.h"
11
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/Utility/Stream.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Support/Format.h"
17
18 // C Includes
19 #include <ctype.h>
20 #include <stdio.h>
21 #include <string.h>
22
23 using namespace lldb_private;
24
25 // Whether to put a separator after count uuid bytes.
26 // For the first 16 bytes we follow the traditional UUID format. After that, we
27 // simply put a dash after every 6 bytes.
28 static inline bool separate(size_t count) {
29   if (count >= 10)
30     return (count - 10) % 6 == 0;
31
32   switch (count) {
33   case 4:
34   case 6:
35   case 8:
36     return true;
37   default:
38     return false;
39   }
40 }
41
42 std::string UUID::GetAsString(llvm::StringRef separator) const {
43   std::string result;
44   llvm::raw_string_ostream os(result);
45
46   for (auto B : llvm::enumerate(GetBytes())) {
47     if (separate(B.index()))
48       os << separator;
49
50     os << llvm::format_hex_no_prefix(B.value(), 2, true);
51   }
52   os.flush();
53
54   return result;
55 }
56
57 void UUID::Dump(Stream *s) const {
58   s->PutCString(GetAsString().c_str());
59 }
60
61 static inline int xdigit_to_int(char ch) {
62   ch = tolower(ch);
63   if (ch >= 'a' && ch <= 'f')
64     return 10 + ch - 'a';
65   return ch - '0';
66 }
67
68 llvm::StringRef
69 UUID::DecodeUUIDBytesFromString(llvm::StringRef p,
70                                 llvm::SmallVectorImpl<uint8_t> &uuid_bytes,
71                                 uint32_t num_uuid_bytes) {
72   uuid_bytes.clear();
73   while (!p.empty()) {
74     if (isxdigit(p[0]) && isxdigit(p[1])) {
75       int hi_nibble = xdigit_to_int(p[0]);
76       int lo_nibble = xdigit_to_int(p[1]);
77       // Translate the two hex nibble characters into a byte
78       uuid_bytes.push_back((hi_nibble << 4) + lo_nibble);
79
80       // Skip both hex digits
81       p = p.drop_front(2);
82
83       // Increment the byte that we are decoding within the UUID value and
84       // break out if we are done
85       if (uuid_bytes.size() == num_uuid_bytes)
86         break;
87     } else if (p.front() == '-') {
88       // Skip dashes
89       p = p.drop_front();
90     } else {
91       // UUID values can only consist of hex characters and '-' chars
92       break;
93     }
94   }
95   return p;
96 }
97
98 size_t UUID::SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes) {
99   llvm::StringRef p = str;
100
101   // Skip leading whitespace characters
102   p = p.ltrim();
103
104   llvm::SmallVector<uint8_t, 20> bytes;
105   llvm::StringRef rest =
106       UUID::DecodeUUIDBytesFromString(p, bytes, num_uuid_bytes);
107
108   // If we successfully decoded a UUID, return the amount of characters that
109   // were consumed
110   if (bytes.size() == num_uuid_bytes) {
111     *this = fromData(bytes);
112     return str.size() - rest.size();
113   }
114
115   // Else return zero to indicate we were not able to parse a UUID value
116   return 0;
117 }