diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Utility/UUID.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Utility/UUID.cpp | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/Utility/UUID.cpp b/contrib/llvm-project/lldb/source/Utility/UUID.cpp new file mode 100644 index 000000000000..57e3a39d1f8e --- /dev/null +++ b/contrib/llvm-project/lldb/source/Utility/UUID.cpp @@ -0,0 +1,113 @@ +//===-- UUID.cpp ----------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/UUID.h" + +#include "lldb/Utility/Stream.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Format.h" + +#include <cctype> +#include <cstdio> +#include <cstring> + +using namespace lldb_private; + +// Whether to put a separator after count uuid bytes. +// For the first 16 bytes we follow the traditional UUID format. After that, we +// simply put a dash after every 6 bytes. +static inline bool separate(size_t count) { + if (count >= 10) + return (count - 10) % 6 == 0; + + switch (count) { + case 4: + case 6: + case 8: + return true; + default: + return false; + } +} + +UUID::UUID(UUID::CvRecordPdb70 debug_info) { + llvm::sys::swapByteOrder(debug_info.Uuid.Data1); + llvm::sys::swapByteOrder(debug_info.Uuid.Data2); + llvm::sys::swapByteOrder(debug_info.Uuid.Data3); + llvm::sys::swapByteOrder(debug_info.Age); + if (debug_info.Age) + *this = UUID(&debug_info, sizeof(debug_info)); + else + *this = UUID(&debug_info.Uuid, sizeof(debug_info.Uuid)); +} + +std::string UUID::GetAsString(llvm::StringRef separator) const { + std::string result; + llvm::raw_string_ostream os(result); + + for (auto B : llvm::enumerate(GetBytes())) { + if (separate(B.index())) + os << separator; + + os << llvm::format_hex_no_prefix(B.value(), 2, true); + } + os.flush(); + + return result; +} + +void UUID::Dump(Stream &s) const { s.PutCString(GetAsString()); } + +static inline int xdigit_to_int(char ch) { + ch = tolower(ch); + if (ch >= 'a' && ch <= 'f') + return 10 + ch - 'a'; + return ch - '0'; +} + +llvm::StringRef +UUID::DecodeUUIDBytesFromString(llvm::StringRef p, + llvm::SmallVectorImpl<uint8_t> &uuid_bytes) { + uuid_bytes.clear(); + while (p.size() >= 2) { + if (isxdigit(p[0]) && isxdigit(p[1])) { + int hi_nibble = xdigit_to_int(p[0]); + int lo_nibble = xdigit_to_int(p[1]); + // Translate the two hex nibble characters into a byte + uuid_bytes.push_back((hi_nibble << 4) + lo_nibble); + + // Skip both hex digits + p = p.drop_front(2); + } else if (p.front() == '-') { + // Skip dashes + p = p.drop_front(); + } else { + // UUID values can only consist of hex characters and '-' chars + break; + } + } + return p; +} + +bool UUID::SetFromStringRef(llvm::StringRef str) { + llvm::StringRef p = str; + + // Skip leading whitespace characters + p = p.ltrim(); + + llvm::SmallVector<uint8_t, 20> bytes; + llvm::StringRef rest = UUID::DecodeUUIDBytesFromString(p, bytes); + + // Return false if we could not consume the entire string or if the parsed + // UUID is empty. + if (!rest.empty() || bytes.empty()) + return false; + + *this = UUID(bytes); + return true; +} |