The open source OpenXR runtime
at main 165 lines 3.4 kB view raw
1// Copyright 2019-2020, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Hashset struct header. 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 * @ingroup aux_util 8 */ 9 10#include "util/u_misc.h" 11#include "util/u_hashset.h" 12 13#include <cstring> 14#include <string> 15#include <unordered_map> 16#include <vector> 17 18 19/* 20 * 21 * Private structs and defines. 22 * 23 */ 24 25struct u_hashset 26{ 27 std::unordered_map<std::string, struct u_hashset_item *> map = {}; 28}; 29 30 31/* 32 * 33 * "Exported" functions. 34 * 35 */ 36 37extern "C" int 38u_hashset_create(struct u_hashset **out_hashset) 39{ 40 auto *hs = new u_hashset; 41 *out_hashset = hs; 42 return 0; 43} 44 45extern "C" int 46u_hashset_destroy(struct u_hashset **hs) 47{ 48 delete *hs; 49 *hs = NULL; 50 return 0; 51} 52 53extern "C" int 54u_hashset_find_str(struct u_hashset *hs, const char *str, size_t length, struct u_hashset_item **out_item) 55{ 56 std::string key = std::string(str, length); 57 auto search = hs->map.find(key); 58 59 if (search != hs->map.end()) { 60 *out_item = search->second; 61 return 0; 62 } 63 return -1; 64} 65 66extern "C" int 67u_hashset_find_c_str(struct u_hashset *hs, const char *c_str, struct u_hashset_item **out_item) 68{ 69 size_t length = strlen(c_str); 70 return u_hashset_find_str(hs, c_str, length, out_item); 71} 72 73extern "C" int 74u_hashset_insert_item(struct u_hashset *hs, struct u_hashset_item *item) 75{ 76 std::string key = std::string(item->c_str(), item->length); 77 hs->map[key] = item; 78 return 0; 79} 80 81extern "C" int 82u_hashset_create_and_insert_str(struct u_hashset *hs, const char *str, size_t length, struct u_hashset_item **out_item) 83{ 84 struct u_hashset_item *unused = NULL; 85 struct u_hashset_item *item = NULL; 86 size_t size = 0; 87 int ret; 88 89 ret = u_hashset_find_str(hs, str, length, &unused); 90 if (ret >= 0) { 91 return -1; 92 } 93 94 size += sizeof(struct u_hashset_item); // Hashset item. 95 size += length; // String. 96 size += 1; // Null terminate it. 97 98 // Now allocate and setup the path. 99 item = U_CALLOC_WITH_CAST(struct u_hashset_item, size); 100 if (item == NULL) { 101 return -1; 102 } 103 104 item->length = length; 105 // Yes a const cast! D: 106 char *store = const_cast<char *>(item->c_str()); 107 for (size_t i = 0; i < length; i++) { 108 store[i] = str[i]; 109 } 110 store[length] = '\0'; 111 112 std::string key = std::string(item->c_str(), item->length); 113 hs->map[key] = item; 114 115 *out_item = item; 116 117 return 0; 118} 119 120extern "C" int 121u_hashset_create_and_insert_str_c(struct u_hashset *hs, const char *c_str, struct u_hashset_item **out_item) 122{ 123 size_t length = strlen(c_str); 124 return u_hashset_create_and_insert_str(hs, c_str, length, out_item); 125} 126 127extern "C" int 128u_hashset_erase_item(struct u_hashset *hs, struct u_hashset_item *item) 129{ 130 std::string key = std::string(item->c_str(), item->length); 131 hs->map.erase(key); 132 return 0; 133} 134 135extern "C" int 136u_hashset_erase_str(struct u_hashset *hs, const char *str, size_t length) 137{ 138 std::string key = std::string(str, length); 139 hs->map.erase(key); 140 return 0; 141} 142 143extern "C" int 144u_hashset_erase_c_str(struct u_hashset *hs, const char *c_str) 145{ 146 size_t length = strlen(c_str); 147 return u_hashset_erase_str(hs, c_str, length); 148} 149 150extern "C" void 151u_hashset_clear_and_call_for_each(struct u_hashset *hs, u_hashset_callback cb, void *priv) 152{ 153 std::vector<struct u_hashset_item *> tmp; 154 tmp.reserve(hs->map.size()); 155 156 for (auto &n : hs->map) { 157 tmp.push_back(n.second); 158 } 159 160 hs->map.clear(); 161 162 for (auto *n : tmp) { 163 cb(n, priv); 164 } 165}