| 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 |  | 
|---|