Coverage Report

Created: 2025-10-10 06:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/c-ares/src/lib/dsa/ares_htable_szvp.c
Line
Count
Source
1
/* MIT License
2
 *
3
 * Copyright (c) 2023 Brad House
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a copy
6
 * of this software and associated documentation files (the "Software"), to deal
7
 * in the Software without restriction, including without limitation the rights
8
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the Software is
10
 * furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice (including the next
13
 * paragraph) shall be included in all copies or substantial portions of the
14
 * Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
 * SOFTWARE.
23
 *
24
 * SPDX-License-Identifier: MIT
25
 */
26
#include "ares_private.h"
27
#include "ares_htable.h"
28
#include "ares_htable_szvp.h"
29
30
struct ares_htable_szvp {
31
  ares_htable_szvp_val_free_t free_val;
32
  ares_htable_t              *hash;
33
};
34
35
typedef struct {
36
  size_t              key;
37
  void               *val;
38
  ares_htable_szvp_t *parent;
39
} ares_htable_szvp_bucket_t;
40
41
void ares_htable_szvp_destroy(ares_htable_szvp_t *htable)
42
4.17k
{
43
4.17k
  if (htable == NULL) {
44
0
    return;
45
0
  }
46
47
4.17k
  ares_htable_destroy(htable->hash);
48
4.17k
  ares_free(htable);
49
4.17k
}
50
51
static unsigned int hash_func(const void *key, unsigned int seed)
52
0
{
53
0
  const size_t *arg = key;
54
0
  return ares_htable_hash_FNV1a((const unsigned char *)arg, sizeof(*arg), seed);
55
0
}
56
57
static const void *bucket_key(const void *bucket)
58
0
{
59
0
  const ares_htable_szvp_bucket_t *arg = bucket;
60
0
  return &arg->key;
61
0
}
62
63
static void bucket_free(void *bucket)
64
0
{
65
0
  ares_htable_szvp_bucket_t *arg = bucket;
66
67
0
  if (arg->parent->free_val) {
68
0
    arg->parent->free_val(arg->val);
69
0
  }
70
71
0
  ares_free(arg);
72
0
}
73
74
static ares_bool_t key_eq(const void *key1, const void *key2)
75
0
{
76
0
  const size_t *k1 = key1;
77
0
  const size_t *k2 = key2;
78
79
0
  if (*k1 == *k2) {
80
0
    return ARES_TRUE;
81
0
  }
82
83
0
  return ARES_FALSE;
84
0
}
85
86
ares_htable_szvp_t *
87
  ares_htable_szvp_create(ares_htable_szvp_val_free_t val_free)
88
4.17k
{
89
4.17k
  ares_htable_szvp_t *htable = ares_malloc(sizeof(*htable));
90
4.17k
  if (htable == NULL) {
91
0
    goto fail;
92
0
  }
93
94
4.17k
  htable->hash = ares_htable_create(hash_func, bucket_key, bucket_free, key_eq);
95
4.17k
  if (htable->hash == NULL) {
96
0
    goto fail;
97
0
  }
98
99
4.17k
  htable->free_val = val_free;
100
101
4.17k
  return htable;
102
103
0
fail:
104
0
  if (htable) {
105
0
    ares_htable_destroy(htable->hash);
106
0
    ares_free(htable);
107
0
  }
108
0
  return NULL;
109
4.17k
}
110
111
ares_bool_t ares_htable_szvp_insert(ares_htable_szvp_t *htable, size_t key,
112
                                    void *val)
113
0
{
114
0
  ares_htable_szvp_bucket_t *bucket = NULL;
115
116
0
  if (htable == NULL) {
117
0
    goto fail;
118
0
  }
119
120
0
  bucket = ares_malloc(sizeof(*bucket));
121
0
  if (bucket == NULL) {
122
0
    goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
123
0
  }
124
125
0
  bucket->parent = htable;
126
0
  bucket->key    = key;
127
0
  bucket->val    = val;
128
129
0
  if (!ares_htable_insert(htable->hash, bucket)) {
130
0
    goto fail; /* LCOV_EXCL_LINE: OutOfMemory */
131
0
  }
132
133
0
  return ARES_TRUE;
134
135
0
fail:
136
0
  if (bucket) {
137
0
    ares_free(bucket); /* LCOV_EXCL_LINE: OutOfMemory */
138
0
  }
139
0
  return ARES_FALSE;
140
0
}
141
142
ares_bool_t ares_htable_szvp_get(const ares_htable_szvp_t *htable, size_t key,
143
                                 void **val)
144
0
{
145
0
  ares_htable_szvp_bucket_t *bucket = NULL;
146
147
0
  if (val) {
148
0
    *val = NULL;
149
0
  }
150
151
0
  if (htable == NULL) {
152
0
    return ARES_FALSE;
153
0
  }
154
155
0
  bucket = ares_htable_get(htable->hash, &key);
156
0
  if (bucket == NULL) {
157
0
    return ARES_FALSE;
158
0
  }
159
160
0
  if (val) {
161
0
    *val = bucket->val;
162
0
  }
163
0
  return ARES_TRUE;
164
0
}
165
166
void *ares_htable_szvp_get_direct(const ares_htable_szvp_t *htable, size_t key)
167
0
{
168
0
  void *val = NULL;
169
0
  ares_htable_szvp_get(htable, key, &val);
170
0
  return val;
171
0
}
172
173
ares_bool_t ares_htable_szvp_remove(ares_htable_szvp_t *htable, size_t key)
174
0
{
175
0
  if (htable == NULL) {
176
0
    return ARES_FALSE;
177
0
  }
178
179
0
  return ares_htable_remove(htable->hash, &key);
180
0
}
181
182
size_t ares_htable_szvp_num_keys(const ares_htable_szvp_t *htable)
183
4.17k
{
184
4.17k
  if (htable == NULL) {
185
0
    return 0;
186
0
  }
187
4.17k
  return ares_htable_num_keys(htable->hash);
188
4.17k
}