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
24inline 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
38template <typename T>
39inline 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.
45template <typename T>
46static inline uint64_t MakeHandleGeneric(T handle) {
47 return reinterpret_cast<uint64_t>(handle);
48}
49
50/// Treat an integer as a handle
51template <typename T>
52static inline T& TreatIntegerAsHandle(uint64_t& handle) {
53 return reinterpret_cast<T&>(handle);
54}
55
56/// @overload
57template <typename T>
58static 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?
63static 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
68static inline uint64_t MakeHandleGeneric(uint64_t handle) { return handle; }
69
70/// Treat an integer as a handle: no-op on 32-bit systems
71template <typename T>
72static inline T& TreatIntegerAsHandle(uint64_t& handle) {
73 return handle;
74}
75
76/// @overload
77template <typename T>
78static inline T const& TreatIntegerAsHandle(uint64_t const& handle) {
79 return handle;
80}
81
82/// Does a correctly-sized integer represent a null handle?
83static 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.
90inline std::string Uint64ToHexString(uint64_t val) { return to_hex(val); }
91
92/// Turns a uint32_t into a string formatted as hex.
93inline std::string Uint32ToHexString(uint32_t val) { return to_hex(val); }
94
95/// Turns an OpenXR handle into a string formatted as hex.
96template <typename T>
97inline std::string HandleToHexString(T handle) {
98 return to_hex(handle);
99}
100
101/// Turns a pointer-sized integer into a string formatted as hex.
102inline std::string UintptrToHexString(uintptr_t val) { return to_hex(val); }
103
104/// Convert a pointer to a string formatted as hex.
105template <typename T>
106inline std::string PointerToHexString(T const* ptr) {
107 return to_hex(ptr);
108}
109