1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 
8 #include "strmap.h"
9 
10 #define kmalloc git__malloc
11 #define kcalloc git__calloc
12 #define krealloc git__realloc
13 #define kreallocarray git__reallocarray
14 #define kfree git__free
15 #include "khash.h"
16 
__KHASH_TYPE(str,const char *,void *)17 __KHASH_TYPE(str, const char *, void *)
18 
19 __KHASH_IMPL(str, static kh_inline, const char *, void *, 1, kh_str_hash_func, kh_str_hash_equal)
20 
21 int git_strmap_new(git_strmap **out)
22 {
23 	*out = kh_init(str);
24 	GIT_ERROR_CHECK_ALLOC(*out);
25 
26 	return 0;
27 }
28 
git_strmap_free(git_strmap * map)29 void git_strmap_free(git_strmap *map)
30 {
31 	kh_destroy(str, map);
32 }
33 
git_strmap_clear(git_strmap * map)34 void git_strmap_clear(git_strmap *map)
35 {
36 	kh_clear(str, map);
37 }
38 
git_strmap_size(git_strmap * map)39 size_t git_strmap_size(git_strmap *map)
40 {
41 	return kh_size(map);
42 }
43 
git_strmap_get(git_strmap * map,const char * key)44 void *git_strmap_get(git_strmap *map, const char *key)
45 {
46 	size_t idx = kh_get(str, map, key);
47 	if (idx == kh_end(map) || !kh_exist(map, idx))
48 		return NULL;
49 	return kh_val(map, idx);
50 }
51 
git_strmap_set(git_strmap * map,const char * key,void * value)52 int git_strmap_set(git_strmap *map, const char *key, void *value)
53 {
54 	size_t idx;
55 	int rval;
56 
57 	idx = kh_put(str, map, key, &rval);
58 	if (rval < 0)
59 		return -1;
60 
61 	if (rval == 0)
62 		kh_key(map, idx) = key;
63 
64 	kh_val(map, idx) = value;
65 
66 	return 0;
67 }
68 
git_strmap_delete(git_strmap * map,const char * key)69 int git_strmap_delete(git_strmap *map, const char *key)
70 {
71 	khiter_t idx = kh_get(str, map, key);
72 	if (idx == kh_end(map))
73 		return GIT_ENOTFOUND;
74 	kh_del(str, map, idx);
75 	return 0;
76 }
77 
git_strmap_exists(git_strmap * map,const char * key)78 int git_strmap_exists(git_strmap *map, const char *key)
79 {
80 	return kh_get(str, map, key) != kh_end(map);
81 }
82 
git_strmap_iterate(void ** value,git_strmap * map,size_t * iter,const char ** key)83 int git_strmap_iterate(void **value, git_strmap *map, size_t *iter, const char **key)
84 {
85 	size_t i = *iter;
86 
87 	while (i < map->n_buckets && !kh_exist(map, i))
88 		i++;
89 
90 	if (i >= map->n_buckets)
91 		return GIT_ITEROVER;
92 
93 	if (key)
94 		*key = kh_key(map, i);
95 	if (value)
96 		*value = kh_val(map, i);
97 	*iter = ++i;
98 
99 	return 0;
100 }
101