xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Utility/UUID.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric //===-- UUID.h --------------------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLDB_UTILITY_UUID_H
100b57cec5SDimitry Andric #define LLDB_UTILITY_UUID_H
110b57cec5SDimitry Andric 
129dba64beSDimitry Andric #include "llvm/ADT/ArrayRef.h"
139dba64beSDimitry Andric #include "llvm/ADT/StringRef.h"
14e8d8bef9SDimitry Andric #include "llvm/Support/Endian.h"
15fe6060f1SDimitry Andric #include <cstddef>
16fe6060f1SDimitry Andric #include <cstdint>
170b57cec5SDimitry Andric #include <string>
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric namespace lldb_private {
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric   class Stream;
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric class UUID {
24bdd1243dSDimitry Andric   // Represents UUID's of various sizes.  In all cases, a uuid of all zeros is
25bdd1243dSDimitry Andric   // treated as an "Invalid UUID" marker, and the UUID created from such data
26bdd1243dSDimitry Andric   // will return false for IsValid.
270b57cec5SDimitry Andric public:
280b57cec5SDimitry Andric   UUID() = default;
290b57cec5SDimitry Andric 
30bdd1243dSDimitry Andric   /// Creates a uuid from the data pointed to by the bytes argument.
UUID(llvm::ArrayRef<uint8_t> bytes)31bdd1243dSDimitry Andric   UUID(llvm::ArrayRef<uint8_t> bytes) : m_bytes(bytes.begin(), bytes.end()) {
32bdd1243dSDimitry Andric     if (llvm::all_of(m_bytes, [](uint8_t b) { return b == 0; })) {
33bdd1243dSDimitry Andric       Clear();
34bdd1243dSDimitry Andric    }
35bdd1243dSDimitry Andric   }
36bdd1243dSDimitry Andric 
37e8d8bef9SDimitry Andric   // Reference:
38e8d8bef9SDimitry Andric   // https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html
39e8d8bef9SDimitry Andric   struct CvRecordPdb70 {
40e8d8bef9SDimitry Andric     struct {
41e8d8bef9SDimitry Andric       llvm::support::ulittle32_t Data1;
42e8d8bef9SDimitry Andric       llvm::support::ulittle16_t Data2;
43e8d8bef9SDimitry Andric       llvm::support::ulittle16_t Data3;
44e8d8bef9SDimitry Andric       uint8_t Data4[8];
45e8d8bef9SDimitry Andric     } Uuid;
46e8d8bef9SDimitry Andric     llvm::support::ulittle32_t Age;
47e8d8bef9SDimitry Andric     // char PDBFileName[];
48e8d8bef9SDimitry Andric   };
49e8d8bef9SDimitry Andric 
50e8d8bef9SDimitry Andric   /// Create a UUID from CvRecordPdb70.
51bdd1243dSDimitry Andric   UUID(CvRecordPdb70 debug_info);
52e8d8bef9SDimitry Andric 
53bdd1243dSDimitry Andric   /// Creates a UUID from the data pointed to by the bytes argument.
UUID(const void * bytes,uint32_t num_bytes)54bdd1243dSDimitry Andric   UUID(const void *bytes, uint32_t num_bytes) {
55bdd1243dSDimitry Andric     if (!bytes)
56bdd1243dSDimitry Andric       return;
57bdd1243dSDimitry Andric     *this
58bdd1243dSDimitry Andric         = UUID(llvm::ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(bytes),
59bdd1243dSDimitry Andric                num_bytes));
600b57cec5SDimitry Andric   }
610b57cec5SDimitry Andric 
Clear()620b57cec5SDimitry Andric   void Clear() { m_bytes.clear(); }
630b57cec5SDimitry Andric 
64*06c3fb27SDimitry Andric   void Dump(Stream &s) const;
650b57cec5SDimitry Andric 
GetBytes()660b57cec5SDimitry Andric   llvm::ArrayRef<uint8_t> GetBytes() const { return m_bytes; }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   explicit operator bool() const { return IsValid(); }
IsValid()690b57cec5SDimitry Andric   bool IsValid() const { return !m_bytes.empty(); }
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   std::string GetAsString(llvm::StringRef separator = "-") const;
720b57cec5SDimitry Andric 
735ffd83dbSDimitry Andric   bool SetFromStringRef(llvm::StringRef str);
740b57cec5SDimitry Andric 
755ffd83dbSDimitry Andric   /// Decode as many UUID bytes as possible from the C string \a cstr.
760b57cec5SDimitry Andric   ///
779dba64beSDimitry Andric   /// \param[in] str
789dba64beSDimitry Andric   ///     An llvm::StringRef that points at a UUID string value (no leading
799dba64beSDimitry Andric   ///     spaces). The string must contain only hex characters and optionally
809dba64beSDimitry Andric   ///     can contain the '-' sepearators.
810b57cec5SDimitry Andric   ///
820b57cec5SDimitry Andric   /// \param[in] uuid_bytes
839dba64beSDimitry Andric   ///     A buffer of bytes that will contain a full or partially decoded UUID.
840b57cec5SDimitry Andric   ///
850b57cec5SDimitry Andric   /// \return
860b57cec5SDimitry Andric   ///     The original string, with all decoded bytes removed.
870b57cec5SDimitry Andric   static llvm::StringRef
880b57cec5SDimitry Andric   DecodeUUIDBytesFromString(llvm::StringRef str,
895ffd83dbSDimitry Andric                             llvm::SmallVectorImpl<uint8_t> &uuid_bytes);
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric private:
920b57cec5SDimitry Andric   // GNU ld generates 20-byte build-ids. Size chosen to avoid heap allocations
930b57cec5SDimitry Andric   // for this case.
940b57cec5SDimitry Andric   llvm::SmallVector<uint8_t, 20> m_bytes;
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   friend bool operator==(const UUID &LHS, const UUID &RHS) {
970b57cec5SDimitry Andric     return LHS.m_bytes == RHS.m_bytes;
980b57cec5SDimitry Andric   }
990b57cec5SDimitry Andric   friend bool operator!=(const UUID &LHS, const UUID &RHS) {
1000b57cec5SDimitry Andric     return !(LHS == RHS);
1010b57cec5SDimitry Andric   }
1020b57cec5SDimitry Andric   friend bool operator<(const UUID &LHS, const UUID &RHS) {
1030b57cec5SDimitry Andric     return LHS.m_bytes < RHS.m_bytes;
1040b57cec5SDimitry Andric   }
1050b57cec5SDimitry Andric   friend bool operator<=(const UUID &LHS, const UUID &RHS) {
1060b57cec5SDimitry Andric     return !(RHS < LHS);
1070b57cec5SDimitry Andric   }
1080b57cec5SDimitry Andric   friend bool operator>(const UUID &LHS, const UUID &RHS) { return RHS < LHS; }
1090b57cec5SDimitry Andric   friend bool operator>=(const UUID &LHS, const UUID &RHS) {
1100b57cec5SDimitry Andric     return !(LHS < RHS);
1110b57cec5SDimitry Andric   }
1120b57cec5SDimitry Andric };
1130b57cec5SDimitry Andric } // namespace lldb_private
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric #endif // LLDB_UTILITY_UUID_H
116