File: UUID.cpp

package info (click to toggle)
llvm-toolchain-17 1%3A17.0.6-22
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,799,624 kB
  • sloc: cpp: 6,428,607; ansic: 1,383,196; asm: 793,408; python: 223,504; objc: 75,364; f90: 60,502; lisp: 33,869; pascal: 15,282; sh: 9,684; perl: 7,453; ml: 4,937; awk: 3,523; makefile: 2,889; javascript: 2,149; xml: 888; fortran: 619; cs: 573
file content (113 lines) | stat: -rw-r--r-- 3,025 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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;
}