Coverage Report

Created: 2025-07-23 06:46

/src/open62541/deps/mdnsd/libmdnsd/xht.c
Line
Count
Source (jump to first uncovered line)
1
#include "xht.h"
2
#include <string.h>
3
#include <stdlib.h>
4
5
typedef struct xhn {
6
  char flag;
7
  struct xhn *next;
8
  char *key;
9
  void *val;
10
} xhn_t;
11
12
struct xht {
13
  int prime;
14
  xhn_t *zen;
15
};
16
17
/* Generates a hash code for a string.
18
 * This function uses the ELF hashing algorithm as reprinted in 
19
 * Andrew Binstock, "Hashing Rehashed," Dr. Dobb's Journal, April 1996.
20
 */
21
static int _xhter(const char *s)
22
13.1k
{
23
  /* ELF hash uses unsigned chars and unsigned arithmetic for portability */
24
13.1k
  const unsigned char *name = (const unsigned char *)s;
25
13.1k
  unsigned long int h = 0;
26
27
3.81M
  while (*name) {   /* do some fancy bitwanking on the string */
28
3.80M
    unsigned long int g;
29
3.80M
    h = (h << 4) + (unsigned long int)(*name++);
30
3.80M
    if ((g = (h & 0xF0000000UL)) != 0)
31
3.11M
      h ^= (g >> 24);
32
3.80M
    h &= ~g;
33
34
3.80M
  }
35
36
13.1k
  return (int)h;
37
13.1k
}
38
39
40
static xhn_t *_xht_node_find(xhn_t *n, const char *key)
41
13.1k
{
42
108k
  for (; n != 0; n = n->next)
43
98.7k
    if (n->key != 0 && strcmp(key, n->key) == 0)
44
3.67k
      return n;
45
9.49k
  return 0;
46
13.1k
}
47
48
49
xht_t *xht_new(int prime)
50
602
{
51
602
  xht_t *xnew;
52
53
602
  xnew = (xht_t *)MDNSD_malloc(sizeof(struct xht));
54
602
  xnew->prime = prime;
55
602
  xnew->zen = (xhn_t *)MDNSD_calloc(1, (sizeof(struct xhn) * (size_t)prime));  /* array of xhn_t size of prime */
56
57
602
  return xnew;
58
602
}
59
60
/* does the set work, used by xht_set and xht_store */
61
static xhn_t *_xht_set(xht_t *h, char *key, void *val, char flag)
62
13.1k
{
63
13.1k
  int i;
64
13.1k
  xhn_t *n;
65
66
  /* get our index for this key */
67
13.1k
  i = _xhter(key) % h->prime;
68
69
  /* check for existing key first, or find an empty one */
70
13.1k
  if ((n = _xht_node_find(&h->zen[i], key)) == 0) {
71
68.8k
    for (n = &h->zen[i]; n != 0; n = n->next) {
72
61.5k
      if (n->val == 0)
73
2.17k
        break;
74
61.5k
    }
75
9.49k
  }
76
77
  /* if none, make a new one, link into this index */
78
13.1k
  if (n == NULL) {
79
7.32k
    if (h->zen != NULL) {
80
7.32k
      n = (xhn_t *)MDNSD_malloc(sizeof(struct xhn));
81
7.32k
      n->next = NULL;
82
7.32k
      n->next = h->zen[i].next;
83
7.32k
      h->zen[i].next = n;
84
7.32k
    }
85
7.32k
  } else if (n->flag) {
86
    /* When flag is set, we manage their mem and free em first */
87
3.67k
    MDNSD_free((void *)n->key);
88
3.67k
    MDNSD_free(n->val);
89
3.67k
  }
90
91
13.1k
  if (n != NULL) {
92
13.1k
    n->flag = flag;
93
13.1k
    n->key = key;
94
13.1k
    n->val = val;
95
13.1k
  } else {
96
0
    MDNSD_free(key);
97
0
    MDNSD_free(val);
98
0
  }
99
100
13.1k
  return n;
101
13.1k
}
102
103
void xht_set(xht_t *h, char *key, void *val)
104
845
{
105
845
  if (h == 0 || key == 0)
106
2
    return;
107
843
  _xht_set(h, key, val, 0);
108
843
}
109
110
void xht_store(xht_t *h, char *key, int klen, void *val, int vlen)
111
13.1k
{
112
13.1k
  char *ckey, *cval;
113
114
13.1k
  if (h == 0 || key == 0 || klen == 0)
115
794
    return;
116
117
12.3k
  ckey = (char *)MDNSD_malloc((size_t)klen + 1);
118
12.3k
  memcpy(ckey, key, (size_t)klen);
119
12.3k
  ckey[klen] = '\0';
120
12.3k
  cval = (char *)MDNSD_malloc((size_t)vlen + 1);
121
12.3k
  memcpy(cval, val, (size_t)vlen);
122
12.3k
  cval[vlen] = '\0';  /* convenience, in case it was a string too */
123
12.3k
  _xht_set(h, ckey, cval, 1);
124
12.3k
}
125
126
127
void *xht_get(xht_t *h, char *key)
128
0
{
129
0
  xhn_t *n;
130
131
0
  if (h == 0 || key == 0 || (n = _xht_node_find(&h->zen[_xhter(key) % h->prime], key)) == 0)
132
0
    return 0;
133
134
0
  return n->val;
135
0
}
136
137
138
void xht_free(xht_t *h)
139
604
{
140
604
  int i;
141
604
  xhn_t *n, *f;
142
143
604
  if (h == 0)
144
2
    return;
145
146
11.5k
  for (i = 0; i < h->prime; i++) {
147
10.9k
    if ((n = (&h->zen[i])) == NULL)
148
0
      continue;
149
10.9k
    if (n->flag) {
150
1.55k
      MDNSD_free((void *)n->key);
151
1.55k
      MDNSD_free(n->val);
152
1.55k
    }
153
18.2k
    for (n = (&h->zen[i])->next; n != 0;) {
154
7.32k
      f = n->next;
155
7.32k
      if (n->flag) {
156
7.09k
        MDNSD_free((void *)n->key);
157
7.09k
        MDNSD_free(n->val);
158
7.09k
      }
159
7.32k
      MDNSD_free(n);
160
7.32k
      n = f;
161
7.32k
    }
162
10.9k
  }
163
164
602
  MDNSD_free(h->zen);
165
602
  MDNSD_free(h);
166
602
}
167
168
void xht_walk(xht_t *h, xht_walker w, void *arg)
169
1.20k
{
170
1.20k
  int i;
171
1.20k
  xhn_t *n;
172
173
1.20k
  if (h == 0 || w == 0)
174
2
    return;
175
176
23.1k
  for (i = 0; i < h->prime; i++) {
177
58.4k
    for (n = &h->zen[i]; n != 0; n = n->next) {
178
36.5k
      if (n->key != 0 && n->val != 0)
179
18.9k
        (*w)(h, n->key, n->val, arg);
180
36.5k
    }
181
21.9k
  }
182
1.20k
}