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