Coverage Report

Created: 2026-03-31 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open62541/deps/mdnsd/libmdnsd/xht.c
Line
Count
Source
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
18.1k
{
23
  /* ELF hash uses unsigned chars and unsigned arithmetic for portability */
24
18.1k
  const unsigned char *name = (const unsigned char *)s;
25
18.1k
  unsigned long int h = 0;
26
27
3.98M
  while (*name) {   /* do some fancy bitwanking on the string */
28
3.96M
    unsigned long int g;
29
3.96M
    h = (h << 4) + (unsigned long int)(*name++);
30
3.96M
    if ((g = (h & 0xF0000000UL)) != 0)
31
3.22M
      h ^= (g >> 24);
32
3.96M
    h &= ~g;
33
34
3.96M
  }
35
36
18.1k
  return (int)h;
37
18.1k
}
38
39
40
static xhn_t *_xht_node_find(xhn_t *n, const char *key)
41
18.1k
{
42
167k
  for (; n != 0; n = n->next)
43
156k
    if (n->key != 0 && strcmp(key, n->key) == 0)
44
6.59k
      return n;
45
11.5k
  return 0;
46
18.1k
}
47
48
49
xht_t *xht_new(int prime)
50
652
{
51
652
  xht_t *xnew;
52
53
652
  xnew = (xht_t *)MDNSD_malloc(sizeof(struct xht));
54
652
  xnew->prime = prime;
55
652
  xnew->zen = (xhn_t *)MDNSD_calloc(1, (sizeof(struct xhn) * (size_t)prime));  /* array of xhn_t size of prime */
56
57
652
  return xnew;
58
652
}
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
18.1k
{
63
18.1k
  int i;
64
18.1k
  xhn_t *n;
65
66
  /* get our index for this key */
67
18.1k
  i = _xhter(key) % h->prime;
68
69
  /* check for existing key first, or find an empty one */
70
18.1k
  if ((n = _xht_node_find(&h->zen[i], key)) == 0) {
71
94.5k
    for (n = &h->zen[i]; n != 0; n = n->next) {
72
85.4k
      if (n->val == 0)
73
2.37k
        break;
74
85.4k
    }
75
11.5k
  }
76
77
  /* if none, make a new one, link into this index */
78
18.1k
  if (n == NULL) {
79
9.15k
    if (h->zen != NULL) {
80
9.15k
      n = (xhn_t *)MDNSD_malloc(sizeof(struct xhn));
81
9.15k
      n->next = NULL;
82
9.15k
      n->next = h->zen[i].next;
83
9.15k
      h->zen[i].next = n;
84
9.15k
    }
85
9.15k
  } else if (n->flag) {
86
    /* When flag is set, we manage their mem and free em first */
87
6.59k
    MDNSD_free((void *)n->key);
88
6.59k
    MDNSD_free(n->val);
89
6.59k
  }
90
91
18.1k
  if (n != NULL) {
92
18.1k
    n->flag = flag;
93
18.1k
    n->key = key;
94
18.1k
    n->val = val;
95
18.1k
  } else {
96
0
    MDNSD_free(key);
97
0
    MDNSD_free(val);
98
0
  }
99
100
18.1k
  return n;
101
18.1k
}
102
103
void xht_set(xht_t *h, char *key, void *val)
104
928
{
105
928
  if (h == 0 || key == 0)
106
3
    return;
107
925
  _xht_set(h, key, val, 0);
108
925
}
109
110
void xht_store(xht_t *h, char *key, int klen, void *val, int vlen)
111
32.0k
{
112
32.0k
  char *ckey, *cval;
113
114
32.0k
  if (h == 0 || key == 0 || klen == 0)
115
14.8k
    return;
116
117
17.1k
  ckey = (char *)MDNSD_malloc((size_t)klen + 1);
118
17.1k
  memcpy(ckey, key, (size_t)klen);
119
17.1k
  ckey[klen] = '\0';
120
17.1k
  cval = (char *)MDNSD_malloc((size_t)vlen + 1);
121
17.1k
  memcpy(cval, val, (size_t)vlen);
122
17.1k
  cval[vlen] = '\0';  /* convenience, in case it was a string too */
123
17.1k
  _xht_set(h, ckey, cval, 1);
124
17.1k
}
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
655
{
140
655
  int i;
141
655
  xhn_t *n, *f;
142
143
655
  if (h == 0)
144
3
    return;
145
146
12.3k
  for (i = 0; i < h->prime; i++) {
147
11.7k
    if ((n = (&h->zen[i])) == NULL)
148
0
      continue;
149
11.7k
    if (n->flag) {
150
1.68k
      MDNSD_free((void *)n->key);
151
1.68k
      MDNSD_free(n->val);
152
1.68k
    }
153
20.8k
    for (n = (&h->zen[i])->next; n != 0;) {
154
9.15k
      f = n->next;
155
9.15k
      if (n->flag) {
156
8.91k
        MDNSD_free((void *)n->key);
157
8.91k
        MDNSD_free(n->val);
158
8.91k
      }
159
9.15k
      MDNSD_free(n);
160
9.15k
      n = f;
161
9.15k
    }
162
11.7k
  }
163
164
652
  MDNSD_free(h->zen);
165
652
  MDNSD_free(h);
166
652
}
167
168
void xht_walk(xht_t *h, xht_walker w, void *arg)
169
1.30k
{
170
1.30k
  int i;
171
1.30k
  xhn_t *n;
172
173
1.30k
  if (h == 0 || w == 0)
174
3
    return;
175
176
24.7k
  for (i = 0; i < h->prime; i++) {
177
65.1k
    for (n = &h->zen[i]; n != 0; n = n->next) {
178
41.7k
      if (n->key != 0 && n->val != 0)
179
23.0k
        (*w)(h, n->key, n->val, arg);
180
41.7k
    }
181
23.4k
  }
182
1.30k
}