1 | // Copyright (c) 2017-2023, The Khronos Group Inc. |
2 | // Copyright (c) 2017-2019 Valve Corporation |
3 | // Copyright (c) 2017-2019 LunarG, Inc. |
4 | // Copyright (c) 2019 Collabora, Ltd. |
5 | // |
6 | // SPDX-License-Identifier: Apache-2.0 OR MIT |
7 | // |
8 | // Initial Author: Ryan Pavlik <ryan.pavlik@collabora.com> |
9 | // |
10 | |
11 | /*! |
12 | * @file |
13 | * |
14 | * Some utilities, primarily for working with OpenXR handles in a generic way. |
15 | */ |
16 | |
17 | #pragma once |
18 | |
19 | #include <openxr/openxr.h> |
20 | |
21 | #include <string> |
22 | #include <stdint.h> |
23 | |
24 | inline std::string to_hex(const uint8_t* const data, size_t bytes) { |
25 | std::string out(2 + bytes * 2, '?'); |
26 | out[0] = '0'; |
27 | out[1] = 'x'; |
28 | static const char* hex = "0123456789abcdef" ; |
29 | auto ch = out.end(); |
30 | for (size_t i = 0; i < bytes; ++i) { |
31 | auto b = data[i]; |
32 | *--ch = hex[(b >> 0) & 0xf]; |
33 | *--ch = hex[(b >> 4) & 0xf]; |
34 | } |
35 | return out; |
36 | } |
37 | |
38 | template <typename T> |
39 | inline std::string to_hex(const T& data) { |
40 | return to_hex(reinterpret_cast<const uint8_t* const>(&data), sizeof(data)); |
41 | } |
42 | |
43 | #if XR_PTR_SIZE == 8 |
44 | /// Convert a handle into a same-sized integer. |
45 | template <typename T> |
46 | static inline uint64_t MakeHandleGeneric(T handle) { |
47 | return reinterpret_cast<uint64_t>(handle); |
48 | } |
49 | |
50 | /// Treat an integer as a handle |
51 | template <typename T> |
52 | static inline T& TreatIntegerAsHandle(uint64_t& handle) { |
53 | return reinterpret_cast<T&>(handle); |
54 | } |
55 | |
56 | /// @overload |
57 | template <typename T> |
58 | static inline T const& TreatIntegerAsHandle(uint64_t const& handle) { |
59 | return reinterpret_cast<T const&>(handle); |
60 | } |
61 | |
62 | /// Does a correctly-sized integer represent a null handle? |
63 | static inline bool IsIntegerNullHandle(uint64_t handle) { return XR_NULL_HANDLE == reinterpret_cast<void*>(handle); } |
64 | |
65 | #else |
66 | |
67 | /// Convert a handle into a same-sized integer: no-op on 32-bit systems |
68 | static inline uint64_t MakeHandleGeneric(uint64_t handle) { return handle; } |
69 | |
70 | /// Treat an integer as a handle: no-op on 32-bit systems |
71 | template <typename T> |
72 | static inline T& TreatIntegerAsHandle(uint64_t& handle) { |
73 | return handle; |
74 | } |
75 | |
76 | /// @overload |
77 | template <typename T> |
78 | static inline T const& TreatIntegerAsHandle(uint64_t const& handle) { |
79 | return handle; |
80 | } |
81 | |
82 | /// Does a correctly-sized integer represent a null handle? |
83 | static inline bool IsIntegerNullHandle(uint64_t handle) { return XR_NULL_HANDLE == handle; } |
84 | |
85 | #endif |
86 | |
87 | /// Turns a uint64_t into a string formatted as hex. |
88 | /// |
89 | /// The core of the HandleToHexString implementation is in here. |
90 | inline std::string Uint64ToHexString(uint64_t val) { return to_hex(val); } |
91 | |
92 | /// Turns a uint32_t into a string formatted as hex. |
93 | inline std::string Uint32ToHexString(uint32_t val) { return to_hex(val); } |
94 | |
95 | /// Turns an OpenXR handle into a string formatted as hex. |
96 | template <typename T> |
97 | inline std::string HandleToHexString(T handle) { |
98 | return to_hex(handle); |
99 | } |
100 | |
101 | /// Turns a pointer-sized integer into a string formatted as hex. |
102 | inline std::string UintptrToHexString(uintptr_t val) { return to_hex(val); } |
103 | |
104 | /// Convert a pointer to a string formatted as hex. |
105 | template <typename T> |
106 | inline std::string PointerToHexString(T const* ptr) { |
107 | return to_hex(ptr); |
108 | } |
109 | |